func main() { // GA parameters C := goga.ReadConfParams("tsp-simple.json") rnd.Init(C.Seed) // location / coordinates of stations locations := [][]float64{ {60, 200}, {180, 200}, {80, 180}, {140, 180}, {20, 160}, {100, 160}, {200, 160}, {140, 140}, {40, 120}, {100, 120}, {180, 100}, {60, 80}, {120, 80}, {180, 60}, {20, 40}, {100, 40}, {200, 40}, {20, 20}, {60, 20}, {160, 20}, } nstations := len(locations) C.SetIntOrd(nstations) C.CalcDerived() // objective value function C.OvaOor = func(ind *goga.Individual, idIsland, time int, report *bytes.Buffer) { L := locations ids := ind.Ints dist := 0.0 for i := 1; i < nstations; i++ { a, b := ids[i-1], ids[i] dist += math.Sqrt(math.Pow(L[b][0]-L[a][0], 2.0) + math.Pow(L[b][1]-L[a][1], 2.0)) } a, b := ids[nstations-1], ids[0] dist += math.Sqrt(math.Pow(L[b][0]-L[a][0], 2.0) + math.Pow(L[b][1]-L[a][1], 2.0)) ind.Ovas[0] = dist return } // evolver nova, noor := 1, 0 evo := goga.NewEvolver(nova, noor, C) evo.Run() // results io.Pfgreen("best = %v\n", evo.Best.Ints) io.Pfgreen("best OVA = %v (871.117353844847)\n\n", evo.Best.Ovas[0]) // plot travelling salesman path if C.DoPlot { plt.SetForEps(1, 300) X, Y := make([]float64, nstations), make([]float64, nstations) for k, id := range evo.Best.Ints { X[k], Y[k] = locations[id][0], locations[id][1] plt.PlotOne(X[k], Y[k], "'r.', ms=5, clip_on=0, zorder=20") plt.Text(X[k], Y[k], io.Sf("%d", id), "fontsize=7, clip_on=0, zorder=30") } plt.Plot(X, Y, "'b-', clip_on=0, zorder=10") plt.Plot([]float64{X[0], X[nstations-1]}, []float64{Y[0], Y[nstations-1]}, "'b-', clip_on=0, zorder=10") plt.Equal() plt.AxisRange(10, 210, 10, 210) plt.Gll("$x$", "$y$", "") plt.SaveD("/tmp/goga", "test_evo04.eps") } }
// SolveC solves the linear Complex system A.x = b func (o *LinSolUmfpack) SolveC(xR, xC, bR, bC []float64, dummy bool) (err error) { // check if !o.cmplx { return chk.Err(_linsol_umfpack_err12) } // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolUmfpack.SolveC . . . . . . . . . . . . . . . \n\n") } // UMFPACK: pointers pxR := (*C.double)(unsafe.Pointer(&xR[0])) pxC := (*C.double)(unsafe.Pointer(&xC[0])) pbR := (*C.double)(unsafe.Pointer(&bR[0])) pbC := (*C.double)(unsafe.Pointer(&bC[0])) // UMFPACK: solve st := C.umfpack_zl_solve(C.UMFPACK_A, o.ap, o.ai, o.ax, o.az, pxR, pxC, pbR, pbC, o.unum, o.uctrl, nil) if st != C.UMFPACK_OK { chk.Err(_linsol_umfpack_err13, Uerr2Text[int(st)]) } // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolUmfpack.Solve = %v\n", o.name, time.Now().Sub(o.tini)) } return }
// Clean deletes temporary data structures func (o *LinSolUmfpack) Clean() { // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolUmfpack.Clean . . . . . . . . . . . . . . . \n\n") } // clean up if o.cmplx { C.umfpack_zl_free_symbolic(&o.usymb) C.umfpack_zl_free_numeric(&o.unum) } else { C.umfpack_dl_free_symbolic(&o.usymb) C.umfpack_dl_free_numeric(&o.unum) } // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolUmfpack.Clean = %v\n", o.name, time.Now().Sub(o.tini)) } }
// Clean deletes temporary data structures func (o *LinSolMumps) Clean() { // exit if not initialised if !o.is_initialised { return } // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolMumps.Clean . . . . . . . . . . . . . . . \n\n") } // clean up if o.cmplx { o.mz.job = -2 // finalize code C.zmumps_c(&o.mz) // do finalize } else { o.m.job = -2 // finalize code C.dmumps_c(&o.m) // do finalize } // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolMumps.Clean = %v\n", o.name, time.Now().Sub(o.tini)) } }
// SolveC solves the linear Complex system A.x = b // NOTES: // 1) sum_b_to_root is a flag for MUMPS; it tells Solve to sum the values in 'b' arrays to the root processor func (o *LinSolMumps) SolveC(xR, xC, bR, bC []float64, sum_b_to_root bool) (err error) { // check if !o.cmplx { return chk.Err(_linsol_mumps_err11) } // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolMumps.SolveC . . . . . . . . . . . . . . . \n\n") } // MUMPS: set RHS in processor # 0 if sum_b_to_root { mpi.SumToRoot(xR, bR) mpi.SumToRoot(xC, bC) // join complex values if mpi.Rank() == 0 { for i := 0; i < len(xR); i++ { o.xRC[i*2], o.xRC[i*2+1] = xR[i], xC[i] } } } else { // join complex values if mpi.Rank() == 0 { for i := 0; i < len(xR); i++ { o.xRC[i*2], o.xRC[i*2+1] = bR[i], bC[i] } } } // MUMPS: solve o.mz.job = 3 // solution code C.zmumps_c(&o.mz) // solve if o.mz.info[1-1] < 0 { return chk.Err(_linsol_mumps_err12, mumps_error(o.mz.info[1-1], o.mz.info[2-1])) } // MUMPS: split complex values if mpi.Rank() == 0 { for i := 0; i < len(xR); i++ { xR[i], xC[i] = o.xRC[i*2], o.xRC[i*2+1] } } // MUMPS: broadcast from root mpi.BcastFromRoot(xR) mpi.BcastFromRoot(xC) // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolMumps.Solve = %v\n", o.name, time.Now().Sub(o.tini)) } return }
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) }
func Test_2dinteg02(tst *testing.T) { //verbose() chk.PrintTitle("2dinteg02. bidimensional integral") // Γ(1/4, 1) gamma_1div4_1 := 0.2462555291934987088744974330686081384629028737277219 x := utl.LinSpace(0, 1, 11) y := utl.LinSpace(0, 1, 11) m, n := len(x), len(y) f := la.MatAlloc(m, n) for i := 0; i < m; i++ { for j := 0; j < n; j++ { f[i][j] = 8.0 * math.Exp(-math.Pow(x[i], 2)-math.Pow(y[j], 4)) } } dx, dy := x[1]-x[0], y[1]-y[0] Vt := Trapz2D(dx, dy, f) Vs := Simps2D(dx, dy, f) Vc := math.Sqrt(math.Pi) * math.Erf(1) * (math.Gamma(1.0/4.0) - gamma_1div4_1) io.Pforan("Vt = %v\n", Vt) io.Pforan("Vs = %v\n", Vs) io.Pfgreen("Vc = %v\n", Vc) chk.Scalar(tst, "Vt", 0.0114830435645548, Vt, Vc) chk.Scalar(tst, "Vs", 1e-4, Vs, Vc) }
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) }
func Test_elast02(tst *testing.T) { //verbose() chk.PrintTitle("elast02") //K, G := 2.0, 3.0/4.0 K, G := 1116.6666666666667, 837.5 io.Pfgreen("K = %v\n", Calc_K_from_Enu(2010, 0.2)) io.Pfgreen("G = %v\n", Calc_G_from_Knu(K, 0.2)) ndim, pstress := 2, false var ec SmallElasticity err := ec.Init(ndim, pstress, []*fun.Prm{ &fun.Prm{N: "K", V: K}, &fun.Prm{N: "G", V: G}, }) io.Pforan("ec: %+v\n", &ec) if err != nil { tst.Errorf("test failed: %v\n", err) return } nsig, nalp, large, nle := 2*ndim, 0, false, false state := NewState(nsig, nalp, large, nle) D := la.MatAlloc(nsig, nsig) ec.CalcD(D, state) a := K + 4.0*G/3.0 b := K - 2.0*G/3.0 c := 2.0 * G chk.Matrix(tst, "D", 1e-12, D, [][]float64{ {a, b, b, 0}, {b, a, b, 0}, {b, b, a, 0}, {0, 0, 0, c}, }) }
// SolveR solves the linear Real system A.x = b // NOTES: // 1) sum_b_to_root is a flag for MUMPS; it tells Solve to sum the values in 'b' arrays to the root processor func (o *LinSolMumps) SolveR(xR, bR []float64, sum_b_to_root bool) (err error) { // check if !o.is_initialised { return chk.Err("linear solver must be initialised first\n") } if o.cmplx { return chk.Err(_linsol_mumps_err09) } // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolMumps.SolveR . . . . . . . . . . . . . . . \n\n") } // MUMPS: set RHS in processor # 0 if sum_b_to_root { mpi.SumToRoot(xR, bR) } else { if mpi.Rank() == 0 { copy(xR, bR) // x := b } } // only proc # 0 needs the RHS if mpi.Rank() == 0 { o.m.rhs = (*C.double)(unsafe.Pointer(&xR[0])) } // MUMPS: solve o.m.job = 3 // solution code C.dmumps_c(&o.m) // solve if o.m.info[1-1] < 0 { return chk.Err(_linsol_mumps_err10, mumps_error(o.m.info[1-1], o.m.info[2-1])) } mpi.BcastFromRoot(xR) // broadcast from root // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolMumps.Solve = %v\n", o.name, time.Now().Sub(o.tini)) } return }
func Test_MTshuffleInts01(tst *testing.T) { //verbose() chk.PrintTitle("MTshuffleInts01. Mersenne Twister") Init(0) n := 10 nums := utl.IntRange(n) io.Pfgreen("before = %v\n", nums) MTintShuffle(nums) io.Pfcyan("after = %v\n", nums) sort.Ints(nums) io.Pforan("sorted = %v\n", nums) chk.Ints(tst, "nums", nums, utl.IntRange(n)) }
// Fact performs symbolic/numeric factorisation. This method also converts the triplet form // to the column-compressed form, including the summation of duplicated entries func (o *LinSolMumps) Fact() (err error) { // check if !o.is_initialised { return chk.Err("linear solver must be initialised first\n") } // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolMumps.Fact . . . . . . . . . . . . . . . \n\n") } // complex if o.cmplx { // MUMPS: factorisation o.mz.job = 2 // factorisation code C.zmumps_c(&o.mz) // factorise if o.mz.info[1-1] < 0 { return chk.Err(_linsol_mumps_err08, "Real", mumps_error(o.mz.info[1-1], o.mz.info[2-1])) } // real } else { // MUMPS: factorisation o.m.job = 2 // factorisation code C.dmumps_c(&o.m) // factorise if o.m.info[1-1] < 0 { return chk.Err(_linsol_mumps_err08, "Complex", mumps_error(o.m.info[1-1], o.m.info[2-1])) } } // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolMumps.Fact = %v\n", o.name, time.Now().Sub(o.tini)) } return }
// SolveR solves the linear Real system A.x = b func (o *LinSolUmfpack) SolveR(xR, bR []float64, dummy bool) (err error) { // check if !o.is_initialised { return chk.Err("linear solver must be initialised first\n") } if o.cmplx { return chk.Err(_linsol_umfpack_err10) } // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolUmfpack.SolveR . . . . . . . . . . . . . . . \n\n") } // UMFPACK: pointers pxR := (*C.double)(unsafe.Pointer(&xR[0])) pbR := (*C.double)(unsafe.Pointer(&bR[0])) // UMFPACK: solve st := C.umfpack_dl_solve(C.UMFPACK_A, o.ap, o.ai, o.ax, pxR, pbR, o.unum, o.uctrl, o.uinfo) if st != C.UMFPACK_OK { return chk.Err(_linsol_umfpack_err11, Uerr2Text[int(st)]) } if o.verb { C.umfpack_dl_report_info(o.uctrl, o.uinfo) } // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolUmfpack.Solve = %v\n", o.name, time.Now().Sub(o.tini)) } return }
func Test_GOshuffleInts01(tst *testing.T) { //verbose() chk.PrintTitle("GOshuffleInts01") Init(0) n := 10 nums := utl.IntRange(n) io.Pfgreen("before = %v\n", nums) IntShuffle(nums) io.Pfcyan("after = %v\n", nums) sort.Ints(nums) io.Pforan("sorted = %v\n", nums) chk.Ints(tst, "nums", nums, utl.IntRange(n)) shufled := IntGetShuffled(nums) io.Pfyel("shufled = %v\n", shufled) sort.Ints(shufled) chk.Ints(tst, "shufled", shufled, utl.IntRange(n)) }
func Test_getunique01(tst *testing.T) { //verbose() chk.PrintTitle("getunique01") Init(0) nsel := 5 // number of selections size := 10 nums := utl.IntRange(size) hist := IntHistogram{Stations: utl.IntRange(size + 5)} sel := IntGetUnique(nums, nsel) io.Pfgreen("nums = %v\n", nums) io.Pfcyan("sel = %v\n", sel) for i := 0; i < NSAMPLES; i++ { sel := IntGetUnique(nums, nsel) check_repeated(sel) hist.Count(sel, false) //io.Pfgrey("sel = %v\n", sel) } io.Pf(TextHist(hist.GenLabels("%d"), hist.Counts, 60)) }
func Test_intordcx01(tst *testing.T) { //verbose() chk.PrintTitle("intordcx01") var ops OpsData ops.SetDefault() ops.Pc = 1 rnd.Init(0) A := []int{1, 2, 3, 4, 5, 6, 7, 8} B := []int{2, 4, 6, 8, 7, 5, 3, 1} a := make([]int, len(A)) b := make([]int, len(A)) ops.Cuts = []int{2, 5} IntOrdCrossover(a, b, A, B, 0, &ops) io.Pforan("A = %v\n", A) io.Pfblue2("B = %v\n", B) io.Pfgreen("a = %v\n", a) io.Pfyel("b = %v\n", b) chk.Ints(tst, "A", A, []int{1, 2, 3, 4, 5, 6, 7, 8}) chk.Ints(tst, "B", B, []int{2, 4, 6, 8, 7, 5, 3, 1}) chk.Ints(tst, "a", a, []int{4, 5, 6, 8, 7, 1, 2, 3}) chk.Ints(tst, "b", b, []int{8, 7, 3, 4, 5, 1, 2, 6}) sort.Ints(a) sort.Ints(b) nums := utl.IntRange2(1, 9) chk.Ints(tst, "asorted = 12345678", a, nums) chk.Ints(tst, "bsorted = 12345678", b, nums) A = []int{1, 3, 5, 7, 6, 2, 4, 8} B = []int{5, 6, 3, 8, 2, 1, 4, 7} ops.Cuts = []int{3, 6} IntOrdCrossover(a, b, A, B, 0, &ops) io.Pforan("\nA = %v\n", A) io.Pfblue2("B = %v\n", B) io.Pfgreen("a = %v\n", a) io.Pfyel("b = %v\n", b) chk.Ints(tst, "A", A, []int{1, 3, 5, 7, 6, 2, 4, 8}) chk.Ints(tst, "B", B, []int{5, 6, 3, 8, 2, 1, 4, 7}) chk.Ints(tst, "a", a, []int{5, 7, 6, 8, 2, 1, 4, 3}) chk.Ints(tst, "b", b, []int{3, 8, 1, 7, 6, 2, 4, 5}) sort.Ints(a) sort.Ints(b) chk.Ints(tst, "asorted = 12345678", a, nums) chk.Ints(tst, "bsorted = 12345678", b, nums) A = []int{1, 2, 3, 4, 5, 6, 7, 8} B = []int{2, 4, 6, 8, 7, 5, 3, 1} ops.Cuts = []int{} IntOrdCrossover(a, b, A, B, 0, &ops) io.Pforan("\nA = %v\n", A) io.Pfblue2("B = %v\n", B) io.Pfgreen("a = %v\n", a) io.Pfyel("b = %v\n", b) sort.Ints(a) sort.Ints(b) chk.Ints(tst, "asorted = 12345678", a, nums) chk.Ints(tst, "bsorted = 12345678", b, nums) C := []int{1, 2, 3} D := []int{3, 1, 2} c := make([]int, len(C)) d := make([]int, len(D)) IntOrdCrossover(c, d, C, D, 0, &ops) io.Pforan("\nC = %v\n", C) io.Pfblue2("D = %v\n", D) io.Pfgreen("c = %v\n", c) io.Pfyel("d = %v\n", d) chk.Ints(tst, "c", c, []int{2, 1, 3}) chk.Ints(tst, "d", d, []int{1, 2, 3}) sort.Ints(c) sort.Ints(d) chk.Ints(tst, "csorted = 123", c, []int{1, 2, 3}) chk.Ints(tst, "dsorted = 123", d, []int{1, 2, 3}) }
// testing_compare_results_u compares results with u-formulation func TestingCompareResultsU(tst *testing.T, simfilepath, cmpfname, alias string, tolK, tolu, tols float64, skipK, verbose bool) { // FEM structure fem := NewFEM(simfilepath, alias, false, false, true, false, verbose, 0) // set stage err := fem.SetStage(0) if err != nil { chk.Panic("cannot set stage:\n%v", err) } // zero solution err = fem.ZeroStage(0, true) if err != nil { chk.Panic("cannot zero stage data:\n%v", err) } // read file with comparison results buf, err := io.ReadFile(cmpfname) if err != nil { tst.Errorf("TestingCompareResultsU: ReadFile failed\n") return } // unmarshal json var cmp_set T_results_set err = json.Unmarshal(buf, &cmp_set) if err != nil { tst.Errorf("TestingCompareResultsU: Unmarshal failed\n") return } // run comparisons dom := fem.Domains[0] dmult := 1.0 for idx, cmp := range cmp_set { // displacements multiplier if idx == 0 && math.Abs(cmp.DispMult) > 1e-10 { dmult = cmp.DispMult } // time index tidx := idx + 1 if verbose { io.PfYel("\n\ntidx = %d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", tidx) } // load gofem results err = dom.Read(fem.Summary, tidx, 0, true) if err != nil { chk.Panic("cannot read 'gofem' results:\n%v", err) } if verbose { io.Pfyel("time = %v\n", dom.Sol.T) } // check K matrices if !skipK { if verbose { io.Pfgreen(". . . checking K matrices . . .\n") } for eid, Ksg := range cmp.Kmats { if e, ok := dom.Elems[eid].(*ElemU); ok { err = e.AddToKb(dom.Kb, dom.Sol, true) if err != nil { chk.Panic("TestingCompareResultsU: AddToKb failed\n") } chk.Matrix(tst, io.Sf("K%d", eid), tolK, e.K, Ksg) } if e, ok := dom.Elems[eid].(*Rod); ok { err = e.AddToKb(dom.Kb, dom.Sol, true) if err != nil { chk.Panic("TestingCompareResultsU: AddToKb failed\n") } chk.Matrix(tst, io.Sf("K%d", eid), tolK, e.K, Ksg) } if e, ok := dom.Elems[eid].(*ElastRod); ok { err = e.AddToKb(dom.Kb, dom.Sol, true) if err != nil { chk.Panic("TestingCompareResultsU: AddToKb failed\n") } chk.Matrix(tst, io.Sf("K%d", eid), tolK, e.K, Ksg) } } } // check displacements if verbose { io.Pfgreen(". . . checking displacements . . .\n") } for nid, usg := range cmp.Disp { ix := dom.Vid2node[nid].Dofs[0].Eq iy := dom.Vid2node[nid].Dofs[1].Eq chk.AnaNum(tst, "ux", tolu, dom.Sol.Y[ix], usg[0]*dmult, verbose) chk.AnaNum(tst, "uy", tolu, dom.Sol.Y[iy], usg[1]*dmult, verbose) if len(usg) == 3 { iz := dom.Vid2node[nid].Dofs[2].Eq chk.AnaNum(tst, "uz", tolu, dom.Sol.Y[iz], usg[2]*dmult, verbose) } } // check stresses if true { if verbose { io.Pfgreen(". . . checking stresses . . .\n") } for eid, sig := range cmp.Sigmas { if verbose { io.Pforan("eid = %d\n", eid) } if e, ok := dom.Cid2elem[eid].(*ElemU); ok { for ip, val := range sig { if verbose { io.Pfgrey2("ip = %d\n", ip) } σ := e.States[ip].Sig if len(val) == 6 { chk.AnaNum(tst, "sx ", tols, σ[0], val[0], verbose) chk.AnaNum(tst, "sy ", tols, σ[1], val[1], verbose) } else { chk.AnaNum(tst, "sx ", tols, σ[0], val[0], verbose) chk.AnaNum(tst, "sy ", tols, σ[1], val[1], verbose) chk.AnaNum(tst, "sxy", tols, σ[3]/SQ2, val[2], verbose) if len(val) > 3 { // sx, sy, sxy, sz chk.AnaNum(tst, "sz ", tols, σ[2], val[3], verbose) } } } } if e, ok := dom.Cid2elem[eid].(*Rod); ok { for ip, val := range sig { if verbose { io.Pfgrey2("ip = %d\n", ip) } σ := e.States[ip].Sig chk.AnaNum(tst, "sig", tols, σ, val[0], verbose) } } if e, ok := dom.Cid2elem[eid].(*ElastRod); ok { dat := e.OutIpsData() for ip, val := range sig { if verbose { io.Pfgrey2("ip = %d\n", ip) } res := dat[ip].Calc(dom.Sol) σ := res["sig"] chk.AnaNum(tst, "sig", tols, σ, val[0], verbose) } } } } } }
func Test_int02(tst *testing.T) { //verbose() chk.PrintTitle("int02. TSP") // location / coordinates of stations locations := [][]float64{ {60, 200}, {180, 200}, {80, 180}, {140, 180}, {20, 160}, {100, 160}, {200, 160}, {140, 140}, {40, 120}, {100, 120}, {180, 100}, {60, 80}, {120, 80}, {180, 60}, {20, 40}, {100, 40}, {200, 40}, {20, 20}, {60, 20}, {160, 20}, } nstations := len(locations) // parameters C := NewConfParams() C.Nova = 1 C.Noor = 0 C.Nisl = 4 C.Ninds = 24 C.RegTol = 0.3 C.RegPct = 0.2 //C.Dtmig = 30 C.GAtype = "crowd" C.ParetoPhi = 0.1 C.Elite = false C.DoPlot = false //chk.Verbose //C.Rws = true C.SetIntOrd(nstations) C.CalcDerived() // initialise random numbers generator rnd.Init(0) // objective value function C.OvaOor = func(ind *Individual, idIsland, t int, report *bytes.Buffer) { L := locations ids := ind.Ints //io.Pforan("ids = %v\n", ids) dist := 0.0 for i := 1; i < nstations; i++ { a, b := ids[i-1], ids[i] dist += math.Sqrt(math.Pow(L[b][0]-L[a][0], 2.0) + math.Pow(L[b][1]-L[a][1], 2.0)) } a, b := ids[nstations-1], ids[0] dist += math.Sqrt(math.Pow(L[b][0]-L[a][0], 2.0) + math.Pow(L[b][1]-L[a][1], 2.0)) ind.Ovas[0] = dist return } // evolver evo := NewEvolver(C) // print initial population pop := evo.Islands[0].Pop //io.Pf("\n%v\n", pop.Output(nil, false)) // 0,4,8,11,14,17,18,15,12,19,13,16,10,6,1,3,7,9,5,2 894.363 if false { for i, x := range []int{0, 4, 8, 11, 14, 17, 18, 15, 12, 19, 13, 16, 10, 6, 1, 3, 7, 9, 5, 2} { pop[0].Ints[i] = x } evo.Islands[0].CalcOvs(pop, 0) evo.Islands[0].CalcDemeritsAndSort(pop) } // check initial population ints := make([]int, nstations) if false { for i := 0; i < C.Ninds; i++ { for j := 0; j < nstations; j++ { ints[j] = pop[i].Ints[j] } sort.Ints(ints) chk.Ints(tst, "ints", ints, utl.IntRange(nstations)) } } // run evo.Run() //io.Pf("%v\n", pop.Output(nil, false)) io.Pfgreen("best = %v\n", evo.Best.Ints) io.Pfgreen("best OVA = %v (871.117353844847)\n\n", evo.Best.Ovas[0]) // best = [18 17 14 11 8 4 0 2 5 9 12 7 6 1 3 10 16 13 19 15] // best OVA = 953.4643474956656 // best = [8 11 14 17 18 15 12 19 16 13 10 6 1 3 7 9 5 2 0 4] // best OVA = 871.117353844847 // best = [5 2 0 4 8 11 14 17 18 15 12 19 16 13 10 6 1 3 7 9] // best OVA = 871.1173538448469 // best = [6 10 13 16 19 15 18 17 14 11 8 4 0 2 5 9 12 7 3 1] // best OVA = 880.7760751923065 // check final population if false { for i := 0; i < C.Ninds; i++ { for j := 0; j < nstations; j++ { ints[j] = pop[i].Ints[j] } sort.Ints(ints) chk.Ints(tst, "ints", ints, utl.IntRange(nstations)) } } // plot travelling salesman path if C.DoPlot { plt.SetForEps(1, 300) X, Y := make([]float64, nstations), make([]float64, nstations) for k, id := range evo.Best.Ints { X[k], Y[k] = locations[id][0], locations[id][1] plt.PlotOne(X[k], Y[k], "'r.', ms=5, clip_on=0, zorder=20") plt.Text(X[k], Y[k], io.Sf("%d", id), "fontsize=7, clip_on=0, zorder=30") } plt.Plot(X, Y, "'b-', clip_on=0, zorder=10") plt.Plot([]float64{X[0], X[nstations-1]}, []float64{Y[0], Y[nstations-1]}, "'b-', clip_on=0, zorder=10") plt.Equal() plt.AxisRange(10, 210, 10, 210) plt.Gll("$x$", "$y$", "") plt.SaveD("/tmp/goga", "test_evo04.eps") } }
// Run computes β starting witn an initial guess func (o *ReliabFORM) Run(βtrial float64, verbose bool, args ...interface{}) (β float64, μ, σ, x []float64) { // initial random variables β = βtrial nx := len(o.μ) μ = make([]float64, nx) // mean values (equivalent normal value) σ = make([]float64, nx) // deviation values (equivalent normal value) x = make([]float64, nx) // current vector of random variables defining min(β) for i := 0; i < nx; i++ { μ[i] = o.μ[i] σ[i] = o.σ[i] x[i] = o.μ[i] } // lognormal distribution structure var lnd DistLogNormal // has lognormal random variable? haslrv := false for _, found := range o.lrv { if found { haslrv = true break } } // function to compute β with x-constant // gβ(β) = g(μ - β・A・σ) = 0 var err error gβfcn := func(fy, y []float64) error { βtmp := y[0] for i := 0; i < nx; i++ { o.xtmp[i] = μ[i] - βtmp*o.α[i]*σ[i] } fy[0], err = o.gfcn(o.xtmp, args) if err != nil { chk.Panic("cannot compute gfcn(%v):\n%v", o.xtmp, err) } return nil } // derivative of gβ w.r.t β hβfcn := func(dfdy [][]float64, y []float64) error { βtmp := y[0] for i := 0; i < nx; i++ { o.xtmp[i] = μ[i] - βtmp*o.α[i]*σ[i] } err = o.hfcn(o.dgdx, o.xtmp, args) if err != nil { chk.Panic("cannot compute hfcn(%v):\n%v", o.xtmp, err) } dfdy[0][0] = 0 for i := 0; i < nx; i++ { dfdy[0][0] -= o.dgdx[i] * o.α[i] * σ[i] } return nil } // nonlinear solver with y[0] = β // solving: gβ(β) = g(μ - β・A・σ) = 0 var nls num.NlSolver nls.Init(1, gβfcn, nil, hβfcn, true, false, nil) defer nls.Clean() // message if verbose { io.Pf("\n%s", io.StrThickLine(60)) } // plotting plot := o.PlotFnk != "" if nx != 2 { plot = false } if plot { if o.PlotNp < 3 { o.PlotNp = 41 } var umin, umax, vmin, vmax float64 if o.PlotCf < 1 { o.PlotCf = 2 } if len(o.PlotUrange) == 0 { umin, umax = μ[0]-o.PlotCf*μ[0], μ[0]+o.PlotCf*μ[0] vmin, vmax = μ[1]-o.PlotCf*μ[1], μ[1]+o.PlotCf*μ[1] } else { chk.IntAssert(len(o.PlotUrange), 2) chk.IntAssert(len(o.PlotVrange), 2) umin, umax = o.PlotUrange[0], o.PlotUrange[1] vmin, vmax = o.PlotVrange[0], o.PlotVrange[1] } o.PlotU, o.PlotV = utl.MeshGrid2D(umin, umax, vmin, vmax, o.PlotNp, o.PlotNp) o.PlotZ = la.MatAlloc(o.PlotNp, o.PlotNp) plt.SetForEps(0.8, 300) for i := 0; i < o.PlotNp; i++ { for j := 0; j < o.PlotNp; j++ { o.xtmp[0] = o.PlotU[i][j] o.xtmp[1] = o.PlotV[i][j] o.PlotZ[i][j], err = o.gfcn(o.xtmp, args) if err != nil { chk.Panic("cannot compute gfcn(%v):\n%v", x, err) } } } plt.Contour(o.PlotU, o.PlotV, o.PlotZ, "") plt.ContourSimple(o.PlotU, o.PlotV, o.PlotZ, true, 8, "levels=[0], colors=['yellow']") plt.PlotOne(x[0], x[1], "'ro', label='initial'") } // iterations to find β var dat VarData B := []float64{β} itB := 0 for itB = 0; itB < o.NmaxItB; itB++ { // message if verbose { gx, err := o.gfcn(x, args) if err != nil { chk.Panic("cannot compute gfcn(%v):\n%v", x, err) } io.Pf("%s itB=%d β=%g g=%g\n", io.StrThinLine(60), itB, β, gx) } // plot if plot { plt.PlotOne(x[0], x[1], "'r.'") } // compute direction cosines itA := 0 for itA = 0; itA < o.NmaxItA; itA++ { // has lognormal random variable (lrv) if haslrv { // find equivalent normal mean and std deviation for lognormal variables for i := 0; i < nx; i++ { if o.lrv[i] { // set distribution dat.M, dat.S = o.μ[i], o.σ[i] lnd.Init(&dat) // update μ and σ fx := lnd.Pdf(x[i]) Φinvx := (math.Log(x[i]) - lnd.M) / lnd.S φx := math.Exp(-Φinvx*Φinvx/2.0) / math.Sqrt2 / math.SqrtPi σ[i] = φx / fx μ[i] = x[i] - Φinvx*σ[i] } } } // compute direction cosines err = o.hfcn(o.dgdx, x, args) if err != nil { chk.Panic("cannot compute hfcn(%v):\n%v", x, err) } den := 0.0 for i := 0; i < nx; i++ { den += math.Pow(o.dgdx[i]*σ[i], 2.0) } den = math.Sqrt(den) αerr := 0.0 // difference on α for i := 0; i < nx; i++ { αnew := o.dgdx[i] * σ[i] / den αerr += math.Pow(αnew-o.α[i], 2.0) o.α[i] = αnew } αerr = math.Sqrt(αerr) // message if verbose { io.Pf(" itA=%d\n", itA) io.Pf("%12s%12s%12s%12s\n", "x", "μ", "σ", "α") for i := 0; i < nx; i++ { io.Pf("%12.3f%12.3f%12.3f%12.3f\n", x[i], μ[i], σ[i], o.α[i]) } } // update x-star for i := 0; i < nx; i++ { x[i] = μ[i] - β*o.α[i]*σ[i] } // check convergence on α if itA > 1 && αerr < o.TolA { if verbose { io.Pfgrey(". . . converged on α with αerr=%g . . .\n", αerr) } break } } // failed to converge on α if itA == o.NmaxItA { chk.Panic("failed to convege on α") } // compute new β B[0] = β nls.Solve(B, o.NlsSilent) βerr := math.Abs(B[0] - β) β = B[0] if o.NlsCheckJ { nls.CheckJ(B, o.NlsCheckJtol, true, false) } // update x-star for i := 0; i < nx; i++ { x[i] = μ[i] - β*o.α[i]*σ[i] } // check convergence on β if βerr < o.TolB { if verbose { io.Pfgrey2(". . . converged on β with βerr=%g . . .\n", βerr) } break } } // failed to converge on β if itB == o.NmaxItB { chk.Panic("failed to converge on β") } // message if verbose { gx, err := o.gfcn(x, args) if err != nil { chk.Panic("cannot compute gfcn(%v):\n%v", x, err) } io.Pfgreen("x = %v\n", x) io.Pfgreen("g = %v\n", gx) io.PfGreen("β = %v\n", β) } // plot if plot { plt.Gll("$x_0$", "$x_1$", "") plt.Cross("") plt.SaveD("/tmp/gosl", "fig_form_"+o.PlotFnk+".eps") } return }
// testing_compare_results_u compares results with u-formulation func TestingCompareResultsU(tst *testing.T, simfname, cmpfname string, tolK, tolu, tols float64, skipK, verbose bool) { // only root can run this test if !Global.Root { return } // read summary sum := ReadSum(Global.Dirout, Global.Fnkey) if sum == nil { tst.Error("cannot read summary file for simulation=%q\n", simfname) return } // allocate domain distr := false d := NewDomain(Global.Sim.Regions[0], distr) if !d.SetStage(0, Global.Sim.Stages[0], distr) { tst.Errorf("TestingCompareResultsU: SetStage failed\n") return } // read file buf, err := io.ReadFile(cmpfname) if err != nil { tst.Errorf("TestingCompareResultsU: ReadFile failed\n") return } // unmarshal json var cmp_set T_results_set err = json.Unmarshal(buf, &cmp_set) if err != nil { tst.Errorf("TestingCompareResultsU: Unmarshal failed\n") return } // run comparisons dmult := 1.0 for idx, cmp := range cmp_set { // displacements multiplier if idx == 0 && math.Abs(cmp.DispMult) > 1e-10 { dmult = cmp.DispMult } // time index tidx := idx + 1 if verbose { io.PfYel("\n\ntidx = %d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", tidx) } // load gofem results if !d.In(sum, tidx, true) { tst.Errorf("TestingCompareResultsU: reading of results failed\n") return } if verbose { io.Pfyel("time = %v\n", d.Sol.T) } // check K matrices if !skipK { if verbose { io.Pfgreen(". . . checking K matrices . . .\n") } for eid, Ksg := range cmp.Kmats { if e, ok := d.Elems[eid].(*ElemU); ok { if !e.AddToKb(d.Kb, d.Sol, true) { tst.Errorf("TestingCompareResultsU: AddToKb failed\n") return } chk.Matrix(tst, io.Sf("K%d", eid), tolK, e.K, Ksg) } } } // check displacements if verbose { io.Pfgreen(". . . checking displacements . . .\n") } for nid, usg := range cmp.Disp { ix := d.Vid2node[nid].Dofs[0].Eq iy := d.Vid2node[nid].Dofs[1].Eq chk.AnaNum(tst, "ux", tolu, d.Sol.Y[ix], usg[0]*dmult, verbose) chk.AnaNum(tst, "uy", tolu, d.Sol.Y[iy], usg[1]*dmult, verbose) if len(usg) == 3 { iz := d.Vid2node[nid].Dofs[2].Eq chk.AnaNum(tst, "uz", tolu, d.Sol.Y[iz], usg[2]*dmult, verbose) } } // check stresses if true { if verbose { io.Pfgreen(". . . checking stresses . . .\n") } for eid, sig := range cmp.Sigmas { if verbose { io.Pforan("eid = %d\n", eid) } if e, ok := d.Cid2elem[eid].(*ElemU); ok { for ip, val := range sig { if verbose { io.Pfgrey2("ip = %d\n", ip) } σ := e.States[ip].Sig if len(val) == 6 { chk.AnaNum(tst, "sx ", tols, σ[0], val[0], verbose) chk.AnaNum(tst, "sy ", tols, σ[1], val[1], verbose) } else { chk.AnaNum(tst, "sx ", tols, σ[0], val[0], verbose) chk.AnaNum(tst, "sy ", tols, σ[1], val[1], verbose) chk.AnaNum(tst, "sxy", tols, σ[3]/SQ2, val[2], verbose) if len(val) > 3 { // sx, sy, sxy, sz chk.AnaNum(tst, "sz ", tols, σ[2], val[3], verbose) } } } } } } } }
// InitC initialises a LinSolMumps data structure for Complex systems. It also performs some initial analyses. func (o *LinSolMumps) InitC(tC *TripletC, symmetric, verbose, timing bool) (err error) { // check o.tC = tC if tC.pos == 0 { return chk.Err(_linsol_mumps_err04) } // flags o.name = "mumps" o.sym = symmetric o.cmplx = true o.verb = verbose o.ton = timing // start time if mpi.Rank() != 0 { o.verb = false o.ton = false } if o.ton { o.tini = time.Now() } // check xz if len(o.tC.xz) != 2*len(o.tC.i) { return chk.Err(_linsol_mumps_err05, len(o.tC.xz), len(o.tC.i)) } // initialise Mumps o.mz.comm_fortran = -987654 // use Fortran communicator by default o.mz.par = 1 // host also works o.mz.sym = 0 // 0=unsymmetric, 1=sym(pos-def), 2=symmetric(undef) if symmetric { o.mz.sym = 2 } o.mz.job = -1 // initialisation code C.zmumps_c(&o.mz) // initialise if o.mz.info[1-1] < 0 { return chk.Err(_linsol_mumps_err06, mumps_error(o.mz.info[1-1], o.mz.info[2-1])) } // convert indices to C.int (not C.long) and // increment indices since Mumps is 1-based (FORTRAN) o.mi, o.mj = make([]int32, o.tC.pos), make([]int32, o.tC.pos) for k := 0; k < tC.pos; k++ { o.mi[k] = int32(o.tC.i[k]) + 1 o.mj[k] = int32(o.tC.j[k]) + 1 } // set pointers o.mz.n = C.int(o.tC.m) o.mz.nz_loc = C.int(o.tC.pos) o.mz.irn_loc = (*C.int)(unsafe.Pointer(&o.mi[0])) o.mz.jcn_loc = (*C.int)(unsafe.Pointer(&o.mj[0])) o.mz.a_loc = (*C.ZMUMPS_COMPLEX)(unsafe.Pointer(&o.tC.xz[0])) // only proc # 0 needs the RHS if mpi.Rank() == 0 { o.xRC = make([]float64, 2*o.tC.n) o.mz.rhs = (*C.ZMUMPS_COMPLEX)(unsafe.Pointer(&o.xRC[0])) } // control if verbose { if mpi.Rank() == 0 { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolMumps.InitC . . (MUMPS) . . . . . . . . . \n\n") } o.mz.icntl[1-1] = 6 // output stream for error messages o.mz.icntl[2-1] = 0 // output stream for statistics and warnings o.mz.icntl[3-1] = 6 // output stream for global information o.mz.icntl[4-1] = 2 // message level: 2==errors and warnings } else { o.mz.icntl[1-1] = -1 // no output messages o.mz.icntl[2-1] = -1 // no warnings o.mz.icntl[3-1] = -1 // no global information o.mz.icntl[4-1] = -1 // message level } o.mz.icntl[5-1] = 0 // assembled matrix (needed for distributed matrix) o.mz.icntl[6-1] = 7 // automatic (default) permuting strategy for diagonal terms o.mz.icntl[14-1] = 5000 // % increase of working space o.mz.icntl[18-1] = 3 // distributed matrix o.SetOrdScal("", "") // analysis step o.mz.job = 1 // analysis code C.zmumps_c(&o.mz) // analyse if o.mz.info[1-1] < 0 { return chk.Err(_linsol_mumps_err07, mumps_error(o.mz.info[1-1], o.mz.info[2-1])) } // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolMumps.InitC = %v\n", o.name, time.Now().Sub(o.tini)) } return }
// 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() } } } } }
// InitR initialises a LinSolMumps data structure for Real systems. It also performs some initial analyses. func (o *LinSolMumps) InitR(tR *Triplet, symmetric, verbose, timing bool) (err error) { // check o.tR = tR if tR.pos == 0 { return chk.Err(_linsol_mumps_err01) } // flags o.name = "mumps" o.sym = symmetric o.cmplx = false o.verb = verbose o.ton = timing // start time if mpi.Rank() != 0 { o.verb = false o.ton = false } if o.ton { o.tini = time.Now() } // initialise Mumps o.m.comm_fortran = -987654 // use Fortran communicator by default o.m.par = 1 // host also works o.m.sym = 0 // 0=unsymmetric, 1=sym(pos-def), 2=symmetric(undef) if symmetric { o.m.sym = 2 } o.m.job = -1 // initialisation code C.dmumps_c(&o.m) // initialise if o.m.info[1-1] < 0 { return chk.Err(_linsol_mumps_err02, mumps_error(o.m.info[1-1], o.m.info[2-1])) } // convert indices to C.int (not C.long) and // increment indices since Mumps is 1-based (FORTRAN) o.mi, o.mj = make([]int32, o.tR.pos), make([]int32, o.tR.pos) for k := 0; k < tR.pos; k++ { o.mi[k] = int32(o.tR.i[k]) + 1 o.mj[k] = int32(o.tR.j[k]) + 1 } // set pointers o.m.n = C.int(o.tR.m) o.m.nz_loc = C.int(o.tR.pos) o.m.irn_loc = (*C.int)(unsafe.Pointer(&o.mi[0])) o.m.jcn_loc = (*C.int)(unsafe.Pointer(&o.mj[0])) o.m.a_loc = (*C.double)(unsafe.Pointer(&o.tR.x[0])) // control if verbose { if mpi.Rank() == 0 { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolMumps.InitR . . (MUMPS) . . . . . . . . . \n\n") } o.m.icntl[1-1] = 6 // output stream for error messages o.m.icntl[2-1] = 0 // output stream for statistics and warnings o.m.icntl[3-1] = 6 // output stream for global information o.m.icntl[4-1] = 2 // message level: 2==errors and warnings } else { o.m.icntl[1-1] = -1 // no output messages o.m.icntl[2-1] = -1 // no warnings o.m.icntl[3-1] = -1 // no global information o.m.icntl[4-1] = -1 // message level } o.m.icntl[5-1] = 0 // assembled matrix (needed for distributed matrix) o.m.icntl[6-1] = 7 // automatic (default) permuting strategy for diagonal terms o.m.icntl[14-1] = 5000 // % increase of working space o.m.icntl[18-1] = 3 // distributed matrix o.m.icntl[23-1] = 2000 // max 2000Mb per processor // TODO: check this o.SetOrdScal("", "") // analysis step o.m.job = 1 // analysis code C.dmumps_c(&o.m) // analyse if o.m.info[1-1] < 0 { return chk.Err(_linsol_mumps_err03, mumps_error(o.m.info[1-1], o.m.info[2-1])) } // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolMumps.InitR = %v\n", o.name, time.Now().Sub(o.tini)) } // success o.is_initialised = true return }
func (o *RichardsonExtrap) Run(d *Domain, s *Summary, DtOut fun.Func, time *float64, tf, tout float64, tidx *int) (ok bool) { // stat defer func() { if Global.Root { log.Printf("total number of steps = %d\n", o.nsteps) log.Printf("number of accepted steps = %d\n", o.naccept) log.Printf("number of rejected steps = %d\n", o.nreject) log.Printf("number of Gustaffson's corrections = %d\n", o.ngustaf) } }() // constants atol := Global.Sim.Solver.REatol rtol := Global.Sim.Solver.RErtol mmin := Global.Sim.Solver.REmmin mmax := Global.Sim.Solver.REmmax mfac := Global.Sim.Solver.REmfac // time loop t := *time defer func() { *time = t }() var ΔtOld, rerrOld float64 for t < tf { // check for continued divergence if LogErrCond(o.ndiverg >= Global.Sim.Solver.NdvgMax, "continuous divergence after %d steps reached", o.ndiverg) { return } // check time increment if LogErrCond(o.Δt < Global.Sim.Solver.DtMin, "Δt increment is too small: %g < %g", o.Δt, Global.Sim.Solver.DtMin) { return } // compute dynamic coefficients if LogErr(Global.DynCoefs.CalcBoth(o.Δt), "cannot compute dynamic coefficients") { return } // check for maximum number of substeps o.nsteps += 1 if LogErrCond(o.nsteps >= Global.Sim.Solver.REnssmax, "RE: max number of steps reached: %d", o.nsteps) { return } // backup domain d.backup() // single step with Δt d.Sol.T = t + o.Δt o.diverging, ok = run_iterations(t+o.Δt, o.Δt, d, s) if !ok { return } if Global.Sim.Solver.DvgCtrl { if o.divergence_control(d, "big step") { continue } } // save intermediate state for i := 0; i < d.Ny; i++ { o.Y_big[i] = d.Sol.Y[i] } // restore initial state d.restore() // 1st halved step d.Sol.T = t + o.Δt/2.0 o.diverging, ok = run_iterations(t+o.Δt/2.0, o.Δt/2.0, d, s) if !ok { break } if Global.Sim.Solver.DvgCtrl { if o.divergence_control(d, "1st half step") { continue } } // 2nd halved step d.Sol.T = t + o.Δt o.diverging, ok = run_iterations(t+o.Δt, o.Δt/2.0, d, s) if !ok { break } if Global.Sim.Solver.DvgCtrl { if o.divergence_control(d, "2nd half step") { continue } } // Richardson's extrapolation error rerr := la.VecRmsError(d.Sol.Y, o.Y_big, atol, rtol, d.Sol.Y) / 3.0 // step size change m := min(mmax, max(mmin, mfac*math.Pow(1.0/rerr, 1.0/2.0))) ΔtNew := m * o.Δt // accepted if rerr < 1.0 { // update variables o.naccept += 1 t += o.Δt d.Sol.T = t // output if Global.Verbose { if !Global.Sim.Data.ShowR && !Global.Debug { io.PfWhite("%30.15f\r", t) } } //if true { if t >= tout || o.laststep { s.OutTimes = append(s.OutTimes, t) if !d.Out(*tidx) { return } tout += DtOut.F(t, nil) *tidx += 1 } // reached final time if o.laststep { if Global.Verbose { io.Pfgreen("\n\nRichardson extrapolation succeeded\n") } return true } // predictive controller of Gustafsson if !Global.Sim.Solver.REnogus { if o.naccept > 1 { m = mfac * (o.Δt / ΔtOld) * math.Sqrt(1.0/rerr) * math.Sqrt(rerrOld/rerr) if m*o.Δt < ΔtNew { o.ngustaf += 1 } ΔtNew = min(ΔtNew, m*o.Δt) } ΔtOld = o.Δt rerrOld = max(0.9, rerr) // 1e-2 } // next step size if o.reject { // do not alow Δt to grow if previous was a reject ΔtNew = min(o.Δt, ΔtNew) } o.reject = false o.Δt = ΔtNew if t+ΔtNew-tf >= 0.0 { o.laststep = true o.Δt = tf - t } // rejected } else { // restore state d.restore() // set flags o.nreject += 1 o.reject = true o.laststep = false // next step size o.Δt = ΔtNew if t+o.Δt > tf { o.Δt = tf - t } } } return true }
// Solve solves from (xa,ya) to (xb,yb) => find yb (stored in y) func (o *ODE) Solve(y []float64, x, xb, Δx float64, fixstp bool, args ...interface{}) (err error) { // check if xb < x { err = chk.Err(_ode_err3, xb, x) return } // derived variables o.fnewt = max(10.0*o.ϵ/o.Rtol, min(0.03, math.Sqrt(o.Rtol))) // initial step size Δx = min(Δx, xb-x) if fixstp { o.h = Δx } else { o.h = min(Δx, o.IniH) } o.hprev = o.h // output initial state if o.out != nil { o.out(true, o.h, x, y, args...) } // stat variables o.nfeval = 0 o.njeval = 0 o.nsteps = 0 o.naccepted = 0 o.nrejected = 0 o.ndecomp = 0 o.nlinsol = 0 o.nitmax = 0 // control variables o.doinit = true o.first = true o.last = false o.reject = false o.diverg = false o.dvfac = 0 o.η = 1.0 o.jacIsOK = false o.reuseJdec = false o.reuseJ = false o.nit = 0 o.hopt = o.h o.θ = o.θmax // local error indicator var rerr float64 // linear solver lsname := "umfpack" if o.Distr { lsname = "mumps" } o.lsolR = la.GetSolver(lsname) o.lsolC = la.GetSolver(lsname) // clean up and show stat before leaving defer func() { o.lsolR.Clean() o.lsolC.Clean() if !o.silent { o.Stat() } }() // first scaling variable la.VecScaleAbs(o.scal, o.Atol, o.Rtol, y) // o.scal := o.Atol + o.Rtol * abs(y) // fixed steps if fixstp { la.VecCopy(o.w[0], 1, y) // copy initial values to worksapce if o.Verbose { io.Pfgreen("x = %v\n", x) } for x < xb { //if x + o.h > xb { o.h = xb - x } if o.jac == nil { // numerical Jacobian if o.method == "Radau5" { o.nfeval += 1 o.fcn(o.f0, x, y, args...) } } o.reuseJdec = false o.reuseJ = false o.jacIsOK = false o.step(o, y, x, args...) o.nsteps += 1 o.doinit = false o.first = false o.hprev = o.h x += o.h o.accept(o, y) if o.out != nil { o.out(false, o.h, x, y, args...) } if o.Verbose { io.Pfgreen("x = %v\n", x) } } return } // first function evaluation o.nfeval += 1 o.fcn(o.f0, x, y, args...) // o.f0 := f(x,y) // time loop var dxmax, xstep, fac, div, dxnew, facgus, old_h, old_rerr float64 var dxratio float64 var failed bool for x < xb { dxmax, xstep = Δx, x+Δx failed = false for iss := 0; iss < o.NmaxSS+1; iss++ { // total number of substeps o.nsteps += 1 // error: did not converge if iss == o.NmaxSS { failed = true break } // converged? if x-xstep >= 0.0 { break } // step update rerr, err = o.step(o, y, x, args...) // initialise only once o.doinit = false // iterations diverging ? if o.diverg { o.diverg = false o.reject = true o.last = false o.h = o.dvfac * o.h continue } // step size change fac = min(o.Mfac, o.Mfac*float64(1+2*o.NmaxIt)/float64(o.nit+2*o.NmaxIt)) div = max(o.Mmin, min(o.Mmax, math.Pow(rerr, 0.25)/fac)) dxnew = o.h / div // accepted if rerr < 1.0 { // set flags o.naccepted += 1 o.first = false o.jacIsOK = false // update x and y o.hprev = o.h x += o.h o.accept(o, y) // output if o.out != nil { o.out(false, o.h, x, y, args...) } // converged ? if o.last { o.hopt = o.h // optimal h break } // predictive controller of Gustafsson if o.PredCtrl { if o.naccepted > 1 { facgus = (old_h / o.h) * math.Pow(math.Pow(rerr, 2.0)/old_rerr, 0.25) / o.Mfac facgus = max(o.Mmin, min(o.Mmax, facgus)) div = max(div, facgus) dxnew = o.h / div } old_h = o.h old_rerr = max(1.0e-2, rerr) } // calc new scal and f0 la.VecScaleAbs(o.scal, o.Atol, o.Rtol, y) // o.scal := o.Atol + o.Rtol * abs(y) o.nfeval += 1 o.fcn(o.f0, x, y, args...) // o.f0 := f(x,y) // new step size dxnew = min(dxnew, dxmax) if o.reject { // do not alow o.h to grow if previous was a reject dxnew = min(o.h, dxnew) } o.reject = false // do not reuse current Jacobian and decomposition by default o.reuseJdec = false // last step ? if x+dxnew-xstep >= 0.0 { o.last = true o.h = xstep - x } else { dxratio = dxnew / o.h o.reuseJdec = (o.θ <= o.θmax && dxratio >= o.C1h && dxratio <= o.C2h) if !o.reuseJdec { o.h = dxnew } } // check θ to decide if at least the Jacobian can be reused if !o.reuseJdec { o.reuseJ = (o.θ <= o.θmax) } // rejected } else { // set flags if o.naccepted > 0 { o.nrejected += 1 } o.reject = true o.last = false // new step size if o.first { o.h = 0.1 * o.h } else { o.h = dxnew } // last step if x+o.h > xstep { o.h = xstep - x } } } // sub-stepping failed if failed { err = chk.Err(_ode_err2, o.NmaxSS) break } } return }
// Fact performs symbolic/numeric factorisation. This method also converts the triplet form // to the column-compressed form, including the summation of duplicated entries func (o *LinSolUmfpack) Fact() (err error) { // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolUmfpack.Fact . . . . . . . . . . . . . . . \n\n") } // factorisation if o.cmplx { // UMFPACK: convert triplet to column-compressed format st := C.umfpack_zl_triplet_to_col(C.LONG(o.tC.m), C.LONG(o.tC.n), C.LONG(o.tC.pos), o.ti, o.tj, o.tx, o.tz, o.ap, o.ai, o.ax, o.az, nil) if st != C.UMFPACK_OK { return chk.Err(_linsol_umfpack_err04, Uerr2Text[int(st)]) } // UMFPACK: symbolic factorisation st = C.umfpack_zl_symbolic(C.LONG(o.tC.m), C.LONG(o.tC.n), o.ap, o.ai, o.ax, o.az, &o.usymb, o.uctrl, nil) if st != C.UMFPACK_OK { return chk.Err(_linsol_umfpack_err05, Uerr2Text[int(st)]) } // UMFPACK: numeric factorisation st = C.umfpack_zl_numeric(o.ap, o.ai, o.ax, o.az, o.usymb, &o.unum, o.uctrl, nil) if st != C.UMFPACK_OK { return chk.Err(_linsol_umfpack_err06, Uerr2Text[int(st)]) } } else { // UMFPACK: convert triplet to column-compressed format st := C.umfpack_dl_triplet_to_col(C.LONG(o.tR.m), C.LONG(o.tR.n), C.LONG(o.tR.pos), o.ti, o.tj, o.tx, o.ap, o.ai, o.ax, nil) if st != C.UMFPACK_OK { return chk.Err(_linsol_umfpack_err07, Uerr2Text[int(st)]) } // UMFPACK: symbolic factorisation st = C.umfpack_dl_symbolic(C.LONG(o.tR.m), C.LONG(o.tR.n), o.ap, o.ai, o.ax, &o.usymb, o.uctrl, nil) if st != C.UMFPACK_OK { return chk.Err(_linsol_umfpack_err08, Uerr2Text[int(st)]) } // UMFPACK: numeric factorisation st = C.umfpack_dl_numeric(o.ap, o.ai, o.ax, o.usymb, &o.unum, o.uctrl, nil) if st != C.UMFPACK_OK { return chk.Err(_linsol_umfpack_err09, Uerr2Text[int(st)]) } return } // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolUmfpack.Fact = %v\n", o.name, time.Now().Sub(o.tini)) } return }
func (o *RichardsonExtrap) Run(tf float64, dtFunc, dtoFunc fun.Func, verbose bool, dbgKb DebugKb_t) (err error) { // constants dat := o.doms[0].Sim.Solver atol := dat.REatol rtol := dat.RErtol mmin := dat.REmmin mmax := dat.REmmax mfac := dat.REmfac // control t := o.doms[0].Sol.T tout := t + dtoFunc.F(t, nil) steady := o.doms[0].Sim.Data.Steady // first output if o.sum != nil { err = o.sum.SaveDomains(t, o.doms, false) if err != nil { return chk.Err("cannot save results:\n%v", err) } } // domain and variables d := o.doms[0] o.Y_big = make([]float64, d.Ny) // time loop o.Δt = dtFunc.F(t, nil) o.Δtcpy = o.Δt var ΔtOld, rerrOld float64 for t < tf { // check for continued divergence if o.ndiverg >= dat.NdvgMax { return chk.Err("continuous divergence after %d steps reached", o.ndiverg) } // check time increment if o.Δt < dat.DtMin { return chk.Err("Δt increment is too small: %g < %g", o.Δt, dat.DtMin) } // dynamic coefficients if !steady { err = o.dc.CalcBoth(o.Δt) if err != nil { return chk.Err("cannot compute dynamic coefficients:\n%v", err) } } // check for maximum number of substeps o.nsteps += 1 if o.nsteps >= dat.REnssmax { return chk.Err("RE: max number of steps reached: %d", o.nsteps) } // backup domain d.backup() // single step with Δt d.Sol.T = t + o.Δt d.Sol.Dt = o.Δt o.diverging, err = run_iterations(t+o.Δt, o.Δt, d, o.dc, o.sum, dbgKb) if err != nil { return chk.Err("single step with Δt: run_iterations failed:\n%v", err) } if dat.DvgCtrl { if o.divergence_control(d, "big step", verbose) { continue } } // save intermediate state for i := 0; i < d.Ny; i++ { o.Y_big[i] = d.Sol.Y[i] } // restore initial state d.restore() // 1st halved step d.Sol.T = t + o.Δt/2.0 d.Sol.Dt = o.Δt / 2.0 o.diverging, err = run_iterations(t+o.Δt/2.0, o.Δt/2.0, d, o.dc, o.sum, dbgKb) if err != nil { return chk.Err("1st halved step: run_iterations failed:\n%v", err) } if dat.DvgCtrl { if o.divergence_control(d, "1st half step", verbose) { continue } } // 2nd halved step d.Sol.T = t + o.Δt d.Sol.Dt = o.Δt o.diverging, err = run_iterations(t+o.Δt, o.Δt/2.0, d, o.dc, o.sum, dbgKb) if err != nil { return chk.Err("2nd halved step: run_iterations failed:\n%v", err) } if dat.DvgCtrl { if o.divergence_control(d, "2nd half step", verbose) { continue } } // Richardson's extrapolation error rerr := la.VecRmsError(d.Sol.Y, o.Y_big, atol, rtol, d.Sol.Y) / 3.0 // step size change m := utl.Min(mmax, utl.Max(mmin, mfac*math.Pow(1.0/rerr, 1.0/2.0))) ΔtNew := m * o.Δt // accepted if rerr < 1.0 { // update variables o.naccept += 1 t += o.Δt d.Sol.T = t // output if verbose { if !dat.ShowR { io.PfWhite("%30.15f\r", t) } } if t >= tout || o.laststep { if o.sum != nil { err = o.sum.SaveDomains(t, o.doms, false) if err != nil { return chk.Err("cannot save results:\n%v", err) } } tout += dtoFunc.F(t, nil) } // reached final time if o.laststep { if verbose { io.Pfgreen("\n\nRichardson extrapolation succeeded\n") } return } // predictive controller of Gustafsson if !dat.REnogus { if o.naccept > 1 { m = mfac * (o.Δt / ΔtOld) * math.Sqrt(1.0/rerr) * math.Sqrt(rerrOld/rerr) if m*o.Δt < ΔtNew { o.ngustaf += 1 } ΔtNew = utl.Min(ΔtNew, m*o.Δt) } ΔtOld = o.Δt rerrOld = utl.Max(0.9, rerr) // 1e-2 } // next step size if o.reject { // do not alow Δt to grow if previous was a reject ΔtNew = utl.Min(o.Δt, ΔtNew) } o.reject = false o.Δt = ΔtNew if t+ΔtNew-tf >= 0.0 { o.laststep = true o.Δt = tf - t } // rejected } else { // restore state d.restore() // set flags o.nreject += 1 o.reject = true o.laststep = false // next step size o.Δt = ΔtNew if t+o.Δt > tf { o.Δt = tf - t } } } return }
// Init initialises system func (o *System) Init(Pdemand float64, lossless, check bool) { o.Pdemand = Pdemand o.Lossless = lossless // units: // a [$ / (hMW²)] // b [$ / (hMW)] // c [$ / h] // α [tons / (hMW²)] // β [tons / (hMW)] // γ [tons / h] // ζ [tons / h] // λ [MW⁻¹] // Pmin [MW / 100] // Pmax [MW / 100] o.G = []Generator{ {a: 10, b: 200, c: 100, α: 4.091e-2, β: -5.554e-2, γ: 6.490e-2, ζ: 2.0e-4, λ: 2.857, Pmin: 0.05, Pmax: 0.5}, {a: 10, b: 150, c: 120, α: 2.543e-2, β: -6.047e-2, γ: 5.638e-2, ζ: 5.0e-4, λ: 3.333, Pmin: 0.05, Pmax: 0.6}, {a: 20, b: 180, c: 40., α: 4.258e-2, β: -5.094e-2, γ: 4.586e-2, ζ: 1.0e-6, λ: 8.000, Pmin: 0.05, Pmax: 1.0}, {a: 10, b: 100, c: 60., α: 5.326e-2, β: -3.550e-2, γ: 3.380e-2, ζ: 2.0e-3, λ: 2.000, Pmin: 0.05, Pmax: 1.2}, {a: 20, b: 180, c: 40., α: 4.258e-2, β: -5.094e-2, γ: 4.586e-2, ζ: 1.0e-6, λ: 8.000, Pmin: 0.05, Pmax: 1.0}, {a: 10, b: 150, c: 100, α: 6.131e-2, β: -5.555e-2, γ: 5.151e-2, ζ: 1.0e-5, λ: 6.667, Pmin: 0.05, Pmax: 0.6}, } o.B00 = 0.00098573 o.B0 = []float64{-0.0107, +0.0060, -0.0017, +0.0009, +0.0002, +0.0030} o.B = [][]float64{ {+0.1382, -0.0299, +0.0044, -0.0022, -0.0010, -0.0008}, {-0.0299, +0.0487, -0.0025, +0.0004, +0.0016, +0.0041}, {+0.0044, -0.0025, +0.0182, -0.0070, -0.0066, -0.0066}, {-0.0022, +0.0004, -0.0070, +0.0137, +0.0050, +0.0033}, {-0.0010, +0.0016, -0.0066, +0.0050, +0.0109, +0.0005}, {-0.0008, +0.0041, -0.0066, +0.0033, +0.0005, +0.0244}, } if check { // lossless and unsecured: cost only P_best_cost := []float64{0.10954, 0.29967, 0.52447, 1.01601, 0.52469, 0.35963} c := o.FuelCost(P_best_cost) e := o.Emission(P_best_cost) io.Pf("lossless and unsecured: cost only\n") io.Pforan("c = %.3f (600.114)\n", c) io.Pforan("e = %.5f (0.22214)\n", e) P_best_cost = []float64{0.1265, 0.2843, 0.5643, 1.0468, 0.5278, 0.2801} c = o.FuelCost(P_best_cost) io.Pfgreen("c = %.3f\n", c) Pdemand := 2.834 o.PrintConstraints(P_best_cost, Pdemand, true) // lossless and unsecured: emission only P_best_emission := []float64{0.40584, 0.45915, 0.53797, 0.38300, 0.53791, 0.51012} c = o.FuelCost(P_best_emission) e = o.Emission(P_best_emission) io.Pf("\nlossless and unsecured: emission only\n") io.Pforan("c = %.3f (638.260)\n", c) io.Pforan("e = %.5f (0.19420)\n", e) P_best_cost = []float64{0.1500, 0.3000, 0.5500, 1.0500, 0.4600, 0.3500} c = o.FuelCost(P_best_cost) e = o.Emission(P_best_cost) io.Pforan("\nc = %.3f (606.314)\n", c) io.Pforan("e = %.5f (0.22330)\n", e) P_best_emission = []float64{0.4000, 0.4500, 0.5500, 0.4000, 0.5500, 0.5000} c = o.FuelCost(P_best_emission) e = o.Emission(P_best_emission) io.Pforan("\nc = %.3f (639.600)\n", c) io.Pforan("e = %.5f (0.19424)\n", e) } return }
func Test_contact01b(tst *testing.T) { //verbose() chk.PrintTitle("contact01b") // start simulation analysis := NewFEM("data/contact01.sim", "", true, true, false, false, chk.Verbose, 0) // for debugging Kb //if true { if false { u_DebugKb(analysis, &testKb{ tst: tst, eid: 3, tol: 1e-7, verb: chk.Verbose, ni: -1, nj: -1, itmin: 1, itmax: 1, tmin: 0.2, tmax: -1, }) } // run simulation err := analysis.Run() if err != nil { io.PfRed("Run failed:\n%v", err) tst.Errorf("Run failed:\n%v", err) return } // check //if true { if false { // domain dom := analysis.Domains[0] // solution var sol ana.CteStressPstrain sol.Init(fun.Prms{ &fun.Prm{N: "qnH", V: 0}, &fun.Prm{N: "qnV", V: -100}, }) // check displacements t := dom.Sol.T 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]} io.Pfgreen("u = %v\n", u) sol.CheckDispl(tst, t, u, n.Vert.C, tolu) } // check stresses e := dom.Elems[3].(*ElemU) tols := 1e-13 for idx, ip := range e.IpsElem { x := e.Cell.Shp.IpRealCoords(e.X, ip) σ := e.States[idx].Sig io.Pforan("σ = %v\n", σ) sol.CheckStress(tst, t, σ, x, tols) } } }