Exemple #1
0
// ReadTable loads path from datafile in table format
//  Note: n -- number of lines to read. use -1 to read all lines
func (o *Path) ReadTable(ndim, nincs, niout int, fname string, n int, mσ, mε float64, stresspath bool) (err error) {

	// constants
	o.Nincs, o.Niout = nincs, niout

	// read data table
	keys, d, err := io.ReadTable(fname)
	if err != nil {
		return
	}
	if n < 0 {
		n = len(d[keys[0]])
	}

	// find x-y-z keys
	ex, ey, ez := "ex", "ey", "ez"
	sx, sy, sz := "sx", "sy", "sz"
	for _, key := range keys {
		switch key {
		case "Ex":
			ex, ey, ez = "Ex", "Ey", "Ez"
		case "Ea":
			ex, ey, ez = "Et", "Er", "Ea"
		case "ea":
			ex, ey, ez = "et", "er", "ea"
		case "Sx":
			sx, sy, sz = "Sx", "Sy", "Sz"
		case "Sa":
			sx, sy, sz = "St", "Sr", "Sa"
		case "sa":
			sx, sy, sz = "st", "sr", "sa"
		}
	}

	// set stress path
	if stresspath {
		o.Sx, o.Sy, o.Sz = make([]float64, n), make([]float64, n), make([]float64, n)
		for i := 0; i < n; i++ {
			o.Sx[i], o.Sy[i], o.Sz[i] = mσ*d[sx][i], mσ*d[sy][i], mσ*d[sz][i]
		}
		o.UseS = utl.IntVals(n, 1)

		// set strain path
	} else {
		o.Ex, o.Ey, o.Ez = make([]float64, n), make([]float64, n), make([]float64, n)
		for i := 0; i < n; i++ {
			o.Ex[i], o.Ey[i], o.Ez[i] = mε*d[ex][i], mε*d[ey][i], mε*d[ez][i]
		}
		o.Sx, o.Sy, o.Sz = []float64{mσ * d[sx][0]}, []float64{mσ * d[sy][0]}, []float64{mσ * d[sz][0]}
		o.UseE = utl.IntVals(n, 1)
	}

	// set additional information
	return o.Init(ndim)
}
Exemple #2
0
// contact_init initialises variables need by contact model
func (o *ElemU) contact_init(edat *inp.ElemData) {

	// vertices on faces with contact
	var contactverts []int
	if len(o.Cell.FaceBcs) > 0 {
		lverts := o.Cell.FaceBcs.GetVerts("contact")
		for _, m := range lverts {
			contactverts = append(contactverts, m)
		}
	}
	o.Nq = len(contactverts)

	// contact flag
	o.HasContact = o.Nq > 0
	if !o.HasContact {
		return
	}

	// vertices on contact face; numbering
	o.ContactId2vid = contactverts
	o.Vid2contactId = utl.IntVals(o.Nu, -1)
	o.Qmap = make([]int, o.Nq)
	for μ, m := range o.ContactId2vid {
		o.Vid2contactId[m] = μ
	}

	// flags
	o.Macaulay, o.βrmp, o.κ = GetContactFaceFlags(edat.Extra)

	// allocate coupling matrices
	o.Kuq = la.MatAlloc(o.Nu, o.Nq)
	o.Kqu = la.MatAlloc(o.Nq, o.Nu)
	o.Kqq = la.MatAlloc(o.Nq, o.Nq)
}
Exemple #3
0
// register element
func init() {

	// information allocator
	infogetters["p"] = func(cellType string, faceConds []*FaceCond) *Info {

		// new info
		var info Info

		// number of nodes in element
		nverts := shp.GetNverts(cellType)

		// solution variables
		ykeys := []string{"pl"}
		info.Dofs = make([][]string, nverts)
		for m := 0; m < nverts; m++ {
			info.Dofs[m] = ykeys
		}

		// maps
		info.Y2F = map[string]string{"pl": "ql"}

		// vertices on seepage faces
		lverts := GetVertsWithCond(faceConds, "seep")
		for _, m := range lverts {
			if m < nverts { // avoid adding vertices of superelement (e.g. qua8 vertices in this qua4 cell)
				info.Dofs[m] = append(info.Dofs[m], "fl")
			}
		}
		if len(lverts) > 0 {
			ykeys = append(ykeys, "fl")
			info.Y2F["fl"] = "nil"
		}

		// t1 and t2 variables
		info.T1vars = ykeys
		return &info
	}

	// element allocator
	eallocators["p"] = func(cellType string, faceConds []*FaceCond, cid int, edat *inp.ElemData, x [][]float64) Elem {

		// basic data
		var o ElemP
		o.Cid = cid
		o.X = x
		o.Shp = shp.Get(cellType)
		o.Np = o.Shp.Nverts

		// integration points
		o.IpsElem, o.IpsFace = GetIntegrationPoints(edat.Nip, edat.Nipf, cellType)
		if o.IpsElem == nil || o.IpsFace == nil {
			return nil
		}
		nip := len(o.IpsElem)

		// models
		o.Mdl = GetAndInitPorousModel(edat.Mat)
		if o.Mdl == nil {
			return nil
		}

		// local starred variables
		o.ψl = make([]float64, nip)

		// scratchpad. computed @ each ip
		ndim := Global.Ndim
		o.g = make([]float64, ndim)
		o.gpl = make([]float64, ndim)
		o.ρwl = make([]float64, ndim)
		o.tmp = make([]float64, ndim)
		o.Kpp = la.MatAlloc(o.Np, o.Np)
		o.res = new(mporous.LsVars)

		// vertices on seepage faces
		var seepverts []int
		lverts := GetVertsWithCond(faceConds, "seep")
		for _, m := range lverts {
			if m < o.Np { // avoid adding vertices of superelement (e.g. qua8 vertices in this qua4 cell)
				seepverts = append(seepverts, m)
			}
		}

		o.Nf = len(seepverts)
		o.HasSeep = o.Nf > 0
		if o.HasSeep {

			// vertices on seepage face; numbering
			o.SeepId2vid = seepverts
			o.Vid2seepId = utl.IntVals(o.Np, -1)
			o.Fmap = make([]int, o.Nf)
			for μ, m := range o.SeepId2vid {
				o.Vid2seepId[m] = μ
			}

			// flags
			o.Macaulay, o.βrmp, o.κ = GetSeepFaceFlags(edat.Extra)

			// allocate coupling matrices
			o.Kpf = la.MatAlloc(o.Np, o.Nf)
			o.Kfp = la.MatAlloc(o.Nf, o.Np)
			o.Kff = la.MatAlloc(o.Nf, o.Nf)
		}

		// set natural boundary conditions
		for idx, fc := range faceConds {
			o.NatBcs = append(o.NatBcs, &NaturalBc{fc.Cond, fc.FaceId, fc.Func, fc.Extra})

			// allocate extrapolation structures
			if fc.Cond == "ql" || fc.Cond == "seep" {
				nv := o.Shp.Nverts
				nip := len(o.IpsElem)
				o.ρl_ex = make([]float64, nv)
				o.dρldpl_ex = la.MatAlloc(nv, nv)
				o.Emat = la.MatAlloc(nv, nip)
				o.DoExtrap = true
				if LogErr(o.Shp.Extrapolator(o.Emat, o.IpsElem), "element allocation") {
					return nil
				}
			}

			// additional seepage condition structures: hydrostatic flags
			if fc.Cond == "seep" {
				if len(o.Hst) == 0 {
					o.Hst = make([]bool, len(faceConds))
				}
				if s_val, found := io.Keycode(fc.Extra, "plmax"); found {
					o.Hst[idx] = (s_val == "hst")
				}
			}
		}

		// return new element
		return &o
	}
}
Exemple #4
0
// Init initialises states variables after {Sx, Sy, Sz} or {Ex, Ey, Ez} have been set
func (o *Path) Init(ndim int) (err error) {

	// constants
	o.ndim = ndim
	o.ncp = 2 * ndim

	// size of slices and flags
	hasS, hasE := false, false
	allS, allE := true, true
	nSx, nSy, nSz := len(o.Sx), len(o.Sy), len(o.Sz)
	nEx, nEy, nEz := len(o.Ex), len(o.Ey), len(o.Ez)
	if nSx > 0 {
		hasS, allE = true, false
	}
	if nSy > 0 {
		hasS, allE = true, false
	}
	if nSz > 0 {
		hasS, allE = true, false
	}
	if nEx > 0 {
		hasE, allS = true, false
	}
	if nEy > 0 {
		hasE, allS = true, false
	}
	if nEz > 0 {
		hasE, allS = true, false
	}

	// check nS
	if nSx != nSy || nSx != nSz {
		return chk.Err(_path_err02, nSx, nSy, nSz)
	}

	// check for initial stresses
	if nSx < 1 || nSy < 1 || nSz < 1 {
		return chk.Err(_path_err03)
	}

	// unset hasS if only initial stress were given
	if nSx == 1 {
		hasS, allE = false, true
		if !hasE {
			return chk.Err(_path_err04)
		}
	}

	// other checks
	o.size = 0 // number of path components
	if hasS {
		o.size = nSx
	}
	if hasE {
		if nEx != nEy || nEx != nEz {
			return chk.Err(_path_err05, nEx, nEy, nEz)
		}
		o.size = nEx
	}
	if hasS && hasE {
		if nEx != nSx || nEy != nSx || nEz != nSx {
			return chk.Err(_path_err06)
		}
	}
	if !allS && !allE {
		if len(o.UseS) != nSx || len(o.UseE) != nSx {
			return chk.Err(_path_err07, len(o.UseS), len(o.UseE), nSx)
		}
	}

	// check size and Nincs
	if o.size < 2 {
		return chk.Err(_path_err08)
	}
	if o.Nincs < 1 {
		o.Nincs = 1
	}

	// multipliers
	if o.MultS < 1e-7 {
		o.MultS = 1
	}
	if o.MultE < 1e-7 {
		o.MultE = 1
	}

	// set use flags
	if allS {
		o.UseS = utl.IntVals(o.size, 1)
		o.UseE = make([]int, o.size)
	}
	if allE {
		o.UseE = utl.IntVals(o.size, 1)
		o.UseS = make([]int, o.size)
	}
	return
}
Exemple #5
0
// register element
func init() {

	// information allocator
	infogetters["p"] = func(sim *inp.Simulation, cell *inp.Cell, edat *inp.ElemData) *Info {

		// new info
		var info Info

		// number of nodes in element
		nverts := cell.GetNverts(edat.Lbb)

		// solution variables
		ykeys := []string{"pl"}
		info.Dofs = make([][]string, nverts)
		for m := 0; m < nverts; m++ {
			info.Dofs[m] = ykeys
		}

		// maps
		info.Y2F = map[string]string{"pl": "ql"}

		// vertices on seepage faces
		if len(cell.FaceBcs) > 0 {
			lverts := cell.FaceBcs.GetVerts("seep")
			for _, m := range lverts {
				if m < nverts { // avoid adding vertices of superelement (e.g. qua8 vertices in this qua4 cell)
					info.Dofs[m] = append(info.Dofs[m], "fl")
				}
			}
			if len(lverts) > 0 {
				ykeys = append(ykeys, "fl")
				info.Y2F["fl"] = "nil"
			}
		}

		// t1 and t2 variables
		info.T1vars = ykeys
		return &info
	}

	// element allocator
	eallocators["p"] = func(sim *inp.Simulation, cell *inp.Cell, edat *inp.ElemData, x [][]float64) Elem {

		// basic data
		var o ElemP
		o.Cell = cell
		o.X = x
		o.Np = o.Cell.Shp.Nverts
		o.Ndim = sim.Ndim

		// integration points
		var err error
		o.IpsElem, o.IpsFace, err = o.Cell.Shp.GetIps(edat.Nip, edat.Nipf)
		if err != nil {
			chk.Panic("cannot allocate integration points of p-element with nip=%d and nipf=%d:\n%v", edat.Nip, edat.Nipf, err)
		}
		nip := len(o.IpsElem)

		// models
		o.Mdl, err = GetAndInitPorousModel(sim.MatParams, edat.Mat, sim.Key)
		if err != nil {
			chk.Panic("cannot get model for p-element {tag=%d id=%d material=%q}:\n%v", cell.Tag, cell.Id, edat.Mat, err)
		}

		// local starred variables
		o.ψl = make([]float64, nip)

		// scratchpad. computed @ each ip
		o.g = make([]float64, o.Ndim)
		o.gpl = make([]float64, o.Ndim)
		o.ρwl = make([]float64, o.Ndim)
		o.tmp = make([]float64, o.Ndim)
		o.Kpp = la.MatAlloc(o.Np, o.Np)
		o.res = new(mporous.LsVars)

		// vertices on seepage faces
		var seepverts []int
		if len(cell.FaceBcs) > 0 {
			lverts := cell.FaceBcs.GetVerts("seep")
			for _, m := range lverts {
				if m < o.Np { // avoid adding vertices of superelement (e.g. qua8 vertices in this qua4 cell)
					seepverts = append(seepverts, m)
				}
			}
		}

		o.Nf = len(seepverts)
		o.HasSeep = o.Nf > 0
		if o.HasSeep {

			// vertices on seepage face; numbering
			o.SeepId2vid = seepverts
			o.Vid2seepId = utl.IntVals(o.Np, -1)
			o.Fmap = make([]int, o.Nf)
			for μ, m := range o.SeepId2vid {
				o.Vid2seepId[m] = μ
			}

			// flags
			o.Macaulay, o.βrmp, o.κ = GetSeepFaceFlags(edat.Extra)

			// allocate coupling matrices
			o.Kpf = la.MatAlloc(o.Np, o.Nf)
			o.Kfp = la.MatAlloc(o.Nf, o.Np)
			o.Kff = la.MatAlloc(o.Nf, o.Nf)
		}

		// set natural boundary conditions
		for idx, fc := range cell.FaceBcs {
			o.NatBcs = append(o.NatBcs, &NaturalBc{fc.Cond, fc.FaceId, fc.Func, fc.Extra})

			// allocate extrapolation structures
			if fc.Cond == "ql" || fc.Cond == "seep" {
				nv := o.Cell.Shp.Nverts
				nip := len(o.IpsElem)
				o.ρl_ex = make([]float64, nv)
				o.dρldpl_ex = la.MatAlloc(nv, nv)
				o.Emat = la.MatAlloc(nv, nip)
				o.DoExtrap = true
				err = o.Cell.Shp.Extrapolator(o.Emat, o.IpsElem)
				if err != nil {
					chk.Panic("cannot build extrapolator matrix for p-element:\n%v", err)
				}
			}

			// additional seepage condition structures: hydrostatic flags
			if fc.Cond == "seep" {
				if len(o.Hst) == 0 {
					o.Hst = make([]bool, len(cell.FaceBcs))
				}
				if s_val, found := io.Keycode(fc.Extra, "plmax"); found {
					o.Hst[idx] = (s_val == "hst")
				}
			}
		}

		// return new element
		return &o
	}
}