// Init initialises model func (o *Ogden) Init(ndim int, pstress bool, prms fun.Prms) (err error) { // basic data o.Nsig = 2 * ndim // parameters for _, p := range prms { if p.N == "K" { o.K = p.V } if p.N[:3] == "alp" { o.Alp = append(o.Alp, p.V) } if p.N[:3] == "mu" { o.Mu = append(o.Mu, p.V) } } if len(o.Alp) != len(o.Mu) { return chk.Err("number of alp must be equal to number of mu. %d != %d\n", len(o.Alp), len(o.Mu)) } // auxiliary o.Fi = tsr.Alloc2() o.b = tsr.Alloc2() o.bm = make([]float64, o.Nsig) o.λ = make([]float64, 3) o.P = tsr.M_AllocEigenprojs(o.Nsig) o.τ = make([]float64, 3) return }
// Connect connects rod/solid elements in this Rjoint func (o *Rjoint) Connect(cid2elem []Elem, c *inp.Cell) (nnzK int, err error) { // get rod and solid elements rodId := c.JlinId sldId := c.JsldId o.Rod = cid2elem[rodId].(*Rod) o.Sld = cid2elem[sldId].(*ElemU) if o.Rod == nil { err = chk.Err("cannot find joint's rod cell with id == %d", rodId) return } if o.Sld == nil { err = chk.Err("cannot find joint's solid cell with id == %d", sldId) return } // total number of dofs o.Ny = o.Rod.Nu + o.Sld.Nu // material model name matdata := o.Sim.MatParams.Get(o.Edat.Mat) if matdata == nil { err = chk.Err("materials database failed on getting %q material\n", o.Edat.Mat) return } // initialise model err = o.Mdl.Init(matdata.Prms) if err != nil { err = chk.Err("model initialisation failed:\n%v", err) return } // parameters for _, p := range matdata.Prms { switch p.N { case "h": o.h = p.V case "k1": o.k1 = p.V case "k2": o.k2 = p.V case "mu": if p.V > 0.0 { o.Coulomb = true } } } // auxiliary nsig := 2 * o.Ndim // rod data rodH := o.Rod.Cell.Shp rodNp := len(o.Rod.IpsElem) rodNn := rodH.Nverts rodNu := o.Rod.Nu // solid data sldH := o.Sld.Cell.Shp sldS := sldH.S sldNp := len(o.Sld.IpsElem) sldNn := sldH.Nverts sldNu := o.Sld.Nu // shape functions of solid @ nodes of rod o.Nmat = la.MatAlloc(sldNn, rodNn) rodYn := make([]float64, o.Ndim) rodRn := make([]float64, 3) for m := 0; m < rodNn; m++ { for i := 0; i < o.Ndim; i++ { rodYn[i] = o.Rod.X[i][m] } err = sldH.InvMap(rodRn, rodYn, o.Sld.X) if err != nil { return } err = sldH.CalcAtR(o.Sld.X, rodRn, false) if err != nil { return } for n := 0; n < sldNn; n++ { o.Nmat[n][m] = sldH.S[n] } } // coulomb model => σc depends on p values of solid if o.Coulomb { // allocate variables o.Pmat = la.MatAlloc(sldNn, rodNp) o.Emat = la.MatAlloc(sldNn, sldNp) o.rodRp = la.MatAlloc(rodNp, 3) o.σNo = la.MatAlloc(sldNn, nsig) o.σIp = make([]float64, nsig) o.t1 = make([]float64, o.Ndim) o.t2 = make([]float64, o.Ndim) // extrapolator matrix err = sldH.Extrapolator(o.Emat, o.Sld.IpsElem) if err != nil { return } // shape function of solid @ ips of rod for idx, ip := range o.Rod.IpsElem { rodYp := rodH.IpRealCoords(o.Rod.X, ip) err = sldH.InvMap(o.rodRp[idx], rodYp, o.Sld.X) if err != nil { return } err = sldH.CalcAtR(o.Sld.X, o.rodRp[idx], false) if err != nil { return } for n := 0; n < sldNn; n++ { o.Pmat[n][idx] = sldS[n] } } } // joint direction @ ip[idx]; corotational system aligned with rod element o.e0 = la.MatAlloc(rodNp, o.Ndim) o.e1 = la.MatAlloc(rodNp, o.Ndim) o.e2 = la.MatAlloc(rodNp, o.Ndim) π := make([]float64, o.Ndim) // Eq. (27) Q := la.MatAlloc(o.Ndim, o.Ndim) α := 666.0 Jvec := rodH.Jvec3d[:o.Ndim] for idx, ip := range o.Rod.IpsElem { // auxiliary e0, e1, e2 := o.e0[idx], o.e1[idx], o.e2[idx] // interpolation functions and gradients err = rodH.CalcAtIp(o.Rod.X, ip, true) if err != nil { return } // compute basis vectors J := rodH.J π[0] = Jvec[0] + α π[1] = Jvec[1] e0[0] = Jvec[0] / J e0[1] = Jvec[1] / J if o.Ndim == 3 { π[2] = Jvec[2] e0[2] = Jvec[2] / J } la.MatSetDiag(Q, 1) la.VecOuterAdd(Q, -1, e0, e0) // Q := I - e0 dyad e0 la.MatVecMul(e1, 1, Q, π) // Eq. (29) * norm(E1) la.VecScale(e1, 0, 1.0/la.VecNorm(e1), e1) if o.Ndim == 3 { e2[0] = e0[1]*e1[2] - e0[2]*e1[1] e2[1] = e0[2]*e1[0] - e0[0]*e1[2] e2[2] = e0[0]*e1[1] - e0[1]*e1[0] } // compute auxiliary tensors if o.Coulomb { e1_dy_e1 := tsr.Alloc2() e2_dy_e2 := tsr.Alloc2() for i := 0; i < o.Ndim; i++ { for j := 0; j < o.Ndim; j++ { e1_dy_e1[i][j] = e1[i] * e1[j] e2_dy_e2[i][j] = e2[i] * e2[j] } } } } // auxiliary variables o.ΔuC = la.MatAlloc(rodNn, o.Ndim) o.Δw = make([]float64, o.Ndim) o.qb = make([]float64, o.Ndim) o.fC = make([]float64, rodNu) // temporary Jacobian matrices. see Eq. (57) o.Krr = la.MatAlloc(rodNu, rodNu) o.Krs = la.MatAlloc(rodNu, sldNu) o.Ksr = la.MatAlloc(sldNu, rodNu) o.Kss = la.MatAlloc(sldNu, sldNu) // debugging //if true { if false { o.debug_print_init() } // success return o.Ny * o.Ny, nil }