Example #1
0
// CalcD computes D = dσ_new/dε_new consistent with StressUpdate
func (o *VonMises) CalcD(D [][]float64, s *State, firstIt bool) (err error) {

	// set first Δγ
	if firstIt {
		s.Dgam = 0
	}

	// elastic
	if !s.Loading {
		return o.SmallElasticity.CalcD(D, s)
	}

	// elastoplastic => consistent stiffness
	σ := s.Sig
	Δγ := s.Dgam
	p, q := tsr.M_p(σ), tsr.M_q(σ)
	qtr := q + Δγ*3.0*o.G
	m := 1.0 - Δγ*3.0*o.G/qtr
	nstr := tsr.SQ2by3 * qtr // norm(str)
	for i := 0; i < o.Nsig; i++ {
		o.ten[i] = (σ[i] + p*tsr.Im[i]) / (m * nstr) // ten := unit(str) = snew / (m * nstr)
	}
	hp := 3.0*o.G + o.H
	a1 := o.K
	b2 := 6.0 * o.G * o.G * (Δγ/qtr - 1.0/hp)
	for i := 0; i < o.Nsig; i++ {
		for j := 0; j < o.Nsig; j++ {
			D[i][j] = 2.0*o.G*m*tsr.Psd[i][j] + a1*tsr.Im[i]*tsr.Im[j] + b2*o.ten[i]*o.ten[j]
		}
	}
	return
}
Example #2
0
// Update updates stresses for given strains
func (o *DruckerPrager) Update(s *State, ε, Δε []float64, eid, ipid int, time float64) (err error) {

	// set flags
	s.Loading = false    // => not elastoplastic
	s.ApexReturn = false // => not return-to-apex
	s.Dgam = 0           // Δγ := 0

	// accessors
	σ := s.Sig
	α0 := &s.Alp[0]

	// copy of α0 at beginning of step
	α0ini := *α0

	// trial stress
	var devΔε_i float64
	trΔε := Δε[0] + Δε[1] + Δε[2]
	for i := 0; i < o.Nsig; i++ {
		devΔε_i = Δε[i] - trΔε*tsr.Im[i]/3.0
		o.ten[i] = σ[i] + o.K*trΔε*tsr.Im[i] + 2.0*o.G*devΔε_i // ten := σtr
	}
	ptr, qtr := tsr.M_p(o.ten), tsr.M_q(o.ten)

	// trial yield function
	ftr := qtr - o.M*ptr - o.qy0 - o.H*(*α0)

	// elastic update
	if ftr <= 0.0 {
		copy(σ, o.ten) // σ := ten = σtr
		return
	}

	// elastoplastic update
	var str_i float64
	hp := 3.0*o.G + o.K*o.M*o.Mb + o.H
	s.Dgam = ftr / hp
	*α0 += s.Dgam
	pnew := ptr + s.Dgam*o.K*o.Mb
	m := 1.0 - s.Dgam*3.0*o.G/qtr
	for i := 0; i < o.Nsig; i++ {
		str_i = o.ten[i] + ptr*tsr.Im[i]
		σ[i] = m*str_i - pnew*tsr.Im[i]
	}
	s.Loading = true

	// check for apex singularity
	acone := qtr - s.Dgam*3.0*o.G
	if acone < 0 {
		s.Dgam = (-o.M*ptr - o.qy0 - o.H*α0ini) / (3.0*o.K*o.M + o.H)
		*α0 = α0ini + s.Dgam
		pnew = ptr + s.Dgam*3.0*o.K
		for i := 0; i < o.Nsig; i++ {
			σ[i] = -pnew * tsr.Im[i]
		}
		s.ApexReturn = true
	}
	return
}
Example #3
0
// CalcD computes D = dσ_new/dε_new consistent with StressUpdate
func (o *DruckerPrager) CalcD(D [][]float64, s *State, firstIt bool) (err error) {

	// set first Δγ
	if firstIt {
		s.Dgam = 0
	}

	// elastic
	if !s.Loading {
		return o.SmallElasticity.CalcD(D, s)
	}

	// return to apex
	if s.ApexReturn {
		a1 := o.K * o.H / (3.0*o.K*o.M + o.H)
		for i := 0; i < o.Nsig; i++ {
			for j := 0; j < o.Nsig; j++ {
				D[i][j] = a1 * tsr.Im[i] * tsr.Im[j]
			}
		}
		return
	}

	// elastoplastic => consistent stiffness
	σ := s.Sig
	Δγ := s.Dgam
	p, q := tsr.M_p(σ), tsr.M_q(σ)
	qtr := q + Δγ*3.0*o.G
	m := 1.0 - Δγ*3.0*o.G/qtr
	nstr := tsr.SQ2by3 * qtr // norm(str)
	for i := 0; i < o.Nsig; i++ {
		o.ten[i] = (σ[i] + p*tsr.Im[i]) / (m * nstr) // ten := unit(str) = snew / (m * nstr)
	}
	hp := 3.0*o.G + o.K*o.M*o.Mb + o.H
	a1 := o.K - o.K*o.K*o.Mb*o.M/hp
	a2 := -2.0 * o.G * o.K * o.Mb * tsr.SQ3by2 / hp
	b1 := -tsr.SQ6 * o.G * o.M * o.K / hp
	b2 := 6.0 * o.G * o.G * (Δγ/qtr - 1.0/hp)
	for i := 0; i < o.Nsig; i++ {
		for j := 0; j < o.Nsig; j++ {
			D[i][j] = 2.0*o.G*m*tsr.Psd[i][j] +
				a1*tsr.Im[i]*tsr.Im[j] +
				a2*tsr.Im[i]*o.ten[j] +
				b1*o.ten[i]*tsr.Im[j] +
				b2*o.ten[i]*o.ten[j]
		}
	}
	return
}
Example #4
0
// Update updates stresses for given strains
func (o *VonMises) Update(s *State, ε, Δε []float64, eid, ipid int, time float64) (err error) {

	// set flags
	s.Loading = false    // => not elastoplastic
	s.ApexReturn = false // => not return-to-apex
	s.Dgam = 0           // Δγ := 0

	// accessors
	σ := s.Sig
	α0 := &s.Alp[0]

	// trial stress
	var devΔε_i float64
	trΔε := Δε[0] + Δε[1] + Δε[2]
	for i := 0; i < o.Nsig; i++ {
		devΔε_i = Δε[i] - trΔε*tsr.Im[i]/3.0
		o.ten[i] = σ[i] + o.K*trΔε*tsr.Im[i] + 2.0*o.G*devΔε_i // ten := σtr
	}
	ptr, qtr := tsr.M_p(o.ten), tsr.M_q(o.ten)

	// trial yield function
	ftr := qtr - o.qy0 - o.H*(*α0)

	// elastic update
	if ftr <= 0.0 {
		copy(σ, o.ten) // σ := ten = σtr
		return
	}

	// elastoplastic update
	var str_i float64
	hp := 3.0*o.G + o.H
	s.Dgam = ftr / hp
	*α0 += s.Dgam
	pnew := ptr
	m := 1.0 - s.Dgam*3.0*o.G/qtr
	for i := 0; i < o.Nsig; i++ {
		str_i = o.ten[i] + ptr*tsr.Im[i]
		σ[i] = m*str_i - pnew*tsr.Im[i]
	}
	s.Loading = true
	return
}
Example #5
0
func (o *Plotter) Plot_oct(x, y []float64, res []*State, sts [][]float64, last bool) {
	// stress path
	nr := len(res)
	k := nr - 1
	var σa, σb, xmi, xma, ymi, yma float64
	for i := 0; i < nr; i++ {
		σa, σb, _ = tsr.PQW2O(o.P[i], o.Q[i], o.W[i])
		x[i], y[i] = σa, σb
		o.maxR = max(o.maxR, math.Sqrt(σa*σa+σb*σb))
		if i == 0 {
			xmi, xma = x[i], x[i]
			ymi, yma = y[i], y[i]
		} else {
			xmi = min(xmi, x[i])
			xma = max(xma, x[i])
			ymi = min(ymi, y[i])
			yma = max(yma, y[i])
		}
	}
	plt.Plot(x, y, io.Sf("'r.', ls='%s', clip_on=0, color='%s', marker='%s', label=r'%s'", o.Ls, o.Clr, o.Mrk, o.Lbl))
	plt.PlotOne(x[0], y[0], io.Sf("'bo', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.SpMrk, o.SpMs))
	plt.PlotOne(x[k], y[k], io.Sf("'bs', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.EpMrk, o.EpMs))
	// fix range and max radius
	xmi, xma, ymi, yma = o.fix_range(0, xmi, xma, ymi, yma)
	rr := math.Sqrt((xma-xmi)*(xma-xmi) + (yma-ymi)*(yma-ymi))
	if o.maxR < rr {
		o.maxR = rr
	}
	if o.maxR < 1e-10 {
		o.maxR = 1
	}
	if yma > -xmi {
		xmi = -yma
	}
	if o.OctLims != nil {
		xmi, xma, ymi, yma = o.OctLims[0], o.OctLims[1], o.OctLims[2], o.OctLims[3]
	}
	//xmi, xma, ymi, yma = -20000, 20000, -20000, 20000
	// yield surface
	var σcmax float64
	if o.WithYs && o.m != nil {
		//io.Pforan("xmi,xma ymi,yma = %v,%v %v,%v\n", xmi,xma, ymi,yma)
		dx := (xma - xmi) / float64(o.NptsOct-1)
		dy := (yma - ymi) / float64(o.NptsOct-1)
		xx := la.MatAlloc(o.NptsOct, o.NptsOct)
		yy := la.MatAlloc(o.NptsOct, o.NptsOct)
		zz := la.MatAlloc(o.NptsOct, o.NptsOct)
		var λ0, λ1, λ2, σc float64
		v := NewState(len(res[0].Sig), len(res[0].Alp), false, len(res[0].EpsE) > 0)
		for k := 0; k < nr; k++ {
			copy(v.Alp, res[k].Alp)
			v.Dgam = res[k].Dgam
			σc = tsr.M_p(res[k].Sig) * tsr.SQ3
			//σc = 30000
			σcmax = max(σcmax, σc)
			for i := 0; i < o.NptsOct; i++ {
				for j := 0; j < o.NptsOct; j++ {
					xx[i][j] = xmi + float64(i)*dx
					yy[i][j] = ymi + float64(j)*dy
					λ0, λ1, λ2 = tsr.O2L(xx[i][j], yy[i][j], σc)
					v.Sig[0], v.Sig[1], v.Sig[2] = λ0, λ1, λ2
					ys := o.m.YieldFuncs(v)
					zz[i][j] = ys[0]
				}
			}
			plt.ContourSimple(xx, yy, zz, io.Sf("colors=['%s'], levels=[0], linestyles=['%s'], linewidths=[%g], clip_on=0", o.YsClr0, o.YsLs0, o.YsLw0)+o.ArgsYs)

		}
	}
	// predictor-corrector
	if len(o.PreCor) > 1 {
		var σa, σb, σanew, σbnew float64
		for i := 1; i < len(o.PreCor); i++ {
			σa, σb, _ = tsr.M_oct(o.PreCor[i-1])
			σanew, σbnew, _ = tsr.M_oct(o.PreCor[i])
			if math.Abs(σanew-σa) > 1e-7 || math.Abs(σbnew-σb) > 1e-7 {
				//plt.Plot([]float64{σa,σanew}, []float64{σb,σbnew}, "'k+', ms=3, color='k'")
				plt.Arrow(σa, σb, σanew, σbnew, io.Sf("sc=%d, fc='%s', ec='%s'", o.ArrWid, o.ClrPC, o.ClrPC))
			}
			o.maxR = max(o.maxR, math.Sqrt(σa*σa+σb*σb))
			o.maxR = max(o.maxR, math.Sqrt(σanew*σanew+σbnew*σbnew))
		}
	}
	// rosette and settings
	if last {
		tsr.PlotRefOct(o.Phi, σcmax, true)
		tsr.PlotRosette(o.maxR, false, true, true, 6)
		if o.OctAxOff {
			plt.AxisOff()
		}
		plt.Gll("$\\sigma_a$", "$\\sigma_b$", "")
		if lims, ok := o.Lims["oct"]; ok {
			plt.AxisLims(lims)
		}
		if lims, ok := o.Lims["oct,ys"]; ok {
			plt.AxisLims(lims)
		}
	}
}
Example #6
0
func (o *Plotter) Plot_p_q(x, y []float64, res []*State, sts [][]float64, last bool) {
	// stress path
	nr := len(res)
	k := nr - 1
	var xmi, xma, ymi, yma float64
	for i := 0; i < nr; i++ {
		x[i], y[i] = o.P[i], o.Q[i]
		if o.Multq {
			mult := fun.Sign(o.W[i])
			y[i] *= mult
		}
		if o.UseOct {
			x[i] *= tsr.SQ3
			y[i] *= tsr.SQ2by3
		}
		if i == 0 {
			xmi, xma = x[i], x[i]
			ymi, yma = y[i], y[i]
		} else {
			xmi = min(xmi, x[i])
			xma = max(xma, x[i])
			ymi = min(ymi, y[i])
			yma = max(yma, y[i])
		}
		if o.SMPon {
			x[i], y[i], _ = tsr.M_pq_smp(res[i].Sig, o.SMPa, o.SMPb, o.SMPβ, o.SMPϵ)
		}
	}
	plt.Plot(x, y, io.Sf("'r.', ls='%s', clip_on=0, color='%s', marker='%s', label=r'%s'", o.Ls, o.Clr, o.Mrk, o.Lbl))
	plt.PlotOne(x[0], y[0], io.Sf("'bo', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.SpMrk, o.SpMs))
	plt.PlotOne(x[k], y[k], io.Sf("'bs', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.EpMrk, o.EpMs))
	// yield surface
	if o.WithYs && o.m != nil {
		mx, my := 1.0, 1.0
		if o.UseOct {
			mx, my = tsr.SQ3, tsr.SQ2by3
		}
		if o.UsePmin {
			xmi = min(xmi, o.Pmin*mx)
		}
		if o.UsePmax {
			xma = max(xma, o.Pmax*mx)
			yma = max(yma, o.Pmax*my)
		}
		xmi, xma, ymi, yma = o.fix_range(xmi, xmi, xma, ymi, yma)
		if o.PqLims != nil {
			xmi, xma, ymi, yma = o.PqLims[0], o.PqLims[1], o.PqLims[2], o.PqLims[3]
		}
		//io.Pforan("xmi,xma ymi,yma = %v,%v %v,%v\n", xmi,xma, ymi,yma)
		dx := (xma - xmi) / float64(o.NptsPq-1)
		dy := (yma - ymi) / float64(o.NptsPq-1)
		xx := la.MatAlloc(o.NptsPq, o.NptsPq)
		yy := la.MatAlloc(o.NptsPq, o.NptsPq)
		za := la.MatAlloc(o.NptsPq, o.NptsPq)
		zb := la.MatAlloc(o.NptsPq, o.NptsPq)
		var p, q, σa, σb, σc, λ0, λ1, λ2 float64
		v := NewState(len(res[0].Sig), len(res[0].Alp), false, len(res[0].EpsE) > 0)
		for k := 0; k < nr; k++ {
			copy(v.Alp, res[k].Alp)
			v.Dgam = res[k].Dgam
			for i := 0; i < o.NptsPq; i++ {
				for j := 0; j < o.NptsPq; j++ {
					xx[i][j] = xmi + float64(i)*dx
					yy[i][j] = ymi + float64(j)*dy
					p, q = xx[i][j], yy[i][j]
					if o.UseOct {
						p /= tsr.SQ3
						q /= tsr.SQ2by3
					}
					σa, σb, σc = tsr.PQW2O(p, q, o.W[k])
					λ0, λ1, λ2 = tsr.O2L(σa, σb, σc)
					v.Sig[0], v.Sig[1], v.Sig[2] = λ0, λ1, λ2
					ys := o.m.YieldFuncs(v)
					za[i][j] = ys[0]
					if o.nsurf > 1 {
						zb[i][j] = ys[1]
					}
					if o.SMPon {
						xx[i][j], yy[i][j], _ = tsr.M_pq_smp(v.Sig, o.SMPa, o.SMPb, o.SMPβ, o.SMPϵ)
					}
				}
			}
			plt.ContourSimple(xx, yy, za, io.Sf("colors=['%s'], levels=[0], linestyles=['%s'], linewidths=[%g], clip_on=0", o.YsClr0, o.YsLs0, o.YsLw0)+o.ArgsYs)
			if o.nsurf > 1 {
				plt.ContourSimple(xx, yy, zb, io.Sf("colors=['%s'], levels=[0], linestyles=['%s'], linewidths=[%g], clip_on=0", o.YsClr1, o.YsLs1, o.YsLw1)+o.ArgsYs)
			}
		}
	}
	// predictor-corrector
	if len(o.PreCor) > 1 {
		var p, q, pnew, qnew float64
		for i := 1; i < len(o.PreCor); i++ {
			p = tsr.M_p(o.PreCor[i-1])
			q = tsr.M_q(o.PreCor[i-1])
			pnew = tsr.M_p(o.PreCor[i])
			qnew = tsr.M_q(o.PreCor[i])
			if o.UseOct {
				p *= tsr.SQ3
				pnew *= tsr.SQ3
				q *= tsr.SQ2by3
				qnew *= tsr.SQ2by3
			}
			if o.SMPon {
				p, q, _ = tsr.M_pq_smp(o.PreCor[i-1], o.SMPa, o.SMPb, o.SMPβ, o.SMPϵ)
				pnew, qnew, _ = tsr.M_pq_smp(o.PreCor[i], o.SMPa, o.SMPb, o.SMPβ, o.SMPϵ)
			}
			if math.Abs(pnew-p) > 1e-10 || math.Abs(qnew-q) > 1e-10 {
				plt.Arrow(p, q, pnew, qnew, io.Sf("sc=%d, fc='%s', ec='%s'", o.ArrWid, o.ClrPC, o.ClrPC))
			}
		}
	}
	// settings
	if last {
		plt.Equal()
		xl, yl := "$p_{cam}$", "$q_{cam}$"
		if o.UseOct {
			xl, yl = "$p_{oct}$", "$q_{oct}$"
		}
		if o.SMPon {
			xl, yl = "$p_{smp}$", "$q_{smp}$"
		}
		if o.AxLblX != "" {
			xl = o.AxLblX
		}
		if o.AxLblY != "" {
			yl = o.AxLblY
		}
		plt.Gll(xl, yl, "leg_out=1, leg_ncol=4, leg_hlen=1.5")
		if lims, ok := o.Lims["p,q"]; ok {
			plt.AxisLims(lims)
		}
		if lims, ok := o.Lims["p,q,ys"]; ok {
			plt.AxisLims(lims)
		}
	}
}
Example #7
0
// YieldFs computes the yield functions
func (o DruckerPrager) YieldFuncs(s *State) []float64 {
	p, q := tsr.M_p(s.Sig), tsr.M_q(s.Sig)
	α0 := s.Alp[0]
	return []float64{q - o.M*p - o.qy0 - o.H*α0}
}