Пример #1
0
// msg prints information on residuals
func (o *NlSolver) msg(typ string, it int, Ldx, fx_max float64, first, last bool) {
	if first {
		io.Pfpink("\n%4s%23s%23s\n", "it", "Ldx", "fx_max")
		io.Pfpink("%4s%23s%23s\n", "", io.Sf("(%7.1e)", o.fnewt), io.Sf("(%7.1e)", o.ftol))
		return
	}
	io.Pfyel("%4d%23.15e%23.15e\n", it, Ldx, fx_max)
	if last {
		io.Pfgrey(". . . converged with %s. nit=%d, nFeval=%d, nJeval=%d\n", typ, it, o.NFeval, o.NJeval)
	}
}
Пример #2
0
func Test_GOflt01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("GOflt01. float64")

	Init(1234)

	xmin := 10.0
	xmax := 20.0
	vals := make([]float64, NSAMPLES)

	// using Float64
	t0 := time.Now()
	for i := 0; i < NSAMPLES; i++ {
		vals[i] = Float64(xmin, xmax)
	}
	io.Pforan("time elapsed = %v\n", time.Now().Sub(t0))

	hist := Histogram{Stations: []float64{10, 12.5, 15, 17.5, 20}}
	hist.Count(vals, true)
	io.Pfpink(TextHist(hist.GenLabels("%4g"), hist.Counts, 60))

	// using Float64s
	t0 = time.Now()
	Float64s(vals, xmin, xmax)
	io.Pforan("time elapsed = %v\n", time.Now().Sub(t0))

	hist.Count(vals, true)
	io.Pfblue2(TextHist(hist.GenLabels("%4g"), hist.Counts, 60))
}
Пример #3
0
func Test_fileio01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("fileio01")

	// start
	analysis := NewFEM("data/bh16.sim", "", true, false, false, false, chk.Verbose, 0)

	// domain A
	domsA := NewDomains(analysis.Sim, analysis.DynCfs, analysis.HydSta, 0, 1, false)
	if len(domsA) == 0 {
		tst.Errorf("NewDomains failed\n")
		return
	}
	domA := domsA[0]
	err := domA.SetStage(0)
	if err != nil {
		tst.Errorf("SetStage failed\n%v", err)
		return
	}
	for i, _ := range domA.Sol.Y {
		domA.Sol.Y[i] = float64(i)
	}
	io.Pforan("domA.Sol.Y = %v\n", domA.Sol.Y)

	// write file
	tidx := 123
	err = domA.SaveSol(tidx, true)
	if err != nil {
		tst.Errorf("SaveSol failed:\n%v", err)
		return
	}

	// domain B
	domsB := NewDomains(analysis.Sim, analysis.DynCfs, analysis.HydSta, 0, 1, false)
	if len(domsB) == 0 {
		tst.Errorf("NewDomains failed\n")
		return
	}
	domB := domsB[0]
	err = domB.SetStage(0)
	if err != nil {
		tst.Errorf("SetStage failed\n%v", err)
		return
	}
	io.Pfpink("domB.Sol.Y (before) = %v\n", domB.Sol.Y)

	// read file
	err = domB.ReadSol(analysis.Sim.DirOut, analysis.Sim.Key, analysis.Sim.EncType, tidx)
	if err != nil {
		tst.Errorf("ReadSol failed:\n%v", err)
		return
	}
	io.Pfgreen("domB.Sol.Y (after) = %v\n", domB.Sol.Y)

	// check
	chk.Vector(tst, "Y", 1e-17, domA.Sol.Y, domB.Sol.Y)
	chk.Vector(tst, "dy/dt", 1e-17, domA.Sol.Dydt, domB.Sol.Dydt)
	chk.Vector(tst, "d²y/dt²", 1e-17, domA.Sol.D2ydt2, domB.Sol.D2ydt2)
}
Пример #4
0
func Test_ind02(tst *testing.T) {

	//verbose()
	chk.PrintTitle("ind02. copy into")

	rnd.Init(0)

	nbases := 1
	A := get_individual(0, nbases)
	B := get_individual(1, nbases)

	fmts := map[string][]string{
		"int": {"%2d", "%4d", "%5d"}, // ints
		"flt": {"%6g", "%6g", "%5g"}, // floats
		"str": {"%4s", "%2s", "%2s"}, // strings
		"key": {"%3x", "%3x", "%3x"}, // keys
		"byt": {"%4s", "%4s", "%4s"}, // bytes
		"fun": {"%3s", "%3s", "%3s"}, // funcs
	}
	io.Pfpink("A = %v\n", A.Output(fmts, false))
	io.Pfcyan("B = %v\n", B.Output(fmts, false))

	var ops OpsData
	ops.SetDefault()
	ops.Pc = 1.0
	ops.Cuts = []int{1, 2}
	ops.Xrange = [][]float64{{0, 1}, {-20, 20}, {-300, 300}}

	a := A.GetCopy()
	b := A.GetCopy()
	IndCrossover(a, b, A, B, 0, &ops)

	io.Pforan("a = %v\n", a.Output(fmts, false))
	io.Pfblue2("b = %v\n", b.Output(fmts, false))

	chk.Ints(tst, "a.Ints   ", a.Ints, []int{1, -20, 300})
	chk.Ints(tst, "b.Ints   ", b.Ints, []int{-1, 20, -300})
	chk.Strings(tst, "a.Strings", a.Strings, []string{"abc", "Y", "c"})
	chk.Strings(tst, "b.Strings", b.Strings, []string{"X", "b", "Z"})
	// TODO: add other tests here
	io.Pf("\n")

	x := get_individual(0, nbases)
	x.Ovas = []float64{0, 0}
	x.Oors = []float64{0, 0, 0}
	io.Pfblue2("x = %v\n", x.Output(fmts, false))
	B.CopyInto(x)

	chk.Scalar(tst, "ova0", 1e-17, x.Ovas[0], 200)
	chk.Scalar(tst, "ova1", 1e-17, x.Ovas[1], 100)
	chk.Scalar(tst, "oor0", 1e-17, x.Oors[0], 15)
	chk.Scalar(tst, "oor1", 1e-17, x.Oors[1], 25)
	chk.Scalar(tst, "oor2", 1e-17, x.Oors[2], 35)

	io.Pforan("x = %v\n", x.Output(fmts, false))
	chk.String(tst, x.Output(fmts, false), B.Output(fmts, false))
}
Пример #5
0
func Test_fileio01(tst *testing.T) {

	chk.PrintTitle("fileio01")

	// start
	if !Start("data/bh16.sim", true, chk.Verbose) {
		tst.Errorf("test failed\n")
	}
	defer End()

	// domain A
	distr := false
	domA := NewDomain(Global.Sim.Regions[0], distr)
	if domA == nil {
		tst.Errorf("test failed\n")
	}
	if !domA.SetStage(0, Global.Sim.Stages[0], distr) {
		tst.Errorf("test failed\n")
	}
	for i, _ := range domA.Sol.Y {
		domA.Sol.Y[i] = float64(i)
	}
	io.Pforan("domA.Sol.Y = %v\n", domA.Sol.Y)

	// write file
	tidx := 123
	if !domA.SaveSol(tidx) {
		tst.Errorf("test failed")
		return
	}
	dir, fnk := Global.Dirout, Global.Fnkey
	io.Pfblue2("file %v written\n", out_nod_path(dir, fnk, tidx, Global.Rank))

	// domain B
	domB := NewDomain(Global.Sim.Regions[0], distr)
	if domB == nil {
		tst.Errorf("test failed\n")
	}
	if !domB.SetStage(0, Global.Sim.Stages[0], distr) {
		tst.Errorf("test failed")
	}
	io.Pfpink("domB.Sol.Y (before) = %v\n", domB.Sol.Y)

	// read file
	if !domB.ReadSol(dir, fnk, tidx) {
		tst.Errorf("test failed")
		return
	}
	io.Pfgreen("domB.Sol.Y (after) = %v\n", domB.Sol.Y)

	// check
	chk.Vector(tst, "Y", 1e-17, domA.Sol.Y, domB.Sol.Y)
	chk.Vector(tst, "dy/dt", 1e-17, domA.Sol.Dydt, domB.Sol.Dydt)
	chk.Vector(tst, "d²y/dt²", 1e-17, domA.Sol.D2ydt2, domB.Sol.D2ydt2)
}
Пример #6
0
func Test_sort05(tst *testing.T) {

	//verbose()
	chk.PrintTitle("sort05")

	a := map[string]int{"a": 1, "z": 2, "c": 3, "y": 4, "d": 5, "b": 6, "x": 7}
	b := map[string]float64{"a": 1, "z": 2, "c": 3, "y": 4, "d": 5, "b": 6, "x": 7}
	c := map[string]bool{"a": false, "z": true, "c": false, "y": true, "d": true, "b": false, "x": true}
	ka := StrIntMapSort(a)
	kb := StrDblMapSort(b)
	kc := StrBoolMapSort(c)
	io.Pforan("sorted_keys(a) = %v\n", ka)
	io.Pforan("sorted_keys(b) = %v\n", kb)
	io.Pforan("sorted_keys(c) = %v\n", kc)
	chk.Strings(tst, "ka", ka, []string{"a", "b", "c", "d", "x", "y", "z"})
	chk.Strings(tst, "kb", kb, []string{"a", "b", "c", "d", "x", "y", "z"})
	chk.Strings(tst, "kc", kc, []string{"a", "b", "c", "d", "x", "y", "z"})

	ka, va := StrIntMapSortSplit(a)
	io.Pfpink("sorted_keys(a) = %v\n", ka)
	io.Pfpink("sorted_vals(a) = %v\n", va)
	chk.Strings(tst, "ka", ka, []string{"a", "b", "c", "d", "x", "y", "z"})
	chk.Ints(tst, "va", va, []int{1, 6, 3, 5, 7, 4, 2})

	kb, vb := StrDblMapSortSplit(b)
	io.Pfcyan("sorted_keys(b) = %v\n", kb)
	io.Pfcyan("sorted_vals(b) = %v\n", vb)
	chk.Strings(tst, "kb", kb, []string{"a", "b", "c", "d", "x", "y", "z"})
	chk.Vector(tst, "vb", 1e-16, vb, []float64{1, 6, 3, 5, 7, 4, 2})

	kc, vc := StrBoolMapSortSplit(c)
	io.Pfcyan("sorted_keys(c) = %v\n", kc)
	io.Pfcyan("sorted_vals(c) = %v\n", vc)
	chk.Strings(tst, "kc", kc, []string{"a", "b", "c", "d", "x", "y", "z"})
	chk.Bools(tst, "vc", vc, []bool{false, false, false, true, true, true, true})
}
Пример #7
0
// KrefineN return a new Nurbs with each span divided into ndiv parts = [2, 3, ...]
func (o *Nurbs) KrefineN(ndiv int, hughesEtAlPaper bool) *Nurbs {
	X := make([][]float64, o.gnd)
	if hughesEtAlPaper {
		elems := o.Elements()
		switch o.gnd {
		case 2:
			for _, e := range elems {
				umin, umax := o.b[0].T[e[0]], o.b[0].T[e[1]]
				vmin, vmax := o.b[1].T[e[2]], o.b[1].T[e[3]]
				xa := o.Point([]float64{umin, vmin})
				xb := o.Point([]float64{umax, vmin})
				xc := []float64{(xa[0] + xb[0]) / 2.0, (xa[1] + xb[1]) / 2.0}

				io.Pf("xa = %v\n", xa)
				io.Pf("xb = %v\n", xb)
				io.Pf("xc = %v\n", xc)

				xa = o.Point([]float64{umin, vmax})
				xb = o.Point([]float64{umax, vmax})
				xc = []float64{(xa[0] + xb[0]) / 2.0, (xa[1] + xb[1]) / 2.0}

				io.Pfpink("xa, xb, xc = %v, %v, %v\n", xa, xb, xc)
				chk.Panic("KrefineN with hughesEtAlPaper==true is not implemented in 2D yet")
			}
		case 3:
			chk.Panic("KrefineN with hughesEtAlPaper==true is not implemented in 3D yet")
		}
		io.Pfgrey("KrefineN with hughesEtAlPaper==true => not implemented yet\n")
		return nil
	} else {
		for d := 0; d < o.gnd; d++ {
			nspans := o.b[d].m - 2*o.p[d] - 1
			nnewk := nspans * (ndiv - 1)
			X[d] = make([]float64, nnewk)
			k := 0
			for i := 0; i < nspans; i++ {
				umin, umax := o.b[d].T[o.p[d]+i], o.b[d].T[o.p[d]+i+1]
				du := (umax - umin) / float64(ndiv)
				for j := 1; j < ndiv; j++ {
					X[d][k] = umin + du*float64(j)
					k += 1
				}
			}
		}
	}
	return o.Krefine(X)
}
Пример #8
0
func Test_nurbs01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("nurbs01")

	nurbs := get_nurbs_A()
	faces := nurbs.ExtractSurfaces()
	spans := nurbs.Elements()
	ibasis0 := nurbs.IndBasis(spans[0])
	ibasis1 := nurbs.IndBasis(spans[1])
	io.Pforan("spans = %v\n", spans)
	chk.Ints(tst, "span0", spans[0], []int{2, 3, 1, 2})
	chk.Ints(tst, "span1", spans[1], []int{3, 4, 1, 2})
	chk.Ints(tst, "ibasis0", ibasis0, []int{0, 1, 2, 4, 5, 6})
	chk.Ints(tst, "ibasis1", ibasis1, []int{1, 2, 3, 5, 6, 7})

	shape0 := GetShapeNurbs(nurbs, faces, spans[0])
	shape1 := GetShapeNurbs(nurbs, faces, spans[1])

	dux := 0.5
	duy := 1.0
	drx := 2.0
	dry := 2.0

	r := []float64{0.75, 0.75, 0}

	shape0.NurbsFunc(shape0.S, shape0.DSdR, r, true, -1)
	io.Pforan("0: u = %v\n", shape0.U)
	chk.Scalar(tst, "0: ux", 1e-17, shape0.U[0], (1.0+r[0])*dux/drx)
	chk.Scalar(tst, "0: uy", 1e-17, shape0.U[1], (1.0+r[1])*duy/dry)
	chk.Ints(tst, "0: ibasis", shape0.Ibasis, []int{0, 1, 2, 4, 5, 6})

	io.Pforan("S(u(r)) = %v\n", shape0.S)

	shape1.NurbsFunc(shape1.S, shape1.DSdR, r, true, -1)
	io.Pfpink("\n1: u = %v\n", shape1.U)
	chk.Scalar(tst, "1: ux", 1e-17, shape1.U[0], 0.5+(1.0+r[0])*dux/drx)
	chk.Scalar(tst, "1: uy", 1e-17, shape1.U[1], (1.0+r[1])*duy/dry)
	chk.Ints(tst, "1: ibasis", shape1.Ibasis, []int{1, 2, 3, 5, 6, 7})

	if chk.Verbose {
		gm.PlotNurbs("/tmp/gofem", "tst_nurbs01", nurbs, 21, false, nil)
	}
}
Пример #9
0
func Test_pareto01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("pareto01. compare vectors: Pareto-optimal")

	u := []float64{1, 2, 3, 4, 5, 6}
	v := []float64{1, 2, 3, 4, 5, 6}
	io.Pforan("u = %v\n", u)
	io.Pfblue2("v = %v\n", v)
	u_dominates, v_dominates := DblsParetoMin(u, v)
	io.Pfpink("u_dominates = %v\n", u_dominates)
	io.Pfpink("v_dominates = %v\n", v_dominates)
	if u_dominates {
		tst.Errorf("test failed\n")
		return
	}
	if v_dominates {
		tst.Errorf("test failed\n")
		return
	}

	v = []float64{1, 1.8, 3, 4, 5, 6}
	io.Pforan("\nu = %v\n", u)
	io.Pfblue2("v = %v\n", v)
	u_dominates, v_dominates = DblsParetoMin(u, v)
	io.Pfpink("u_dominates = %v\n", u_dominates)
	io.Pfpink("v_dominates = %v\n", v_dominates)
	if u_dominates {
		tst.Errorf("test failed\n")
		return
	}
	if !v_dominates {
		tst.Errorf("test failed\n")
		return
	}

	v = []float64{1, 2.1, 3, 4, 5, 6}
	io.Pforan("\nu = %v\n", u)
	io.Pfblue2("v = %v\n", v)
	u_dominates, v_dominates = DblsParetoMin(u, v)
	io.Pfpink("u_dominates = %v\n", u_dominates)
	io.Pfpink("v_dominates = %v\n", v_dominates)
	if !u_dominates {
		tst.Errorf("test failed\n")
		return
	}
	if v_dominates {
		tst.Errorf("test failed\n")
		return
	}
}
Пример #10
0
func RunInvCheck(tst *testing.T, key string, M, CorrectInvM [][]float64, checkI bool, Tol, TolI float64) {
	m, n := len(M), len(M[0])
	Mi := MatAlloc(n, m)
	t0 := time.Now()
	err := MatInvG(Mi, M, 1e-13)
	if err != nil {
		chk.Panic("%v", err.Error())
	}
	io.Pfpink("Lapack: time elapsed = %v\n", time.Now().Sub(t0))
	MMi := MatAlloc(m, m)
	MMiM := MatAlloc(m, n)
	MatMul(MMi, 1, M, Mi)   // MMi = M * Mi
	MatMul(MMiM, 1, MMi, M) // MMiM = M * Mi * M == M
	chk.Matrix(tst, io.Sf("%s => Mi - CorrectInvM ", key), Tol, Mi, CorrectInvM)
	chk.Matrix(tst, io.Sf("%s => M*Mi*M = M       ", key), Tol, MMiM, M)
	if checkI {
		I := MatAlloc(m, m)
		MatSetDiag(I, 1)
		chk.Matrix(tst, io.Sf("%s => M*Mi = I         ", key), TolI, MMi, I)
	}
}
Пример #11
0
// KrefineN return a new Nurbs with each span divided into ndiv parts = [2, 3, ...]
func (o *Nurbs) KrefineN(ndiv int, useCspace bool) *Nurbs {
	X := make([][]float64, o.gnd)
	if useCspace {
		elems := o.Elements()
		for _, e := range elems {
			switch o.gnd {
			case 2:
				umin, umax := o.b[0].T[e[0]], o.b[0].T[e[1]]
				vmin, vmax := o.b[1].T[e[2]], o.b[1].T[e[3]]
				xa := o.Point([]float64{umin, vmin})
				xb := o.Point([]float64{umax, vmin})
				xc := []float64{(xa[0] + xb[0]) / 2.0, (xa[1] + xb[1]) / 2.0}
				io.Pforan("xa, xb, xc = %v, %v, %v\n", xa, xb, xc)
				xa = o.Point([]float64{umin, vmax})
				xb = o.Point([]float64{umax, vmax})
				xc = []float64{(xa[0] + xb[0]) / 2.0, (xa[1] + xb[1]) / 2.0}
				io.Pfpink("xa, xb, xc = %v, %v, %v\n", xa, xb, xc)
			}
		}
		chk.Panic("nurbs.go: KrefineN with useCspace==true => not implemented yet")
	} else {
		for d := 0; d < o.gnd; d++ {
			nspans := o.b[d].m - 2*o.p[d] - 1
			nnewk := nspans * (ndiv - 1)
			X[d] = make([]float64, nnewk)
			k := 0
			for i := 0; i < nspans; i++ {
				umin, umax := o.b[d].T[o.p[d]+i], o.b[d].T[o.p[d]+i+1]
				du := (umax - umin) / float64(ndiv)
				for j := 1; j < ndiv; j++ {
					X[d][k] = umin + du*float64(j)
					k += 1
				}
			}
		}
	}
	return o.Krefine(X)
}
Пример #12
0
func Test_map03(tst *testing.T) {

	//verbose()
	chk.PrintTitle("map03")

	m := map[string][]int{
		"a": []int{100, 101},
		"b": []int{1000},
		"c": []int{200, 300, 400},
	}
	io.Pforan("m (before) = %v\n", m)
	StrIntsMapAppend(&m, "a", 102)
	io.Pfpink("m (after) = %v\n", m)
	chk.Ints(tst, "m[\"a\"]", m["a"], []int{100, 101, 102})
	chk.Ints(tst, "m[\"b\"]", m["b"], []int{1000})
	chk.Ints(tst, "m[\"c\"]", m["c"], []int{200, 300, 400})
	StrIntsMapAppend(&m, "d", 666)
	io.Pfcyan("m (after) = %v\n", m)
	chk.Ints(tst, "m[\"a\"]", m["a"], []int{100, 101, 102})
	chk.Ints(tst, "m[\"b\"]", m["b"], []int{1000})
	chk.Ints(tst, "m[\"c\"]", m["c"], []int{200, 300, 400})
	chk.Ints(tst, "m[\"d\"]", m["d"], []int{666})
	chk.Ints(tst, "m[\"e\"]", m["e"], nil)
}
Пример #13
0
func Test_frechet_03(tst *testing.T) {

	//verbose()
	chk.PrintTitle("dist_frechet_03")

	μ := 10.0
	σ := 5.0
	δ := σ / μ
	d := 1.0 + δ*δ
	io.Pforan("μ=%v σ=%v δ=%v d=%v\n", μ, σ, δ, d)

	if chk.Verbose {
		plt.AxHline(d, "color='k'")
		FrechetPlotCoef("/tmp/gosl", "fig_frechet_coef.eps", 3.0, 5.0)
	}

	k := 0.2441618
	α := 1.0 / k
	l := μ - math.Gamma(1.0-k)
	io.Pfpink("l=%v α=%v\n", l, α)

	l = 8.782275
	α = 4.095645

	var dist DistFrechet
	dist.Init(&VarData{L: l, A: α})
	io.Pforan("dist = %+#v\n", dist)
	io.Pforan("mean = %v\n", dist.Mean())
	io.Pforan("var  = %v\n", dist.Variance())
	io.Pforan("σ    = %v\n", math.Sqrt(dist.Variance()))

	if chk.Verbose {
		plot_frechet(l, 1, α, 8, 16)
		plt.SaveD("/tmp/gosl", "rnd_dist_frechet_03.eps")
	}
}
Пример #14
0
func Test_map01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("map01")

	m := map[int][]int{
		1: []int{100, 101},
		2: []int{1000},
		3: []int{200, 300, 400},
	}
	io.Pforan("m (before) = %v\n", m)
	IntIntsMapAppend(&m, 1, 102)
	io.Pfpink("m (after) = %v\n", m)
	chk.Ints(tst, "m[1]", m[1], []int{100, 101, 102})
	chk.Ints(tst, "m[2]", m[2], []int{1000})
	chk.Ints(tst, "m[3]", m[3], []int{200, 300, 400})
	IntIntsMapAppend(&m, 4, 666)
	io.Pfcyan("m (after) = %v\n", m)
	chk.Ints(tst, "m[1]", m[1], []int{100, 101, 102})
	chk.Ints(tst, "m[2]", m[2], []int{1000})
	chk.Ints(tst, "m[3]", m[3], []int{200, 300, 400})
	chk.Ints(tst, "m[4]", m[4], []int{666})
	chk.Ints(tst, "m[5]", m[5], nil)
}
Пример #15
0
func Test_ends01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("ends01")

	size := 8
	cuts := []int{5, 7}
	ends := GenerateCxEnds(size, 0, cuts)
	io.Pfpink("size=%v cuts=%v\n", size, cuts)
	io.Pfyel("ends = %v\n", ends)
	chk.IntAssert(len(ends), 3)
	chk.IntAssert(ends[len(ends)-1], size)
	checkRepeated(ends)
	io.Pf("\n")

	size = 2
	cuts = []int{}
	ends = GenerateCxEnds(size, 0, cuts)
	io.Pfpink("size=%v cuts=%v\n", size, cuts)
	io.Pforan("ends = %v\n", ends)
	chk.Ints(tst, "ends", ends, []int{1, 2})
	chk.IntAssert(ends[len(ends)-1], size)
	checkRepeated(ends)
	io.Pf("\n")

	size = 3
	ncuts := 3
	ends = GenerateCxEnds(size, ncuts, nil)
	io.Pfpink("size=%v ncuts=%v\n", size, ncuts)
	io.Pforan("ends = %v\n", ends)
	chk.Ints(tst, "ends", ends, []int{1, 2, 3})
	chk.IntAssert(ends[len(ends)-1], size)
	checkRepeated(ends)
	io.Pf("\n")

	size = 3
	ncuts = 2
	ends = GenerateCxEnds(size, ncuts, nil)
	io.Pfpink("size=%v ncuts=%v\n", size, ncuts)
	io.Pforan("ends = %v\n", ends)
	chk.Ints(tst, "ends", ends, []int{1, 2, 3})
	chk.IntAssert(ends[len(ends)-1], size)
	checkRepeated(ends)
	io.Pf("\n")

	size = 8
	cuts = []int{7}
	ends = GenerateCxEnds(size, 0, cuts)
	io.Pfpink("size=%v cuts=%v\n", size, cuts)
	io.Pforan("ends = %v\n", ends)
	chk.Ints(tst, "ends", ends, []int{7, 8})
	chk.IntAssert(ends[len(ends)-1], size)
	checkRepeated(ends)
	io.Pf("\n")

	size = 8
	cuts = []int{2, 5}
	ends = GenerateCxEnds(size, 0, cuts)
	io.Pfpink("size=%v cuts=%v\n", size, cuts)
	io.Pforan("ends = %v\n", ends)
	chk.Ints(tst, "ends", ends, []int{2, 5, 8})
	chk.IntAssert(ends[len(ends)-1], size)
	checkRepeated(ends)
	io.Pf("\n")

	size = 20
	cuts = []int{1, 5, 15, 17}
	ends = GenerateCxEnds(size, 0, cuts)
	io.Pfpink("size=%v cuts=%v\n", size, cuts)
	io.Pfyel("ends = %v\n", ends)
	chk.Ints(tst, "ends", ends, []int{1, 5, 15, 17, 20})
	chk.IntAssert(ends[len(ends)-1], size)
	checkRepeated(ends)
	io.Pf("\n")

	size = 20
	ncuts = 5
	ends = GenerateCxEnds(size, ncuts, cuts)
	io.Pfpink("size=%v cuts=%v\n", size, cuts)
	io.Pfyel("ends = %v\n", ends)
	chk.IntAssert(ends[len(ends)-1], size)
	checkRepeated(ends)
	io.Pf("\n")
}
Пример #16
0
func Test_isofun01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("isofun01. rounded cone")

	// SMP director parameters
	//  Note:
	//   1) eps and ϵ have an effect on how close to DP/MC SMP will be
	//   2) as eps increases, SMP is closer to DP/MC
	//   3) as ϵ increases, SMP is closer to DP/MC
	//   4) eps also changes the shape of FC surface
	a, b, eps, ϵ := -1.0, 0.5, 1e-3, 1e-3
	shift := 1.0

	// radius
	r := 2.0

	// failure crit parameters and number of stress components
	φ, ncp := 30.0, 6

	// q/p coefficient
	μ := SmpCalcμ(φ, a, b, eps, ϵ)
	io.Pforan("μ = %v\n", μ)

	// isotropic functions
	var o IsoFun
	o.Init(a, b, eps, ϵ, shift, ncp, rounded_cone_ffcn, rounded_cone_gfcn, rounded_cone_hfcn)

	// plot
	if false {
		//if true {
		σcCte := 10.0
		M := Phi2M(φ, "oct")
		rmin, rmax := 0.0, 1.28*M*σcCte
		nr, nα := 31, 81
		//nr,   nα   := 31, 1001
		npolarc := true
		simplec := true
		only0 := true
		grads := false
		showpts := false
		ferr := 10.0
		PlotOct("fig_isofun01.png", σcCte, rmin, rmax, nr, nα, φ, o.Fa, o.Ga,
			npolarc, simplec, only0, grads, showpts, true, true, ferr, r, μ)
	}

	// 3D view
	if false {
		//if true {
		grads := true
		gftol := 5e-2
		o.View(10, nil, grads, gftol, func(e *vtk.IsoSurf) {
			e.Nlevels = 7
		}, r, μ)
	}

	// constants
	ver := chk.Verbose
	tol := 1e-6
	tol2 := 1e-6
	tolq := tol2

	// check gradients
	for idxA := 0; idxA < len(test_nd); idxA++ {
		//for idxA := 0; idxA < 1; idxA++ {
		//for idxA := 2; idxA < 3; idxA++ {
		//for idxA := 10; idxA < 11; idxA++ {
		//for idxA := 11; idxA < 12; idxA++ {
		//for idxA := 12; idxA < 13; idxA++ {

		// tensor
		AA := test_AA[idxA]
		A := M_Alloc2(3)
		Ten2Man(A, AA)
		io.PfYel("\n\ntst # %d ###################################################################################\n", idxA)
		io.Pfblue2("A = %v\n", A)

		// function evaluation and shifted eigenvalues
		fval, err := o.Fa(A, r, μ)
		if err != nil {
			chk.Panic("cannot compute F(A):\n%v", err)
		}
		io.Pfpink("shift = %v\n", shift)
		io.Pforan("p, q  = %v, %v\n", o.p, o.q)
		io.Pforan("f(A)  = %v\n", fval)

		// change tolerances
		tol3 := tol2
		tol2_tmp := tol2
		switch idxA {
		case 7:
			tolq = 1e-5
		case 10:
			tolq = 2508  // TODO
			tol3 = 0.772 // TODO: check why test # 10 fails with d2f/dAdA
		case 11:
			tol2 = 0.0442 // TODO: check this
			tol3 = 440    //TODO: check this
		case 12:
			tol2 = 1e-3
			tol3 = 0.082 // TODO: check this
		}

		// check gradients
		err = o.CheckDerivs(A, tol, tol2, tolq, tol3, ver, r, μ)
		if err != nil {

			// plot
			if true {
				np := 41
				pmin, pmax := -o.p*10, o.p*10
				pq_point := []float64{o.p, o.q}
				o.PlotFfcn("/tmp", io.Sf("t_isofun01_%d.png", idxA), pmin, pmax, np, pq_point, "", "'ro'", nil, nil, r, μ)
			}

			// test failed
			chk.Panic("CheckDerivs failed:%v\n", err)
		}

		// recover tolerances
		tol2 = tol2_tmp
	}
}
Пример #17
0
func Test_nurbs01(tst *testing.T) {

	/*  4 (1,2)             (2,2) 6
	    5  2@o--------------o@3   7
	         |              |
	         |              |      @     -- control point
	         |              |      o     -- node
	         |              |      (a,b) -- span
	         |              |
	         |              |
	    0  0@o--------------o@1   2
	    1 (1,1)             (2,1) 3
	*/

	//verbose()
	chk.PrintTitle("nurb01. square with initial stress")

	// fem
	analysis := NewFEM("data/nurbs01.sim", "", true, false, false, false, chk.Verbose, 0)

	// set stage
	err := analysis.SetStage(0)
	if err != nil {
		tst.Errorf("SetStage failed:\n%v", err)
		return
	}

	// initialise solution vectors
	err = analysis.ZeroStage(0, true)
	if err != nil {
		tst.Errorf("ZeroStage failed:\n%v", err)
		return
	}

	// domain
	dom := analysis.Domains[0]

	// draw NURBS
	if false {
		nurbs := dom.Msh.Cells[0].Shp.Nurbs
		gm.PlotNurbs("/tmp/gofem", "test_nurbs01", nurbs, 21, false, nil)
	}

	// nodes and elements
	chk.IntAssert(len(dom.Nodes), 4)
	chk.IntAssert(len(dom.Elems), 1)

	// check dofs
	for _, nod := range dom.Nodes {
		chk.IntAssert(len(nod.Dofs), 2)
		chk.StrAssert(nod.Dofs[0].Key, "ux")
		chk.StrAssert(nod.Dofs[1].Key, "uy")
	}

	// check equations
	nids, eqs := get_nids_eqs(dom)
	chk.Ints(tst, "eqs", eqs, utl.IntRange(4*2))
	chk.Ints(tst, "nids", nids, []int{0, 1, 2, 3})

	// check Umap
	Umaps := [][]int{
		{0, 1, 2, 3, 4, 5, 6, 7},
	}
	for i, ele := range dom.Elems {
		e := ele.(*ElemU)
		io.Pfpink("%2d : Umap = %v\n", e.Id(), e.Umap)
		chk.Ints(tst, "Umap", e.Umap, Umaps[i])
	}

	// constraints
	chk.IntAssert(len(dom.EssenBcs.Bcs), 4)
	var ct_ux_eqs []int // equations with ux prescribed [sorted]
	var ct_uy_eqs []int // equations with uy prescribed [sorted]
	for _, c := range dom.EssenBcs.Bcs {
		chk.IntAssert(len(c.Eqs), 1)
		eq := c.Eqs[0]
		io.Pfgrey("key=%v eq=%v\n", c.Key, eq)
		switch c.Key {
		case "ux":
			ct_ux_eqs = append(ct_ux_eqs, eq)
		case "uy":
			ct_uy_eqs = append(ct_uy_eqs, eq)
		default:
			tst.Errorf("key %s is incorrect", c.Key)
		}
	}
	sort.Ints(ct_ux_eqs)
	sort.Ints(ct_uy_eqs)
	chk.Ints(tst, "equations with ux prescribed", ct_ux_eqs, []int{0, 4})
	chk.Ints(tst, "equations with uy prescribed", ct_uy_eqs, []int{1, 3})

	// check displacements
	tolu := 1e-16
	for _, n := range dom.Nodes {
		eqx := n.GetEq("ux")
		eqy := n.GetEq("uy")
		u := []float64{dom.Sol.Y[eqx], dom.Sol.Y[eqy]}
		chk.Vector(tst, "u", tolu, u, nil)
	}

	// analytical solution
	qnV, qnH := -100.0, -50.0
	ν := 0.25
	σx, σy := qnH, qnV
	σz := ν * (σx + σy)
	σref := []float64{σx, σy, σz, 0}

	// check stresses
	e := dom.Elems[0].(*ElemU)
	tols := 1e-13
	for idx, _ := range e.IpsElem {
		σ := e.States[idx].Sig
		io.Pforan("σ = %v\n", σ)
		chk.Vector(tst, "σ", tols, σ, σref)
	}
}
Пример #18
0
func Test_up01a(tst *testing.T) {

	/* this tests simulates seepage flow along a column
	 * by reducing the initial hydrostatic pressure at
	 * at the bottom of the column
	 *
	 *   using mesh from col104elay.msh
	 *
	 *      Nodes / Tags                       Equations
	 *                              ux uy pl               ux uy pl
	 *     8 o----o----o 9 (-5)     53 54 55  o----o----o  50 51 52
	 *       |   14    |             .  .  .  |  58 59  |   .  .  .
	 *       |  (-1)   |             .  .  .  |         |   .  .  .
	 *    21 o    o    o 22 (-6)    60 61  .  o    o    o  56 57  .
	 *       |   26    |             .  .  .  |  62 63  |   .  .  .
	 *       |         |             .  .  .  |         |   .  .  .
	 *     6 o----o----o 7 (-4)     39 40 41  o----o----o  36 37 38
	 *       |   13    |             .  .  .  |  44 45  |   .  .  .
	 *       |  (-1)   |             .  .  .  |         |   .  .  .
	 *    19 |    o    o 20 (-6)    46 47  .  |    o    o  42 43  .
	 *       |   25    |             .  .  .  |  48 49  |   .  .  .
	 *       |         |             .  .  .  |         |   .  .  .
	 *     4 o----o----o 5 (-3)     25 26 27  o----o----o  22 23 24
	 *       |   12    |             .  .  .  |  30 31  |   .  .  .
	 *       |  (-2)   |             .  .  .  |         |   .  .  .
	 *    17 o    o    o 18 (-6)    32 33  .  o    o    o  28 29  .
	 *       |   24    |             .  .  .  |  34 35  |   .  .  .
	 *       |         |             .  .  .  |         |   .  .  .
	 *     2 o----o----o 3 (-2)      9 10 11  o----o----o   6  7  8
	 *       |   11    |             .  .  .  |  16 17  |   .  .  .
	 *       |  (-2)   |             .  .  .  |         |   .  .  .
	 *    15 o    o    o 16 (-6)    18 19     o    o    o  14 15
	 *       |   23    |             .  .  .  |  20 21  |   .  .  .
	 *       |         |             .  .  .  |         |   .  .  .
	 *     0 o----o----o 1 (-1)      0  1  2  o----o----o   3  4  5
	 *           10                              12 13
	 */

	// capture errors and flush log
	defer End()

	//verbose()
	chk.PrintTitle("up01a")

	// start simulation
	if !Start("data/up01.sim", true, chk.Verbose) {
		chk.Panic("cannot start simulation")
	}

	// domain
	distr := false
	dom := NewDomain(Global.Sim.Regions[0], distr)
	if dom == nil {
		chk.Panic("cannot allocate new domain")
	}

	// set stage
	if !dom.SetStage(0, Global.Sim.Stages[0], distr) {
		chk.Panic("cannot set stage")
	}

	// nodes and elements
	chk.IntAssert(len(dom.Nodes), 27)
	chk.IntAssert(len(dom.Elems), 4)

	if true {

		// nodes with pl
		nods_with_pl := map[int]bool{0: true, 2: true, 4: true, 6: true, 8: true, 1: true, 3: true, 5: true, 7: true, 9: true}

		// check dofs
		for _, nod := range dom.Nodes {
			if nods_with_pl[nod.Vert.Id] {
				chk.IntAssert(len(nod.Dofs), 3)
				chk.StrAssert(nod.Dofs[0].Key, "ux")
				chk.StrAssert(nod.Dofs[1].Key, "uy")
				chk.StrAssert(nod.Dofs[2].Key, "pl")
			} else {
				chk.IntAssert(len(nod.Dofs), 2)
				chk.StrAssert(nod.Dofs[0].Key, "ux")
				chk.StrAssert(nod.Dofs[1].Key, "uy")
			}
		}

		// check equations
		nids, eqs := get_nids_eqs(dom)
		chk.Ints(tst, "eqs", eqs, utl.IntRange(10*3+17*2))
		chk.Ints(tst, "nids", nids, []int{
			0, 1, 3, 2, 10, 16, 11, 15, 23,
			5, 4, 18, 12, 17, 24,
			7, 6, 20, 13, 19, 25,
			9, 8, 22, 14, 21, 26,
		})

		// check pmap
		Pmaps := [][]int{
			{2, 5, 8, 11},
			{11, 8, 24, 27},
			{27, 24, 38, 41},
			{41, 38, 52, 55},
		}
		Umaps := [][]int{
			{0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21},
			{9, 10, 6, 7, 22, 23, 25, 26, 16, 17, 28, 29, 30, 31, 32, 33, 34, 35},
			{25, 26, 22, 23, 36, 37, 39, 40, 30, 31, 42, 43, 44, 45, 46, 47, 48, 49},
			{39, 40, 36, 37, 50, 51, 53, 54, 44, 45, 56, 57, 58, 59, 60, 61, 62, 63},
		}
		for i, ele := range dom.Elems {
			e := ele.(*ElemUP)
			io.Pfpink("%2d : Pmap = %v\n", e.Id(), e.P.Pmap)
			io.Pfpink("%2d : Umap = %v\n", e.Id(), e.U.Umap)
			chk.Ints(tst, "Pmap", e.P.Pmap, Pmaps[i])
			chk.Ints(tst, "Umap", e.U.Umap, Umaps[i])
		}

		// constraints
		chk.IntAssert(len(dom.EssenBcs.Bcs), 9*2+2+3)
		var ct_ux_eqs []int // equations with ux prescribed [sorted]
		var ct_uy_eqs []int // equations with uy prescribed [sorted]
		var ct_pl_eqs []int // equations with pl prescribed [sorted]
		for _, c := range dom.EssenBcs.Bcs {
			chk.IntAssert(len(c.Eqs), 1)
			eq := c.Eqs[0]
			io.Pfgrey("key=%v eq=%v\n", c.Key, eq)
			switch c.Key {
			case "ux":
				ct_ux_eqs = append(ct_ux_eqs, eq)
			case "uy":
				ct_uy_eqs = append(ct_uy_eqs, eq)
			case "pl":
				ct_pl_eqs = append(ct_pl_eqs, eq)
			default:
				tst.Errorf("key %s is incorrect", c.Key)
			}
		}
		sort.Ints(ct_ux_eqs)
		sort.Ints(ct_uy_eqs)
		sort.Ints(ct_pl_eqs)
		chk.Ints(tst, "equations with ux prescribed", ct_ux_eqs, []int{0, 3, 6, 9, 14, 18, 22, 25, 28, 32, 36, 39, 42, 46, 50, 53, 56, 60})
		chk.Ints(tst, "equations with uy prescribed", ct_uy_eqs, []int{1, 4, 13})
		chk.Ints(tst, "equations with pl prescribed", ct_pl_eqs, []int{2, 5})

	}

	// initial values @ nodes
	io.Pforan("initial values @ nodes\n")
	for _, nod := range dom.Nodes {
		z := nod.Vert.C[1]
		for _, dof := range nod.Dofs {
			u := dom.Sol.Y[dof.Eq]
			switch dof.Key {
			case "ux":
				chk.Scalar(tst, io.Sf("nod %3d : ux(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-17, u, 0)
			case "uy":
				chk.Scalar(tst, io.Sf("nod %3d : uy(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-17, u, 0)
			case "pl":
				plC, _, _ := Global.HydroSt.Calc(z)
				chk.Scalar(tst, io.Sf("nod %3d : pl(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-13, u, plC)
			}
		}
	}

	// intial values @ integration points
	io.Pforan("initial values @ integration points\n")
	for _, ele := range dom.Elems {
		e := ele.(*ElemUP)
		for idx, ip := range e.P.IpsElem {
			s := e.P.States[idx]
			z := e.P.Shp.IpRealCoords(e.P.X, ip)[1]
			chk.AnaNum(tst, io.Sf("sl(z=%11.8f)", z), 1e-17, s.A_sl, 1, chk.Verbose)
		}
	}

	// parameters
	ν := 0.2            // Poisson's coefficient
	K0 := ν / (1.0 - ν) // earth pressure at rest
	nf := 0.3           // porosity
	sl := 1.0           // saturation
	ρL := 1.0           // intrinsic (real) density of liquid
	ρS_top := 2.0       // intrinsic (real) density of solids in top layer
	ρS_bot := 3.0       // intrinsic (real) density of solids in bottom layer
	h := 5.0            // height of each layer
	g := 10.0           // gravity

	// densities
	nl := nf * sl         // volume fraction of luqid
	ns := 1.0 - nf        // volume fraction of solid
	ρl := nl * ρL         // partial density of liquid
	ρs_top := ns * ρS_top // partial density of solids in top layer
	ρs_bot := ns * ρS_bot // partial density of solids in bottom layer
	ρ_top := ρl + ρs_top  // density of mixture in top layer
	ρ_bot := ρl + ρs_bot  // density of mixture in bottom layer

	// absolute values of stresses
	σV_z5 := ρ_top * g * h     // total vertical stress @ elevation z = 5 m (absolute value)
	σV_z0 := σV_z5 + ρ_bot*g*h // total vertical stress @ elevation z = 0 m (absolute value)
	io.Pfyel("ρ_top       = %g\n", ρ_top)
	io.Pfyel("ρ_bot       = %g\n", ρ_bot)
	io.Pfyel("|ΔσV_top|   = %g\n", ρ_top*g*h)
	io.Pfyel("|ΔσV_bot|   = %g\n", ρ_bot*g*h)
	io.PfYel("|σV|(@ z=0) = %g\n", σV_z0)
	io.PfYel("|σV|(@ z=5) = %g\n", σV_z5)

	// stress functions
	var sig fun.Pts
	var pres fun.Pts
	sig.Init(fun.Prms{
		&fun.Prm{N: "t0", V: 0.00}, {N: "y0", V: -σV_z0},
		&fun.Prm{N: "t1", V: 5.00}, {N: "y1", V: -σV_z5},
		&fun.Prm{N: "t2", V: 10.00}, {N: "y2", V: 0.0},
	})
	pres.Init(fun.Prms{
		&fun.Prm{N: "t0", V: 0.00}, {N: "y0", V: 100},
		&fun.Prm{N: "t1", V: 10.00}, {N: "y1", V: 0},
	})

	// check stresses
	io.Pforan("initial stresses @ integration points\n")
	for _, ele := range dom.Elems {
		e := ele.(*ElemUP)
		for idx, ip := range e.U.IpsElem {
			z := e.U.Shp.IpRealCoords(e.U.X, ip)[1]
			σe := e.U.States[idx].Sig
			sv := sig.F(z, nil)
			sve := sv + pres.F(z, nil)
			she := sve * K0
			if math.Abs(σe[2]-σe[0]) > 1e-17 {
				tst.Errorf("σx is not equal to σz: %g != %g\n", σe[2], σe[0])
				return
			}
			if math.Abs(σe[3]) > 1e-17 {
				tst.Errorf("σxy is not equal to zero: %g != 0\n", σe[3])
				return
			}
			chk.AnaNum(tst, io.Sf("sx(z=%11.8f)", z), 0.0003792, σe[0], she, chk.Verbose)
			chk.AnaNum(tst, io.Sf("sy(z=%11.8f)", z), 0.001517, σe[1], sve, chk.Verbose)
		}
	}
	return
}
Пример #19
0
func Test_mylab06(tst *testing.T) {

	//verbose()
	chk.PrintTitle("mylab06. scaling")

	// |dx|>0: increasing
	io.Pfblue2("\n|dx|>0: increasing\n")
	reverse := false
	useinds := true
	x := []float64{10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
	s := make([]float64, len(x))
	Scaling(s, x, -2.0, 1e-16, reverse, useinds)
	io.Pfpink("x = %v\n", x)
	io.Pforan("s = %v\n", s)
	chk.Vector(tst, "s", 1e-15, s, LinSpace(-2, -1, len(x)))

	// |dx|>0: reverse
	io.Pfblue2("\n|dx|>0: reverse\n")
	reverse = true
	Scaling(s, x, -3.0, 1e-16, reverse, useinds)
	io.Pfpink("x = %v\n", x)
	io.Pforan("s = %v\n", s)
	chk.Vector(tst, "s", 1e-15, s, LinSpace(-2, -3, len(x)))

	// |dx|>0: increasing
	io.Pfblue2("\n|dx|>0: increasing (shuffled)\n")
	reverse = false
	x = []float64{11, 10, 12, 19, 15, 20, 17, 16, 18, 13, 14}
	Scaling(s, x, 0.0, 1e-16, reverse, useinds)
	io.Pfpink("x = %v\n", x)
	io.Pforan("s = %v\n", s)
	chk.Vector(tst, "s", 1e-15, s, []float64{0.1, 0.0, 0.2, 0.9, 0.5, 1.0, 0.7, 0.6, 0.8, 0.3, 0.4})

	// |dx|=0: increasing (using indices)
	io.Pfblue2("\n|dx|=0: increasing (using indices)\n")
	reverse = false
	x = []float64{123, 123, 123, 123, 123}
	s = make([]float64, len(x))
	Scaling(s, x, 10.0, 1e-16, reverse, useinds)
	io.Pfpink("x = %v\n", x)
	io.Pforan("s = %v\n", s)
	chk.Vector(tst, "s", 1e-15, s, []float64{10, 10.25, 10.5, 10.75, 11})

	// |dx|=0: reverse (using indices)
	io.Pfblue2("\n|dx|=0: reverse (using indices)\n")
	reverse = true
	Scaling(s, x, 10.0, 1e-16, reverse, useinds)
	io.Pfpink("x = %v\n", x)
	io.Pforan("s = %v\n", s)
	chk.Vector(tst, "s", 1e-15, s, []float64{11, 10.75, 10.5, 10.25, 10})

	// |dx|=0: increasing (not using indices)
	io.Pfblue2("\n|dx|=0: increasing (not using indices)\n")
	reverse = false
	useinds = false
	Scaling(s, x, 88.0, 1e-16, reverse, useinds)
	io.Pfpink("x = %v\n", x)
	io.Pforan("s = %v\n", s)
	chk.Vector(tst, "s", 1e-15, s, DblVals(len(x), 88))

	// |dx|=0: reverse (not using indices)
	io.Pfblue2("\n|dx|=0: reverse (not using indices)\n")
	reverse = true
	Scaling(s, x, 88.0, 1e-16, reverse, useinds)
	io.Pfpink("x = %v\n", x)
	io.Pforan("s = %v\n", s)
	chk.Vector(tst, "s", 1e-15, s, DblVals(len(x), 88))
}
Пример #20
0
func Test_smpinvs02(tst *testing.T) {

	//verbose()
	chk.PrintTitle("smpinvs02")

	// coefficients for smp invariants
	smp_a := -1.0
	smp_b := 0.5
	smp_β := 1e-1 // derivative values become too high with
	smp_ϵ := 1e-1 // small β and ϵ @ zero

	// constants for checking derivatives
	dver := chk.Verbose
	dtol := 1e-9
	dtol2 := 1e-8

	// run tests
	nd := test_nd
	for idxA := 0; idxA < len(test_nd); idxA++ {
		//for idxA := 0; idxA < 1; idxA++ {
		//for idxA := 10; idxA < 11; idxA++ {

		// tensor and eigenvalues
		A := test_AA[idxA]
		a := M_Alloc2(nd[idxA])
		Ten2Man(a, A)
		L := make([]float64, 3)
		M_EigenValsNum(L, a)

		// SMP director
		N := make([]float64, 3)
		n := make([]float64, 3)
		m := SmpDirector(N, L, smp_a, smp_b, smp_β, smp_ϵ)
		SmpUnitDirector(n, m, N)

		// output
		io.PfYel("\n\ntst # %d ###################################################################################\n", idxA)
		io.Pforan("L = %v\n", L)
		io.Pforan("N = %v\n", N)
		io.Pforan("m = %v\n", m)
		io.Pfpink("n = %v\n", n)
		chk.Vector(tst, "L", 1e-12, L, test_λ[idxA])
		chk.Scalar(tst, "norm(n)==1", 1e-15, la.VecNorm(n), 1)
		chk.Scalar(tst, "m=norm(N)", 1e-14, m, la.VecNorm(N))

		// dN/dL
		var tmp float64
		N_tmp := make([]float64, 3)
		dNdL := make([]float64, 3)
		SmpDirectorDeriv1(dNdL, L, smp_a, smp_b, smp_β, smp_ϵ)
		io.Pfpink("\ndNdL = %v\n", dNdL)
		for i := 0; i < 3; i++ {
			dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
				tmp, L[i] = L[i], x
				SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
				L[i] = tmp
				return N_tmp[i]
			}, L[i], 1e-6)
			chk.AnaNum(tst, io.Sf("dN/dL[%d][%d]", i, i), dtol, dNdL[i], dnum, dver)
		}

		// dm/dL
		n_tmp := make([]float64, 3)
		dmdL := make([]float64, 3)
		SmpNormDirectorDeriv1(dmdL, m, N, dNdL)
		io.Pfpink("\ndmdL = %v\n", dmdL)
		for j := 0; j < 3; j++ {
			dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
				tmp, L[j] = L[j], x
				m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
				L[j] = tmp
				return m_tmp
			}, L[j], 1e-6)
			chk.AnaNum(tst, io.Sf("dm/dL[%d]", j), dtol, dmdL[j], dnum, dver)
		}

		// dn/dL
		dndL := la.MatAlloc(3, 3)
		SmpUnitDirectorDeriv1(dndL, m, N, dNdL, dmdL)
		io.Pfpink("\ndndL = %v\n", dndL)
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
					tmp, L[j] = L[j], x
					m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
					SmpUnitDirector(n_tmp, m_tmp, N_tmp)
					L[j] = tmp
					return n_tmp[i]
				}, L[j], 1e-6)
				chk.AnaNum(tst, io.Sf("dn/dL[%d][%d]", i, j), dtol, dndL[i][j], dnum, dver)
			}
		}

		// change tolerance
		dtol2_tmp := dtol2
		if idxA == 10 || idxA == 11 {
			dtol2 = 1e-6
		}

		// d²m/dLdL
		dNdL_tmp := make([]float64, 3)
		dmdL_tmp := make([]float64, 3)
		d2NdL2 := make([]float64, 3)
		d2mdLdL := la.MatAlloc(3, 3)
		SmpDirectorDeriv2(d2NdL2, L, smp_a, smp_b, smp_β, smp_ϵ)
		SmpNormDirectorDeriv2(d2mdLdL, L, smp_a, smp_b, smp_β, smp_ϵ, m, N, dNdL, d2NdL2, dmdL)
		io.Pfpink("\nd2mdLdL = %v\n", d2mdLdL)
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
					tmp, L[j] = L[j], x
					m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
					SmpDirectorDeriv1(dNdL_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
					SmpNormDirectorDeriv1(dmdL_tmp, m_tmp, N_tmp, dNdL_tmp)
					L[j] = tmp
					return dmdL_tmp[i]
				}, L[j], 1e-6)
				chk.AnaNum(tst, io.Sf("d2m/dL[%d]dL[%d]", i, j), dtol2, d2mdLdL[i][j], dnum, dver)
			}
		}

		// d²N/dLdL
		io.Pfpink("\nd²N/dLdL\n")
		for i := 0; i < 3; i++ {
			dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
				tmp, L[i] = L[i], x
				SmpDirectorDeriv1(dNdL_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
				L[i] = tmp
				return dNdL_tmp[i]
			}, L[i], 1e-6)
			chk.AnaNum(tst, io.Sf("d²N[%d]/dL[%d]dL[%d]", i, i, i), dtol2, d2NdL2[i], dnum, dver)
		}

		// d²n/dLdL
		io.Pfpink("\nd²n/dLdL\n")
		dndL_tmp := la.MatAlloc(3, 3)
		d2ndLdL := utl.Deep3alloc(3, 3, 3)
		SmpUnitDirectorDeriv2(d2ndLdL, m, N, dNdL, d2NdL2, dmdL, n, d2mdLdL, dndL)
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				for k := 0; k < 3; k++ {
					dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
						tmp, L[k] = L[k], x
						m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
						SmpDirectorDeriv1(dNdL_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
						SmpNormDirectorDeriv1(dmdL_tmp, m_tmp, N_tmp, dNdL_tmp)
						SmpUnitDirectorDeriv1(dndL_tmp, m_tmp, N_tmp, dNdL_tmp, dmdL_tmp)
						L[k] = tmp
						return dndL_tmp[i][j]
					}, L[k], 1e-6)
					chk.AnaNum(tst, io.Sf("d²n[%d]/dL[%d]dL[%d]", i, j, k), dtol2, d2ndLdL[i][j][k], dnum, dver)
				}
			}
		}

		// recover tolerance
		dtol2 = dtol2_tmp

		// SMP derivs
		//if false {
		if true {
			io.Pfpink("\nSMP derivs\n")
			dndL_ := la.MatAlloc(3, 3)
			dNdL_ := make([]float64, 3)
			d2ndLdL_ := utl.Deep3alloc(3, 3, 3)
			N_ := make([]float64, 3)
			F_ := make([]float64, 3)
			G_ := make([]float64, 3)
			m_ := SmpDerivs1(dndL_, dNdL_, N_, F_, G_, L, smp_a, smp_b, smp_β, smp_ϵ)
			SmpDerivs2(d2ndLdL_, L, smp_a, smp_b, smp_β, smp_ϵ, m_, N_, F_, G_, dNdL_, dndL_)
			chk.Scalar(tst, "m_", 1e-14, m_, m)
			chk.Vector(tst, "N_", 1e-15, N_, N)
			chk.Vector(tst, "dNdL_", 1e-15, dNdL_, dNdL)
			chk.Matrix(tst, "dndL_", 1e-13, dndL_, dndL)
			chk.Deep3(tst, "d2ndLdL_", 1e-11, d2ndLdL_, d2ndLdL)
		}
	}
}
Пример #21
0
func Test_list02(tst *testing.T) {

	//verbose()
	chk.PrintTitle("list02. DblSlist.Append")

	var L DblSlist

	L.Append(true, 0.0)
	io.Pforan("L.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "0: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "0: vals", 1e-17, L.Vals, []float64{0.0})
	chk.Ints(tst, "0: ptrs", L.Ptrs, []int{0, 1})

	L.Append(true, 1.0)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "1: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "1: vals", 1e-17, L.Vals, []float64{0.0, 1.0})
	chk.Ints(tst, "1: ptrs", L.Ptrs, []int{0, 1, 2})

	L.Append(false, 1.1)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "2: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "2: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1})
	chk.Ints(tst, "2: ptrs", L.Ptrs, []int{0, 1, 3})

	L.Append(false, 1.2)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "3: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "3: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2})
	chk.Ints(tst, "3: ptrs", L.Ptrs, []int{0, 1, 4})

	L.Append(false, 1.3)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "4: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "4: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3})
	chk.Ints(tst, "4: ptrs", L.Ptrs, []int{0, 1, 5})

	L.Append(true, 2.0)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "5: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "5: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0})
	chk.Ints(tst, "5: ptrs", L.Ptrs, []int{0, 1, 5, 6})

	L.Append(false, 2.1)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "6: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "6: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0, 2.1})
	chk.Ints(tst, "6: ptrs", L.Ptrs, []int{0, 1, 5, 7})

	L.Append(true, 3.0)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "7: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "7: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0})
	chk.Ints(tst, "7: ptrs", L.Ptrs, []int{0, 1, 5, 7, 8})

	L.Append(false, 3.1)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "8: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "8: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0, 3.1})
	chk.Ints(tst, "8: ptrs", L.Ptrs, []int{0, 1, 5, 7, 9})

	L.Append(false, 3.2)
	io.Pforan("\nL.Vals = %v\n", L.Vals)
	io.Pfpink("L.Ptrs = %v\n", L.Ptrs)
	chk.Ints(tst, "9: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)})
	chk.Vector(tst, "9: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0, 3.1, 3.2})
	chk.Ints(tst, "9: ptrs", L.Ptrs, []int{0, 1, 5, 7, 10})

	io.Pf("\n")
	L.Print("%10g")
}
Пример #22
0
// Solve solves y(x) = 0 for x in [xa, xb] with f(xa) * f(xb) < 0
//
//  Based on ZEROIN C math library: http://www.netlib.org/c/
//  By: Oleg Keselyov <[email protected], [email protected]> May 23, 1991
//
//   G.Forsythe, M.Malcolm, C.Moler, Computer methods for mathematical
//   computations. M., Mir, 1980, p.180 of the Russian edition
//
//   The function makes use of the bissection procedure combined with
//   the linear or quadric inverse interpolation.
//   At every step program operates on three abscissae - a, b, and c.
//   b - the last and the best approximation to the root
//   a - the last but one approximation
//   c - the last but one or even earlier approximation than a that
//       1) |f(b)| <= |f(c)|
//       2) f(b) and f(c) have opposite signs, i.e. b and c confine
//          the root
//   At every step Zeroin selects one of the two new approximations, the
//   former being obtained by the bissection procedure and the latter
//   resulting in the interpolation (if a,b, and c are all different
//   the quadric interpolation is utilized, otherwise the linear one).
//   If the latter (i.e. obtained by the interpolation) point is
//   reasonable (i.e. lies within the current interval [b,c] not being
//   too close to the boundaries) it is accepted. The bissection result
//   is used in the other case. Therefore, the range of uncertainty is
//   ensured to be reduced at least by the factor 1.6
//
func (o *Brent) Solve(xa, xb float64, silent bool) (res float64, err error) {

	// basic variables and function evaluation
	a := xa // the last but one approximation
	b := xb // the last and the best approximation to the root
	c := a  // the last but one or even earlier approximation than a that
	fa, erra := o.Ffcn(a)
	fb, errb := o.Ffcn(b)
	o.NFeval = 2
	if erra != nil {
		return 0, chk.Err(_brent_err1, "a", xa, erra.Error())
	}
	if errb != nil {
		return 0, chk.Err(_brent_err1, "b", xb, errb.Error())
	}
	fc := fa

	// check input
	if fa*fb >= -EPS {
		return 0, chk.Err(_brent_err2, xa, xb, fa, fb)
	}

	// message
	if !silent {
		io.Pfpink("%4s%23s%23s%23s\n", "it", "x", "f(x)", "err")
		io.Pfpink("%50s%23.1e\n", "", o.Tol)
	}

	// solve
	var prev_step float64  // distance from the last but one to the last approximation
	var tol_act float64    // actual tolerance
	var p, q float64       // interpol. step is calculated in the form p/q (divisions are delayed)
	var new_step float64   // step at this iteration
	var t1, cb, t2 float64 // auxiliary variables
	for o.It = 0; o.It < o.MaxIt; o.It++ {

		// distance
		prev_step = b - a

		// swap data for b to be the best approximation
		if math.Abs(fc) < math.Abs(fb) {
			a = b
			b = c
			c = a
			fa = fb
			fb = fc
			fc = fa
		}
		tol_act = 2.0*EPS*math.Abs(b) + o.Tol/2.0
		new_step = (c - b) / 2.0

		// converged?
		if !silent {
			io.Pfyel("%4d%23.15e%23.15e%23.15e\n", o.It, b, fb, math.Abs(new_step))
		}
		if math.Abs(new_step) <= tol_act || fb == 0.0 {
			return b, nil
		}

		// decide if the interpolation can be tried
		if math.Abs(prev_step) >= tol_act && math.Abs(fa) > math.Abs(fb) {
			// if prev_step was large enough and was in true direction, interpolatiom may be tried
			cb = c - b

			// with two distinct points, linear interpolation must be applied
			if a == c {
				t1 = fb / fa
				p = cb * t1
				q = 1.0 - t1

				// otherwise, quadric inverse interpolation is applied
			} else {
				q = fa / fc
				t1 = fb / fc
				t2 = fb / fa
				p = t2 * (cb*q*(q-t1) - (b-a)*(t1-1.0))
				q = (q - 1.0) * (t1 - 1.0) * (t2 - 1.0)
			}

			// p was calculated with the opposite sign;
			// make p positive and assign possible minus to q
			if p > 0.0 {
				q = -q
			} else {
				p = -p
			}

			// if b+p/q falls in [b,c] and isn't too large, it is accepted
			// if p/q is too large then the bissection procedure can reduce [b,c] range to more extent
			if p < (0.75*cb*q-math.Abs(tol_act*q)/2.0) && p < math.Abs(prev_step*q/2.0) {
				new_step = p / q
			}
		}

		// adjust the step to be not less than tolerance
		if math.Abs(new_step) < tol_act {
			if new_step > 0.0 {
				new_step = tol_act
			} else {
				new_step = -tol_act
			}
		}

		// save the previous approximation
		a = b
		fa = fb

		// do step to a new approximation
		b += new_step
		fb, errb = o.Ffcn(b)
		o.NFeval += 1
		if errb != nil {
			return 0, chk.Err(_brent_err1, "", b, errb.Error())
		}

		// adjust c for it to have a sign opposite to that of b
		if (fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0) {
			c = a
			fc = fa
		}
	}

	// did not converge
	return fb, chk.Err(_brent_err3, "Solve", o.It)
}
Пример #23
0
func Test_geninvs01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("geninvs01")

	// coefficients for smp invariants
	smp_a := -1.0
	smp_b := 0.5
	smp_β := 1e-1 // derivative values become too high with
	smp_ϵ := 1e-1 // small β and ϵ @ zero

	// constants for checking derivatives
	dver := chk.Verbose
	dtol := 1e-6
	dtol2 := 1e-6

	// run tests
	nd := test_nd
	for idxA := 0; idxA < len(test_nd); idxA++ {
		//for idxA := 10; idxA < 11; idxA++ {

		// tensor and eigenvalues
		A := test_AA[idxA]
		a := M_Alloc2(nd[idxA])
		Ten2Man(a, A)
		L := make([]float64, 3)
		M_EigenValsNum(L, a)

		// SMP derivs and SMP director
		dndL := la.MatAlloc(3, 3)
		dNdL := make([]float64, 3)
		d2ndLdL := utl.Deep3alloc(3, 3, 3)
		N := make([]float64, 3)
		F := make([]float64, 3)
		G := make([]float64, 3)
		m := SmpDerivs1(dndL, dNdL, N, F, G, L, smp_a, smp_b, smp_β, smp_ϵ)
		SmpDerivs2(d2ndLdL, L, smp_a, smp_b, smp_β, smp_ϵ, m, N, F, G, dNdL, dndL)
		n := make([]float64, 3)
		SmpUnitDirector(n, m, N)

		// SMP invariants
		p, q, err := GenInvs(L, n, smp_a)
		if err != nil {
			chk.Panic("SmpInvs failed:\n%v", err)
		}

		// output
		io.PfYel("\n\ntst # %d ###################################################################################\n", idxA)
		io.Pfblue2("L = %v\n", L)
		io.Pforan("n = %v\n", n)
		io.Pforan("p = %v\n", p)
		io.Pforan("q = %v\n", q)

		// check invariants
		tvec := make([]float64, 3)
		GenTvec(tvec, L, n)
		proj := make([]float64, 3) // projection of tvec along n
		tdn := la.VecDot(tvec, n)  // tvec dot n
		for i := 0; i < 3; i++ {
			proj[i] = tdn * n[i]
		}
		norm_proj := la.VecNorm(proj)
		norm_tvec := la.VecNorm(tvec)
		q_ := GENINVSQEPS + math.Sqrt(norm_tvec*norm_tvec-norm_proj*norm_proj)
		io.Pforan("proj = %v\n", proj)
		io.Pforan("norm(proj) = %v == p\n", norm_proj)
		chk.Scalar(tst, "p", 1e-14, math.Abs(p), norm_proj)
		chk.Scalar(tst, "q", 1e-13, q, q_)

		// dt/dL
		var tmp float64
		N_tmp := make([]float64, 3)
		n_tmp := make([]float64, 3)
		tvec_tmp := make([]float64, 3)
		dtdL := la.MatAlloc(3, 3)
		GenTvecDeriv1(dtdL, L, n, dndL)
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
					tmp, L[j] = L[j], x
					m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
					SmpUnitDirector(n_tmp, m_tmp, N_tmp)
					GenTvec(tvec_tmp, L, n_tmp)
					L[j] = tmp
					return tvec_tmp[i]
				}, L[j], 1e-6)
				chk.AnaNum(tst, io.Sf("dt/dL[%d][%d]", i, j), dtol, dtdL[i][j], dnum, dver)
			}
		}

		// d²t/dLdL
		io.Pfpink("\nd²t/dLdL\n")
		dNdL_tmp := make([]float64, 3)
		dndL_tmp := la.MatAlloc(3, 3)
		dtdL_tmp := la.MatAlloc(3, 3)
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				for k := 0; k < 3; k++ {
					dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
						tmp, L[k] = L[k], x
						m_tmp := SmpDerivs1(dndL_tmp, dNdL_tmp, N_tmp, F, G, L, smp_a, smp_b, smp_β, smp_ϵ)
						SmpUnitDirector(n_tmp, m_tmp, N_tmp)
						GenTvecDeriv1(dtdL_tmp, L, n_tmp, dndL_tmp)
						L[k] = tmp
						return dtdL_tmp[i][j]
					}, L[k], 1e-6)
					dana := GenTvecDeriv2(i, j, k, L, dndL, d2ndLdL[i][j][k])
					chk.AnaNum(tst, io.Sf("d²t[%d]/dL[%d]dL[%d]", i, j, k), dtol2, dana, dnum, dver)
				}
			}
		}

		// change tolerance
		dtol_tmp := dtol
		switch idxA {
		case 5, 11:
			dtol = 1e-5
		case 12:
			dtol = 0.0013
		}

		// first order derivatives
		dpdL := make([]float64, 3)
		dqdL := make([]float64, 3)
		p_, q_, err := GenInvsDeriv1(dpdL, dqdL, L, n, dndL, smp_a)
		if err != nil {
			chk.Panic("%v", err)
		}
		chk.Scalar(tst, "p", 1e-17, p, p_)
		chk.Scalar(tst, "q", 1e-17, q, q_)
		var ptmp, qtmp float64
		io.Pfpink("\ndp/dL\n")
		for j := 0; j < 3; j++ {
			dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
				tmp, L[j] = L[j], x
				m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
				SmpUnitDirector(n_tmp, m_tmp, N_tmp)
				ptmp, _, err = GenInvs(L, n_tmp, smp_a)
				if err != nil {
					chk.Panic("DerivCentral: SmpInvs failed:\n%v", err)
				}
				L[j] = tmp
				return ptmp
			}, L[j], 1e-6)
			chk.AnaNum(tst, io.Sf("dp/dL[%d]", j), dtol, dpdL[j], dnum, dver)
		}
		io.Pfpink("\ndq/dL\n")
		for j := 0; j < 3; j++ {
			dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
				tmp, L[j] = L[j], x
				m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ)
				SmpUnitDirector(n_tmp, m_tmp, N_tmp)
				_, qtmp, err = GenInvs(L, n_tmp, smp_a)
				if err != nil {
					chk.Panic("DerivCentral: SmpInvs failed:\n%v", err)
				}
				L[j] = tmp
				return qtmp
			}, L[j], 1e-6)
			chk.AnaNum(tst, io.Sf("dq/dL[%d]", j), dtol, dqdL[j], dnum, dver)
		}

		// recover tolerance
		dtol = dtol_tmp

		// change tolerance
		io.Pforan("dtol2 = %v\n", dtol2)
		dtol2_tmp := dtol2
		switch idxA {
		case 5:
			dtol2 = 1e-5
		case 10:
			dtol2 = 0.72
		case 11:
			dtol2 = 1e-5
		case 12:
			dtol2 = 544
		}

		// second order derivatives
		dpdL_tmp := make([]float64, 3)
		dqdL_tmp := make([]float64, 3)
		d2pdLdL := la.MatAlloc(3, 3)
		d2qdLdL := la.MatAlloc(3, 3)
		GenInvsDeriv2(d2pdLdL, d2qdLdL, L, n, dpdL, dqdL, p, q, dndL, d2ndLdL, smp_a)
		io.Pfpink("\nd²p/dLdL\n")
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
					tmp, L[j] = L[j], x
					m_tmp := SmpDerivs1(dndL_tmp, dNdL_tmp, N_tmp, F, G, L, smp_a, smp_b, smp_β, smp_ϵ)
					SmpUnitDirector(n_tmp, m_tmp, N_tmp)
					GenInvsDeriv1(dpdL_tmp, dqdL_tmp, L, n_tmp, dndL_tmp, smp_a)
					L[j] = tmp
					return dpdL_tmp[i]
				}, L[j], 1e-6)
				chk.AnaNum(tst, io.Sf("d²p/dL[%d][%d]", i, j), dtol2, d2pdLdL[i][j], dnum, dver)
			}
		}
		io.Pfpink("\nd²q/dLdL\n")
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
					tmp, L[j] = L[j], x
					m_tmp := SmpDerivs1(dndL_tmp, dNdL_tmp, N_tmp, F, G, L, smp_a, smp_b, smp_β, smp_ϵ)
					SmpUnitDirector(n_tmp, m_tmp, N_tmp)
					GenInvsDeriv1(dpdL_tmp, dqdL_tmp, L, n_tmp, dndL_tmp, smp_a)
					L[j] = tmp
					return dqdL_tmp[i]
				}, L[j], 1e-6)
				chk.AnaNum(tst, io.Sf("d²q/dL[%d][%d]", i, j), dtol2, d2qdLdL[i][j], dnum, dver)
			}
		}

		// recover tolerance
		dtol2 = dtol2_tmp
	}
}
Пример #24
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
}
Пример #25
0
func Test_bspline03(tst *testing.T) {

	//verbose()
	chk.PrintTitle("bspline03")

	//             0 1 2 3 4 5 6 7 8 9 10
	T := []float64{0, 0, 0, 1, 2, 3, 4, 4, 5, 5, 5}
	var s Bspline
	s.Init(T, 2)
	s.SetControl([][]float64{{0, 0}, {0.5, 1}, {1, 0}, {1.5, 0}, {2, 1}, {2.5, 1}, {3, 0.5}, {3.5, 0}})

	// analytical derivatives
	s.CalcBasisAndDerivs(3.99)
	io.Pfpink("ana: dNdt(t=3.99, i=5) = %v\n", s.GetDeriv(5))
	io.Pfpink("ana: dNdt(t=3.99, i=6) = %v\n", s.GetDeriv(6))
	io.Pfpink("ana: dNdt(t=3.99, i=7) = %v\n", s.GetDeriv(7))
	s.CalcBasisAndDerivs(4.0)
	io.Pforan("ana: dNdt(t=4.00, i=5) = %v\n", s.GetDeriv(5))
	io.Pforan("ana: dNdt(t=4.00, i=6) = %v\n", s.GetDeriv(6))
	io.Pforan("ana: dNdt(t=4.00, i=7) = %v\n", s.GetDeriv(7))

	// numerical derivatives
	io.Pfcyan("num: dNdt(t=3.99, i=5) = %v\n", s.NumericalDeriv(3.99, 5))
	io.Pfcyan("num: dNdt(t=3.99, i=6) = %v\n", s.NumericalDeriv(3.99, 6))
	io.Pfcyan("num: dNdt(t=3.99, i=7) = %v\n", s.NumericalDeriv(3.99, 7))
	io.Pfblue2("num: dNdt(t=4.00, i=5) = %v\n", s.NumericalDeriv(4.00, 5))
	io.Pfblue2("num: dNdt(t=4.00, i=6) = %v\n", s.NumericalDeriv(4.00, 6))
	io.Pfblue2("num: dNdt(t=4.00, i=7) = %v\n", s.NumericalDeriv(4.00, 7))

	ver := false
	tol := 1e-5
	tt := utl.LinSpace(0, 5, 11)
	numd := make([]float64, s.NumBasis())
	anad := make([]float64, s.NumBasis())
	for _, t := range tt {
		for i := 0; i < s.NumBasis(); i++ {
			s.CalcBasisAndDerivs(t)
			anad[i] = s.GetDeriv(i)
			numd[i] = s.NumericalDeriv(t, i)
			// numerical fails @ 4 [4,5,6]
			if t == 4 {
				numd[4] = anad[4]
				numd[5] = anad[5]
				numd[6] = anad[6]
			}
			chk.PrintAnaNum(io.Sf("i=%d t=%v", i, t), tol, anad[i], numd[i], ver)
		}
		chk.Vector(tst, io.Sf("derivs @ %v", t), tol, numd, anad)
	}

	if chk.Verbose {

		npts := 201
		plt.SetForPng(1.5, 600, 150)
		plt.SplotGap(0, 0.3)

		str0 := ",lw=2"
		str1 := ",ls='none',marker='+',color='cyan',markevery=10"
		str2 := ",ls='none',marker='x',markevery=10"
		str3 := ",ls='none',marker='+',markevery=10"
		str4 := ",ls='none',marker='4',markevery=10"

		plt.Subplot(3, 1, 1)
		s.Draw2d(str0, "", npts, 0) // 0 => CalcBasis
		s.Draw2d(str1, "", npts, 1) // 1 => RecursiveBasis

		plt.Subplot(3, 1, 2)
		s.PlotBasis("", npts, 0)   // 0 => CalcBasis
		s.PlotBasis(str2, npts, 1) // 1 => CalcBasisAndDerivs
		s.PlotBasis(str3, npts, 2) // 2 => RecursiveBasis

		plt.Subplot(3, 1, 3)
		s.PlotDerivs("", npts, 0)   // 0 => CalcBasisAndDerivs
		s.PlotDerivs(str4, npts, 1) // 1 => NumericalDeriv

		plt.SaveD("/tmp/gosl/gm", "bspline03.png")
	}
}