示例#1
0
func Test_imap(tst *testing.T) {

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

	for name, shape := range factory {
		gndim := shape.Gndim
		if gndim == 1 {
			continue
		}

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

		// check inverse mapping
		tol := 1e-14
		noise := 0.01
		if name == "tri10" {
			tol = 1e-14
		}
		if shape.FaceNvertsMax > 2 {
			noise = 0.0
		}
		nverts := shape.Nverts
		C := la.MatAlloc(gndim, nverts)
		s := []float64{rand.Float64(), rand.Float64(), rand.Float64()} // scale factors
		la.MatCopy(C, 1.0, shape.NatCoords)
		_ = tol
		io.Pf("nverts:%v\n", nverts)
		io.Pf("gndim:%v\n", gndim)
		for i := 0; i < gndim; i++ {
			for j := 0; j < nverts; j++ {
				C[i][j] *= s[i]
				C[i][j] += noise * rand.Float64() // noise
			}
		}

		r := make([]float64, 3)
		x := make([]float64, 3)
		R := la.MatAlloc(gndim, nverts)

		for j := 0; j < nverts; j++ {
			for i := 0; i < gndim; i++ {
				x[i] = C[i][j]
			}
			err := shape.InvMap(r, x, C)
			io.Pf("r:%v\n", r)
			_ = err
			for i := 0; i < gndim; i++ {
				R[i][j] = r[i]
			}
		}

		chk.Matrix(tst, "checking", tol, R, shape.NatCoords)

		io.PfGreen("OK\n")
	}
}
示例#2
0
// Set copies states
//  Note: 1) this and other states must have been pre-allocated with the same sizes
//        2) this method does not check for errors
func (o *State) Set(other *State) {

	// essential
	copy(o.Sig, other.Sig)

	// for plasticity
	if len(o.Alp) > 0 {
		copy(o.EpsTr, other.EpsTr)
		copy(o.Alp, other.Alp)
		o.Dgam = other.Dgam
		o.Loading = other.Loading
		o.ApexReturn = other.ApexReturn
	}

	// non-linear elasticity
	if len(o.EpsE) > 0 {
		copy(o.EpsE, other.EpsE)
	}

	// large deformations
	if len(o.F) > 0 {
		la.MatCopy(o.F, 1, other.F)
	}
}
示例#3
0
func Test_nls04(tst *testing.T) {

	//verbose()
	chk.PrintTitle("nls04. finite differences problem")

	// grid
	var g fdm.Grid2D
	g.Init(1.0, 1.0, 6, 6)

	// equations numbering
	var e fdm.Equations
	peq := utl.IntUnique(g.L, g.R, g.B, g.T)
	e.Init(g.N, peq)

	// K11 and K12
	var K11, K12 la.Triplet
	fdm.InitK11andK12(&K11, &K12, &e)

	// assembly
	F1 := make([]float64, e.N1)
	fdm.Assemble(&K11, &K12, F1, nil, &g, &e)

	// prescribed values
	U2 := make([]float64, e.N2)
	for _, eq := range g.L {
		U2[e.FR2[eq]] = 50.0
	}
	for _, eq := range g.R {
		U2[e.FR2[eq]] = 0.0
	}
	for _, eq := range g.B {
		U2[e.FR2[eq]] = 0.0
	}
	for _, eq := range g.T {
		U2[e.FR2[eq]] = 50.0
	}

	// functions
	k11 := K11.ToMatrix(nil)
	k12 := K12.ToMatrix(nil)
	ffcn := func(fU1, U1 []float64) error { // K11*U1 + K12*U2 - F1
		la.VecCopy(fU1, -1, F1)            // fU1 := (-F1)
		la.SpMatVecMulAdd(fU1, 1, k11, U1) // fU1 += K11*U1
		la.SpMatVecMulAdd(fU1, 1, k12, U2) // fU1 += K12*U2
		return nil
	}
	Jfcn := func(dfU1dU1 *la.Triplet, U1 []float64) error {
		fdm.Assemble(dfU1dU1, &K12, F1, nil, &g, &e)
		return nil
	}
	JfcnD := func(dfU1dU1 [][]float64, U1 []float64) error {
		la.MatCopy(dfU1dU1, 1, K11.ToMatrix(nil).ToDense())
		return nil
	}

	prms := map[string]float64{
		"atol":    1e-8,
		"rtol":    1e-8,
		"ftol":    1e-12,
		"lSearch": 0.0,
	}

	// init
	var nls_sps NlSolver // sparse analytical
	var nls_num NlSolver // sparse numerical
	var nls_den NlSolver // dense analytical
	nls_sps.Init(e.N1, ffcn, Jfcn, nil, false, false, prms)
	nls_num.Init(e.N1, ffcn, nil, nil, false, true, prms)
	nls_den.Init(e.N1, ffcn, nil, JfcnD, true, false, prms)
	defer nls_sps.Clean()
	defer nls_num.Clean()
	defer nls_den.Clean()

	// results
	U1sps := make([]float64, e.N1)
	U1num := make([]float64, e.N1)
	U1den := make([]float64, e.N1)
	Usps := make([]float64, e.N)
	Unum := make([]float64, e.N)
	Uden := make([]float64, e.N)

	// solution
	Uc := []float64{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 50.0, 25.0, 325.0 / 22.0, 100.0 / 11.0, 50.0 / 11.0,
		0.0, 50.0, 775.0 / 22.0, 25.0, 375.0 / 22.0, 100.0 / 11.0, 0.0, 50.0, 450.0 / 11.0, 725.0 / 22.0,
		25.0, 325.0 / 22.0, 0.0, 50.0, 500.0 / 11.0, 450.0 / 11.0, 775.0 / 22.0, 25.0, 0.0, 50.0, 50.0,
		50.0, 50.0, 50.0, 50.0,
	}

	io.PfYel("\n---- sparse -------- Analytical Jacobian -------------------\n")

	// solve
	err := nls_sps.Solve(U1sps, false)
	if err != nil {
		chk.Panic(err.Error())
	}

	// check
	fdm.JoinVecs(Usps, U1sps, U2, &e)
	chk.Vector(tst, "Usps", 1e-14, Usps, Uc)

	// plot
	if false {
		g.Contour("results", "fig_t_heat_square", nil, Usps, 11, false)
	}

	io.PfYel("\n---- dense -------- Analytical Jacobian -------------------\n")

	// solve
	err = nls_den.Solve(U1den, false)
	if err != nil {
		chk.Panic(err.Error())
	}

	// check
	fdm.JoinVecs(Uden, U1den, U2, &e)
	chk.Vector(tst, "Uden", 1e-14, Uden, Uc)

	io.PfYel("\n---- sparse -------- Numerical Jacobian -------------------\n")

	// solve
	err = nls_num.Solve(U1num, false)
	if err != nil {
		chk.Panic(err.Error())
	}

	// check
	fdm.JoinVecs(Unum, U1num, U2, &e)
	chk.Vector(tst, "Unum", 1e-14, Unum, Uc)
}
示例#4
0
// CheckDerivs check derivatives computed by isotropic function
func (o *IsoFun) CheckDerivs(A []float64, tol, tol2, tolq, tol3 float64, ver bool, args ...interface{}) (err error) {

	// L and invariants
	chk.IntAssert(len(A), o.ncp)
	L := make([]float64, 3)
	err = M_EigenValsNum(L, A)
	if err != nil {
		return
	}
	p, q, err := GenInvs(L, o.n, o.a)
	if err != nil {
		return
	}
	io.Pforan("L     = %v\n", L)
	io.Pforan("p, q  = %v, %v\n", p, q)

	// constants
	h := 1e-6
	var has_error error

	// derivatives of callback functions ///////////////

	// df/dp, df/dq, d²f/dp², d²f/dq², d²f/dpdq
	dfdp, dfdq := o.gfcn(p, q, args...)
	d2fdp2, d2fdq2, d2fdpdq := o.hfcn(p, q, args...)
	if ver {
		io.Pfpink("\nd w.r.t invariants . . . \n")
	}

	// check df/dp
	dfdp_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
		return o.ffcn(x, q, args...)
	}, p, h)
	err = chk.PrintAnaNum("df/dp   ", tol, dfdp, dfdp_num, ver)
	if err != nil {
		has_error = err
	}

	// check df/dq
	dfdq_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
		return o.ffcn(p, x, args...)
	}, q, h)
	err = chk.PrintAnaNum("df/dq   ", tol, dfdq, dfdq_num, ver)
	if err != nil {
		has_error = err
	}

	// check d²f/dp²
	d2fdp2_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
		dfdp_tmp, _ := o.gfcn(x, q, args...)
		return dfdp_tmp
	}, p, h)
	err = chk.PrintAnaNum("d²f/dp² ", tol, d2fdp2, d2fdp2_num, ver)
	if err != nil {
		has_error = err
	}

	// check d²f/dq²
	d2fdq2_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
		_, dfdq_tmp := o.gfcn(p, x, args...)
		return dfdq_tmp
	}, q, h)
	err = chk.PrintAnaNum("d²f/dq² ", tol, d2fdq2, d2fdq2_num, ver)
	if err != nil {
		has_error = err
	}

	// check d²f/dpdq
	d2fdpdq_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
		dfdp_tmp, _ := o.gfcn(p, x, args...)
		return dfdp_tmp
	}, q, h)
	err = chk.PrintAnaNum("d²f/dpdq", tol, d2fdpdq, d2fdpdq_num, ver)
	if err != nil {
		has_error = err
	}

	// derivatives w.r.t eigenvalues ///////////////////

	// df/dL and d²f/dLdL
	_, err = o.Gp(L, args...)
	if err != nil {
		chk.Panic("Gp failed:\n%v", err)
	}
	err = o.HafterGp(args...)
	if err != nil {
		chk.Panic("HafterGp failed:\n%v", err)
	}
	dfdL := make([]float64, 3)
	d2pdLdL := la.MatAlloc(3, 3)
	d2qdLdL := la.MatAlloc(3, 3)
	d2fdLdL := la.MatAlloc(3, 3)
	copy(dfdL, o.DfdL)
	la.MatCopy(d2pdLdL, 1, o.d2pdLdL)
	la.MatCopy(d2qdLdL, 1, o.d2qdLdL)
	la.MatCopy(d2fdLdL, 1, o.DgdL)

	// check df/dL
	if ver {
		io.Pfpink("\ndf/dL . . . . . . . . \n")
	}
	var fval, tmp float64
	for j := 0; j < 3; j++ {
		dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
			tmp, L[j] = L[j], x
			defer func() { L[j] = tmp }()
			fval, err = o.Fp(L, args...)
			if err != nil {
				chk.Panic("Fp failed:\n%v", err)
			}
			return fval
		}, L[j], h)
		err := chk.PrintAnaNum(io.Sf("df/dL[%d]", j), tol, dfdL[j], dnum, ver)
		if err != nil {
			has_error = err
		}
	}

	// check d²p/dLdL
	if ver {
		io.Pfpink("\nd²p/dLdL . . . . . . . . \n")
	}
	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
				tmp, L[j] = L[j], x
				defer func() { L[j] = tmp }()
				_, err = o.Gp(L, args...)
				if err != nil {
					chk.Panic("Gp failed\n%v", err)
				}
				return o.dpdL[i]
			}, L[j], h)
			err := chk.PrintAnaNum(io.Sf("d²p/dL[%d]dL[%d]", i, j), tol2, d2pdLdL[i][j], dnum, ver)
			if err != nil {
				has_error = err
			}
		}
	}

	// check d²q/dLdL
	if ver {
		io.Pfpink("\nd²q/dLdL . . . . . . . . \n")
	}
	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
				tmp, L[j] = L[j], x
				defer func() { L[j] = tmp }()
				_, err = o.Gp(L, args...)
				if err != nil {
					chk.Panic("Gp failed\n%v", err)
				}
				return o.dqdL[i]
			}, L[j], h)
			err := chk.PrintAnaNum(io.Sf("d²q/dL[%d]dL[%d]", i, j), tolq, d2qdLdL[i][j], dnum, ver)
			if err != nil {
				has_error = err
			}
		}
	}

	// check d²f/dLdL
	if ver {
		io.Pfpink("\nd²f/dLdL . . . . . . . . \n")
	}
	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
				tmp, L[j] = L[j], x
				defer func() { L[j] = tmp }()
				_, err = o.Gp(L, args...)
				if err != nil {
					chk.Panic("Gp failed\n%v", err)
				}
				return o.DfdL[i]
			}, L[j], h)
			err := chk.PrintAnaNum(io.Sf("d²f/dL[%d]dL[%d]", i, j), tol2, d2fdLdL[i][j], dnum, ver)
			if err != nil {
				has_error = err
			}
		}
	}

	// derivatives w.r.t full tensor ///////////////////

	// dfdA and d²f/dAdA
	ncp := len(A)
	dfdA := make([]float64, ncp)
	d2fdAdA := la.MatAlloc(ncp, ncp)
	_, err = o.Ga(dfdA, A, args...) // also computes P, L and Acpy
	if err != nil {
		chk.Panic("Ga failed:\n%v", err)
	}
	err = o.HafterGa(d2fdAdA, args...) // also computes dPdA
	if err != nil {
		chk.Panic("HafterGa failed:\n%v", err)
	}

	// check df/dA
	if ver {
		io.Pfpink("\ndf/dA . . . . . . . . \n")
	}
	for j := 0; j < ncp; j++ {
		dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
			tmp, A[j] = A[j], x
			defer func() { A[j] = tmp }()
			fval, err = o.Fa(A, args...)
			if err != nil {
				chk.Panic("Fa failed:\n%v", err)
			}
			return fval
		}, A[j], h)
		err := chk.PrintAnaNum(io.Sf("df/dA[%d]", j), tol, dfdA[j], dnum, ver)
		if err != nil {
			has_error = err
		}
	}

	// check dP/dA
	if false {
		for k := 0; k < 3; k++ {
			if ver {
				io.Pfpink("\ndP%d/dA . . . . . . . . \n", k)
			}
			for i := 0; i < ncp; i++ {
				for j := 0; j < ncp; j++ {
					dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
						tmp, A[j] = A[j], x
						defer func() { A[j] = tmp }()
						err = M_EigenValsProjsNum(o.P, o.L, o.Acpy)
						if err != nil {
							chk.Panic("M_EigenValsProjsNum failed:\n%v", err)
						}
						return o.P[k][i]
					}, A[j], h)
					err := chk.PrintAnaNum(io.Sf("dP%d/dA[%d]dA[%d]", k, i, j), tol, o.dPdA[k][i][j], dnum, ver)
					if err != nil {
						has_error = err
					}
				}
			}
		}
	}

	// check d²f/dAdA
	if ver {
		io.Pfpink("\nd²f/dAdA . . . . . . . . \n")
	}
	dfdA_tmp := make([]float64, ncp)
	for i := 0; i < ncp; i++ {
		for j := 0; j < ncp; j++ {
			dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) {
				tmp, A[j] = A[j], x
				defer func() { A[j] = tmp }()
				_, err = o.Ga(dfdA_tmp, A, args...)
				if err != nil {
					chk.Panic("Ga failed:\n%v", err)
				}
				return dfdA_tmp[i]
			}, A[j], h)
			dtol := tol2
			if i == j && (i == 3 || i == 4 || i == 5) {
				dtol = tol3
			}
			err := chk.PrintAnaNum(io.Sf("d²f/dA[%d]dA[%d]", i, j), dtol, d2fdAdA[i][j], dnum, ver)
			if err != nil {
				has_error = err
			}
		}
	}

	// any errors?
	if has_error != nil {
		err = has_error
	}
	return
}