예제 #1
0
// CheckDSdR checks dSdR derivatives of shape structures
func CheckDSdR(tst *testing.T, shape *Shape, r []float64, tol float64, verbose bool) {

	// auxiliary
	r_tmp := make([]float64, len(r))
	S_tmp := make([]float64, shape.Nverts)

	// analytical
	shape.Func(shape.S, shape.DSdR, r, true, -1)

	// numerical
	for n := 0; n < shape.Nverts; n++ {
		for i := 0; i < shape.Gndim; i++ {
			dSndRi, _ := num.DerivCentral(func(t float64, args ...interface{}) (Sn float64) {
				copy(r_tmp, r)
				r_tmp[i] = t
				shape.Func(S_tmp, nil, r_tmp, false, -1)
				Sn = S_tmp[n]
				return
			}, r[i], 1e-1)
			if verbose {
				io.Pfgrey2("  dS%ddR%d @ %5.2f = %v (num: %v)\n", n, i, r, shape.DSdR[n][i], dSndRi)
			}
			if math.Abs(shape.DSdR[n][i]-dSndRi) > tol {
				tst.Errorf("nurbs dS%ddR%d failed with err = %g\n", n, i, math.Abs(shape.DSdR[n][i]-dSndRi))
				return
			}
		}
	}
}
예제 #2
0
// CheckDSdx checks G=dSdx derivatives of shape structures
func CheckDSdx(tst *testing.T, shape *Shape, xmat [][]float64, x []float64, tol float64, verbose bool) {

	// find r corresponding to x
	r := make([]float64, 3)
	err := shape.InvMap(r, x, xmat)
	if err != nil {
		tst.Errorf("InvMap failed:\n%v", err)
		return
	}

	// analytical
	err = shape.CalcAtIp(xmat, r, true)
	if err != nil {
		tst.Errorf("CalcAtIp failed:\n%v", err)
		return
	}

	// numerical
	x_tmp := make([]float64, len(x))
	for n := 0; n < shape.Nverts; n++ {
		for i := 0; i < shape.Gndim; i++ {
			dSnDxi, _ := num.DerivCentral(func(t float64, args ...interface{}) (Sn float64) {
				copy(x_tmp, x)
				x_tmp[i] = t
				err = shape.InvMap(r, x_tmp, xmat)
				if err != nil {
					tst.Errorf("InvMap failed:\n%v", err)
					return
				}
				err = shape.CalcAtIp(xmat, r, false)
				if err != nil {
					tst.Errorf("CalcAtIp failed:\n%v", err)
					return
				}
				Sn = shape.S[n]
				return
			}, x[i], 1e-1)
			if verbose {
				io.Pfgrey2("  dS%dDx%d @ %5.2f = %v (num: %v)\n", n, i, x, shape.G[n][i], dSnDxi)
			}
			if math.Abs(shape.G[n][i]-dSnDxi) > tol {
				tst.Errorf("nurbs dS%dDx%d failed with err = %g\n", n, i, math.Abs(shape.G[n][i]-dSnDxi))
				return
			}
		}
	}
}
예제 #3
0
// checkDerivs checks dSdR derivatives of shape structures
func checkDerivs(tst *testing.T, shape string, r []float64, tol float64, verbose bool) {

	// information
	fcn := Functions[shape]
	ndim := GeomNdim[shape]
	nverts := NumVerts[shape]

	// allocate slices
	S := make([]float64, nverts)
	dSdR := utl.DblsAlloc(nverts, ndim)

	// auxiliary
	r_tmp := make([]float64, len(r))
	S_tmp := make([]float64, nverts)

	// analytical
	fcn(S, dSdR, r, true)

	// numerical
	for n := 0; n < nverts; n++ {
		for i := 0; i < ndim; i++ {
			dSndRi, _ := num.DerivCentral(func(t float64, args ...interface{}) (Sn float64) {
				copy(r_tmp, r)
				r_tmp[i] = t
				fcn(S_tmp, nil, r_tmp, false)
				Sn = S_tmp[n]
				return
			}, r[i], 1e-1)
			if verbose {
				io.Pfgrey2("  dS%ddR%d @ %5.2f = %v (num: %v)\n", n, i, r, dSdR[n][i], dSndRi)
			}
			if math.Abs(dSdR[n][i]-dSndRi) > tol {
				tst.Errorf("nurbs dS%ddR%d failed with err = %g\n", n, i, math.Abs(dSdR[n][i]-dSndRi))
				return
			}
		}
	}
}
예제 #4
0
// testing_compare_results_u compares results with u-formulation
func TestingCompareResultsU(tst *testing.T, simfname, cmpfname string, tolK, tolu, tols float64, skipK, verbose bool) {

	// only root can run this test
	if !Global.Root {
		return
	}

	// read summary
	sum := ReadSum(Global.Dirout, Global.Fnkey)
	if sum == nil {
		tst.Error("cannot read summary file for simulation=%q\n", simfname)
		return
	}

	// allocate domain
	distr := false
	d := NewDomain(Global.Sim.Regions[0], distr)
	if !d.SetStage(0, Global.Sim.Stages[0], distr) {
		tst.Errorf("TestingCompareResultsU: SetStage failed\n")
		return
	}

	// read file
	buf, err := io.ReadFile(cmpfname)
	if err != nil {
		tst.Errorf("TestingCompareResultsU: ReadFile failed\n")
		return
	}

	// unmarshal json
	var cmp_set T_results_set
	err = json.Unmarshal(buf, &cmp_set)
	if err != nil {
		tst.Errorf("TestingCompareResultsU: Unmarshal failed\n")
		return
	}

	// run comparisons
	dmult := 1.0
	for idx, cmp := range cmp_set {

		// displacements multiplier
		if idx == 0 && math.Abs(cmp.DispMult) > 1e-10 {
			dmult = cmp.DispMult
		}

		// time index
		tidx := idx + 1
		if verbose {
			io.PfYel("\n\ntidx = %d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", tidx)
		}

		// load gofem results
		if !d.In(sum, tidx, true) {
			tst.Errorf("TestingCompareResultsU: reading of results failed\n")
			return
		}
		if verbose {
			io.Pfyel("time = %v\n", d.Sol.T)
		}

		// check K matrices
		if !skipK {
			if verbose {
				io.Pfgreen(". . . checking K matrices . . .\n")
			}
			for eid, Ksg := range cmp.Kmats {
				if e, ok := d.Elems[eid].(*ElemU); ok {
					if !e.AddToKb(d.Kb, d.Sol, true) {
						tst.Errorf("TestingCompareResultsU: AddToKb failed\n")
						return
					}
					chk.Matrix(tst, io.Sf("K%d", eid), tolK, e.K, Ksg)
				}
			}
		}

		// check displacements
		if verbose {
			io.Pfgreen(". . . checking displacements . . .\n")
		}
		for nid, usg := range cmp.Disp {
			ix := d.Vid2node[nid].Dofs[0].Eq
			iy := d.Vid2node[nid].Dofs[1].Eq
			chk.AnaNum(tst, "ux", tolu, d.Sol.Y[ix], usg[0]*dmult, verbose)
			chk.AnaNum(tst, "uy", tolu, d.Sol.Y[iy], usg[1]*dmult, verbose)
			if len(usg) == 3 {
				iz := d.Vid2node[nid].Dofs[2].Eq
				chk.AnaNum(tst, "uz", tolu, d.Sol.Y[iz], usg[2]*dmult, verbose)
			}
		}

		// check stresses
		if true {
			if verbose {
				io.Pfgreen(". . . checking stresses . . .\n")
			}
			for eid, sig := range cmp.Sigmas {
				if verbose {
					io.Pforan("eid = %d\n", eid)
				}
				if e, ok := d.Cid2elem[eid].(*ElemU); ok {
					for ip, val := range sig {
						if verbose {
							io.Pfgrey2("ip = %d\n", ip)
						}
						σ := e.States[ip].Sig
						if len(val) == 6 {
							chk.AnaNum(tst, "sx ", tols, σ[0], val[0], verbose)
							chk.AnaNum(tst, "sy ", tols, σ[1], val[1], verbose)
						} else {
							chk.AnaNum(tst, "sx ", tols, σ[0], val[0], verbose)
							chk.AnaNum(tst, "sy ", tols, σ[1], val[1], verbose)
							chk.AnaNum(tst, "sxy", tols, σ[3]/SQ2, val[2], verbose)
							if len(val) > 3 { // sx, sy, sxy, sz
								chk.AnaNum(tst, "sz ", tols, σ[2], val[3], verbose)
							}
						}
					}
				}
			}
		}
	}
}
예제 #5
0
// Run computes β starting witn an initial guess
func (o *ReliabFORM) Run(βtrial float64, verbose bool, args ...interface{}) (β float64, μ, σ, x []float64) {

	// initial random variables
	β = βtrial
	nx := len(o.μ)
	μ = make([]float64, nx) // mean values (equivalent normal value)
	σ = make([]float64, nx) // deviation values (equivalent normal value)
	x = make([]float64, nx) // current vector of random variables defining min(β)
	for i := 0; i < nx; i++ {
		μ[i] = o.μ[i]
		σ[i] = o.σ[i]
		x[i] = o.μ[i]
	}

	// lognormal distribution structure
	var lnd DistLogNormal

	// has lognormal random variable?
	haslrv := false
	for _, found := range o.lrv {
		if found {
			haslrv = true
			break
		}
	}

	// function to compute β with x-constant
	//  gβ(β) = g(μ - β・A・σ) = 0
	var err error
	gβfcn := func(fy, y []float64) error {
		βtmp := y[0]
		for i := 0; i < nx; i++ {
			o.xtmp[i] = μ[i] - βtmp*o.α[i]*σ[i]
		}
		fy[0], err = o.gfcn(o.xtmp, args)
		if err != nil {
			chk.Panic("cannot compute gfcn(%v):\n%v", o.xtmp, err)
		}
		return nil
	}

	// derivative of gβ w.r.t β
	hβfcn := func(dfdy [][]float64, y []float64) error {
		βtmp := y[0]
		for i := 0; i < nx; i++ {
			o.xtmp[i] = μ[i] - βtmp*o.α[i]*σ[i]
		}
		err = o.hfcn(o.dgdx, o.xtmp, args)
		if err != nil {
			chk.Panic("cannot compute hfcn(%v):\n%v", o.xtmp, err)
		}
		dfdy[0][0] = 0
		for i := 0; i < nx; i++ {
			dfdy[0][0] -= o.dgdx[i] * o.α[i] * σ[i]
		}
		return nil
	}

	// nonlinear solver with y[0] = β
	// solving:  gβ(β) = g(μ - β・A・σ) = 0
	var nls num.NlSolver
	nls.Init(1, gβfcn, nil, hβfcn, true, false, nil)
	defer nls.Clean()

	// message
	if verbose {
		io.Pf("\n%s", io.StrThickLine(60))
	}

	// plotting
	plot := o.PlotFnk != ""
	if nx != 2 {
		plot = false
	}
	if plot {
		if o.PlotNp < 3 {
			o.PlotNp = 41
		}
		var umin, umax, vmin, vmax float64
		if o.PlotCf < 1 {
			o.PlotCf = 2
		}
		if len(o.PlotUrange) == 0 {
			umin, umax = μ[0]-o.PlotCf*μ[0], μ[0]+o.PlotCf*μ[0]
			vmin, vmax = μ[1]-o.PlotCf*μ[1], μ[1]+o.PlotCf*μ[1]
		} else {
			chk.IntAssert(len(o.PlotUrange), 2)
			chk.IntAssert(len(o.PlotVrange), 2)
			umin, umax = o.PlotUrange[0], o.PlotUrange[1]
			vmin, vmax = o.PlotVrange[0], o.PlotVrange[1]
		}
		o.PlotU, o.PlotV = utl.MeshGrid2D(umin, umax, vmin, vmax, o.PlotNp, o.PlotNp)
		o.PlotZ = la.MatAlloc(o.PlotNp, o.PlotNp)
		plt.SetForEps(0.8, 300)
		for i := 0; i < o.PlotNp; i++ {
			for j := 0; j < o.PlotNp; j++ {
				o.xtmp[0] = o.PlotU[i][j]
				o.xtmp[1] = o.PlotV[i][j]
				o.PlotZ[i][j], err = o.gfcn(o.xtmp, args)
				if err != nil {
					chk.Panic("cannot compute gfcn(%v):\n%v", x, err)
				}
			}
		}
		plt.Contour(o.PlotU, o.PlotV, o.PlotZ, "")
		plt.ContourSimple(o.PlotU, o.PlotV, o.PlotZ, true, 8, "levels=[0], colors=['yellow']")
		plt.PlotOne(x[0], x[1], "'ro', label='initial'")
	}

	// iterations to find β
	var dat VarData
	B := []float64{β}
	itB := 0
	for itB = 0; itB < o.NmaxItB; itB++ {

		// message
		if verbose {
			gx, err := o.gfcn(x, args)
			if err != nil {
				chk.Panic("cannot compute gfcn(%v):\n%v", x, err)
			}
			io.Pf("%s itB=%d β=%g g=%g\n", io.StrThinLine(60), itB, β, gx)
		}

		// plot
		if plot {
			plt.PlotOne(x[0], x[1], "'r.'")
		}

		// compute direction cosines
		itA := 0
		for itA = 0; itA < o.NmaxItA; itA++ {

			// has lognormal random variable (lrv)
			if haslrv {

				// find equivalent normal mean and std deviation for lognormal variables
				for i := 0; i < nx; i++ {
					if o.lrv[i] {

						// set distribution
						dat.M, dat.S = o.μ[i], o.σ[i]
						lnd.Init(&dat)

						// update μ and σ
						fx := lnd.Pdf(x[i])
						Φinvx := (math.Log(x[i]) - lnd.M) / lnd.S
						φx := math.Exp(-Φinvx*Φinvx/2.0) / math.Sqrt2 / math.SqrtPi
						σ[i] = φx / fx
						μ[i] = x[i] - Φinvx*σ[i]
					}
				}
			}

			// compute direction cosines
			err = o.hfcn(o.dgdx, x, args)
			if err != nil {
				chk.Panic("cannot compute hfcn(%v):\n%v", x, err)
			}
			den := 0.0
			for i := 0; i < nx; i++ {
				den += math.Pow(o.dgdx[i]*σ[i], 2.0)
			}
			den = math.Sqrt(den)
			αerr := 0.0 // difference on α
			for i := 0; i < nx; i++ {
				αnew := o.dgdx[i] * σ[i] / den
				αerr += math.Pow(αnew-o.α[i], 2.0)
				o.α[i] = αnew
			}
			αerr = math.Sqrt(αerr)

			// message
			if verbose {
				io.Pf(" itA=%d\n", itA)
				io.Pf("%12s%12s%12s%12s\n", "x", "μ", "σ", "α")
				for i := 0; i < nx; i++ {
					io.Pf("%12.3f%12.3f%12.3f%12.3f\n", x[i], μ[i], σ[i], o.α[i])
				}
			}

			// update x-star
			for i := 0; i < nx; i++ {
				x[i] = μ[i] - β*o.α[i]*σ[i]
			}

			// check convergence on α
			if itA > 1 && αerr < o.TolA {
				if verbose {
					io.Pfgrey(". . . converged on α with αerr=%g . . .\n", αerr)
				}
				break
			}
		}

		// failed to converge on α
		if itA == o.NmaxItA {
			chk.Panic("failed to convege on α")
		}

		// compute new β
		B[0] = β
		nls.Solve(B, o.NlsSilent)
		βerr := math.Abs(B[0] - β)
		β = B[0]
		if o.NlsCheckJ {
			nls.CheckJ(B, o.NlsCheckJtol, true, false)
		}

		// update x-star
		for i := 0; i < nx; i++ {
			x[i] = μ[i] - β*o.α[i]*σ[i]
		}

		// check convergence on β
		if βerr < o.TolB {
			if verbose {
				io.Pfgrey2(". . . converged on β with βerr=%g . . .\n", βerr)
			}
			break
		}
	}

	// failed to converge on β
	if itB == o.NmaxItB {
		chk.Panic("failed to converge on β")
	}

	// message
	if verbose {
		gx, err := o.gfcn(x, args)
		if err != nil {
			chk.Panic("cannot compute gfcn(%v):\n%v", x, err)
		}
		io.Pfgreen("x = %v\n", x)
		io.Pfgreen("g = %v\n", gx)
		io.PfGreen("β = %v\n", β)
	}

	// plot
	if plot {
		plt.Gll("$x_0$", "$x_1$", "")
		plt.Cross("")
		plt.SaveD("/tmp/gosl", "fig_form_"+o.PlotFnk+".eps")
	}
	return
}
예제 #6
0
func Test_shape01(tst *testing.T) {

	//utl.Tsilent = false
	chk.PrintTitle("Test shape01")

	for name, shape := range factory {

		io.Pfyel("--------------------------------- %-6s---------------------------------\n", name)

		// check S
		tol := 1e-17
		errS := 0.0
		if name == "tri10" {
			tol = 1e-14
		}
		for n := 0; n < shape.Nverts; n++ {
			rst := []float64{0, 0, 0}
			for i := 0; i < shape.Gndim; i++ {
				rst[i] = shape.NatCoords[i][n]
			}
			shape.Func(shape.S, shape.dSdR, rst[0], rst[1], rst[2], false)
			io.Pforan("S = %v\n", shape.S)
			for m := 0; m < shape.Nverts; m++ {
				if n == m {
					errS += math.Abs(shape.S[m] - 1.0)
				} else {
					errS += math.Abs(shape.S[m])
				}
			}
		}
		if errS > tol {
			tst.Errorf("%s failed with err = %g\n", name, errS)
			return
		}

		// check dSdR
		tol = 1e-14
		h := 1.0e-1
		S_temp := make([]float64, shape.Nverts)
		if name == "lin5" || name == "tri15" || name == "lin4" || name == "tri10" || name == "qua12" || name == "qua16" {
			tol = 1.0e-10
		}
		for n := 0; n < shape.Nverts; n++ {
			rst := []float64{0, 0, 0}
			for i := 0; i < shape.Gndim; i++ {
				rst[i] = shape.NatCoords[i][n]
			}
			// analytical
			shape.Func(shape.S, shape.dSdR, rst[0], rst[1], rst[2], true)
			// numerical
			for i := 0; i < shape.Gndim; i++ {
				dSndRi, _ := num.DerivCentral(func(x float64, args ...interface{}) (Sn float64) {
					rst_temp := []float64{rst[0], rst[1], rst[2]}
					rst_temp[i] = x
					shape.Func(S_temp, nil, rst_temp[0], rst_temp[1], rst_temp[2], false)
					Sn = S_temp[n]
					return
				}, rst[i], h)
				io.Pfgrey2("  dS%ddR%d @ [% 4.1f % 4.1f % 4.1f] = %v (num: %v)\n", n, i, rst[0], rst[1], rst[2], shape.dSdR[n][i], dSndRi)
				tol2 := tol
				if name == "tri15" && n == 11 && i == 1 {
					tol2 = 1.0e-9
				}
				if math.Abs(shape.dSdR[n][i]-dSndRi) > tol2 {
					tst.Errorf("%s dS%ddR%d failed with err = %g\n", name, n, i, math.Abs(shape.dSdR[n][i]-dSndRi))
					return
				}
				//chk.Scalar(tst, fmt.Sprintf("dS%ddR%d", n, i), tol2, dSdR[n][i], dSndRi)
			}
		}

		// check face vertices
		tol = 1e-17
		errS = 0.0
		if name == "tri10" {
			tol = 1e-14
		}

		nfaces := len(shape.FaceLocalV)
		if nfaces == 0 {
			continue
		}
		for k := 0; k < nfaces; k++ {
			for n := range shape.FaceLocalV[k] {
				rst := []float64{0, 0, 0}
				for i := 0; i < shape.Gndim; i++ {
					rst[i] = shape.NatCoords[i][n]
				}
				shape.Func(shape.S, shape.dSdR, rst[0], rst[1], rst[2], false)
				io.Pforan("S = %v\n", shape.S)
				for m := range shape.FaceLocalV[k] {
					if n == m {
						errS += math.Abs(shape.S[m] - 1.0)
					} else {
						errS += math.Abs(shape.S[m])
					}
				}
			}
		}
		io.Pforan("%g\n", errS)
		if errS > tol {
			tst.Errorf("%s failed with err = %g\n", name, errS)
			return
		}

		io.PfGreen("OK\n")
	}
}
예제 #7
0
// testing_compare_results_u compares results with u-formulation
func TestingCompareResultsU(tst *testing.T, simfilepath, cmpfname, alias string, tolK, tolu, tols float64, skipK, verbose bool) {

	// FEM structure
	fem := NewFEM(simfilepath, alias, false, false, true, false, verbose, 0)

	// set stage
	err := fem.SetStage(0)
	if err != nil {
		chk.Panic("cannot set stage:\n%v", err)
	}

	// zero solution
	err = fem.ZeroStage(0, true)
	if err != nil {
		chk.Panic("cannot zero stage data:\n%v", err)
	}

	// read file with comparison results
	buf, err := io.ReadFile(cmpfname)
	if err != nil {
		tst.Errorf("TestingCompareResultsU: ReadFile failed\n")
		return
	}

	// unmarshal json
	var cmp_set T_results_set
	err = json.Unmarshal(buf, &cmp_set)
	if err != nil {
		tst.Errorf("TestingCompareResultsU: Unmarshal failed\n")
		return
	}

	// run comparisons
	dom := fem.Domains[0]
	dmult := 1.0
	for idx, cmp := range cmp_set {

		// displacements multiplier
		if idx == 0 && math.Abs(cmp.DispMult) > 1e-10 {
			dmult = cmp.DispMult
		}

		// time index
		tidx := idx + 1
		if verbose {
			io.PfYel("\n\ntidx = %d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", tidx)
		}

		// load gofem results
		err = dom.Read(fem.Summary, tidx, 0, true)
		if err != nil {
			chk.Panic("cannot read 'gofem' results:\n%v", err)
		}
		if verbose {
			io.Pfyel("time = %v\n", dom.Sol.T)
		}

		// check K matrices
		if !skipK {
			if verbose {
				io.Pfgreen(". . . checking K matrices . . .\n")
			}
			for eid, Ksg := range cmp.Kmats {
				if e, ok := dom.Elems[eid].(*ElemU); ok {
					err = e.AddToKb(dom.Kb, dom.Sol, true)
					if err != nil {
						chk.Panic("TestingCompareResultsU: AddToKb failed\n")
					}
					chk.Matrix(tst, io.Sf("K%d", eid), tolK, e.K, Ksg)
				}
				if e, ok := dom.Elems[eid].(*Rod); ok {
					err = e.AddToKb(dom.Kb, dom.Sol, true)
					if err != nil {
						chk.Panic("TestingCompareResultsU: AddToKb failed\n")
					}
					chk.Matrix(tst, io.Sf("K%d", eid), tolK, e.K, Ksg)
				}
				if e, ok := dom.Elems[eid].(*ElastRod); ok {
					err = e.AddToKb(dom.Kb, dom.Sol, true)
					if err != nil {
						chk.Panic("TestingCompareResultsU: AddToKb failed\n")
					}
					chk.Matrix(tst, io.Sf("K%d", eid), tolK, e.K, Ksg)
				}
			}
		}

		// check displacements
		if verbose {
			io.Pfgreen(". . . checking displacements . . .\n")
		}
		for nid, usg := range cmp.Disp {
			ix := dom.Vid2node[nid].Dofs[0].Eq
			iy := dom.Vid2node[nid].Dofs[1].Eq
			chk.AnaNum(tst, "ux", tolu, dom.Sol.Y[ix], usg[0]*dmult, verbose)
			chk.AnaNum(tst, "uy", tolu, dom.Sol.Y[iy], usg[1]*dmult, verbose)
			if len(usg) == 3 {
				iz := dom.Vid2node[nid].Dofs[2].Eq
				chk.AnaNum(tst, "uz", tolu, dom.Sol.Y[iz], usg[2]*dmult, verbose)
			}
		}

		// check stresses
		if true {
			if verbose {
				io.Pfgreen(". . . checking stresses . . .\n")
			}
			for eid, sig := range cmp.Sigmas {
				if verbose {
					io.Pforan("eid = %d\n", eid)
				}
				if e, ok := dom.Cid2elem[eid].(*ElemU); ok {
					for ip, val := range sig {
						if verbose {
							io.Pfgrey2("ip = %d\n", ip)
						}
						σ := e.States[ip].Sig
						if len(val) == 6 {
							chk.AnaNum(tst, "sx ", tols, σ[0], val[0], verbose)
							chk.AnaNum(tst, "sy ", tols, σ[1], val[1], verbose)
						} else {
							chk.AnaNum(tst, "sx ", tols, σ[0], val[0], verbose)
							chk.AnaNum(tst, "sy ", tols, σ[1], val[1], verbose)
							chk.AnaNum(tst, "sxy", tols, σ[3]/SQ2, val[2], verbose)
							if len(val) > 3 { // sx, sy, sxy, sz
								chk.AnaNum(tst, "sz ", tols, σ[2], val[3], verbose)
							}
						}
					}
				}
				if e, ok := dom.Cid2elem[eid].(*Rod); ok {
					for ip, val := range sig {
						if verbose {
							io.Pfgrey2("ip = %d\n", ip)
						}
						σ := e.States[ip].Sig
						chk.AnaNum(tst, "sig", tols, σ, val[0], verbose)
					}
				}
				if e, ok := dom.Cid2elem[eid].(*ElastRod); ok {
					dat := e.OutIpsData()
					for ip, val := range sig {
						if verbose {
							io.Pfgrey2("ip = %d\n", ip)
						}
						res := dat[ip].Calc(dom.Sol)
						σ := res["sig"]
						chk.AnaNum(tst, "sig", tols, σ, val[0], verbose)
					}
				}
			}
		}
	}
}