func checkinput(tst *testing.T, m *Mesh, nverts, ncells int, X [][]float64, vtags, ctags, parts []int, types []string, V [][]int, etags, ftags [][]int) { if len(m.Verts) != nverts { tst.Errorf("nverts is incorrect: %d != %d", len(m.Verts), nverts) return } if len(m.Cells) != ncells { tst.Errorf("ncells is incorrect: %d != %d", len(m.Cells), ncells) return } io.Pfyel("\nvertices:\n") for i, v := range m.Verts { io.Pf("%+v\n", v) chk.Vector(tst, io.Sf("vertex %2d: X", v.Id), 1e-15, v.X, X[v.Id]) if v.Tag != vtags[i] { tst.Errorf("vtag is incorrect: %d != %d", v.Tag, vtags[i]) return } } io.Pfyel("\ncells:\n") for i, c := range m.Cells { io.Pf("%+v\n", c) if c.Tag != ctags[i] { tst.Errorf("ctag is incorrect: %d != %d", c.Tag, ctags[i]) return } if c.Part != parts[i] { tst.Errorf("part is incorrect: %d != %d", c.Part, parts[i]) return } chk.String(tst, types[i], c.Type) chk.Ints(tst, io.Sf("cell %2d : V", c.Id), c.V, V[c.Id]) chk.Ints(tst, io.Sf("cell %2d : edgetags", c.Id), c.EdgeTags, etags[c.Id]) } }
func Test_ind01(tst *testing.T) { //verbose() chk.PrintTitle("ind01. representation and copying") rnd.Init(0) nbases := 3 A := get_individual(0, nbases) B := A.GetCopy() chk.Scalar(tst, "ova0", 1e-17, B.Ovas[0], 123) chk.Scalar(tst, "ova1", 1e-17, B.Ovas[1], 345) chk.Scalar(tst, "oor0", 1e-17, B.Oors[0], 10) chk.Scalar(tst, "oor1", 1e-17, B.Oors[1], 20) chk.Scalar(tst, "oor2", 1e-17, B.Oors[2], 30) fmts := map[string][]string{"int": {" %d"}, "flt": {" %.1f"}, "str": {" %q"}, "key": {" %x"}, "byt": {" %q"}, "fun": {" %q"}} oA := A.Output(fmts, false) oB := B.Output(fmts, false) io.Pfyel("\n%v\n", oA) io.Pfyel("%v\n\n", oB) chk.String(tst, oA, " 1 20 300 4.4 5.5 666.0 \"abc\" \"b\" \"c\" 53 47 41 \"ABC\" \"DEF\" \"GHI\" \"f0\" \"f1\" \"f2\"") chk.String(tst, oB, " 1 20 300 4.4 5.5 666.0 \"abc\" \"b\" \"c\" 53 47 41 \"ABC\" \"DEF\" \"GHI\" \"f0\" \"f1\" \"f2\"") A.SetFloat(1, 33) A.SetFloat(2, 88) oA = A.Output(fmts, false) io.Pfyel("\n%v\n", oA) chk.String(tst, oA, " 1 20 300 4.4 33.0 88.0 \"abc\" \"b\" \"c\" 53 47 41 \"ABC\" \"DEF\" \"GHI\" \"f0\" \"f1\" \"f2\"") }
func Test_stat02(tst *testing.T) { //verbose() chk.PrintTitle("stat02") x := [][]float64{ {100, 100, 102, 98, 77, 99, 70, 105, 98}, {80, 101, 12, 58, 47, 80, 20, 111, 89}, {50, 130, 72, 38, 71, 15, 10, 12, 55}, } y, z := StatTable(x, true, true) la.PrintMat("x", x, "%5g", false) la.PrintMat("y", y, "%13.6f", false) la.PrintMat("z", z, "%13.6f", false) io.Pforan("\nmin\n") chk.Scalar(tst, "y00=min(x[0,:])", 1e-17, y[0][0], 70) chk.Scalar(tst, "y01=min(x[1,:])", 1e-17, y[0][1], 12) chk.Scalar(tst, "y02=min(x[2,:])", 1e-17, y[0][2], 10) io.Pforan("\nave\n") chk.Scalar(tst, "y10=ave(x[0,:])", 1e-17, y[1][0], 849.0/9.0) chk.Scalar(tst, "y11=ave(x[1,:])", 1e-17, y[1][1], 598.0/9.0) chk.Scalar(tst, "y12=ave(x[2,:])", 1e-17, y[1][2], 453.0/9.0) io.Pforan("\nmax\n") chk.Scalar(tst, "y20=max(x[0,:])", 1e-17, y[2][0], 105) chk.Scalar(tst, "y21=max(x[1,:])", 1e-17, y[2][1], 111) chk.Scalar(tst, "y22=max(x[2,:])", 1e-17, y[2][2], 130) io.Pforan("\ndev\n") chk.Scalar(tst, "y30=dev(x[0,:])", 1e-17, y[3][0], 12.134661099511597) chk.Scalar(tst, "y31=dev(x[1,:])", 1e-17, y[3][1], 34.688294535444918) chk.Scalar(tst, "y32=dev(x[2,:])", 1e-17, y[3][2], 38.343839140075687) io.Pfyel("\nmin\n") chk.Scalar(tst, "z00=min(y[0,:])=min(min)", 1e-17, z[0][0], 10) chk.Scalar(tst, "z01=min(y[1,:])=min(ave)", 1e-17, z[0][1], 453.0/9.0) chk.Scalar(tst, "z02=min(y[2,:])=min(max)", 1e-17, z[0][2], 105) chk.Scalar(tst, "z03=min(y[3,:])=min(dev)", 1e-17, z[0][3], 12.134661099511597) io.Pfyel("\nave\n") chk.Scalar(tst, "z10=ave(y[0,:])=ave(min)", 1e-17, z[1][0], 92.0/3.0) chk.Scalar(tst, "z11=ave(y[1,:])=ave(ave)", 1e-17, z[1][1], ((849.0+598.0+453.0)/9.0)/3.0) chk.Scalar(tst, "z12=ave(y[2,:])=ave(max)", 1e-17, z[1][2], 346.0/3.0) chk.Scalar(tst, "z13=ave(y[3,:])=ave(dev)", 1e-17, z[1][3], (12.134661099511597+34.688294535444918+38.343839140075687)/3.0) io.Pfyel("\nmax\n") chk.Scalar(tst, "z20=max(y[0,:])=max(min)", 1e-17, z[2][0], 70) chk.Scalar(tst, "z21=max(y[1,:])=max(ave)", 1e-17, z[2][1], 849.0/9.0) chk.Scalar(tst, "z22=max(y[2,:])=max(max)", 1e-17, z[2][2], 130) chk.Scalar(tst, "z23=max(y[3,:])=max(dev)", 1e-17, z[2][3], 38.343839140075687) io.Pfyel("\ndev\n") chk.Scalar(tst, "z30=dev(y[0,:])=dev(min)", 1e-17, z[3][0], 34.078341117685483) chk.Scalar(tst, "z31=dev(y[1,:])=dev(ave)", 1e-17, z[3][1], 22.261169573539771) chk.Scalar(tst, "z32=dev(y[2,:])=dev(max)", 1e-17, z[3][2], 13.051181300301263) chk.Scalar(tst, "z33=dev(y[3,:])=dev(dev)", 1e-17, z[3][3], 14.194778389023206) }
// CalcΔεElast calculates Δε corresponding to an elastic loading with Δp and Δq func CalcΔεElast(Δε []float64, K, G float64, Δp, Δq float64, axsym bool) (Δεv, Δεd float64, err error) { Δεv = -Δp / K Δεd = Δq / (3.0 * G) var Δεx, Δεy, Δεz float64 if axsym { // axisymmetric compression := true if compression { Δεx = Δεv/3.0 + Δεd/2.0 Δεy = Δεx Δεz = Δεv/3.0 - Δεd } else { Δεx = Δεv/3.0 - Δεd/2.0 Δεy = Δεv/3.0 + Δεd Δεz = Δεx } } else { // plane-strain with Δεy = Δεx / 2 c := 9.0 * Δεd * Δεd / (4.0 * Δεv * Δεv) α := 0.0 if math.Abs(c-1.0) > 1e-15 { d := 3.0 * (4.0*c - 1.0) if d < 0.0 { return 0, 0, chk.Err("discriminant < 0: c=%v d=%v", c, d) } α1 := (1.0 + 2.0*c + math.Sqrt(d)) / (2.0 - 2.0*c) α2 := (1.0 + 2.0*c - math.Sqrt(d)) / (2.0 - 2.0*c) α = α1 io.Pfyel("d, α1, α2 = %v, %v, %v\n", d, α1, α2) } io.Pfyel("c, α = %v, %v\n", c, α) Δεy = Δεv / (1.0 + α) Δεx = α * Δεy Δεz = 0 } //io.Pfpink("Δp=%v, Δq=%v => Δεv=%v, Δεd=%v => Δεx=%v, Δεy=%v, Δεz=%v\n", Δp, Δq, Δεv, Δεd, Δεx, Δεy, Δεz) Δε[0] = Δεx Δε[1] = Δεy Δε[2] = Δεz Δε[3] = 0 Δεv_ := tsr.M_εv(Δε) Δεd_ := tsr.M_εd(Δε) if math.Abs(Δεv-Δεv_) > 1e-15 { return 0, 0, chk.Err(_path_err09, Δεv, Δεv_) } if Δεd < 0 { Δεd_ = -Δεd_ // allow negative values } if math.Abs(Δεd-Δεd_) > 1e-15 { return 0, 0, chk.Err(_path_err10, Δεd, Δεd_) } return }
func Test_shp01(tst *testing.T) { //verbose() chk.PrintTitle("shp01") r := []float64{0, 0, 0} verb := true for name, _ := range Functions { io.Pfyel("--------------------------------- %-6s---------------------------------\n", name) // check S tol := 1e-17 if name == "tri10" { tol = 1e-14 } checkShape(tst, name, tol, verb) // check dSdR tol = 1e-14 if name == "lin5" || name == "lin4" || name == "tri10" || name == "qua12" || name == "qua16" { tol = 1e-10 } if name == "tri15" { tol = 1e-9 } checkDerivs(tst, name, r, tol, verb) io.PfGreen("OK\n") } }
func Test_MTint01(tst *testing.T) { //verbose() chk.PrintTitle("MTint01. integers (Mersenne Twister)") Init(1234) nints := 10 vals := make([]int, NSAMPLES) // using MTint t0 := time.Now() for i := 0; i < NSAMPLES; i++ { vals[i] = MTint(0, nints-1) } io.Pforan("time elapsed = %v\n", time.Now().Sub(t0)) hist := IntHistogram{Stations: utl.IntRange(nints + 1)} hist.Count(vals, true) io.Pfyel(TextHist(hist.GenLabels("%d"), hist.Counts, 60)) // using MTints t0 = time.Now() MTints(vals, 0, nints-1) io.Pforan("time elapsed = %v\n", time.Now().Sub(t0)) hist.Count(vals, true) io.Pfcyan(TextHist(hist.GenLabels("%d"), hist.Counts, 60)) }
func Test_imap(tst *testing.T) { //utl.Tsilent = false chk.PrintTitle("Test imap") for name, shape := range factory { gndim := shape.Gndim if gndim == 1 { continue } io.Pfyel("--------------------------------- %-6s---------------------------------\n", name) // check inverse mapping tol := 1e-14 noise := 0.01 if name == "tri10" { tol = 1e-14 } if shape.FaceNvertsMax > 2 { noise = 0.0 } nverts := shape.Nverts C := la.MatAlloc(gndim, nverts) s := []float64{rand.Float64(), rand.Float64(), rand.Float64()} // scale factors la.MatCopy(C, 1.0, shape.NatCoords) _ = tol io.Pf("nverts:%v\n", nverts) io.Pf("gndim:%v\n", gndim) for i := 0; i < gndim; i++ { for j := 0; j < nverts; j++ { C[i][j] *= s[i] C[i][j] += noise * rand.Float64() // noise } } r := make([]float64, 3) x := make([]float64, 3) R := la.MatAlloc(gndim, nverts) for j := 0; j < nverts; j++ { for i := 0; i < gndim; i++ { x[i] = C[i][j] } err := shape.InvMap(r, x, C) io.Pf("r:%v\n", r) _ = err for i := 0; i < gndim; i++ { R[i][j] = r[i] } } chk.Matrix(tst, "checking", tol, R, shape.NatCoords) io.PfGreen("OK\n") } }
func Test_out02(tst *testing.T) { // finalise analysis process and catch errors defer func() { if err := recover(); err != nil { tst.Fail() io.PfRed("ERROR: %v\n", err) } }() // test title //verbose() chk.PrintTitle("out02") // start simulation processing := fem.NewFEM("data/twoqua4.sim", "", true, true, false, false, chk.Verbose, 0) // run simulation err := processing.Run() if err != nil { tst.Errorf("Run failed:\n%v", err) return } // start post-processing Start("data/twoqua4.sim", 0, 0) // get second ip coordinates xip := Ipoints[1].X io.Pfcyan("xip = %v\n", xip) // define points Define("A", N{-1}) Define("ips", Along{{xip[0], 0}, {xip[0], 1}}) // load results LoadResults(nil) // solution var sol ana.CteStressPstrain sol.Init(fun.Prms{ &fun.Prm{N: "qnH", V: -50}, &fun.Prm{N: "qnV", V: -100}, }) // check displacements tolu := 1e-15 x := GetCoords("A") ux := GetRes("ux", "A", 0) uy := GetRes("uy", "A", 0) io.Pforan("ux=%v uy=%v\n", ux, uy) for j, t := range Times { io.Pfyel("t=%g\n", t) sol.CheckDispl(tst, t, []float64{ux[j], uy[j]}, x, tolu) } }
// msg prints information on residuals func (o *NlSolver) msg(typ string, it int, Ldx, fx_max float64, first, last bool) { if first { io.Pfpink("\n%4s%23s%23s\n", "it", "Ldx", "fx_max") io.Pfpink("%4s%23s%23s\n", "", io.Sf("(%7.1e)", o.fnewt), io.Sf("(%7.1e)", o.ftol)) return } io.Pfyel("%4d%23.15e%23.15e\n", it, Ldx, fx_max) if last { io.Pfgrey(". . . converged with %s. nit=%d, nFeval=%d, nJeval=%d\n", typ, it, o.NFeval, o.NJeval) } }
// PrintConstraints prints violated or not constraints func (o System) PrintConstraints(P []float64, Pdemand float64, full bool) { sumP := 0.0 for i, g := range o.G { if full { io.Pfyel("P%d range error = %v\n", i, utl.GtePenalty(P[i], g.Pmin, 1)+utl.GtePenalty(g.Pmax, P[i], 1)) } sumP += P[i] } Ploss := 0.0 io.Pf("balance error = %v\n", math.Abs(sumP-Pdemand-Ploss)) }
func Test_nurbs02(tst *testing.T) { //verbose() chk.PrintTitle("nurbs02. square with initial stress. run") // fem analysis := NewFEM("data/nurbs02.sim", "", true, false, false, false, chk.Verbose, 0) // run simulation err := analysis.Run() if err != nil { tst.Errorf("Run failed\n%v", err) return } // domain dom := analysis.Domains[0] e := dom.Elems[0].(*ElemU) io.PfYel("fex = %v\n", e.fex) io.PfYel("fey = %v\n", e.fey) la.PrintMat("K", e.K, "%10.2f", false) // solution var sol ana.CteStressPstrain sol.Init(fun.Prms{ &fun.Prm{N: "qnH0", V: -20}, &fun.Prm{N: "qnV0", V: -20}, &fun.Prm{N: "qnH", V: -50}, &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.Pfyel("u = %v\n", u) sol.CheckDispl(tst, t, u, n.Vert.C, tolu) } // check stresses 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) } }
// PrintMemStat prints memory statistics func PrintMemStat(msg string) { var mem runtime.MemStats runtime.ReadMemStats(&mem) io.PfYel("%s\n", msg) io.Pfyel("Alloc = %v [KB] %v [MB] %v [GB]\n", mem.Alloc/KBSIZE, mem.Alloc/MBSIZE, mem.Alloc/GBSIZE) io.Pfyel("HeapAlloc = %v [KB] %v [MB] %v [GB]\n", mem.HeapAlloc/KBSIZE, mem.HeapAlloc/MBSIZE, mem.HeapAlloc/GBSIZE) io.Pfyel("Sys = %v [KB] %v [MB] %v [GB]\n", mem.Sys/KBSIZE, mem.Sys/MBSIZE, mem.Sys/GBSIZE) io.Pfyel("HeapSys = %v [KB] %v [MB] %v [GB]\n", mem.HeapSys/KBSIZE, mem.HeapSys/MBSIZE, mem.HeapSys/GBSIZE) io.Pfyel("TotalAlloc = %v [KB] %v [MB] %v [GB]\n", mem.TotalAlloc/KBSIZE, mem.TotalAlloc/MBSIZE, mem.TotalAlloc/GBSIZE) io.Pfyel("Mallocs = %v\n", mem.Mallocs) io.Pfyel("Frees = %v\n", mem.Frees) }
func Test_nurbs03(tst *testing.T) { //verbose() chk.PrintTitle("nurbs03. ini stress free square") // fem analysis := NewFEM("data/nurbs03.sim", "", true, false, false, false, chk.Verbose, 0) // run simulation err := analysis.Run() if err != nil { tst.Errorf("Run failed\n%v", err) return } // domain dom := analysis.Domains[0] // element e := dom.Elems[0].(*ElemU) io.PfYel("fex = %v\n", e.fex) io.PfYel("fey = %v\n", e.fey) la.PrintMat("K", e.K, "%10.2f", false) // solution var sol ana.CteStressPstrain sol.Init(fun.Prms{ &fun.Prm{N: "qnH", V: -50}, &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.Pfyel("u = %v\n", u) sol.CheckDispl(tst, t, u, n.Vert.C, tolu) } }
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) } }
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_shape01(tst *testing.T) { //verbose() chk.PrintTitle("shape01") r := []float64{0, 0, 0} verb := true for name, shape := range factory { io.Pfyel("--------------------------------- %-6s---------------------------------\n", name) // check S tol := 1e-17 if name == "tri10" { tol = 1e-14 } CheckShape(tst, shape, tol, verb) // check Sf tol = 1e-18 CheckShapeFace(tst, shape, tol, verb) // check dSdR tol = 1e-14 if name == "lin5" || name == "lin4" || name == "tri10" || name == "qua12" || name == "qua16" { tol = 1e-10 } if name == "tri15" { tol = 1e-9 } CheckDSdR(tst, shape, r, tol, verb) io.PfGreen("OK\n") } }
func Test_sim02(tst *testing.T) { //verbose() chk.PrintTitle("sim01") sim := ReadSim("data", "frees01.sim", "", true) if sim == nil { tst.Errorf("test failed: check error log\n") return } if chk.Verbose { sim.GetInfo(os.Stdout) io.Pf("\n") } io.Pfyel("ndim = %v\n", sim.Ndim) io.Pfyel("maxElev = %v\n", sim.MaxElev) io.Pfyel("grav = %v\n", sim.Gfcn.F(0, nil)) io.Pfyel("Wrho0 = %v\n", sim.WaterRho0) io.Pfyel("Wbulk = %v\n", sim.WaterBulk) io.Pfyel("Wlevel = %v\n", sim.WaterLevel) }
// 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) } } } } } } } }
// Solve solves y(x) = 0 for x in [xa, xb] with f(xa) * f(xb) < 0 // // Based on ZEROIN C math library: http://www.netlib.org/c/ // By: Oleg Keselyov <[email protected], [email protected]> May 23, 1991 // // G.Forsythe, M.Malcolm, C.Moler, Computer methods for mathematical // computations. M., Mir, 1980, p.180 of the Russian edition // // The function makes use of the bissection procedure combined with // the linear or quadric inverse interpolation. // At every step program operates on three abscissae - a, b, and c. // b - the last and the best approximation to the root // a - the last but one approximation // c - the last but one or even earlier approximation than a that // 1) |f(b)| <= |f(c)| // 2) f(b) and f(c) have opposite signs, i.e. b and c confine // the root // At every step Zeroin selects one of the two new approximations, the // former being obtained by the bissection procedure and the latter // resulting in the interpolation (if a,b, and c are all different // the quadric interpolation is utilized, otherwise the linear one). // If the latter (i.e. obtained by the interpolation) point is // reasonable (i.e. lies within the current interval [b,c] not being // too close to the boundaries) it is accepted. The bissection result // is used in the other case. Therefore, the range of uncertainty is // ensured to be reduced at least by the factor 1.6 // func (o *Brent) Solve(xa, xb float64, silent bool) (res float64, err error) { // basic variables and function evaluation a := xa // the last but one approximation b := xb // the last and the best approximation to the root c := a // the last but one or even earlier approximation than a that fa, erra := o.Ffcn(a) fb, errb := o.Ffcn(b) o.NFeval = 2 if erra != nil { return 0, chk.Err(_brent_err1, "a", xa, erra.Error()) } if errb != nil { return 0, chk.Err(_brent_err1, "b", xb, errb.Error()) } fc := fa // check input if fa*fb >= -EPS { return 0, chk.Err(_brent_err2, xa, xb, fa, fb) } // message if !silent { io.Pfpink("%4s%23s%23s%23s\n", "it", "x", "f(x)", "err") io.Pfpink("%50s%23.1e\n", "", o.Tol) } // solve var prev_step float64 // distance from the last but one to the last approximation var tol_act float64 // actual tolerance var p, q float64 // interpol. step is calculated in the form p/q (divisions are delayed) var new_step float64 // step at this iteration var t1, cb, t2 float64 // auxiliary variables for o.It = 0; o.It < o.MaxIt; o.It++ { // distance prev_step = b - a // swap data for b to be the best approximation if math.Abs(fc) < math.Abs(fb) { a = b b = c c = a fa = fb fb = fc fc = fa } tol_act = 2.0*EPS*math.Abs(b) + o.Tol/2.0 new_step = (c - b) / 2.0 // converged? if !silent { io.Pfyel("%4d%23.15e%23.15e%23.15e\n", o.It, b, fb, math.Abs(new_step)) } if math.Abs(new_step) <= tol_act || fb == 0.0 { return b, nil } // decide if the interpolation can be tried if math.Abs(prev_step) >= tol_act && math.Abs(fa) > math.Abs(fb) { // if prev_step was large enough and was in true direction, interpolatiom may be tried cb = c - b // with two distinct points, linear interpolation must be applied if a == c { t1 = fb / fa p = cb * t1 q = 1.0 - t1 // otherwise, quadric inverse interpolation is applied } else { q = fa / fc t1 = fb / fc t2 = fb / fa p = t2 * (cb*q*(q-t1) - (b-a)*(t1-1.0)) q = (q - 1.0) * (t1 - 1.0) * (t2 - 1.0) } // p was calculated with the opposite sign; // make p positive and assign possible minus to q if p > 0.0 { q = -q } else { p = -p } // if b+p/q falls in [b,c] and isn't too large, it is accepted // if p/q is too large then the bissection procedure can reduce [b,c] range to more extent if p < (0.75*cb*q-math.Abs(tol_act*q)/2.0) && p < math.Abs(prev_step*q/2.0) { new_step = p / q } } // adjust the step to be not less than tolerance if math.Abs(new_step) < tol_act { if new_step > 0.0 { new_step = tol_act } else { new_step = -tol_act } } // save the previous approximation a = b fa = fb // do step to a new approximation b += new_step fb, errb = o.Ffcn(b) o.NFeval += 1 if errb != nil { return 0, chk.Err(_brent_err1, "", b, errb.Error()) } // adjust c for it to have a sign opposite to that of b if (fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0) { c = a fc = fa } } // did not converge return fb, chk.Err(_brent_err3, "Solve", o.It) }
func Test_up01a(tst *testing.T) { /* this tests simulates seepage flow along a column * by reducing the initial hydrostatic pressure at * at the bottom of the column * * using mesh from col104elay.msh * * Nodes / Tags Equations * ux uy pl ux uy pl * 8 o----o----o 9 (-5) 53 54 55 o----o----o 50 51 52 * | 14 | . . . | 58 59 | . . . * | (-1) | . . . | | . . . * 21 o o o 22 (-6) 60 61 . o o o 56 57 . * | 26 | . . . | 62 63 | . . . * | | . . . | | . . . * 6 o----o----o 7 (-4) 39 40 41 o----o----o 36 37 38 * | 13 | . . . | 44 45 | . . . * | (-1) | . . . | | . . . * 19 | o o 20 (-6) 46 47 . | o o 42 43 . * | 25 | . . . | 48 49 | . . . * | | . . . | | . . . * 4 o----o----o 5 (-3) 25 26 27 o----o----o 22 23 24 * | 12 | . . . | 30 31 | . . . * | (-2) | . . . | | . . . * 17 o o o 18 (-6) 32 33 . o o o 28 29 . * | 24 | . . . | 34 35 | . . . * | | . . . | | . . . * 2 o----o----o 3 (-2) 9 10 11 o----o----o 6 7 8 * | 11 | . . . | 16 17 | . . . * | (-2) | . . . | | . . . * 15 o o o 16 (-6) 18 19 o o o 14 15 * | 23 | . . . | 20 21 | . . . * | | . . . | | . . . * 0 o----o----o 1 (-1) 0 1 2 o----o----o 3 4 5 * 10 12 13 */ // capture errors and flush log defer End() //verbose() chk.PrintTitle("up01a") // start simulation if !Start("data/up01.sim", true, chk.Verbose) { chk.Panic("cannot start simulation") } // domain distr := false dom := NewDomain(Global.Sim.Regions[0], distr) if dom == nil { chk.Panic("cannot allocate new domain") } // set stage if !dom.SetStage(0, Global.Sim.Stages[0], distr) { chk.Panic("cannot set stage") } // nodes and elements chk.IntAssert(len(dom.Nodes), 27) chk.IntAssert(len(dom.Elems), 4) if true { // nodes with pl nods_with_pl := map[int]bool{0: true, 2: true, 4: true, 6: true, 8: true, 1: true, 3: true, 5: true, 7: true, 9: true} // check dofs for _, nod := range dom.Nodes { if nods_with_pl[nod.Vert.Id] { chk.IntAssert(len(nod.Dofs), 3) chk.StrAssert(nod.Dofs[0].Key, "ux") chk.StrAssert(nod.Dofs[1].Key, "uy") chk.StrAssert(nod.Dofs[2].Key, "pl") } else { chk.IntAssert(len(nod.Dofs), 2) chk.StrAssert(nod.Dofs[0].Key, "ux") chk.StrAssert(nod.Dofs[1].Key, "uy") } } // check equations nids, eqs := get_nids_eqs(dom) chk.Ints(tst, "eqs", eqs, utl.IntRange(10*3+17*2)) chk.Ints(tst, "nids", nids, []int{ 0, 1, 3, 2, 10, 16, 11, 15, 23, 5, 4, 18, 12, 17, 24, 7, 6, 20, 13, 19, 25, 9, 8, 22, 14, 21, 26, }) // check pmap Pmaps := [][]int{ {2, 5, 8, 11}, {11, 8, 24, 27}, {27, 24, 38, 41}, {41, 38, 52, 55}, } Umaps := [][]int{ {0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, {9, 10, 6, 7, 22, 23, 25, 26, 16, 17, 28, 29, 30, 31, 32, 33, 34, 35}, {25, 26, 22, 23, 36, 37, 39, 40, 30, 31, 42, 43, 44, 45, 46, 47, 48, 49}, {39, 40, 36, 37, 50, 51, 53, 54, 44, 45, 56, 57, 58, 59, 60, 61, 62, 63}, } for i, ele := range dom.Elems { e := ele.(*ElemUP) io.Pfpink("%2d : Pmap = %v\n", e.Id(), e.P.Pmap) io.Pfpink("%2d : Umap = %v\n", e.Id(), e.U.Umap) chk.Ints(tst, "Pmap", e.P.Pmap, Pmaps[i]) chk.Ints(tst, "Umap", e.U.Umap, Umaps[i]) } // constraints chk.IntAssert(len(dom.EssenBcs.Bcs), 9*2+2+3) var ct_ux_eqs []int // equations with ux prescribed [sorted] var ct_uy_eqs []int // equations with uy prescribed [sorted] var ct_pl_eqs []int // equations with pl prescribed [sorted] for _, c := range dom.EssenBcs.Bcs { chk.IntAssert(len(c.Eqs), 1) eq := c.Eqs[0] io.Pfgrey("key=%v eq=%v\n", c.Key, eq) switch c.Key { case "ux": ct_ux_eqs = append(ct_ux_eqs, eq) case "uy": ct_uy_eqs = append(ct_uy_eqs, eq) case "pl": ct_pl_eqs = append(ct_pl_eqs, eq) default: tst.Errorf("key %s is incorrect", c.Key) } } sort.Ints(ct_ux_eqs) sort.Ints(ct_uy_eqs) sort.Ints(ct_pl_eqs) chk.Ints(tst, "equations with ux prescribed", ct_ux_eqs, []int{0, 3, 6, 9, 14, 18, 22, 25, 28, 32, 36, 39, 42, 46, 50, 53, 56, 60}) chk.Ints(tst, "equations with uy prescribed", ct_uy_eqs, []int{1, 4, 13}) chk.Ints(tst, "equations with pl prescribed", ct_pl_eqs, []int{2, 5}) } // initial values @ nodes io.Pforan("initial values @ nodes\n") for _, nod := range dom.Nodes { z := nod.Vert.C[1] for _, dof := range nod.Dofs { u := dom.Sol.Y[dof.Eq] switch dof.Key { case "ux": chk.Scalar(tst, io.Sf("nod %3d : ux(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-17, u, 0) case "uy": chk.Scalar(tst, io.Sf("nod %3d : uy(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-17, u, 0) case "pl": plC, _, _ := Global.HydroSt.Calc(z) chk.Scalar(tst, io.Sf("nod %3d : pl(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-13, u, plC) } } } // intial values @ integration points io.Pforan("initial values @ integration points\n") for _, ele := range dom.Elems { e := ele.(*ElemUP) for idx, ip := range e.P.IpsElem { s := e.P.States[idx] z := e.P.Shp.IpRealCoords(e.P.X, ip)[1] chk.AnaNum(tst, io.Sf("sl(z=%11.8f)", z), 1e-17, s.A_sl, 1, chk.Verbose) } } // parameters ν := 0.2 // Poisson's coefficient K0 := ν / (1.0 - ν) // earth pressure at rest nf := 0.3 // porosity sl := 1.0 // saturation ρL := 1.0 // intrinsic (real) density of liquid ρS_top := 2.0 // intrinsic (real) density of solids in top layer ρS_bot := 3.0 // intrinsic (real) density of solids in bottom layer h := 5.0 // height of each layer g := 10.0 // gravity // densities nl := nf * sl // volume fraction of luqid ns := 1.0 - nf // volume fraction of solid ρl := nl * ρL // partial density of liquid ρs_top := ns * ρS_top // partial density of solids in top layer ρs_bot := ns * ρS_bot // partial density of solids in bottom layer ρ_top := ρl + ρs_top // density of mixture in top layer ρ_bot := ρl + ρs_bot // density of mixture in bottom layer // absolute values of stresses σV_z5 := ρ_top * g * h // total vertical stress @ elevation z = 5 m (absolute value) σV_z0 := σV_z5 + ρ_bot*g*h // total vertical stress @ elevation z = 0 m (absolute value) io.Pfyel("ρ_top = %g\n", ρ_top) io.Pfyel("ρ_bot = %g\n", ρ_bot) io.Pfyel("|ΔσV_top| = %g\n", ρ_top*g*h) io.Pfyel("|ΔσV_bot| = %g\n", ρ_bot*g*h) io.PfYel("|σV|(@ z=0) = %g\n", σV_z0) io.PfYel("|σV|(@ z=5) = %g\n", σV_z5) // stress functions var sig fun.Pts var pres fun.Pts sig.Init(fun.Prms{ &fun.Prm{N: "t0", V: 0.00}, {N: "y0", V: -σV_z0}, &fun.Prm{N: "t1", V: 5.00}, {N: "y1", V: -σV_z5}, &fun.Prm{N: "t2", V: 10.00}, {N: "y2", V: 0.0}, }) pres.Init(fun.Prms{ &fun.Prm{N: "t0", V: 0.00}, {N: "y0", V: 100}, &fun.Prm{N: "t1", V: 10.00}, {N: "y1", V: 0}, }) // check stresses io.Pforan("initial stresses @ integration points\n") for _, ele := range dom.Elems { e := ele.(*ElemUP) for idx, ip := range e.U.IpsElem { z := e.U.Shp.IpRealCoords(e.U.X, ip)[1] σe := e.U.States[idx].Sig sv := sig.F(z, nil) sve := sv + pres.F(z, nil) she := sve * K0 if math.Abs(σe[2]-σe[0]) > 1e-17 { tst.Errorf("[1;31mσx is not equal to σz: %g != %g[0m\n", σe[2], σe[0]) return } if math.Abs(σe[3]) > 1e-17 { tst.Errorf("[1;31mσxy is not equal to zero: %g != 0[0m\n", σe[3]) return } chk.AnaNum(tst, io.Sf("sx(z=%11.8f)", z), 0.0003792, σe[0], she, chk.Verbose) chk.AnaNum(tst, io.Sf("sy(z=%11.8f)", z), 0.001517, σe[1], sve, chk.Verbose) } } return }
// 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() } } } } }
func TestVector01(tst *testing.T) { //verbose() chk.PrintTitle("TestVector 01") io.Pfyel("func VecFill(v []float64, s float64)\n") v := make([]float64, 5) VecFill(v, 666) PrintVec("v", v, "%5g", false) chk.Vector(tst, "v", 1e-17, v, []float64{666, 666, 666, 666, 666}) io.Pfyel("\nfunc VecFillC(v []complex128, s complex128)\n") vc := make([]complex128, 5) VecFillC(vc, 666+666i) PrintVecC("vc", vc, "(%2g +", "%4gi) ", false) chk.VectorC(tst, "vc", 1e-17, vc, []complex128{666 + 666i, 666 + 666i, 666 + 666i, 666 + 666i, 666 + 666i}) io.Pfyel("func VecClone(a []float64) (b []float64)\n") va := []float64{1, 2, 3, 4, 5, 6} vb := VecClone(va) PrintVec("vb", vb, "%5g", false) chk.Vector(tst, "vb==va", 1e-17, vb, va) io.Pfyel("\nfunc VecAccum(v []float64) (sum float64)\n") PrintVec("v", v, "%5g", false) sum := VecAccum(v) io.Pf("sum(v) = %23.15e\n", sum) chk.Scalar(tst, "sum(v)", 1e-17, sum, 5*666) io.Pfyel("\nfunc VecNorm(v []float64) (nrm float64)\n") PrintVec("v", v, "%5g", false) nrm := VecNorm(v) io.Pf("norm(v) = %23.15e\n", nrm) chk.Scalar(tst, "norm(v)", 1e-17, nrm, 1.489221273014860e+03) io.Pfyel("\nfunc VecNormDiff(u, v []float64) (nrm float64)\n") u := []float64{333, 333, 333, 333, 333} PrintVec("u", u, "%5g", false) PrintVec("v", v, "%5g", false) nrm = VecNormDiff(u, v) io.Pf("norm(u-v) = %23.15e\n", nrm) chk.Scalar(tst, "norm(u-v)", 1e-17, nrm, math.Sqrt(5.0*333.0*333.0)) io.Pfyel("\nfunc VecDot(u, v []float64) (res float64)\n") u = []float64{0.1, 0.2, 0.3, 0.4, 0.5} PrintVec("u", u, "%5g", false) PrintVec("v", v, "%5g", false) udotv := VecDot(u, v) io.Pf("u dot v = %v\n", udotv) chk.Scalar(tst, "u dot v", 1e-12, udotv, 999) io.Pfyel("\nfunc VecCopy(a []float64, alp float64, b []float64)\n") a := make([]float64, len(u)) VecCopy(a, 1, u) PrintVec("u ", u, "%5g", false) PrintVec("a := u", a, "%5g", false) chk.Vector(tst, "a", 1e-17, a, []float64{0.1, 0.2, 0.3, 0.4, 0.5}) io.Pfyel("\nfunc VecAdd(a []float64, alp float64, b []float64)\n") b := []float64{1.0, 2.0, 3.0, 4.0, 5.0} PrintVec("b ", b, "%5g", false) VecAdd(b, 10, b) // b += 10.0*b PrintVec("b += 10*b", b, "%5g", false) chk.Vector(tst, "b", 1e-17, b, []float64{11, 22, 33, 44, 55}) io.Pfyel("\nfunc VecAdd2(u []float64, alp float64, a []float64, bet float64, b []float64)\n") PrintVec("a", a, "%7g", false) PrintVec("b", b, "%7g", false) c := make([]float64, len(a)) VecAdd2(c, 1, a, 10, b) // c = 1.0*a + 10.0*b PrintVec("c = 1*a+10*b", c, "%7g", false) chk.Vector(tst, "c", 1e-17, c, []float64{110.1, 220.2, 330.3, 440.4, 550.5}) io.Pfyel("\nfunc VecMin(v []float64) (min float64)\n") PrintVec("a", a, "%5g", false) mina := VecMin(a) io.Pf("min(a) = %v\n", mina) chk.Scalar(tst, "min(a)", 1e-17, mina, 0.1) io.Pfyel("\nfunc VecMax(v []float64) (max float64)\n") PrintVec("a", a, "%5g", false) maxa := VecMax(a) io.Pf("max(a) = %v\n", maxa) chk.Scalar(tst, "max(a)", 1e-17, maxa, 0.5) io.Pfyel("\nfunc VecMinMax(v []float64) (min, max float64)\n") PrintVec("a", a, "%5g", false) min2a, max2a := VecMinMax(a) io.Pf("min(a) = %v\n", min2a) io.Pf("max(a) = %v\n", max2a) chk.Scalar(tst, "min(a)", 1e-17, min2a, 0.1) chk.Scalar(tst, "max(a)", 1e-17, max2a, 0.5) io.Pfyel("\nfunc VecLargest(u []float64, den float64) (largest float64)\n") PrintVec("b ", b, "%5g", false) bdiv11 := []float64{b[0] / 11.0, b[1] / 11.0, b[2] / 11.0, b[3] / 11.0, b[4] / 11.0} PrintVec("b / 11", bdiv11, "%5g", false) maxbdiv11 := VecLargest(b, 11) io.Pf("max(b/11) = %v\n", maxbdiv11) chk.Scalar(tst, "max(b/11)", 1e-17, maxbdiv11, 5) io.Pfyel("\nfunc VecMaxDiff(a, b []float64) (maxdiff float64)\n") amb1 := []float64{a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3], a[4] - b[4]} amb2 := make([]float64, len(a)) VecAdd2(amb2, 1, a, -1, b) PrintVec("a ", a, "%7g", false) PrintVec("b ", b, "%7g", false) PrintVec("a-b", amb1, "%7g", false) PrintVec("a-b", amb2, "%7g", false) maxdiffab := VecMaxDiff(a, b) io.Pf("maxdiff(a,b) = max(abs(a-b)) = %v\n", maxdiffab) chk.Vector(tst, "amb1 == amb2", 1e-17, amb1, amb2) chk.Scalar(tst, "maxdiff(a,b)", 1e-17, maxdiffab, 54.5) io.Pfyel("\nfunc VecMaxDiffC(a, b []complex128) (maxdiff float64)\n") az := []complex128{complex(a[0], 1), complex(a[1], 3), complex(a[2], 0.5), complex(a[3], 1), complex(a[4], 0)} bz := []complex128{complex(b[0], 1), complex(b[1], 6), complex(b[2], 0.8), complex(b[3], -3), complex(b[4], 1)} ambz := []complex128{az[0] - bz[0], az[1] - bz[1], az[2] - bz[2], az[3] - bz[3], az[4] - bz[4]} PrintVecC("az ", az, "(%5g +", "%4gi) ", false) PrintVecC("bz ", bz, "(%5g +", "%4gi) ", false) PrintVecC("az-bz", ambz, "(%5g +", "%4gi) ", false) maxdiffabz := VecMaxDiffC(az, bz) io.Pf("maxdiff(az,bz) = %v\n", maxdiffabz) chk.Scalar(tst, "maxdiff(az,bz)", 1e-17, maxdiffabz, 54.5) io.Pfyel("\nfunc VecScale(res []float64, Atol, Rtol float64, v []float64)\n") scal1 := make([]float64, len(a)) VecScale(scal1, 0.5, 0.1, amb1) PrintVec("a-b ", amb1, "%7g", false) PrintVec("0.5 + 0.1*(a-b)", scal1, "%7g", false) chk.Vector(tst, "0.5 + 0.1*(a-b)", 1e-15, scal1, []float64{-0.59, -1.68, -2.77, -3.86, -4.95}) io.Pfyel("\nfunc VecScaleAbs(res []float64, Atol, Rtol float64, v []float64)\n") scal2 := make([]float64, len(a)) VecScaleAbs(scal2, 0.5, 0.1, amb1) PrintVec("a-b ", amb1, "%7g", false) PrintVec("0.5 + 0.1*|a-b|", scal2, "%7g", false) chk.Vector(tst, "0.5 + 0.1*|a-b|", 1e-15, scal2, []float64{1.59, 2.68, 3.77, 4.86, 5.95}) io.Pfyel("\nfunc VecRms(u []float64) (rms float64)\n") PrintVec("v", v, "%5g", false) rms := VecRms(v) io.Pf("rms(v) = %23.15e\n", rms) chk.Scalar(tst, "rms(v)", 1e-17, rms, 666.0) io.Pfyel("func VecRmsErr(u []float64, Atol, Rtol float64, v []float64) (rms float64)\n") PrintVec("v", v, "%5g", false) rmserr := VecRmsErr(v, 0, 1, v) io.Pf("rmserr(v,v) = %23.15e\n", rmserr) chk.Scalar(tst, "rmserr(v,v,0,1)", 1e-17, rmserr, 1) io.Pfyel("func VecRmsError(u, w []float64, Atol, Rtol float64, v []float64) (rms float64)\n") PrintVec("v", v, "%5g", false) w := []float64{333, 333, 333, 333, 333} rmserr = VecRmsError(v, w, 0, 1, v) io.Pf("rmserr(v,w,v) = %23.15e\n", rmserr) chk.Scalar(tst, "rmserr(v,w,0,1,v)", 1e-17, rmserr, 0.5) }
// ReadLPfortran reads linear program from particular fortran file // download LP files from here: http://users.clas.ufl.edu/hager/coap/format.html // Output: // A -- compressed-column sparse matrix where: // Ap -- pointers to the begining of storage of column (size n+1) // Ai -- row indices for each non zero entry (input, nnz A) // Ax -- non zero entries (input, nnz A) // b -- right hand side (input, size m) // c -- objective vector (minimize, size n) // l -- lower bounds on variables (size n) // u -- upper bounds on variables (size n) func ReadLPfortran(fn string) (A *la.CCMatrix, b, c, l, u []float64) { // variables var m int // number or rows (input) var n int // number of columns (input) var Ap []int // pointers to the begining of storage of column (size n+1) var Ai []int // row indices for each non zero entry (input, nnz A) var Ax []float64 // non zero entries (input, nnz A) var z0 float64 // initial fixed value for objective // auxiliary reading_Ap := false reading_Ai := false reading_Ax := false reading_b := false reading_c := false reading_z0 := false reading_l := false reading_u := false atof := func(s string) float64 { return io.Atof(strings.Replace(s, "D", "E", 1)) } // read data k := 0 io.ReadLines(fn, func(idx int, line string) (stop bool) { if idx == 0 { // skip name return } str := strings.Fields(line) if idx == 1 { // read m and m m, n = io.Atoi(str[0]), io.Atoi(str[1]) Ap = make([]int, n+1) k = 0 reading_Ap = true return } for _, s := range str { if reading_Ap { if k == n+1 { reading_Ap = false reading_Ai = true nnz := Ap[n] Ai = make([]int, nnz) Ax = make([]float64, nnz) b = make([]float64, m) c = make([]float64, n) l = make([]float64, n) u = make([]float64, n) k = 0 } else { Ap[k] = io.Atoi(s) - 1 // subtract 1 because of Fortran indexing } } if reading_Ai { if k == Ap[n] { reading_Ai = false reading_Ax = true k = 0 } else { Ai[k] = io.Atoi(s) - 1 // subtract 1 because of Fortran indexing } } if reading_Ax { if k == Ap[n] { reading_Ax = false reading_b = true k = 0 } else { Ax[k] = atof(s) } } if reading_b { if k == m { reading_b = false reading_c = true k = 0 } else { b[k] = atof(s) } } if reading_c { if k == n { reading_c = false reading_z0 = true k = 0 } else { c[k] = atof(s) } } if reading_z0 { z0 = atof(s) _ = z0 reading_z0 = false reading_l = true k = 0 return } if reading_l { if k == n { reading_l = false reading_u = true k = 0 } else { l[k] = atof(s) } } if reading_u { if k == n { reading_u = false k = 0 } else { u[k] = atof(s) } } k++ } return }) // debug if false { io.Pforan("Ap = %v\n", Ap) io.Pfcyan("Ai = %v\n", Ai) io.Pfyel("Ax = %v\n", Ax) io.Pf("b = %v\n", b) io.Pforan("c = %v\n", c) io.Pfcyan("l = %v\n", l) io.Pfyel("u = %v\n", u) } // results A = new(la.CCMatrix) A.Set(m, n, Ap, Ai, Ax) return }
// Update updates state // pl and pg are updated (new) values func (o Model) Update(s *State, Δpl, Δpg, pl, pg float64) (err error) { // auxiliary variables slmin := o.Lrm.SlMin() Δpc := Δpg - Δpl wet := Δpc < 0 pl0 := pl - Δpl pg0 := pg - Δpg pc0 := pg0 - pl0 sl0 := s.A_sl pc := pc0 + Δpc sl := sl0 // update liquid saturation if pc <= 0.0 { sl = 1 // full liquid saturation if capillary pressure is ineffective } else if o.nonrateLrm != nil && !o.AllBE { sl = o.nonrateLrm.Sl(pc) // handle simple retention models } else { // unsaturated case with rate-type model // trial liquid saturation update fA, e := o.Lrm.Cc(pc0, sl0, wet) if e != nil { return e } if o.MEtrial { slFE := sl0 + Δpc*fA fB, e := o.Lrm.Cc(pc, slFE, wet) if e != nil { return e } sl += 0.5 * Δpc * (fA + fB) } else { sl += Δpc * fA } // fix trial sl out-of-range values if sl < slmin { sl = slmin } if sl > 1 { sl = 1 } // message if o.ShowR { io.PfYel("%6s%18s%18s%18s%18s%8s\n", "it", "Cc", "sl", "δsl", "r", "ex(r)") } // backward-Euler update var f, r, J, δsl float64 var it int for it = 0; it < o.NmaxIt; it++ { f, err = o.Lrm.Cc(pc, sl, wet) if err != nil { return } r = sl - sl0 - Δpc*f if o.ShowR { io.Pfyel("%6d%18.14f%18.14f%18.14f%18.10e%8d\n", it, f, sl, δsl, r, utl.Expon(r)) } if math.Abs(r) < o.Itol { break } J, err = o.Lrm.J(pc, sl, wet) if err != nil { return } δsl = -r / (1.0 - Δpc*J) sl += δsl if math.IsNaN(sl) { return chk.Err("NaN found: Δpc=%v f=%v r=%v J=%v sl=%v\n", Δpc, f, r, J, sl) } } // message if o.ShowR { io.Pfgrey(" pc0=%.6f sl0=%.6f Δpl=%.6f Δpg=%.6f Δpc=%.6f\n", pc0, sl0, Δpl, Δpg, Δpc) io.Pfgrey(" converged with %d iterations\n", it) } // check convergence if it == o.NmaxIt { return chk.Err("saturation update failed after %d iterations\n", it) } } // check results if pc < 0 && sl < 1 { return chk.Err("inconsistent results: saturation must be equal to one when the capillary pressure is ineffective. pc = %g < 0 and sl = %g < 1 is incorrect", pc, sl) } if sl < slmin { return chk.Err("inconsistent results: saturation must be greater than minimum saturation. sl = %g < %g is incorrect", sl, slmin) } // set state s.A_sl = sl // 2 s.A_ρL += o.Cl * Δpl // 3 s.A_ρG += o.Cg * Δpg // 4 s.A_Δpc = Δpc // 5 s.A_wet = wet // 6 return }
func Test_bh16a(tst *testing.T) { /* solid bracket with thickness = 0.25 * * 1 -10 connectivity: * (-100) o'-,__ eid : verts * | '-,__ 3 -10 0 : 0, 2, 3 * | ,'o-,__ 1 : 3, 1, 0 * | 1 ,' | '-,__ 5 2 : 2, 4, 5 * | ,' | 3 ,-'o 3 : 5, 3, 2 * | ,' 0 | ,-' | * |,' |,-' 2 | constraints: * (-100) o----------o---------o -100 : fixed on x and y * 0 2 4 */ //verbose() chk.PrintTitle("bh16a") // start simulation if !Start("data/bh16.sim", true, chk.Verbose) { tst.Errorf("test failed\n") return } // make sure to flush log defer End() // domain distr := false dom := NewDomain(Global.Sim.Regions[0], distr) if dom == nil { tst.Errorf("test failed\n") return } // set stage if !dom.SetStage(0, Global.Sim.Stages[0], distr) { tst.Errorf("test failed\n") return } // nodes and elements chk.IntAssert(len(dom.Nodes), 6) chk.IntAssert(len(dom.Elems), 4) // check dofs for _, nod := range dom.Nodes { chk.IntAssert(len(nod.Dofs), 2) } // check equations nids, eqs := get_nids_eqs(dom) chk.Ints(tst, "nids", nids, []int{0, 2, 3, 1, 4, 5}) chk.Ints(tst, "eqs", eqs, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}) // check solution arrays ny := 6 * 2 nλ := 4 nyb := ny + nλ chk.IntAssert(len(dom.Sol.Y), ny) chk.IntAssert(len(dom.Sol.Dydt), 0) chk.IntAssert(len(dom.Sol.D2ydt2), 0) chk.IntAssert(len(dom.Sol.Psi), 0) chk.IntAssert(len(dom.Sol.Zet), 0) chk.IntAssert(len(dom.Sol.Chi), 0) chk.IntAssert(len(dom.Sol.L), nλ) chk.IntAssert(len(dom.Sol.ΔY), ny) // check linear solver arrays chk.IntAssert(len(dom.Fb), nyb) chk.IntAssert(len(dom.Wb), nyb) // check umap umaps := [][]int{ {0, 1, 2, 3, 4, 5}, {4, 5, 6, 7, 0, 1}, {2, 3, 8, 9, 10, 11}, {10, 11, 4, 5, 2, 3}, } for i, ele := range dom.Elems { e := ele.(*ElemU) io.Pforan("e%d.umap = %v\n", e.Id(), e.Umap) chk.Ints(tst, "umap", e.Umap, umaps[i]) } // constraints chk.IntAssert(len(dom.EssenBcs.Bcs), nλ) var ct_ux_eqs []int // constrained ux equations [sorted] var ct_uy_eqs []int // constrained uy equations [sorted] for _, c := range dom.EssenBcs.Bcs { chk.IntAssert(len(c.Eqs), 1) eq := c.Eqs[0] io.Pforan("key=%v eq=%v\n", c.Key, eq) switch c.Key { case "ux": ct_ux_eqs = append(ct_ux_eqs, eq) case "uy": ct_uy_eqs = append(ct_uy_eqs, eq) default: tst.Errorf("key %s is incorrect", c.Key) } } sort.Ints(ct_ux_eqs) sort.Ints(ct_uy_eqs) chk.Ints(tst, "constrained ux equations", ct_ux_eqs, []int{0, 6}) chk.Ints(tst, "constrained uy equations", ct_uy_eqs, []int{1, 7}) // check ip data for _, ele := range dom.Elems { e := ele.(*ElemU) d := e.OutIpsData() chk.IntAssert(len(d), 1) vals := d[0].Calc(dom.Sol) chk.IntAssert(len(vals), 4) for key, val := range vals { io.Pfyel("key=%v => val=%v\n", key, val) } } }
// DistPoint returns the distance from a point to this Bezier curve // It finds the closest projection which is stored in P func (o *BezierQuad) DistPoint(X []float64, doplot bool) float64 { // TODO: // 1) split this into closest projections finding // 2) finish distance computation // check if len(o.Q) != 3 { chk.Panic("DistPoint: quadratic Bezier must be initialised first (with 3 control points)") } ndim := len(o.Q[0]) chk.IntAssert(len(X), ndim) // solve cubic equation var A_i, B_i, M_i, a, b, c, d float64 for i := 0; i < ndim; i++ { A_i = o.Q[2][i] - 2.0*o.Q[1][i] + o.Q[0][i] B_i = o.Q[1][i] - o.Q[0][i] M_i = o.Q[0][i] - X[i] a += A_i * A_i b += 3.0 * A_i * B_i c += 2.0*B_i*B_i + M_i*A_i d += M_i * B_i } //io.Pforan("a=%v b=%v c=%v d=%v\n", a, b, c, d) if math.Abs(a) < 1e-7 { chk.Panic("DistPoint does not yet work with this type of Bezier (straight line?):\nQ=%v\n", o.Q) } x1, x2, x3, nx := num.EqCubicSolveReal(b/a, c/a, d/a) io.Pfyel("\nx1=%v x2=%v x3=%v nx=%v\n", x1, x2, x3, nx) // auxiliary if len(o.P) != ndim { o.P = make([]float64, ndim) } // closest projections t := x1 if nx == 2 { chk.Panic("nx=2 => not implemented yet") } if nx == 3 { T := []float64{x1, x2, x3} D := []float64{-1, -1, -1} ok := []bool{ !(x1 < 0.0 || x1 > 1.0), !(x2 < 0.0 || x2 > 1.0), !(x3 < 0.0 || x3 > 1.0), } io.Pforan("ok = %v\n", ok) for i, t := range T { if ok[i] { o.Point(o.P, t) if doplot { plt.PlotOne(X[0], X[1], "'ko'") plt.PlotOne(o.P[0], o.P[1], "'k.'") plt.Arrow(X[0], X[1], o.P[0], o.P[1], "ec='none'") } D[i] = ppdist(X, o.P) } } io.Pforan("D = %v\n", D) } o.Point(o.P, t) io.Pfcyan("P = %v\n", o.P) return 0 }
func Test_shape01(tst *testing.T) { //utl.Tsilent = false chk.PrintTitle("Test shape01") for name, shape := range factory { io.Pfyel("--------------------------------- %-6s---------------------------------\n", name) // check S tol := 1e-17 errS := 0.0 if name == "tri10" { tol = 1e-14 } for n := 0; n < shape.Nverts; n++ { rst := []float64{0, 0, 0} for i := 0; i < shape.Gndim; i++ { rst[i] = shape.NatCoords[i][n] } shape.Func(shape.S, shape.dSdR, rst[0], rst[1], rst[2], false) io.Pforan("S = %v\n", shape.S) for m := 0; m < shape.Nverts; m++ { if n == m { errS += math.Abs(shape.S[m] - 1.0) } else { errS += math.Abs(shape.S[m]) } } } if errS > tol { tst.Errorf("%s failed with err = %g\n", name, errS) return } // check dSdR tol = 1e-14 h := 1.0e-1 S_temp := make([]float64, shape.Nverts) if name == "lin5" || name == "tri15" || name == "lin4" || name == "tri10" || name == "qua12" || name == "qua16" { tol = 1.0e-10 } for n := 0; n < shape.Nverts; n++ { rst := []float64{0, 0, 0} for i := 0; i < shape.Gndim; i++ { rst[i] = shape.NatCoords[i][n] } // analytical shape.Func(shape.S, shape.dSdR, rst[0], rst[1], rst[2], true) // numerical for i := 0; i < shape.Gndim; i++ { dSndRi, _ := num.DerivCentral(func(x float64, args ...interface{}) (Sn float64) { rst_temp := []float64{rst[0], rst[1], rst[2]} rst_temp[i] = x shape.Func(S_temp, nil, rst_temp[0], rst_temp[1], rst_temp[2], false) Sn = S_temp[n] return }, rst[i], h) io.Pfgrey2(" dS%ddR%d @ [% 4.1f % 4.1f % 4.1f] = %v (num: %v)\n", n, i, rst[0], rst[1], rst[2], shape.dSdR[n][i], dSndRi) tol2 := tol if name == "tri15" && n == 11 && i == 1 { tol2 = 1.0e-9 } if math.Abs(shape.dSdR[n][i]-dSndRi) > tol2 { tst.Errorf("%s dS%ddR%d failed with err = %g\n", name, n, i, math.Abs(shape.dSdR[n][i]-dSndRi)) return } //chk.Scalar(tst, fmt.Sprintf("dS%ddR%d", n, i), tol2, dSdR[n][i], dSndRi) } } // check face vertices tol = 1e-17 errS = 0.0 if name == "tri10" { tol = 1e-14 } nfaces := len(shape.FaceLocalV) if nfaces == 0 { continue } for k := 0; k < nfaces; k++ { for n := range shape.FaceLocalV[k] { rst := []float64{0, 0, 0} for i := 0; i < shape.Gndim; i++ { rst[i] = shape.NatCoords[i][n] } shape.Func(shape.S, shape.dSdR, rst[0], rst[1], rst[2], false) io.Pforan("S = %v\n", shape.S) for m := range shape.FaceLocalV[k] { if n == m { errS += math.Abs(shape.S[m] - 1.0) } else { errS += math.Abs(shape.S[m]) } } } } io.Pforan("%g\n", errS) if errS > tol { tst.Errorf("%s failed with err = %g\n", name, errS) return } io.PfGreen("OK\n") } }
func Test_out01(tst *testing.T) { // finalise analysis process and catch errors defer func() { if err := recover(); err != nil { tst.Fail() io.PfRed("ERROR: %v\n", err) } }() // test title //verbose() chk.PrintTitle("out01") // start simulation processing := fem.NewFEM("data/onequa4.sim", "", true, true, false, false, chk.Verbose, 0) // run simulation err := processing.Run() if err != nil { tst.Errorf("Run failed:\n%v", err) return } // start post-processing Start("data/onequa4.sim", 0, 0) // define points Define("A B C D", N{0, 1, 2, 3}) Define("a b c d", P{{0, 0}, {0, 1}, {-1, 2}, {-1, 3}}) Define("!right side", Along{{1, 0}, {1, 1}}) io.Pfcyan("Entities = %v\n", Results) // check slices nnod := 4 nele := 1 nip := 4 chk.IntAssert(len(Dom.Nodes), nnod) chk.IntAssert(len(Ipoints), nele*nip) chk.IntAssert(len(Cid2ips), 1) chk.IntAssert(len(Ipkey2ips), 4) chk.IntAssert(len(Ipkeys), 4) for key, ips := range Ipkey2ips { chk.Ints(tst, io.Sf("%s : ips", key), ips, utl.IntRange(4)) } // load results LoadResults(nil) // check points nlabels := []string{"A", "B", "C", "D"} for _, l := range nlabels { if _, ok := Results[l]; !ok { chk.Panic("1: %q alias in Entities is not available", l) } } plabels := []string{"a", "b", "c", "d"} for _, l := range plabels { if _, ok := Results[l]; !ok { chk.Panic("2: %q alias in Entities is not available", l) } } if _, ok := Results["right side"]; !ok { chk.Panic("3: %q alias in Entities is not available", "right side") } // check u-keys ukeys := []string{"ux", "uy"} for _, l := range nlabels { for _, p := range Results[l] { //io.Pfyel("p = %v\n", p) if p == nil { chk.Panic("1: p is nil") } for _, key := range ukeys { if _, ok := p.Vals[key]; !ok { chk.Panic("%s is not available in point", key) } } } } // check s-keys skeys := fem.StressKeys(Dom.Sim.Ndim) for _, l := range plabels { for _, p := range Results[l] { //io.Pfgreen("q = %v\n", p) if p == nil { chk.Panic("2: p is nil") } for _, key := range skeys { if _, ok := p.Vals[key]; !ok { chk.Panic("%s is not available in point", key) } } } } // check GetRes uxC := GetRes("ux", "C", 0) uxR := GetRes("ux", "right side", -1) io.Pforan("uxC = %v\n", uxC) io.Pforan("uxR = %v\n", uxR) chk.IntAssert(len(uxC), 2) idx := len(uxC) - 1 chk.Vector(tst, "uxR", 1e-17, uxR, []float64{uxC[idx], uxC[idx]}) // solution var sol ana.CteStressPstrain sol.Init(fun.Prms{ &fun.Prm{N: "qnH", V: -50}, &fun.Prm{N: "qnV", V: -100}, }) // check displacements tolu := 1e-15 for _, l := range nlabels { x := GetCoords(l) ux := GetRes("ux", l, 0) uy := GetRes("uy", l, 0) io.Pforan("ux=%v uy=%v\n", ux, uy) for j, t := range Times { io.Pfyel("t=%g\n", t) sol.CheckDispl(tst, t, []float64{ux[j], uy[j]}, x, tolu) } } // check stresses tolσ := 1e-14 for _, l := range plabels { x := GetCoords(l) sx := GetRes("sx", l, 0) sy := GetRes("sy", l, 0) sz := GetRes("sz", l, 0) sxy := GetRes("sxy", l, 0) for j, t := range Times { io.Pfyel("t=%g\n", t) sol.CheckStress(tst, t, []float64{sx[j], sy[j], sz[j], sxy[j]}, x, tolσ) } } }
func Test_extrapapolation(tst *testing.T) { //verbose() chk.PrintTitle("Test extrapolation") GetIpNums := func(name string) []int { var nums []int for key, _ := range ipsfactory { name_n := strings.Split(key, "_") if name_n[0] == name { nip := io.Atoi(name_n[1]) nums = append(nums, nip) } } return nums } for name, shape := range factory { gndim := shape.Gndim if gndim == 1 { continue } io.Pfyel("--------------------------------- %-6s---------------------------------\n", name) for _, nip := range GetIpNums(shape.Type) { if nip <= 1 { continue } io.Pfblue("nip = %v\n", nip) tol := 1.0e-13 // create a N vector with nodal values nverts := shape.Nverts X := shape.NatCoords delta := rand.Float64() N := make([]float64, shape.Nverts) for i := 0; i < shape.Nverts; i++ { var x, y, z float64 x = X[0][i] y = X[1][i] if shape.Gndim == 3 { z = X[2][i] } N[i] = x + y + z + delta } io.Pfblue("N = %v\n", N) // calculate P vector with corresponding values at ips key := name + "_" + strconv.Itoa(nip) ips := ipsfactory[key] P := make([]float64, nip) Xip := la.MatAlloc(nip, 4) // ips local coordinates for i := 0; i < nip; i++ { var x, y, z float64 x = ips[i][0] y = ips[i][1] z = ips[i][2] Xip[i][0] = x Xip[i][1] = y Xip[i][2] = z P[i] = x + y + z + delta } // Allocate E matrix E := la.MatAlloc(nverts, nip) // Calculate extrapolator matrix shape.Extrapolator(E, ips) // Recalculate nodal values NN = E*P NN := make([]float64, shape.Nverts) la.MatVecMul(NN, 1.0, E, P) io.Pfblue("N ext= %v\n", NN) // Compare vectors N and NN msg := name + "_" + strconv.Itoa(nip) chk.Vector(tst, msg, tol, NN, N) } } }
func checkmaps(tst *testing.T, m *Mesh, tm *TagMaps, vtags, ctags, cparts, etags, ftags []int, ctypes []string, vtagsVids, ctagsCids, cpartsCids, ctypesCids, etagsVids, etagsCids, etagsLocEids, ftagsVids, ftagsCids, ftagsLocEids [][]int) { // VertTag2verts io.Pfyel("\nVertTag2verts:\n") for key, val := range tm.VertTag2verts { io.Pf("%v:\n", key) for _, s := range val { io.Pf(" vert: %v\n", s) } } if len(tm.VertTag2verts) != len(vtags) { tst.Errorf("size of map of vert tags is incorrect. %d != %d", len(tm.VertTag2verts), len(vtags)) return } for i, tag := range vtags { var ids []int if verts, ok := tm.VertTag2verts[tag]; ok { for _, v := range verts { ids = append(ids, v.Id) } } else { tst.Errorf("cannot find tag %d in VertTag2verts map", tag) return } chk.Ints(tst, io.Sf("%d vertices", tag), ids, vtagsVids[i]) } // CellTag2cells io.Pfyel("\nCellTag2cells:\n") for key, val := range tm.CellTag2cells { io.Pf("%v:\n", key) for _, s := range val { io.Pf(" cell: %v\n", s) } } if len(tm.CellTag2cells) != len(ctags) { tst.Errorf("size of map of cell tags is incorrect. %d != %d", len(tm.CellTag2cells), len(ctags)) return } for i, tag := range ctags { var ids []int if cells, ok := tm.CellTag2cells[tag]; ok { for _, v := range cells { ids = append(ids, v.Id) } } else { tst.Errorf("cannot find tag %d in CellTag2cells map", tag) return } chk.Ints(tst, io.Sf("%d cells", tag), ids, ctagsCids[i]) } // CellPart2cells io.Pfyel("\nCellPart2cells:\n") for key, val := range tm.CellPart2cells { io.Pf("%v:\n", key) for _, s := range val { io.Pf(" cell: %v\n", s) } } if len(tm.CellPart2cells) != len(cparts) { tst.Errorf("size of map of cell tags is incorrect. %d != %d", len(tm.CellPart2cells), len(cparts)) return } for i, part := range cparts { var ids []int if cells, ok := tm.CellPart2cells[part]; ok { for _, v := range cells { ids = append(ids, v.Id) } } else { tst.Errorf("cannot find part %d in CellPart2cells map", part) return } chk.Ints(tst, io.Sf("%d cells", part), ids, cpartsCids[i]) } // CellType2cells io.Pfyel("\nCellType2cells:\n") for key, val := range tm.CellType2cells { io.Pf("%v:\n", key) for _, s := range val { io.Pf(" cell: %v\n", s) } } if len(tm.CellType2cells) != len(ctypes) { tst.Errorf("size of map of cell tags is incorrect. %d != %d", len(tm.CellType2cells), len(ctypes)) return } for i, typ := range ctypes { var ids []int if cells, ok := tm.CellType2cells[typ]; ok { for _, v := range cells { ids = append(ids, v.Id) } } else { tst.Errorf("cannot find type %q in CellType2cells map", typ) return } chk.Ints(tst, io.Sf("%q cells", typ), ids, ctypesCids[i]) } // EdgeTag2cells io.Pfyel("\nEdgeTag2cells:\n") for key, val := range tm.EdgeTag2cells { io.Pf("%v:\n", key) for _, s := range val { io.Pf(" cell: %v\n", s) } } if len(tm.EdgeTag2cells) != len(etags) { tst.Errorf("size of map of edge tags (cells) is incorrect. %d != %d", len(tm.EdgeTag2cells), len(etags)) return } for i, tag := range etags { var cids []int var bryids []int if pairs, ok := tm.EdgeTag2cells[tag]; ok { for _, pair := range pairs { cids = append(cids, pair.C.Id) bryids = append(bryids, pair.BryId) } } else { tst.Errorf("cannot find tag %d in EdgeTag2cells map", tag) return } chk.Ints(tst, io.Sf("%d edges => cells ", tag), cids, etagsCids[i]) chk.Ints(tst, io.Sf("%d edges => bry ids", tag), bryids, etagsLocEids[i]) } // EdgeTag2verts io.Pfyel("\nEdgeTag2verts:\n") for key, val := range tm.EdgeTag2verts { io.Pf("%v:\n", key) for _, s := range val { io.Pf(" vert: %v\n", s) } } if len(tm.EdgeTag2verts) != len(etags) { tst.Errorf("size of map of edge tags (verts) is incorrect. %d != %d", len(tm.EdgeTag2verts), len(etags)) return } for i, tag := range etags { var ids []int if verts, ok := tm.EdgeTag2verts[tag]; ok { for _, v := range verts { ids = append(ids, v.Id) } } else { tst.Errorf("cannot find tag %d in EdgeTag2verts map", tag) return } chk.Ints(tst, io.Sf("%d edges => verts", tag), ids, etagsVids[i]) } // FaceTag2cells io.Pfyel("\nFaceTag2cells:\n") for key, val := range tm.FaceTag2cells { io.Pf("%v:\n", key) for _, s := range val { io.Pf(" cell: %v\n", s) } } if len(tm.FaceTag2cells) != len(ftags) { tst.Errorf("size of map of face tags (cells) is incorrect. %d != %d", len(tm.FaceTag2cells), len(ftags)) return } for i, tag := range ftags { var cids []int var bryids []int if pairs, ok := tm.FaceTag2cells[tag]; ok { for _, pair := range pairs { cids = append(cids, pair.C.Id) bryids = append(bryids, pair.BryId) } } else { tst.Errorf("cannot find tag %d in FaceTag2cells map", tag) return } chk.Ints(tst, io.Sf("%d faces => cells ", tag), cids, ftagsCids[i]) chk.Ints(tst, io.Sf("%d faces => bry ids", tag), bryids, ftagsLocEids[i]) } // FaceTag2verts io.Pfyel("\nFaceTag2verts:\n") for key, val := range tm.FaceTag2verts { io.Pf("%v:\n", key) for _, s := range val { io.Pf(" vert: %v\n", s) } } if len(tm.FaceTag2verts) != len(ftags) { tst.Errorf("size of map of face tags (verts) is incorrect. %d != %d", len(tm.FaceTag2verts), len(ftags)) return } for i, tag := range ftags { var ids []int if verts, ok := tm.FaceTag2verts[tag]; ok { for _, v := range verts { ids = append(ids, v.Id) } } else { tst.Errorf("cannot find tag %d in FaceTag2verts map", tag) return } chk.Ints(tst, io.Sf("%d faces => verts", tag), ids, ftagsVids[i]) } }