예제 #1
0
파일: ogden.go 프로젝트: PatrickSchm/gofem
// 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
}
예제 #2
0
// 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
}
예제 #3
0
// 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
}