// spectral_decomp computes the spectral decomposition of b := F*tr(F) tensor func (o *Ogden) b_and_spectral_decomp(F [][]float64) (err error) { // determinant of F o.J, err = tsr.Inv(o.Fi, F) if err != nil { return } // left Cauchy-Green tensor tsr.LeftCauchyGreenDef(o.b, F) // eigenvalues and eigenprojectors tsr.Ten2Man(o.bm, o.b) err = tsr.M_EigenValsProjsNum(o.P, o.λ, o.bm) if err != nil { return } o.λ[0] = math.Sqrt(o.λ[0]) o.λ[1] = math.Sqrt(o.λ[1]) o.λ[2] = math.Sqrt(o.λ[2]) return }
// CalcD computes algorithmic tangent operator func (o *PrincStrainsUp) CalcD(D [][]float64, s *State) (err error) { // elastic response if !s.Loading { o.Mdl.ElastD(D, s) return } // eigenvalues/projectors of trial elastic strain err = tsr.M_EigenValsProjsNum(o.P, o.Lεetr, s.EpsTr) if err != nil { return } // derivatives of eigenprojectors w.r.t trial elastic strains err = tsr.M_EigenProjsDerivAuto(o.dPdT, s.EpsTr, o.Lεetr, o.P) if err != nil { io.Pforan("EpsTr = %v\n", s.EpsTr) io.Pforan("Lεetr = %v\n", o.Lεetr) la.PrintMat("P", o.P, "%10g", false) return } // eigenvalues of strains err = tsr.M_EigenValsNum(o.Lεe, s.EpsE) if err != nil { return } // compute Lσ, De and Jacobian o.Mdl.E_CalcSig(o.Lσ, o.Lεe) err = o.Mdl.L_SecondDerivs(o.N, o.Nb, o.A, o.h, o.Mb, o.a, o.b, o.c, o.Lσ, s.Alp) if err != nil { return err } o.Mdl.E_CalcDe(o.De, o.Lεe) o.calcJafterDerivs(o.J, o.Lεe, s.Alp, s.Dgam) // invert Jacobian => Ji err = la.MatInvG(o.Ji, o.J, 1e-10) if err != nil { return } // compute De and Dt = De * Ji for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { o.Dt[i][j] = 0 for k := 0; k < 3; k++ { o.Dt[i][j] += o.De[i][k] * o.Ji[k][j] } } } // compute D for i := 0; i < o.Nsig; i++ { for j := 0; j < o.Nsig; j++ { D[i][j] = 0.0 for k := 0; k < 3; k++ { for l := 0; l < 3; l++ { D[i][j] += o.Dt[k][l] * o.P[k][i] * o.P[l][j] } D[i][j] += o.Lσ[k] * o.dPdT[k][i][j] } } } return }
// Update updates state func (o *PrincStrainsUp) Update(s *State, ε, Δε []float64, eid, ipid int, time float64) (err error) { // debugging if o.DbgOn { o.dbg_init(s, ε, Δε, eid, ipid) } // trial strains for i := 0; i < o.Nsig; i++ { s.EpsE[i] += Δε[i] } copy(s.EpsTr, s.EpsE) // eigenvalues/projectors of trial elastic strain err = tsr.M_EigenValsProjsNum(o.P, o.Lεetr, s.EpsTr) if err != nil { return } // trial stresses o.Mdl.E_CalcSig(o.Lσ, o.Lεetr) // debugging if o.DbgOn { defer o.dbg_end(s, ε, eid, ipid)() // TODO: fix this } // check loading condition => elastic update? ftr := o.Mdl.L_YieldFunc(o.Lσ, s.Alp) if ftr <= o.Fzero { s.Dgam = 0 s.Loading = false for i := 0; i < o.Nsig; i++ { s.Sig[i] = o.Lσ[0]*o.P[0][i] + o.Lσ[1]*o.P[1][i] + o.Lσ[2]*o.P[2][i] } return } // initial values for i := 0; i < 3; i++ { o.x[i] = o.Lεetr[i] } for i := 0; i < o.Nalp; i++ { o.αn[i] = s.Alp[i] o.x[3+i] = s.Alp[i] } o.x[3+o.Nalp] = 0 // Δγ // check Jacobian if o.ChkJac { var cnd float64 cnd, err = o.nls.CheckJ(o.x, o.ChkJacTol, true, o.ChkSilent) io.Pfred("before: cnd(J) = %v\n", cnd) } // modify b bsmp := o.Mdl.Get_bsmp() if bsmp > 0 && o.Nbsmp > 1 { o.Mdl.Set_bsmp(0) defer func() { o.Mdl.Set_bsmp(bsmp) }() δb := bsmp / float64(o.Nbsmp-1) for i := 0; i < o.Nbsmp; i++ { b := float64(i) * δb err = o.do_solve(b, eid, ipid, time) if err != nil { return } } } else { err = o.do_solve(bsmp, eid, ipid, time) if err != nil { return } } // check Jacobian again if o.ChkJac { var cnd float64 cnd, err = o.nls.CheckJ(o.x, o.ChkJacTol, true, o.ChkSilent) io.Pfred("after: cnd(J) = %v\n", cnd) if err != nil { return } } // set new state εe, α, Δγ := o.x[:3], o.x[3:3+o.Nalp], o.x[3+o.Nalp] o.Mdl.E_CalcSig(o.Lσ, εe) for i := 0; i < o.Nsig; i++ { s.Sig[i] = o.Lσ[0]*o.P[0][i] + o.Lσ[1]*o.P[1][i] + o.Lσ[2]*o.P[2][i] s.EpsE[i] = εe[0]*o.P[0][i] + εe[1]*o.P[1][i] + εe[2]*o.P[2][i] } copy(s.Alp, α) s.Dgam = Δγ s.Loading = true return }