func get_cell_info(ctype string, lbb bool) (ctypeNew string, nverts int) { ctypeNew = ctype if ctypeNew == "qua9" { ctypeNew = "qua8" } if lbb { ctypeNew = shp.GetBasicType(ctypeNew) } nverts = shp.GetNverts(ctypeNew) return }
// register element func init() { // information allocator infogetters["phi"] = func(cellType string, faceConds []*FaceCond) *Info { // new info var info Info nverts := shp.GetNverts(cellType) ykeys := []string{"h"} info.Dofs = make([][]string, nverts) for m := 0; m < nverts; m++ { info.Dofs[m] = ykeys } info.T1vars = ykeys // return information return &info } // element allocator eallocators["phi"] = func(cellType string, faceConds []*FaceCond, cid int, edat *inp.ElemData, x [][]float64) Elem { // basic data var o ElemPhi o.Cid = cid o.X = x o.Shp = shp.Get(cellType) // cellType: e.g. "tri6", "qua8" o.Nu = o.Shp.Nverts // integration points o.IpsElem, _ = GetIntegrationPoints(edat.Nip, edat.Nipf, cellType) if o.IpsElem == nil { return nil // => failed } // local starred variables nip := len(o.IpsElem) o.ψs = make([]float64, nip) // scratchpad. computed @ each ip o.K = la.MatAlloc(o.Nu, o.Nu) // return new element return &o } }
// register element func init() { // information allocator infogetters["u"] = func(cellType string, faceConds []*FaceCond) *Info { // new info var info Info // number of nodes in element nverts := shp.GetNverts(cellType) // solution variables ykeys := []string{"ux", "uy"} if Global.Ndim == 3 { ykeys = []string{"ux", "uy", "uz"} } info.Dofs = make([][]string, nverts) for m := 0; m < nverts; m++ { info.Dofs[m] = ykeys } // maps info.Y2F = map[string]string{"ux": "fx", "uy": "fy", "uz": "fz"} // t1 and t2 variables info.T2vars = ykeys return &info } // element allocator eallocators["u"] = func(cellType string, faceConds []*FaceCond, cid int, edat *inp.ElemData, x [][]float64) Elem { // basic data var o ElemU o.Cid = cid o.X = x o.Shp = shp.Get(cellType) ndim := Global.Ndim o.Nu = ndim * o.Shp.Nverts // parse flags o.UseB, o.Debug, o.Thickness = GetSolidFlags(edat.Extra) // 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) // model var prms fun.Prms o.Model, prms = GetAndInitSolidModel(edat.Mat, ndim) if o.Model == nil { return nil } // model specialisations switch m := o.Model.(type) { case msolid.Small: o.MdlSmall = m case msolid.Large: o.MdlLarge = m default: chk.Panic("__internal_error__: 'u' element cannot determine the type of the material model") } // parameters for _, p := range prms { switch p.N { case "rho": o.Rho = p.V case "Cdam": o.Cdam = p.V } } // local starred variables o.ζs = la.MatAlloc(nip, ndim) o.χs = la.MatAlloc(nip, ndim) o.divχs = make([]float64, nip) // scratchpad. computed @ each ip nsig := 2 * ndim o.grav = make([]float64, ndim) o.us = make([]float64, ndim) o.fi = make([]float64, o.Nu) o.D = la.MatAlloc(nsig, nsig) o.K = la.MatAlloc(o.Nu, o.Nu) if o.UseB { o.B = la.MatAlloc(nsig, o.Nu) } // strains o.ε = make([]float64, nsig) o.Δε = make([]float64, nsig) // variables for debugging if o.Debug { o.fex = make([]float64, o.Shp.Nverts) o.fey = make([]float64, o.Shp.Nverts) if ndim == 3 { o.fez = make([]float64, o.Shp.Nverts) } } // surface loads (natural boundary conditions) for _, fc := range faceConds { o.NatBcs = append(o.NatBcs, &NaturalBc{fc.Cond, fc.FaceId, fc.Func, fc.Extra}) } // return new element return &o } }
// register element func init() { // information allocator infogetters["up"] = func(cellType string, faceConds []*FaceCond) *Info { // new info var info Info // p-element cell type p_cellType := cellType lbb := !Global.Sim.Data.NoLBB if lbb { p_cellType = shp.GetBasicType(cellType) } // underlying cells info u_info := infogetters["u"](cellType, faceConds) p_info := infogetters["p"](p_cellType, faceConds) // solution variables nverts := shp.GetNverts(cellType) info.Dofs = make([][]string, nverts) for i, dofs := range u_info.Dofs { info.Dofs[i] = append(info.Dofs[i], dofs...) } for i, dofs := range p_info.Dofs { info.Dofs[i] = append(info.Dofs[i], dofs...) } // maps info.Y2F = u_info.Y2F for key, val := range p_info.Y2F { info.Y2F[key] = val } // t1 and t2 variables info.T1vars = p_info.T1vars info.T2vars = u_info.T2vars return &info } // element allocator eallocators["up"] = func(cellType string, faceConds []*FaceCond, cid int, edat *inp.ElemData, x [][]float64) Elem { // basic data var o ElemUP o.Fconds = faceConds // p-element cell type p_cellType := cellType lbb := !Global.Sim.Data.NoLBB if lbb { p_cellType = shp.GetBasicType(cellType) } // cell types o.CtypeU = cellType o.CtypeP = p_cellType // allocate u element u_allocator := eallocators["u"] u_elem := u_allocator(cellType, faceConds, cid, edat, x) if LogErrCond(u_elem == nil, "cannot allocate underlying u-element") { return nil } o.U = u_elem.(*ElemU) // make sure p-element uses the same nubmer of integration points than u-element edat.Nip = len(o.U.IpsElem) //edat.Nipf = len(o.U.IpsFace) // TODO: check if this is necessary // allocate p-element p_allocator := eallocators["p"] p_elem := p_allocator(p_cellType, faceConds, cid, edat, x) if LogErrCond(p_elem == nil, "cannot allocate underlying p-element") { return nil } o.P = p_elem.(*ElemP) // scratchpad. computed @ each ip ndim := Global.Ndim o.bs = make([]float64, ndim) o.hl = make([]float64, ndim) o.Kup = la.MatAlloc(o.U.Nu, o.P.Np) o.Kpu = la.MatAlloc(o.P.Np, o.U.Nu) // seepage terms if o.P.DoExtrap { p_nverts := o.P.Shp.Nverts u_nverts := o.U.Shp.Nverts o.dρldus_ex = la.MatAlloc(p_nverts, u_nverts*ndim) } // return new element return &o } }
// register element func init() { // information allocator infogetters["rod"] = func(cellType string, faceConds []*FaceCond) *Info { // new info var info Info // number of nodes in element nverts := shp.GetNverts(cellType) // solution variables ykeys := []string{"ux", "uy"} if Global.Ndim == 3 { ykeys = []string{"ux", "uy", "uz"} } info.Dofs = make([][]string, nverts) for m := 0; m < nverts; m++ { info.Dofs[m] = ykeys } // maps info.Y2F = map[string]string{"ux": "fx", "uy": "fy", "uz": "fz"} // t1 and t2 variables info.T2vars = ykeys return &info } // element allocator eallocators["rod"] = func(cellType string, faceConds []*FaceCond, cid int, edat *inp.ElemData, x [][]float64) Elem { // basic data var o Rod o.Cid = cid o.X = x o.Shp = shp.Get(cellType) ndim := Global.Ndim o.Nu = ndim * o.Shp.Nverts var err error // material model name matname := edat.Mat matdata := Global.Sim.Mdb.Get(matname) if LogErrCond(matdata == nil, "materials database failed on getting %q material\n", matname) { return nil } mdlname := matdata.Model o.Model = msolid.GetOnedSolid(Global.Sim.Data.FnameKey, matname, mdlname, false) if LogErrCond(o.Model == nil, "cannot find model named %s\n", mdlname) { return nil } err = o.Model.Init(ndim, matdata.Prms) if LogErr(err, "Model.Init failed") { return nil } // parameters for _, p := range matdata.Prms { switch p.N { case "A": o.A = p.V case "rho": o.Rho = p.V } } // integration points var nip int if s_nip, found := io.Keycode(edat.Extra, "nip"); found { nip = io.Atoi(s_nip) } o.IpsElem, err = shp.GetIps(o.Shp.Type, nip) if LogErr(err, "GetIps failed") { return nil } nip = len(o.IpsElem) // scratchpad. computed @ each ip o.K = la.MatAlloc(o.Nu, o.Nu) o.M = la.MatAlloc(o.Nu, o.Nu) o.ue = make([]float64, o.Nu) o.Rus = make([]float64, o.Nu) // scratchpad. computed @ each ip o.grav = make([]float64, ndim) o.us = make([]float64, ndim) o.fi = make([]float64, o.Nu) // return new element return &o } }
// 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 } }