Example #1
0
// 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)
}
Example #2
0
// Update perform (tangent) update
func (o *Rjoint) Update(sol *Solution) (err error) {

	// auxiliary
	nsig := 2 * o.Ndim
	rodH := o.Rod.Cell.Shp
	rodS := rodH.S
	rodNn := rodH.Nverts
	sldH := o.Sld.Cell.Shp
	sldNn := sldH.Nverts

	// extrapolate stresses at integration points of solid element to its nodes
	if o.Coulomb {
		la.MatFill(o.σNo, 0)
		for idx, _ := range o.Sld.IpsElem {
			σ := o.Sld.States[idx].Sig
			for i := 0; i < nsig; i++ {
				for m := 0; m < sldNn; m++ {
					o.σNo[m][i] += o.Emat[m][idx] * σ[i]
				}
			}
		}
	}

	// interpolate Δu of solid to find ΔuC @ rod node; Eq (30)
	var r, I int
	for m := 0; m < rodNn; m++ {
		for i := 0; i < o.Ndim; i++ {
			o.ΔuC[m][i] = 0
			for n := 0; n < sldNn; n++ {
				r = i + n*o.Ndim
				I = o.Sld.Umap[r]
				o.ΔuC[m][i] += o.Nmat[n][m] * sol.ΔY[I] // Eq (30)
			}
		}
	}

	// loop over ips of rod
	var Δwb0, Δwb1, Δwb2, σc float64
	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
		}

		// interpolated relative displacements @ ip of join; Eqs (31) and (32)
		for i := 0; i < o.Ndim; i++ {
			o.Δw[i] = 0
			for m := 0; m < rodNn; m++ {
				r = i + m*o.Ndim
				I = o.Rod.Umap[r]
				o.Δw[i] += rodS[m] * (o.ΔuC[m][i] - sol.ΔY[I]) // Eq (31) and (32)
			}
		}

		// relative displacents in the coratational system
		Δwb0, Δwb1, Δwb2 = 0, 0, 0
		for i := 0; i < o.Ndim; i++ {
			Δwb0 += e0[i] * o.Δw[i]
			Δwb1 += e1[i] * o.Δw[i]
			Δwb2 += e2[i] * o.Δw[i]
		}

		// new confining stress
		σc = 0.0
		if o.Coulomb {

			// calculate σIp
			for j := 0; j < nsig; j++ {
				o.σIp[j] = 0
				for n := 0; n < sldNn; n++ {
					o.σIp[j] += o.Pmat[n][idx] * o.σNo[n][j]
				}
			}

			// calculate t1 and t2
			for i := 0; i < o.Ndim; i++ {
				o.t1[i], o.t2[i] = 0, 0
				for j := 0; j < o.Ndim; j++ {
					o.t1[i] += tsr.M2T(o.σIp, i, j) * e1[j]
					o.t2[i] += tsr.M2T(o.σIp, i, j) * e2[j]
				}
			}

			// calculate p1, p2 and σcNew
			p1, p2 := 0.0, 0.0
			for i := 0; i < o.Ndim; i++ {
				p1 += o.t1[i] * e1[i]
				p2 += o.t2[i] * e2[i]
			}

			// σcNew
			σc = -(p1 + p2) / 2.0
		}

		// update model
		err = o.Mdl.Update(o.States[idx], σc, Δwb0)
		if err != nil {
			return
		}
		o.States[idx].Phi[0] += o.k1 * Δwb1 // qn1
		o.States[idx].Phi[1] += o.k2 * Δwb2 // qn2

		// debugging
		//if true {
		if false {
			o.debug_update(idx, Δwb0, Δwb1, Δwb2, σc)
		}
	}
	return
}
Example #3
0
// 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
}
Example #4
0
// 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
}