// adds -R to global residual vector fb func (o Beam) AddToRhs(fb []float64, sol *Solution) (ok bool) { // node displacements for i, I := range o.Umap { o.ue[i] = sol.Y[I] } // steady/dynamics if Global.Sim.Data.Steady { la.MatVecMul(o.fi, 1, o.K, o.ue) } else { dc := Global.DynCoefs for i := 0; i < o.Nu; i++ { o.fi[i] = 0 for j := 0; j < o.Nu; j++ { o.fi[i] += o.M[i][j]*(dc.α1*o.ue[j]-o.ζe[j]) + o.K[i][j]*o.ue[j] } } } // distributed loads if o.Hasq { dx := o.X[0][1] - o.X[0][0] dy := o.X[1][1] - o.X[1][0] l := math.Sqrt(dx*dx + dy*dy) qnL := o.QnL.F(sol.T, nil) qnR := o.QnR.F(sol.T, nil) qt := o.Qt.F(sol.T, nil) o.fxl[0] = qt * l / 2.0 o.fxl[1] = l * (7.0*qnL + 3.0*qnR) / 20.0 o.fxl[2] = l * l * (3.0*qnL + 2.0*qnR) / 60.0 o.fxl[3] = qt * l / 2.0 o.fxl[4] = l * (3.0*qnL + 7.0*qnR) / 20.0 o.fxl[5] = -l * l * (2.0*qnL + 3.0*qnR) / 60.0 la.MatTrVecMulAdd(o.fi, -1.0, o.T, o.fxl) // Rus -= fx; fx = trans(T) * fxl } // add to fb for i, I := range o.Umap { fb[I] -= o.fi[i] } return true }
// adds -R to global residual vector fb func (o *Beam) AddToRhs(fb []float64, sol *Solution) (err error) { // node displacements for i, I := range o.Umap { o.ue[i] = sol.Y[I] } // steady/dynamics if sol.Steady { la.MatVecMul(o.fi, 1, o.K, o.ue) } else { α1 := sol.DynCfs.α1 for i := 0; i < o.Nu; i++ { o.fi[i] = 0 for j := 0; j < o.Nu; j++ { o.fi[i] += o.M[i][j]*(α1*o.ue[j]-o.ζe[j]) + o.K[i][j]*o.ue[j] } } } // distributed loads if o.Hasq { dx := o.X[0][1] - o.X[0][0] dy := o.X[1][1] - o.X[1][0] l := math.Sqrt(dx*dx + dy*dy) qnL, qnR, qt := o.calc_loads(sol.T) o.fxl[0] = qt * l / 2.0 o.fxl[1] = l * (7.0*qnL + 3.0*qnR) / 20.0 o.fxl[2] = l * l * (3.0*qnL + 2.0*qnR) / 60.0 o.fxl[3] = qt * l / 2.0 o.fxl[4] = l * (3.0*qnL + 7.0*qnR) / 20.0 o.fxl[5] = -l * l * (2.0*qnL + 3.0*qnR) / 60.0 la.MatTrVecMulAdd(o.fi, -1.0, o.T, o.fxl) // Rus -= fx; fx = trans(T) * fxl } // add to fb for i, I := range o.Umap { fb[I] -= o.fi[i] } return }
// AddToRhs adds -R to global residual vector fb func (o *ElemU) AddToRhs(fb []float64, sol *Solution) (ok bool) { // clear fi vector if using B matrix if o.UseB { la.VecFill(o.fi, 0) } // for each integration point dc := Global.DynCoefs ndim := Global.Ndim nverts := o.Shp.Nverts for idx, ip := range o.IpsElem { // interpolation functions, gradients and variables @ ip if !o.ipvars(idx, sol) { return } // auxiliary coef := o.Shp.J * ip.W * o.Thickness S := o.Shp.S G := o.Shp.G // add internal forces to fb if o.UseB { radius := 1.0 if Global.Sim.Data.Axisym { radius = o.Shp.AxisymGetRadius(o.X) coef *= radius } IpBmatrix(o.B, ndim, nverts, G, radius, S) la.MatTrVecMulAdd(o.fi, coef, o.B, o.States[idx].Sig) // fi += coef * tr(B) * σ } else { for m := 0; m < nverts; m++ { for i := 0; i < ndim; i++ { r := o.Umap[i+m*ndim] for j := 0; j < ndim; j++ { fb[r] -= coef * tsr.M2T(o.States[idx].Sig, i, j) * G[m][j] // -fi } } } } // dynamic term if !Global.Sim.Data.Steady { for m := 0; m < nverts; m++ { for i := 0; i < ndim; i++ { r := o.Umap[i+m*ndim] fb[r] -= coef * S[m] * (o.Rho*(dc.α1*o.us[i]-o.ζs[idx][i]-o.grav[i]) + o.Cdam*(dc.α4*o.us[i]-o.χs[idx][i])) // -RuBar } } } } // assemble fb if using B matrix if o.UseB { for i, I := range o.Umap { fb[I] -= o.fi[i] } } // external forces return o.add_surfloads_to_rhs(fb, sol) }
// adds -R to global residual vector fb func (o ElemUP) AddToRhs(fb []float64, sol *Solution) (ok bool) { // clear variables if o.P.DoExtrap { la.VecFill(o.P.ρl_ex, 0) } if o.U.UseB { la.VecFill(o.U.fi, 0) } // for each integration point dc := Global.DynCoefs ndim := Global.Ndim u_nverts := o.U.Shp.Nverts p_nverts := o.P.Shp.Nverts var coef, plt, klr, ρl, ρ, p, Cpl, Cvs, divvs float64 var r int for idx, ip := range o.U.IpsElem { // interpolation functions, gradients and variables @ ip if !o.ipvars(idx, sol) { return } coef = o.U.Shp.J * ip.W S := o.U.Shp.S G := o.U.Shp.G Sb := o.P.Shp.S Gb := o.P.Shp.G // axisymmetric case radius := 1.0 if Global.Sim.Data.Axisym { radius = o.U.Shp.AxisymGetRadius(o.U.X) coef *= radius } // auxiliary σe := o.U.States[idx].Sig divvs = dc.α4*o.divus - o.U.divχs[idx] // divergence of Eq. (35a) [1] // tpm variables plt = dc.β1*o.P.pl - o.P.ψl[idx] // Eq. (35c) [1] klr = o.P.Mdl.Cnd.Klr(o.P.States[idx].A_sl) if LogErr(o.P.Mdl.CalcLs(o.P.res, o.P.States[idx], o.P.pl, o.divus, false), "AddToRhs") { return } ρl = o.P.res.A_ρl ρ = o.P.res.A_ρ p = o.P.res.A_p Cpl = o.P.res.Cpl Cvs = o.P.res.Cvs // compute ρwl. see Eq (34b) and (35) of [1] for i := 0; i < ndim; i++ { o.P.ρwl[i] = 0 for j := 0; j < ndim; j++ { o.P.ρwl[i] += klr * o.P.Mdl.Klsat[i][j] * o.hl[j] } } // p: add negative of residual term to fb; see Eqs. (38a) and (45a) of [1] for m := 0; m < p_nverts; m++ { r = o.P.Pmap[m] fb[r] -= coef * Sb[m] * (Cpl*plt + Cvs*divvs) for i := 0; i < ndim; i++ { fb[r] += coef * Gb[m][i] * o.P.ρwl[i] // += coef * div(ρl*wl) } if o.P.DoExtrap { // Eq. (19) of [2] o.P.ρl_ex[m] += o.P.Emat[m][idx] * ρl } } // u: add negative of residual term to fb; see Eqs. (38b) and (45b) [1] if o.U.UseB { IpBmatrix(o.U.B, ndim, u_nverts, G, radius, S) la.MatTrVecMulAdd(o.U.fi, coef, o.U.B, σe) // fi += coef * tr(B) * σ for m := 0; m < u_nverts; m++ { for i := 0; i < ndim; i++ { r = o.U.Umap[i+m*ndim] fb[r] -= coef * S[m] * ρ * o.bs[i] fb[r] += coef * p * G[m][i] } } } else { for m := 0; m < u_nverts; m++ { for i := 0; i < ndim; i++ { r = o.U.Umap[i+m*ndim] fb[r] -= coef * S[m] * ρ * o.bs[i] for j := 0; j < ndim; j++ { fb[r] -= coef * tsr.M2T(σe, i, j) * G[m][j] } fb[r] += coef * p * G[m][i] } } } } // add fi term to fb, if using B matrix if o.U.UseB { for i, I := range o.U.Umap { fb[I] -= o.U.fi[i] } } // external forces if len(o.U.NatBcs) > 0 { if !o.U.add_surfloads_to_rhs(fb, sol) { return } } // contribution from natural boundary conditions if len(o.P.NatBcs) > 0 { return o.P.add_natbcs_to_rhs(fb, sol) } return true }
// AddToRhs adds -R to global residual vector fb func (o *ElemU) AddToRhs(fb []float64, sol *Solution) (err error) { // clear fi vector if using B matrix if o.UseB { la.VecFill(o.fi, 0) } // for each integration point nverts := o.Cell.Shp.Nverts for idx, ip := range o.IpsElem { // interpolation functions, gradients and variables @ ip err = o.ipvars(idx, sol) if err != nil { return } // auxiliary coef := o.Cell.Shp.J * ip[3] * o.Thickness S := o.Cell.Shp.S G := o.Cell.Shp.G // add internal forces to fb if o.UseB { radius := 1.0 if sol.Axisym { radius = o.Cell.Shp.AxisymGetRadius(o.X) coef *= radius } IpBmatrix(o.B, o.Ndim, nverts, G, radius, S, sol.Axisym) la.MatTrVecMulAdd(o.fi, coef, o.B, o.States[idx].Sig) // fi += coef * tr(B) * σ } else { for m := 0; m < nverts; m++ { for i := 0; i < o.Ndim; i++ { r := o.Umap[i+m*o.Ndim] for j := 0; j < o.Ndim; j++ { fb[r] -= coef * tsr.M2T(o.States[idx].Sig, i, j) * G[m][j] // -fi } } } } // dynamic term if !sol.Steady { α1 := sol.DynCfs.α1 α4 := sol.DynCfs.α4 for m := 0; m < nverts; m++ { for i := 0; i < o.Ndim; i++ { r := o.Umap[i+m*o.Ndim] fb[r] -= coef * S[m] * (o.Rho*(α1*o.us[i]-o.ζs[idx][i]-o.grav[i]) + o.Cdam*(α4*o.us[i]-o.χs[idx][i])) // -RuBar } } } } // assemble fb if using B matrix if o.UseB { for i, I := range o.Umap { fb[I] -= o.fi[i] } } // external forces err = o.add_surfloads_to_rhs(fb, sol) if err != nil { return } // contact: additional term to fb err = o.contact_add_to_rhs(fb, sol) // xfem: additional term to fb err = o.xfem_add_to_rhs(fb, sol) return }