Esempio n. 1
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))
}
Esempio n. 2
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
	}
}
Esempio n. 3
0
func main() {

	// input data
	matOld := "matOld.mat"
	matNew := "matNew.mat"
	convSymb := true

	// parse flags
	flag.Parse()
	if len(flag.Args()) > 0 {
		matOld = flag.Arg(0)
	}
	if len(flag.Args()) > 1 {
		matNew = flag.Arg(1)
	}
	if len(flag.Args()) > 2 {
		convSymb = io.Atob(flag.Arg(2))
	}

	// print input data
	io.Pf("\nInput data\n")
	io.Pf("==========\n")
	io.Pf("  matOld   = %30s // old material filename\n", matOld)
	io.Pf("  matNew   = %30s // new material filename\n", matNew)
	io.Pf("  convSymb = %30v // do convert symbols\n", convSymb)
	io.Pf("\n")

	// convert old => new
	inp.MatfileOld2New("", matNew, matOld, convSymb)
	io.Pf("conversion successful\n")
	io.Pfblue2("file <matNew.mat> created\n")
}
Esempio n. 4
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))
}
Esempio n. 5
0
func main() {

	// default input data
	fn := "nurbs01.msh"
	ctrl := true
	ids := true
	npts := 41

	// parse flags
	flag.Parse()
	if len(flag.Args()) > 0 {
		fn = flag.Arg(0)
	}
	if len(flag.Args()) > 1 {
		ctrl = io.Atob(flag.Arg(1))
	}
	if len(flag.Args()) > 2 {
		ids = io.Atob(flag.Arg(2))
	}
	if len(flag.Args()) > 3 {
		npts = io.Atoi(flag.Arg(3))
	}

	// print input data
	io.Pforan("Input data\n")
	io.Pforan("==========\n")
	io.Pfblue2("  fn   = %v\n", fn)
	io.Pfblue2("  ctrl = %v\n", ctrl)
	io.Pfblue2("  ids  = %v\n", ids)
	io.Pfblue2("  npts = %v\n", npts)

	// load nurbss
	fnk := io.FnKey(fn)
	B := gm.ReadMsh(fnk)

	// plot
	plt.SetForEps(0.75, 500)
	for _, b := range B {
		if ctrl {
			b.DrawCtrl2d(ids, "", "")
		}
		b.DrawElems2d(npts, ids, "", "")
	}
	plt.Equal()
	plt.Save(fnk + ".eps")
}
Esempio n. 6
0
func Test_cxint01(tst *testing.T) {

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

	var ops OpsData
	ops.SetDefault()
	ops.Pc = 1
	ops.Ncuts = 1

	A := []int{1, 2}
	B := []int{-1, -2}
	a := make([]int, len(A))
	b := make([]int, len(A))
	IntCrossover(a, b, A, B, 0, &ops)
	io.Pfred("A = %2d\n", A)
	io.PfRed("B = %2d\n", B)
	io.Pfcyan("a = %2d\n", a)
	io.Pfblue2("b = %2d\n", b)
	chk.Ints(tst, "a", a, []int{1, -2})
	chk.Ints(tst, "b", b, []int{-1, 2})
	io.Pf("\n")

	A = []int{1, 2, 3, 4, 5, 6, 7, 8}
	B = []int{-1, -2, -3, -4, -5, -6, -7, -8}
	a = make([]int, len(A))
	b = make([]int, len(A))
	ops.Cuts = []int{1, 3}
	IntCrossover(a, b, A, B, 0, &ops)
	io.Pfred("A = %2v\n", A)
	io.PfRed("B = %2v\n", B)
	io.Pfcyan("a = %2v\n", a)
	io.Pfblue2("b = %2v\n", b)
	chk.Ints(tst, "a", a, []int{1, -2, -3, 4, 5, 6, 7, 8})
	chk.Ints(tst, "b", b, []int{-1, 2, 3, -4, -5, -6, -7, -8})

	ops.Cuts = []int{5, 7}
	IntCrossover(a, b, A, B, 0, &ops)
	io.Pfred("A = %2v\n", A)
	io.PfRed("B = %2v\n", B)
	io.Pfcyan("a = %2v\n", a)
	io.Pfblue2("b = %2v\n", b)
	chk.Ints(tst, "a", a, []int{1, 2, 3, 4, 5, -6, -7, 8})
	chk.Ints(tst, "b", b, []int{-1, -2, -3, -4, -5, 6, 7, -8})
}
Esempio n. 7
0
func Test_split01(tst *testing.T) {

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

	r := DblSplit(" 1e4 1 3   8   88   ")
	io.Pfblue2("r = %v\n", r)
	chk.Vector(tst, "r", 1e-16, r, []float64{1e4, 1, 3, 8, 88})
}
Esempio n. 8
0
func Test_copy01(tst *testing.T) {

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

	v := []float64{1, 2, 3, 4, 4, 5, 5, 6, 6, 6}
	w := DblCopy(v)
	io.Pfblue2("v = %v\n", v)
	chk.Vector(tst, "w==v", 1e-16, w, v)
}
Esempio n. 9
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)
}
Esempio n. 10
0
func save_file(filename string, buf *bytes.Buffer, verbose bool) (err error) {
	fil, err := os.Create(filename)
	if err != nil {
		return
	}
	defer func() { err = fil.Close() }()
	_, err = fil.Write(buf.Bytes())
	if verbose {
		io.Pfblue2("file <%s> written\n", filename)
	}
	return
}
Esempio n. 11
0
func Test_eigenp01(tst *testing.T) {

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

	// constants
	tolP := 1e-14        // eigenprojectors
	tolS := 1e-13        // spectral decomposition
	toldP := 1e-9        // derivatives of eigenprojectors
	ver := chk.Verbose   // check P verbose
	verdP := chk.Verbose // check dPda verbose

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

		// tensor and eigenvalues
		A := test_AA[idxA]
		a := M_Alloc2(nd[idxA])
		Ten2Man(a, A)
		io.PfYel("\n\ntst # %d ###################################################################################\n", idxA)
		io.Pfblue2("a = %v\n", a)
		io.Pfblue2("λ = %v\n", test_λ[idxA])

		// check eigenprojectors
		io.Pforan("\neigenprojectors\n")
		λsorted := CheckEigenprojs(a, tolP, tolS, ver)
		io.Pfyel("λsorted = %v\n", λsorted)
		λchk := utl.DblGetSorted(test_λ[idxA])
		chk.Vector(tst, "λchk", 1e-12, λsorted, λchk)

		// check derivatives of eigenprojectors
		io.Pforan("\nderivatives\n")
		CheckEigenprojsDerivs(a, toldP, verdP, EV_ZERO)

	}
}
Esempio n. 12
0
func Test_mat02(tst *testing.T) {

	chk.PrintTitle("mat02 (conversion)")

	convertsymbols := true
	MatfileOld2New("/tmp/gofem/inp", "new_layers.mat", "data/old_layers.mat", convertsymbols)

	mdb := ReadMat("/tmp/gofem/inp/", "new_layers.mat")
	if mdb == nil {
		tst.Errorf("test failed\n")
		return
	}
	io.Pfblue2("%v\n", mdb)
}
Esempio n. 13
0
func Test_hyperelast02(tst *testing.T) {

	//verbose()
	chk.PrintTitle("hyperelast02 (linear)")

	E, ν := 1500.0, 0.25
	K := Calc_K_from_Enu(E, ν)
	G := Calc_G_from_Enu(E, ν)
	io.Pforan("K = %v\n", K)
	io.Pforan("G = %v\n", G)

	var m HyperElast1
	m.Init(2, false, []*fun.Prm{
		&fun.Prm{N: "K0", V: K},
		&fun.Prm{N: "G0", V: G},
		&fun.Prm{N: "le", V: 1},
	})
	io.Pforan("m = %+v\n", m)

	ε := []float64{-0.001, -0.002, -0.003}
	σ := make([]float64, 3)
	m.L_update(σ, ε)
	io.Pfblue2("ε = %v\n", ε)
	io.Pfcyan("σ = %v\n", σ)

	D := la.MatAlloc(3, 3)
	m.L_CalcD(D, ε)
	la.PrintMat("D", D, "%14.6f", false)

	tol := 1e-11
	verb := io.Verbose
	var tmp float64
	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			dnum := num.DerivCen(func(x float64, args ...interface{}) (res float64) {
				tmp, ε[j] = ε[j], x
				m.L_update(σ, ε)
				res = σ[i]
				ε[j] = tmp
				return
			}, ε[j])
			chk.AnaNum(tst, io.Sf("D%d%d", i, j), tol, D[i][j], dnum, verb)
		}
	}
}
Esempio n. 14
0
func Test_hyperelast03(tst *testing.T) {

	//verbose()
	chk.PrintTitle("hyperelast03 (nonlinear)")

	var m HyperElast1
	m.Init(2, false, []*fun.Prm{
		&fun.Prm{N: "kap", V: 0.05},
		&fun.Prm{N: "kapb", V: 20.0},
		&fun.Prm{N: "G0", V: 1500},
		&fun.Prm{N: "pr", V: 2.2},
		&fun.Prm{N: "pt", V: 11.0},
	})
	io.Pforan("m = %+v\n", m)

	ε := []float64{-0.001, -0.002, -0.003}
	σ := make([]float64, 3)
	m.L_update(σ, ε)
	io.Pfblue2("ε = %v\n", ε)
	io.Pfcyan("σ = %v\n", σ)

	D := la.MatAlloc(3, 3)
	m.L_CalcD(D, ε)
	la.PrintMat("D", D, "%14.6f", false)

	tol := 1e-7
	verb := io.Verbose
	var tmp float64
	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			dnum := num.DerivCen(func(x float64, args ...interface{}) (res float64) {
				tmp, ε[j] = ε[j], x
				m.L_update(σ, ε)
				res = σ[i]
				ε[j] = tmp
				return
			}, ε[j])
			chk.AnaNum(tst, io.Sf("D%d%d", i, j), tol, D[i][j], dnum, verb)
		}
	}
}
Esempio n. 15
0
func Test_mat01(tst *testing.T) {

	chk.PrintTitle("mat01")

	mdb1 := ReadMat("data", "bh.mat")
	if mdb1 == nil {
		tst.Errorf("test failed\n")
		return
	}
	io.Pforan("bh.mat just read:\n%v\n", mdb1)

	fn := "test_bh.mat"
	io.WriteFileSD("/tmp/gofem/inp", fn, mdb1.String())

	mdb2 := ReadMat("/tmp/gofem/inp/", fn)
	if mdb2 == nil {
		tst.Errorf("test failed\n")
		return
	}
	io.Pfblue2("\n%v\n", mdb2)
}
Esempio n. 16
0
func Test_linipm03(tst *testing.T) {

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

	t0 := time.Now()
	defer func() { io.Pfblue2("\ntime elapsed = %v\n", time.Now().Sub(t0)) }()

	// read LP
	A, b, c, l, u := ReadLPfortran("data/afiro.dat")
	//A, b, c, l, u := ReadLPfortran("data/adlittle.dat")
	//A, b, c, l, u := ReadLPfortran("data/share1b.dat")

	// check for unbounded variables
	nx := len(c)
	for i := 0; i < nx; i++ {
		if math.Abs(l[i]) > 1e-15 {
			chk.Panic("cannot handle l != 0 yet")
		}
		if math.Abs(u[i]-1e20) > 1e-15 {
			chk.Panic("cannot handle u != ∞ yet")
		}
	}

	// solve LP
	var ipm LinIpm
	defer ipm.Clean()
	ipm.Init(A, b, c, nil)
	err := ipm.Solve(chk.Verbose)
	if err != nil {
		tst.Errorf("ipm failed:\n%v", err)
		return
	}

	// check
	io.Pf("\n")
	bres := make([]float64, len(b))
	la.MatVecMul(bres, 1, A.ToDense(), ipm.X)
	chk.Vector(tst, "A*x=b", 1e-13, bres, b)
}
Esempio n. 17
0
func main() {

	// catch errors
	defer func() {
		if err := recover(); err != nil {
			io.PfRed("ERROR: %v\n", err)
		}
	}()

	// input data
	matOld := io.ArgToString(0, "matOld.mat")
	matNew := io.ArgToString(1, "matNew.mat")
	convSymb := io.ArgToBool(2, true)
	io.Pf("\n%s\n", io.ArgsTable(
		"old material filename", "matOld", matOld,
		"new material filenamen", "matNew", matNew,
		"do convert symbols", "convSymb", convSymb,
	))

	// convert old => new
	inp.MatfileOld2New("", matNew, matOld, convSymb)
	io.Pf("conversion successful\n")
	io.Pfblue2("file <matNew.mat> created\n")
}
Esempio n. 18
0
// Run runs FE simulation
func Run() (runisok bool) {

	// plot functions
	if Global.Sim.PlotF != nil && Global.Root {
		Global.Sim.Functions.PlotAll(Global.Sim.PlotF, Global.Dirout, Global.Fnkey)
	}

	// alloc domains
	var domains []*Domain
	for _, reg := range Global.Sim.Regions {
		dom := NewDomain(reg, Global.Distr)
		if dom == nil {
			break
		}
		domains = append(domains, dom)
	}
	if Stop() {
		return
	}

	// make sure to call linear solver clean up routines upon exit
	defer func() {
		for _, d := range domains {
			if !d.InitLSol {
				d.LinSol.Clean()
			}
		}
	}()

	// current time and output time
	t := 0.0
	tout := 0.0
	tidx := 0

	// summary of outputs; e.g. with output times
	cputime := time.Now()
	var sum Summary
	sum.OutTimes = []float64{t}
	defer func() {
		sum.Save()
		if Global.Verbose && !Global.Debug {
			io.Pf("\nfinal t  = %v\n", t)
			io.Pfblue2("cpu time = %v\n", time.Now().Sub(cputime))
		}
	}()

	// loop over stages
	for stgidx, stg := range Global.Sim.Stages {

		// time incrementers
		Dt := stg.Control.DtFunc
		DtOut := stg.Control.DtoFunc
		tf := stg.Control.Tf
		tout = t + DtOut.F(t, nil)

		// set stage
		for _, d := range domains {
			if LogErrCond(!d.SetStage(stgidx, Global.Sim.Stages[stgidx], Global.Distr), "SetStage failed") {
				break
			}
			d.Sol.T = t
			if !d.Out(tidx) {
				break
			}
		}
		if Stop() {
			return
		}
		tidx += 1

		// log models
		mconduct.LogModels()
		mreten.LogModels()
		mporous.LogModels()
		msolid.LogModels()

		// skip stage?
		if stg.Skip {
			continue
		}

		// time loop using Richardson's extrapolation
		// TODO: works with only one domain for now
		if Global.Sim.Solver.RE {
			var re RichardsonExtrap
			re.Init(domains[0], Dt)
			if !re.Run(domains[0], &sum, DtOut, &t, tf, tout, &tidx) {
				return
			}
			continue
		}

		// time loop
		ndiverg := 0 // number of steps diverging
		md := 1.0    // time step multiplier if divergence control is on
		var Δt, Δtout float64
		var lasttimestep bool
		for t < tf {

			// check for continued divergence
			if LogErrCond(ndiverg >= Global.Sim.Solver.NdvgMax, "continuous divergence after %d steps reached", ndiverg) {
				return
			}

			// time increment
			Δt = Dt.F(t, nil) * md
			if t+Δt >= tf {
				Δt = tf - t
				lasttimestep = true
			}
			if Δt < Global.Sim.Solver.DtMin {
				if md < 1 {
					LogErrCond(true, "Δt increment is too small: %g < %g", Δt, Global.Sim.Solver.DtMin)
					return false
				}
				return true
			}

			// dynamic coefficients
			if LogErr(Global.DynCoefs.CalcBoth(Δt), "cannot compute dynamic coefficients") {
				return
			}

			// time update
			t += Δt
			for _, d := range domains {
				d.Sol.T = t
			}
			Δtout = DtOut.F(t, nil)

			// message
			if Global.Verbose {
				if !Global.Sim.Data.ShowR && !Global.Debug {
					io.PfWhite("%30.15f\r", t)
				}
			}

			// for all domains
			docontinue := false
			for _, d := range domains {

				// backup solution if divergence control is on
				if Global.Sim.Solver.DvgCtrl {
					d.backup()
				}

				// run iterations
				diverging, ok := run_iterations(t, Δt, d, &sum)
				if !ok {
					return
				}

				// restore solution and reduce time step if divergence control is on
				if Global.Sim.Solver.DvgCtrl {
					if diverging {
						if Global.Verbose {
							io.Pfred(". . . iterations diverging (%2d) . . .\n", ndiverg+1)
						}
						d.restore()
						t -= Δt
						d.Sol.T = t
						md *= 0.5
						ndiverg += 1
						docontinue = true
						break
					}
					ndiverg = 0
					md = 1.0
				}
			}
			if docontinue {
				continue
			}

			// perform output
			if t >= tout || lasttimestep {
				sum.OutTimes = append(sum.OutTimes, t)
				for _, d := range domains {
					//if true {
					if false {
						debug_print_p_results(d)
					}
					if false {
						debug_print_up_results(d)
					}
					if !d.Out(tidx) {
						break
					}
				}
				if Stop() {
					return
				}
				tout += Δtout
				tidx += 1
			}
		}
	}
	return true
}
Esempio n. 19
0
func Test_ind03(tst *testing.T) {

	//verbose()
	chk.PrintTitle("ind03. comparing")

	nbases := 1
	A := get_individual(0, nbases)
	B := get_individual(1, nbases)
	A_dominates, B_dominates := IndCompareDet(A, B)
	io.Pfblue2("A: ovas = %v\n", A.Ovas)
	io.Pfblue2("A: oors = %v\n", A.Oors)
	io.Pfcyan("B: ovas = %v\n", B.Ovas)
	io.Pfcyan("B: oors = %v\n", B.Oors)
	io.Pforan("A_dominates = %v\n", A_dominates)
	io.Pforan("B_dominates = %v\n", B_dominates)
	if !A_dominates {
		tst.Errorf("test failed\n")
		return
	}
	if B_dominates {
		tst.Errorf("test failed\n")
		return
	}

	A.Oors = []float64{0, 0, 0}
	B.Oors = []float64{0, 0, 0}
	A_dominates, B_dominates = IndCompareDet(A, B)
	io.Pfblue2("\nA: ovas = %v\n", A.Ovas)
	io.Pfblue2("A: oors = %v\n", A.Oors)
	io.Pfcyan("B: ovas = %v\n", B.Ovas)
	io.Pfcyan("B: oors = %v\n", B.Oors)
	io.Pforan("A_dominates = %v\n", A_dominates)
	io.Pforan("B_dominates = %v\n", B_dominates)
	if A_dominates {
		tst.Errorf("test failed\n")
		return
	}
	if B_dominates {
		tst.Errorf("test failed\n")
		return
	}

	A.Ovas = []float64{200, 100}
	A_dominates, B_dominates = IndCompareDet(A, B)
	io.Pfblue2("\nA: ovas = %v\n", A.Ovas)
	io.Pfblue2("A: oors = %v\n", A.Oors)
	io.Pfcyan("B: ovas = %v\n", B.Ovas)
	io.Pfcyan("B: oors = %v\n", B.Oors)
	io.Pforan("A_dominates = %v\n", A_dominates)
	io.Pforan("B_dominates = %v\n", B_dominates)
	if A_dominates {
		tst.Errorf("test failed\n")
		return
	}
	if B_dominates {
		tst.Errorf("test failed\n")
		return
	}

	A.Ovas = []float64{200, 99}
	A_dominates, B_dominates = IndCompareDet(A, B)
	io.Pfblue2("\nA: ovas = %v\n", A.Ovas)
	io.Pfblue2("A: oors = %v\n", A.Oors)
	io.Pfcyan("B: ovas = %v\n", B.Ovas)
	io.Pfcyan("B: oors = %v\n", B.Oors)
	io.Pforan("A_dominates = %v\n", A_dominates)
	io.Pforan("B_dominates = %v\n", B_dominates)
	if !A_dominates {
		tst.Errorf("test failed\n")
		return
	}
	if B_dominates {
		tst.Errorf("test failed\n")
		return
	}

	A.Ovas = []float64{200, 100}
	B.Ovas = []float64{199, 100}
	A_dominates, B_dominates = IndCompareDet(A, B)
	io.Pfblue2("\nA: ovas = %v\n", A.Ovas)
	io.Pfblue2("A: oors = %v\n", A.Oors)
	io.Pfcyan("B: ovas = %v\n", B.Ovas)
	io.Pfcyan("B: oors = %v\n", B.Oors)
	io.Pforan("A_dominates = %v\n", A_dominates)
	io.Pforan("B_dominates = %v\n", B_dominates)
	if A_dominates {
		tst.Errorf("test failed\n")
		return
	}
	if !B_dominates {
		tst.Errorf("test failed\n")
		return
	}
}
Esempio n. 20
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")
	}
}
Esempio n. 21
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
	}
}
Esempio n. 22
0
func Test_ops02(tst *testing.T) {

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

	nd := []int{2, 2, 3, 3, 3}
	AA := [][][]float64{
		{
			{1, 2, 0},
			{2, -2, 0},
			{0, 0, -2},
		},
		{
			{-100, 33, 0},
			{33, -200, 0},
			{0, 0, 150},
		},
		{
			{1, 2, 4},
			{2, -2, 3},
			{4, 3, -2},
		},
		{
			{-100, -10, 20},
			{-10, -200, 15},
			{20, 15, -300},
		},
		{
			{-100, 0, -10},
			{0, -200, 0},
			{-10, 0, 100},
		},
	}
	BB := [][][]float64{
		{
			{0.13, 1.2, 0},
			{1.2, -20, 0},
			{0, 0, -28},
		},
		{
			{-10, 3.3, 0},
			{3.3, -2, 0},
			{0, 0, 1.5},
		},
		{
			{0.1, 0.2, 0.8},
			{0.2, -1.3, 0.3},
			{0.8, 0.3, -0.2},
		},
		{
			{-10, -1, 2},
			{-1, -20, 1},
			{2, 1, -30},
		},
		{
			{-10, 3, -1},
			{3, -20, 1},
			{-1, 1, 10},
		},
	}

	nonsymTol := 1e-15

	for m := 0; m < len(nd); m++ {

		// tensors
		A := AA[m]
		B := BB[m]
		a := M_Alloc2(nd[m])
		b := M_Alloc2(nd[m])
		Ten2Man(a, A)
		Ten2Man(b, B)
		io.PfYel("\n\ntst # %d ###################################################################################\n", m)
		io.Pfblue2("a = %v\n", a)
		io.Pfblue2("b = %v\n", b)

		// dyadic
		c := M_Dy(a, b)
		c_ := M_Alloc4(nd[m])
		c__ := M_Alloc4(nd[m])
		M_DyAdd(c_, 1, a, b)
		for i := 0; i < len(a); i++ {
			for j := 0; j < len(a); j++ {
				for k := 0; k < len(a); k++ {
					c__[i][j] = a[i] * b[j]
				}
			}
		}
		chk.Matrix(tst, "a dy b", 1e-12, c, c_)
		chk.Matrix(tst, "a dy b", 1e-12, c, c__)

		// dot product
		d := M_Alloc2(nd[m])
		D := Alloc2()
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				for k := 0; k < 3; k++ {
					D[i][j] += A[i][k] * B[k][j]
				}
			}
		}
		err := M_Dot(d, a, b, nonsymTol)
		for i := 0; i < 3; i++ {
			chk.Scalar(tst, io.Sf("a_dot_b[%d][%d]", i, i), 1e-15, D[i][i], d[i])
		}
		/*
		   for k := 0; k < 2*nd[m]; k++ {
		       I, J := M2Ti[k], M2Tj[k]
		       cf   := 1.0
		       if k > 2 {
		           cf = 1.0 / SQ2
		       }
		       io.Pforan("%v %v\n", D[I][J], d[k] * cf)
		       chk.Scalar(tst, io.Sf("a_dot_b[%d][%d]",I,J), 1e-15, D[I][J], d[k] * cf)
		   }
		*/
		if err == nil {
			chk.Panic("dot product failed: error should be non-nil, since the result is expected to be non-symmetric")
		}

		// dot product (square tensor)
		a2 := M_Alloc2(nd[m])
		M_Sq(a2, a)
		aa := M_Alloc2(nd[m])
		tol_tmp := nonsymTol
		if m == 3 || m == 4 {
			nonsymTol = 1e-12
		}
		err = M_Dot(aa, a, a, nonsymTol)
		io.Pforan("a2 = %v\n", a2)
		io.Pforan("aa = %v\n", aa)
		if err != nil {
			chk.Panic("%v", err)
		}
		chk.Vector(tst, "a2", 1e-15, a2, aa)
		nonsymTol = tol_tmp
	}
}
Esempio n. 23
0
func Test_ops03(tst *testing.T) {

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

	nonsymTol := 1e-15

	dtol := 1e-9
	dver := chk.Verbose

	nd := test_nd
	for idxA := 0; idxA < len(test_nd)-3; idxA++ {
		//for idxA := 0; idxA < 1; idxA++ {

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

		// inverse
		Ai := Alloc2()
		ai := M_Alloc2(nd[idxA])
		detA, err := Inv(Ai, A)
		if err != nil {
			chk.Panic("%v", err)
		}
		deta_ := M_Det(a)
		deta, err := M_Inv(ai, a, MINDET)
		if err != nil {
			chk.Panic("%v", err)
		}
		Ai_ := Alloc2()
		Man2Ten(Ai_, ai)
		aia := M_Alloc2(nd[idxA])
		err = M_Dot(aia, ai, a, nonsymTol)
		if err != nil {
			chk.Panic("%v", err)
		}
		chk.Scalar(tst, "detA", 1e-14, detA, deta)
		chk.Scalar(tst, "deta", 1e-14, deta, deta_)
		chk.Matrix(tst, "Ai", 1e-14, Ai, Ai_)
		chk.Vector(tst, "ai*a", 1e-15, aia, Im[:2*nd[idxA]])
		io.Pforan("ai*a = %v\n", aia)

		// derivative of inverse
		dtol_tmp := dtol
		if idxA == 5 {
			dtol = 1e-8
		}
		var tmp float64
		ai_tmp := M_Alloc2(nd[idxA])
		daida := M_Alloc4(nd[idxA])
		M_InvDeriv(daida, ai)
		io.Pforan("ai = %v\n", ai)
		for i := 0; i < len(a); i++ {
			for j := 0; j < len(a); j++ {
				//dnum, _ := num.DerivForward(func(x float64, args ...interface{}) (res float64) {
				dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
					tmp, a[j] = a[j], x
					_, err := M_Inv(ai_tmp, a, MINDET)
					a[j] = tmp
					if err != nil {
						chk.Panic("daida failed:\n%v", err)
					}
					return ai_tmp[i]
				}, a[j], 1e-6)
				chk.AnaNum(tst, io.Sf("dai/da[%d][%d]", i, j), dtol, daida[i][j], dnum, dver)
			}
		}
		dtol = dtol_tmp
	}
}
Esempio n. 24
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
	}
}
Esempio n. 25
0
func Test_ops01(tst *testing.T) {

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

	// basic derivatives
	dver := chk.Verbose
	dtol := 1e-5

	// invariants derivatives
	dveri := false
	dtoli1 := []float64{1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6}
	dtoli2 := []float64{1e-6, 1e-5, 1e-6, 1e-4, 1e-5, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6}
	dtoli3 := []float64{1e-6, 1e-3, 1e-6, 1e-3, 1e-3, 1e-6, 1e-6, 1e-6, 1e-5, 1e-6}

	// lode derivatives
	dverw := chk.Verbose
	dtolw := 1e-8

	nd := test_nd
	for m := 0; m < len(test_nd)-3; m++ {
		//for m := 0; m < 3; m++ {
		A := test_AA[m]
		a := M_Alloc2(nd[m])
		Ten2Man(a, A)
		trA := Tr(A)
		tra := M_Tr(a)
		detA := Det(A)
		deta := M_Det(a)
		devA := Dev(A)
		deva := M_Dev(a)
		devA_ := Alloc2()
		a2 := M_Alloc2(nd[m])
		A2 := Alloc2()
		A2_ := Alloc2()
		trDevA := Tr(devA)
		deva__ := M_Alloc2(nd[m])
		devA__ := Alloc2()
		s2 := M_Alloc2(nd[m])
		M_Sq(a2, a)
		M_Sq(s2, deva)
		Man2Ten(A2, a2)
		Man2Ten(devA_, deva)
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				for k := 0; k < 3; k++ {
					A2_[i][j] += A[i][k] * A[k][j]
				}
			}
		}
		for i := 0; i < len(a); i++ {
			for j := 0; j < len(a); j++ {
				deva__[i] += Psd[i][j] * a[j]
			}
		}
		for i := 0; i < 3; i++ {
			for j := 0; j < 3; j++ {
				for k := 0; k < 3; k++ {
					for l := 0; l < 3; l++ {
						devA__[i][j] += M2TT(Psd, i, j, k, l) * A[k][l]
					}
				}
			}
		}
		// check basic
		if math.Abs(trA-tra) > 1e-17 {
			chk.Panic("tra failed. diff = %g", trA-tra)
		}
		if math.Abs(detA-deta) > 1e-14 {
			chk.Panic("detA failed. diff = %g", detA-deta)
		}
		if math.Abs(trDevA) > 1e-13 {
			chk.Panic("trDevA failed. error = %g", trDevA)
		}
		chk.Matrix(tst, "devA", 1e-13, devA, devA_)
		chk.Matrix(tst, "devA", 1e-13, devA, devA__)
		chk.Vector(tst, "devA", 1e-13, deva, deva__)
		chk.Matrix(tst, "A²", 1e-11, A2, A2_)
		// check tr(s2)
		io.Pfblue2("tr(s²) = %v\n", M_Tr(s2))
		if M_Tr(s2) < 1 {
			chk.Panic("Tr(s2) failed")
		}
		// check derivatives
		da2da := M_Alloc4(nd[m])
		a2tmp := M_Alloc2(nd[m]) // a2tmp == a²
		M_SqDeriv(da2da, a)
		var tmp float64
		for i := 0; i < len(a); i++ {
			for j := 0; j < len(a); j++ {
				dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
					tmp, a[j] = a[j], x
					M_Sq(a2tmp, a)
					a[j] = tmp
					return a2tmp[i]
				}, a[j], 1e-6)
				chk.AnaNum(tst, io.Sf("da²/da[%d][%d]", i, j), dtol, da2da[i][j], dnum, dver)
			}
		}
		// characteristic invariants
		I1, I2, I3 := M_CharInvs(a)
		I2a := 0.5 * (tra*tra - M_Tr(a2))
		I1_, I2_, I3_, dI1da, dI2da, dI3da := M_CharInvsAndDerivs(a)
		if math.Abs(I1-tra) > 1e-17 {
			chk.Panic("I1 failed (a). error = %v", I1-tra)
		}
		if math.Abs(I2-I2a) > 1e-12 {
			chk.Panic("I2 failed (a). error = %v (I2=%v, I2_=%v)", I2-I2a, I2, I2a)
		}
		if math.Abs(I3-deta) > 1e-17 {
			chk.Panic("I3 failed (a). error = %v", I3-deta)
		}
		if math.Abs(I1-I1_) > 1e-17 {
			chk.Panic("I1 failed (b). error = %v", I1-I1_)
		}
		if math.Abs(I2-I2_) > 1e-17 {
			chk.Panic("I2 failed (b). error = %v", I2-I2_)
		}
		if math.Abs(I3-I3_) > 1e-17 {
			chk.Panic("I3 failed (b). error = %v", I3-I3_)
		}
		// dI1da
		for j := 0; j < len(a); j++ {
			dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
				tmp, a[j] = a[j], x
				i1, _, _ := M_CharInvs(a)
				a[j] = tmp
				return i1
			}, a[j], 1e-6)
			chk.AnaNum(tst, io.Sf("dI1/da[%d]", j), dtoli1[m], dI1da[j], dnum, dveri)
		}
		// dI2da
		for j := 0; j < len(a); j++ {
			dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
				tmp, a[j] = a[j], x
				_, i2, _ := M_CharInvs(a)
				a[j] = tmp
				return i2
			}, a[j], 1e-6)
			chk.AnaNum(tst, io.Sf("dI2/da[%d]", j), dtoli2[m], dI2da[j], dnum, dveri)
		}
		// dI3da
		for j := 0; j < len(a); j++ {
			dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
				tmp, a[j] = a[j], x
				_, _, i3 := M_CharInvs(a)
				a[j] = tmp
				return i3
			}, a[j], 1e-6)
			chk.AnaNum(tst, io.Sf("dI3/da[%d]", j), dtoli3[m], dI3da[j], dnum, dveri)
		}
		// dDet(a)/da
		DdetaDa := make([]float64, len(a))
		M_DetDeriv(DdetaDa, a)
		for j := 0; j < len(a); j++ {
			chk.AnaNum(tst, io.Sf("dDet(a)/da[%d]", j), dtoli3[m], dI3da[j], DdetaDa[j], dveri)
		}
		// lode angle
		if true {
			s := M_Alloc2(nd[m])
			dwda := M_Alloc2(nd[m])
			dwda_ := M_Alloc2(nd[m])
			d2wdada := M_Alloc4(nd[m])
			p, q, w := M_pqws(s, a)
			M_LodeDeriv1(dwda, a, s, p, q, w)
			M_LodeDeriv2(d2wdada, dwda_, a, s, p, q, w)
			chk.Vector(tst, "s", 1e-13, deva, s)
			chk.Vector(tst, "dwda", 1e-13, dwda, dwda_)
			// dwda
			for j := 0; j < len(a); j++ {
				dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
					tmp, a[j] = a[j], x
					res = M_w(a)
					a[j] = tmp
					return res
				}, a[j], 1e-6)
				chk.AnaNum(tst, io.Sf("dw/da[%d]", j), dtolw, dwda[j], dnum, dverw)
			}
			// d2wdada
			s_tmp := M_Alloc2(nd[m])
			dwda_tmp := M_Alloc2(nd[m])
			for i := 0; i < len(a); i++ {
				for j := 0; j < len(a); j++ {
					dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) {
						tmp, a[j] = a[j], x
						p_tmp, q_tmp, w_tmp := M_pqws(s_tmp, a)
						M_LodeDeriv1(dwda_tmp, a, s_tmp, p_tmp, q_tmp, w_tmp)
						a[j] = tmp
						return dwda_tmp[i]
					}, a[j], 1e-6)
					chk.AnaNum(tst, io.Sf("d2w/dada[%d][%d]", i, j), dtolw, d2wdada[i][j], dnum, dverw)
				}
			}
		}
	}
}
Esempio n. 26
0
// Solve solves optimisation problem
func (o *Optimiser) Solve() {

	// benchmark
	if o.Verbose {
		t0 := gotime.Now()
		defer func() {
			io.Pf("\nnfeval = %d\n", o.Nfeval)
			io.Pfblue2("cpu time = %v\n", gotime.Now().Sub(t0))
		}()
	}

	// output
	if o.Output != nil {
		o.Output(0, o.Solutions)
	}

	// perform evolution
	done := make(chan int, o.Ncpu)
	time := 0
	texc := time + o.DtExc
	for time < o.Tf {

		// run groups in parallel. up to exchange time
		for icpu := 0; icpu < o.Ncpu; icpu++ {
			go func(cpu int) {
				nfeval := 0
				for t := time; t < texc; t++ {
					if cpu == 0 && o.Verbose {
						io.Pf("time = %10d\r", t+1)
					}
					nfeval += o.EvolveOneGroup(cpu)
				}
				done <- nfeval
			}(icpu)
		}
		for cpu := 0; cpu < o.Ncpu; cpu++ {
			o.Nfeval += <-done
		}

		// compute metrics with all solutions included
		o.Metrics.Compute(o.Solutions)

		// exchange via tournament
		if o.Ncpu > 1 {
			if o.ExcTour {
				for i := 0; i < o.Ncpu; i++ {
					j := (i + 1) % o.Ncpu
					I := rnd.IntGetUnique(o.Groups[i].Indices, 2)
					J := rnd.IntGetUnique(o.Groups[j].Indices, 2)
					A, B := o.Groups[i].All[I[0]], o.Groups[i].All[I[1]]
					a, b := o.Groups[j].All[J[0]], o.Groups[j].All[J[1]]
					o.Tournament(A, B, a, b, o.Metrics)
				}
			}

			// exchange one randomly
			if o.ExcOne {
				rnd.IntGetGroups(o.cpupairs, utl.IntRange(o.Ncpu))
				for _, pair := range o.cpupairs {
					i, j := pair[0], pair[1]
					n := utl.Imin(o.Groups[i].Ncur, o.Groups[j].Ncur)
					k := rnd.Int(0, n)
					A := o.Groups[i].All[k]
					B := o.Groups[j].All[k]
					B.CopyInto(o.tmp)
					A.CopyInto(B)
					o.tmp.CopyInto(A)
				}
			}
		}

		// update time variables
		time += o.DtExc
		texc += o.DtExc
		time = utl.Imin(time, o.Tf)
		texc = utl.Imin(texc, o.Tf)

		// output
		if o.Output != nil {
			o.Output(time, o.Solutions)
		}
	}
}
Esempio n. 27
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))
}
Esempio n. 28
0
// generate_solutions generate solutions
func (o *Optimiser) generate_solutions(itrial int) {

	// benchmark
	t0 := gotime.Now()
	var tgen, tmsh gotime.Time
	if o.VerbTime && itrial == 0 {
		defer func() {
			io.Pfblue2("time spent in generation of solutions = %v\n", tgen.Sub(t0))
			io.Pfblue2("time spent in Delaunay triangulations = %v\n", tmsh.Sub(tgen))
			io.Pfblue2("total time in generate_solutions      = %v\n", gotime.Now().Sub(t0))
		}()
	}

	// generate
	if o.GenAll {
		o.Generator(o.Solutions, &o.Parameters)
		for _, sol := range o.Solutions {
			o.ObjFunc(sol, 0)
		}
	} else {
		done := make(chan int, o.Ncpu)
		for icpu := 0; icpu < o.Ncpu; icpu++ {
			go func(cpu int) {
				start, endp1 := (cpu*o.Nsol)/o.Ncpu, ((cpu+1)*o.Nsol)/o.Ncpu
				sols := o.Solutions[start:endp1]
				o.Generator(sols, &o.Parameters)
				for _, sol := range sols {
					o.ObjFunc(sol, cpu)
				}
				done <- 1
			}(icpu)
		}
		for cpu := 0; cpu < o.Ncpu; cpu++ {
			<-done
		}
	}
	tgen = gotime.Now()

	// metrics
	o.iova0 = -1
	o.Nfeval = o.Nsol
	o.Metrics.Compute(o.Solutions)

	// meshes
	if o.Nflt > 1 && o.UseMesh {
		var err error
		Xi, Xj := make([]float64, o.Nsol), make([]float64, o.Nsol)
		o.Meshes = make([][]*Mesh, o.Nflt-1)
		for i := 0; i < o.Nflt-1; i++ {
			o.Meshes[i] = make([]*Mesh, o.Nflt)
			for k, s := range o.Solutions {
				Xi[k] = s.Flt[i]
			}
			for j := i + 1; j < o.Nflt; j++ {
				for k, s := range o.Solutions {
					Xj[k] = s.Flt[j]
				}
				o.Meshes[i][j].V, o.Meshes[i][j].C, err = tri.Delaunay(Xi, Xj, false)
				if err != nil {
					chk.Panic("Delaunay2d failed:%v\n", err)
				}
			}
		}
	}
	tmsh = gotime.Now()
}
Esempio n. 29
0
// Run runs optimisations
func (o *SimpleFltProb) Run(verbose bool) {

	// benchmark
	if verbose {
		time0 := time.Now()
		defer func() {
			io.Pfblue2("\ncpu time = %v\n", time.Now().Sub(time0))
		}()
	}

	// run all trials
	for itrial := 0; itrial < o.C.Ntrials; itrial++ {

		// reset populations
		if itrial > 0 {
			for id, isl := range o.Evo.Islands {
				isl.Pop = o.C.PopFltGen(id, o.C)
				isl.CalcOvs(isl.Pop, 0)
				isl.CalcDemeritsAndSort(isl.Pop)
			}
		}

		// run evolution
		o.Evo.Run()

		// results
		xbest := o.Evo.Best.GetFloats()
		o.Fcn(o.ff[0], o.gg[0], o.hh[0], xbest)

		// check if best is unfeasible
		unfeasible := false
		for _, g := range o.gg[0] {
			if g < 0 {
				unfeasible = true
				break
			}
		}
		for _, h := range o.hh[0] {
			if math.Abs(h) > o.C.Eps1 {
				unfeasible = true
				break
			}
		}

		// feasible results
		if !unfeasible {
			for i, x := range xbest {
				o.Xbest[o.Nfeasible][i] = x
			}
			o.Nfeasible++
		}

		// message
		if verbose {
			io.Pfyel("%3d x*="+o.NumfmtX+" f="+o.NumfmtF, itrial, xbest, o.ff[0])
			if unfeasible {
				io.Pfred(" unfeasible\n")
			} else {
				io.Pfgreen(" ok\n")
			}
		}

		// best populations
		if o.C.DoPlot {
			if o.Nfeasible == 1 {
				o.PopsBest = o.Evo.GetPopulations()
			} else {
				fcur := utl.DblCopy(o.ff[0])
				o.Fcn(o.ff[0], o.gg[0], o.hh[0], o.Xbest[o.Nfeasible-1])
				cur_dom, _ := utl.DblsParetoMin(fcur, o.ff[0])
				if cur_dom {
					o.PopsBest = o.Evo.GetPopulations()
				}
			}
		}
	}
}
Esempio n. 30
0
func solve_problem(fnkey string, problem int) (opt *goga.Optimiser) {

	// GA parameters
	opt = new(goga.Optimiser)
	opt.Default()

	// options for report
	opt.RptFmtF = "%.4f"
	opt.RptFmtX = "%.3f"
	opt.RptFmtFdev = "%.1e"
	opt.RptWordF = "\\beta"
	opt.HistFmt = "%.2f"
	opt.HistNdig = 3
	opt.HistDelFmin = 0.005
	opt.HistDelFmax = 0.005

	// FORM data
	var lsft LSF_T
	var vars rnd.Variables

	// simple problem or FEM sim
	if fnkey == "simple" {
		opt.Read("ga-simple.json")
		opt.ProbNum = problem
		lsft, vars = get_simple_data(opt)
		fnkey += io.Sf("-%d", opt.ProbNum)
		io.Pf("\n----------------------------------- simple problem %d --------------------------------\n", opt.ProbNum)
	} else {
		opt.Read("ga-" + fnkey + ".json")
		lsft, vars = get_femsim_data(opt, fnkey)
		io.Pf("\n----------------------------------- femsim %s --------------------------------\n", fnkey)
	}

	// set limits
	nx := len(vars)
	opt.FltMin = make([]float64, nx)
	opt.FltMax = make([]float64, nx)
	for i, dat := range vars {
		opt.FltMin[i] = dat.Min
		opt.FltMax[i] = dat.Max
	}

	// log input
	var buf bytes.Buffer
	io.Ff(&buf, "%s", opt.LogParams())
	io.WriteFileVD("/tmp/gosl", fnkey+".log", &buf)

	// initialise distributions
	err := vars.Init()
	if err != nil {
		chk.Panic("cannot initialise distributions:\n%v", err)
	}

	// plot distributions
	if opt.PlotSet1 {
		io.Pf(". . . . . . . .  plot distributions  . . . . . . . .\n")
		np := 201
		for i, dat := range vars {
			plt.SetForEps(0.75, 250)
			dat.PlotPdf(np, "'b-',lw=2,zorder=1000")
			//plt.AxisXrange(dat.Min, dat.Max)
			plt.SetXnticks(15)
			plt.SaveD("/tmp/sims", io.Sf("distr-%s-%d.eps", fnkey, i))
		}
		return
	}

	// objective function
	nf := 1
	var ng, nh int
	var fcn goga.MinProb_t
	var obj goga.ObjFunc_t
	switch opt.Strategy {

	// argmin_x{ β(y(x)) | lsf(x) ≤ 0 }
	//  f ← sqrt(y dot y)
	//  g ← -lsf(x) ≥ 0
	//  h ← out-of-range in case Transform fails
	case 0:
		ng, nh = 1, 1
		fcn = func(f, g, h, x []float64, ξ []int, cpu int) {

			// original and normalised variables
			h[0] = 0
			y, invalid := vars.Transform(x)
			if invalid {
				h[0] = 1
				return
			}

			// objective value
			f[0] = math.Sqrt(la.VecDot(y, y)) // β

			// inequality constraint
			lsf, failed := lsft(x, cpu)
			g[0] = -lsf
			h[0] = failed
		}

	// argmin_x{ β(y(x)) | lsf(x) = 0 }
	//  f  ← sqrt(y dot y)
	//  h0 ← lsf(x)
	//  h1 ← out-of-range in case Transform fails
	case 1:
		ng, nh = 0, 2
		fcn = func(f, g, h, x []float64, ξ []int, cpu int) {

			// original and normalised variables
			h[0], h[1] = 0, 0
			y, invalid := vars.Transform(x)
			if invalid {
				h[0], h[1] = 1, 1
				return
			}

			// objective value
			f[0] = math.Sqrt(la.VecDot(y, y)) // β

			// equality constraint
			lsf, failed := lsft(x, cpu)
			h[0] = lsf
			h[1] = failed

			// induce minmisation of h0
			//f[0] += math.Abs(lsf)
		}

	case 2:
		opt.Nova = 1
		opt.Noor = 2
		obj = func(sol *goga.Solution, cpu int) {

			// clear out-of-range values
			sol.Oor[0] = 0 // invalid transformation or FEM failed
			sol.Oor[1] = 0 // g(x) ≤ 0 was violated

			// original and normalised variables
			x := sol.Flt
			y, invalid := vars.Transform(x)
			if invalid {
				sol.Oor[0] = goga.INF
				sol.Oor[1] = goga.INF
				return
			}

			// objective value
			sol.Ova[0] = math.Sqrt(la.VecDot(y, y)) // β

			// inequality constraint
			lsf, failed := lsft(x, cpu)
			sol.Oor[0] = failed
			sol.Oor[1] = fun.Ramp(lsf)
		}

	default:
		chk.Panic("strategy %d is not available", opt.Strategy)
	}

	// initialise optimiser
	opt.Init(goga.GenTrialSolutions, obj, fcn, nf, ng, nh)

	// solve
	io.Pf(". . . . . . . .  running  . . . . . . . .\n")
	opt.RunMany("", "")
	goga.StatF(opt, 0, true)
	io.Pfblue2("Tsys = %v\n", opt.SysTimeAve)

	// check
	goga.CheckFront0(opt, true)

	// results
	sols := goga.GetFeasible(opt.Solutions)
	if len(sols) > 0 {
		goga.SortByOva(sols, 0)
		best := sols[0]
		io.Pforan("x    = %.6f\n", best.Flt)
		io.Pforan("xref = %.6f\n", opt.RptXref)
		io.Pforan("β = %v  (%v)\n", best.Ova[0], opt.RptFref[0])
	}
	return
}