func main() { // catch errors var tst testing.T defer func() { if mpi.Rank() == 0 { if err := recover(); err != nil { io.PfRed("ERROR: %v\n", err) } if tst.Failed() { io.PfRed("test failed\n") } } mpi.Stop(false) }() mpi.Start(false) // start global variables and log analysis := fem.NewFEM("data/bh16.sim", "", true, true, false, true, true, 0) // run simulation err := analysis.Run() if err != nil { tst.Error("Run failed\n") return } // check skipK := true tolK := 1e-12 tolu := 1e-15 tols := 1e-12 fem.TestingCompareResultsU(&tst, "data/bh16.sim", "cmp/bh16.cmp", "", tolK, tolu, tols, skipK, true) }
func main() { // catch errors var tst testing.T defer func() { if mpi.Rank() == 0 { if err := recover(); err != nil { io.PfRed("ERROR: %v\n", err) } if tst.Failed() { io.PfRed("test failed\n") } } mpi.Stop(false) }() mpi.Start(false) // start global variables and log analysis := fem.NewFEM("data/p01.sim", "", true, true, false, true, true, 0) // run simulation err := analysis.Run() if err != nil { tst.Error("Run failed\n") return } }
func main() { // catch errors defer func() { if err := recover(); err != nil { if mpi.Rank() == 0 { chk.Verbose = true for i := 8; i > 3; i-- { chk.CallerInfo(i) } io.PfRed("ERROR: %v\n", err) } } mpi.Stop(false) }() mpi.Start(false) // default input parameters // read input parameters fnamepath, _ := io.ArgToFilename(0, "", ".sim", true) verbose := io.ArgToBool(1, true) erasePrev := io.ArgToBool(2, true) saveSummary := io.ArgToBool(3, true) allowParallel := io.ArgToBool(4, true) alias := io.ArgToString(5, "") // message if mpi.Rank() == 0 && verbose { io.PfWhite("\nGofem v3 -- Go Finite Element Method\n\n") io.Pf("Copyright 2015 Dorival Pedroso and Raul Durand. All rights reserved.\n") io.Pf("Use of this source code is governed by a BSD-style\n") io.Pf("license that can be found in the LICENSE file.\n\n") io.Pf("\n%v\n", io.ArgsTable( "filename path", "fnamepath", fnamepath, "show messages", "verbose", verbose, "erase previous results", "erasePrev", erasePrev, "save summary", "saveSummary", saveSummary, "allow parallel run", "allowParallel", allowParallel, "word to add to results", "alias", alias, )) } // profiling? defer utl.DoProf(false)() // analysis data readSummary := false analysis := fem.NewFEM(fnamepath, alias, erasePrev, saveSummary, readSummary, allowParallel, verbose, 0) // run simulation err := analysis.Run() if err != nil { chk.Panic("Run failed:\n%v", err) } }
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) } }
func Test_plot01(tst *testing.T) { // test title //verbose() chk.PrintTitle("plot01") // constants datadir := "$GOPATH/src/github.com/cpmech/gofem/fem/data/" simfn := "p02.sim" // start simulation processing := fem.NewFEM(datadir+simfn, "", 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(datadir+simfn, 0, 0) // define entities Define("A", N{1}) Define("B", At{0, 1}) //Define("left", Along{{0, 0}, {0, 10}}) Define("left", AlongY{0}) // 0 => x_cte // load results LoadResults(nil) plA := GetRes("pl", "A", 0) Splot("liquid pressure") Plot("t", "pl", "B", plt.Fmt{C: "b", M: "."}, -1) Plot("t", plA, "A", plt.Fmt{C: "r", M: "."}, -1) Splot("") Plot("pl", "pl", "A", plt.Fmt{C: "k", M: "o"}, -1) Splot("") Plot("pl", "y", "left", plt.Fmt{C: "b", M: "o"}, 0) Plot("pl", "y", "left", plt.Fmt{C: "g", M: "o"}, -1) Splot("") io.Pforan("T = %v\n", Times) last := len(Times) - 1 Plot("y", "pl", "left", plt.Fmt{C: "b", M: "o", L: io.Sf("t=%g", Times[0])}, 0) Plot("y", "pl", "left", plt.Fmt{C: "m", M: "*", Lw: 2, L: io.Sf("t=%g", Times[last])}, -1) //Draw("", "", true, nil) Draw("", "", false, nil) }
func Test_topo01(tst *testing.T) { // test title //verbose() chk.PrintTitle("topo01") // constants datadir := "data/" simfn := "box.sim" // start simulation processing := fem.NewFEM(datadir+simfn, "", 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(datadir+simfn, 0, 0) // vertices on plane (indenter/surface) ftag := -31 surf := NodesOnPlane(ftag) vids := []int{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63} chk.IntAssert(surf.Plane, 2) // perpendicular to z chk.IntAssert(len(surf.Ids), 16) for _, vid := range vids { if !surf.Ids[vid] { chk.Panic("vid=%d is not in map", vid) } } chk.Scalar(tst, "Δx", 1e-15, surf.Dx[0], 4.0/3.0) chk.Scalar(tst, "Δy", 1e-15, surf.Dx[1], 4.0/3.0) chk.Scalar(tst, "Δz", 1e-15, surf.Dx[2], 0) chk.Ints(tst, "Iu", surf.Iu, []int{0, 1}) chk.Scalar(tst, "Δu", 1e-15, surf.Du[0], 4.0/3.0) chk.Scalar(tst, "Δv", 1e-15, surf.Du[1], 4.0/3.0) chk.Vector(tst, "Umin", 1e-15, surf.Umin, []float64{0, 0}) chk.Vector(tst, "Umax", 1e-15, surf.Umax, []float64{4, 4}) chk.Ints(tst, "Nu", surf.Nu, []int{4, 4}) // define entities lx, ly, lz := 4.0, 4.0, 4.0 Define("A", At{lx, ly, lz}) Define("surf", surf) // load results Extrap = []string{"sz"} LoadResults(nil) // displacements Splot("displacements") Plot("t", "uz", "A", plt.Fmt{C: "b", M: "o"}, -1) // stresses on surface V := IntegOnPlane("ex_sz", "surf") Splot("integral of stresses") Plot(Times, V, "surf", plt.Fmt{C: "r", M: "o"}, -1) Csplot.Xlbl = "time" Csplot.Ylbl = "integ(sz)" //Draw("", "", true, nil) Draw("", "", false, nil) }
func main() { // settings: upward movement /* enabled := []int{1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1} areas := []float64{34.00821693709039, 0.09, 9.968259379257471, 35, 15.831579773931853, 8.654957754397607, 11.965649280046627, 19.413683184371774, 7.6546849806620525, 5.387748841496445, 35, 29.504717529844843, 26.86909134752426, 35, 20.10785632243804, 3.446115518045177, 0.09, 35, 26.216339636590078, 9.542311851327804, 35, 0.09, 0.09, 28.407557441773008, 29.933108719044267, 10.922581748461933, 1.8067072461717366, 0.09, 14.7804274343423, 0.09, 11.730811122600027, 35, 35, 0.09, 35, 35} weight = 10169.99460559597 umax = 0.03190476190476189 smax = 20.518951772912644 */ // settings: upward movement //enabled := []int{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1} //areas := []float64{29.673971565565495, 9.804876568305883, 12.722191736896143, 31.128370429558302, 12.28498763291402, 0.09, 1.0976024620675062, 29.054175458117097, 0.09, 12.074834078336714, 0.9518626611813701, 0.804189446111032, 9.620926416457582, 23.064311560926264, 4.903260570239974, 0.09, 14.345604382360431, 31.10942565747464, 0.09, 7.790214820299472, 7.491266591459749, 21.567320209602265, 4.905574834666627, 0.09, 9.065113525395782, 23.84052973418943, 6.7235867554969975, 3.6046158266920836, 24.589638797955896, 0.09, 31.780396612723077, 23.409598016209728, 3.50718429240112, 15.956651688597585, 35, 12.255743491145445} //enabled := []int{1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1} //areas := []float64{21.480878134095338, 0.09, 14.694965198034584, 24.824367367224532, 6.729854812525405, 0.09, 0.09, 18.170644951273943, 27.43068988046519, 16.340137823665955, 0.09, 35, 33.257655346869484, 0.09, 10.739467844959764, 1.2284583619296825, 0.09, 13.836693890116672, 3.223634459640667, 31.609509632805768, 2.9580912890580233, 0.09, 11.66346650529349, 11.839368679149583, 8.037665593492571, 18.4772618019285, 6.0722754499289335, 8.299339699920758, 18.092667282860184, 0.09, 3.95809930082411, 35, 24.98891088932943, 0.09, 20.001590440636104, 0.4232030075463411} //enabled := []int{1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1} //areas := []float64{1.2035515116115514, 0.811277071473871, 32.37830152936991, 11.012589123896603, 29.419388200704844, 11.517528463414674, 26.842094480154707, 0.09, 7.545801867132738, 22.246892098984826, 33.64813536709853, 35, 18.79453561647245, 19.72091117582699, 24.417433685262015, 17.139485224780174, 14.64143052284774, 6.017622261768879, 18.627730008706013, 6.034380625351308, 15.909160991008125, 3.010643800045916, 35, 1.7855841010723912, 23.882989565364397, 4.179630598025799, 8.060183267136836, 27.61994718378331, 26.443620790772826, 35, 0.9889261275628931, 0.09, 22.110211729649148, 31.153765658657143, 19.868907703384732, 23.523896513200622} enabled := []int{1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1} areas := []float64{22.757099750148996, 28.986754816914374, 6.957451713927281, 8.528672093936208, 9.26287758087651, 2.4766961118094857, 19.144883540012557, 6.382281135196173, 10.365771948733226, 2.0524134188513186, 3.3776112861797856, 22.444923164834712, 0.09, 0.09, 0.09, 8.68418380122592, 0.09, 0.3395486752846164, 4.356831930853984, 12.792965016026955, 20.651430212430448, 4.881368992183173, 17.009172478115723, 14.806321101924194, 9.298936701386527, 5.820319254311902, 11.792969696093445, 12.323517103405779, 1.4343013440743113, 2.3392600723999366, 0.09, 11.352516128577138, 11.223982208350751, 23.98665707191376, 0.09, 0.09} // start simulation processing := fem.NewFEM("cantilever.sim", "", true, true, false, false, true, 0) // set enabled/disabled dom := processing.Domains[0] if true { set_enabled_disabled(dom, enabled) } // set stage err := processing.SetStage(0) if err != nil { io.PfRed("SetStage failed:\n%v", err) return } // set areas lwds := make(map[int]float64) if true { weight := 0.0 for _, elem := range dom.Elems { ele := elem.(*fem.ElastRod) cid := ele.Cell.Id ele.Mdl.A = areas[cid] ele.Recompute(false) weight += ele.Mdl.Rho * ele.Mdl.A * ele.L lwds[cid] = 0.1 + ele.Mdl.A/10.0 } io.Pforan("weight = %v\n", weight) } // mobility n := len(dom.Nodes) m := len(dom.Elems) d := len(dom.EssenBcs.Bcs) F := 2*n - m - d io.Pforan("mobility = %v\n", F) // plot msh := dom.Msh msh.Draw2d(true, lwds) plt.SaveD("/tmp/goga", "rods.eps") // run FE analysis err = processing.SolveOneStage(0, true) if err != nil { io.PfRed("Run failed:\n%v", err) return } // post-processing vid := msh.VertTag2verts[-4][0].Id nod := dom.Vid2node[vid] eqy := nod.GetEq("uy") uy := dom.Sol.Y[eqy] io.PfYel("%2d : uy = %g\n", vid, uy) smax := 0.0 for _, elem := range dom.Elems { ele := elem.(*fem.ElastRod) sig := math.Abs(ele.CalcSig(dom.Sol)) if sig > smax { smax = sig } } io.Pfred("smax = %v\n", smax) }
func main() { // catch errors defer func() { if err := recover(); err != nil { io.PfRed("ERROR: %v\n", err) } }() // filename filename, fnkey := io.ArgToFilename(0, "spo751", ".sim", true) // constants nidx := 20 // selected node at outer surface didx := 0 // selected dof index for plot nels := 4 // number of elements nips := 4 // number of ips // selected P values for stress plot Psel := []float64{100, 140, 180, 190} tolPsel := 2.0 // tolerance to compare P GPa2MPa := 1000.0 // conversion factor // input data Pcen := 200.0 // [Mpa] a, b := 100.0, 200.0 // [mm], [mm] E, ν := 210000.0, 0.3 // [MPa], [-] σy := 240.0 // [MPa] // analytical solution var sol ana.PressCylin sol.Init([]*fun.Prm{ &fun.Prm{N: "a", V: a}, &fun.Prm{N: "b", V: b}, &fun.Prm{N: "E", V: E}, &fun.Prm{N: "ν", V: ν}, &fun.Prm{N: "σy", V: σy}, }) np := 41 P_ana, Ub_ana := sol.CalcPressDisp(np) R_ana, Sr_ana, St_ana := sol.CalcStresses(Psel, np) // fem analysis := fem.NewFEM(filename, "", false, false, true, false, true, 0) err := analysis.SetStage(0) if err != nil { chk.Panic("SetStage failed:\n%v", err) } err = analysis.ZeroStage(0, true) if err != nil { chk.Panic("ZeroStage failed:\n%v", err) } dom := analysis.Domains[0] sum := analysis.Summary // gofem results nto := len(sum.OutTimes) P := make([]float64, nto) Ub := make([]float64, nto) R := utl.Deep3alloc(len(Psel), nels, nips) Sr := utl.Deep3alloc(len(Psel), nels, nips) St := utl.Deep3alloc(len(Psel), nels, nips) i := 0 for tidx, t := range sum.OutTimes { // read results from file err = dom.Read(sum, tidx, 0, true) if err != nil { chk.Panic("cannot read solution\n%v", err) } // collect results for load versus displacement plot nod := dom.Nodes[nidx] eq := nod.Dofs[didx].Eq P[tidx] = t * Pcen Ub[tidx] = dom.Sol.Y[eq] // stresses if isPsel(Psel, P[tidx], tolPsel) { for j, ele := range dom.ElemIntvars { e := ele.(*fem.ElemU) ipsdat := e.OutIpsData() for k, dat := range ipsdat { res := dat.Calc(dom.Sol) x, y := dat.X[0], dat.X[1] sx := res["sx"] * GPa2MPa sy := res["sy"] * GPa2MPa sxy := res["sxy"] * GPa2MPa / math.Sqrt2 R[i][j][k], Sr[i][j][k], St[i][j][k], _ = ana.PolarStresses(x, y, sx, sy, sxy) } } i++ } } // auxiliary data for plotting stresses colors := []string{"r", "m", "g", "k", "y", "c", "r", "m"} markers1 := []string{"o", "s", "x", ".", "^", "*", "o", "s"} markers2 := []string{"+", "+", "+", "+", "+", "+", "+", "+"} // plot load displacements plt.SetForPng(0.8, 400, 200) if true { //if false { plt.Plot(Ub_ana, P_ana, "'b-', ms=2, label='solution', clip_on=0") plt.Plot(Ub, P, "'r.--', label='fem: outer', clip_on=0") plt.Gll("$u_x\\;\\mathrm{[mm]}$", "$P\\;\\mathrm{[MPa]}$", "") plt.SaveD("/tmp", io.Sf("gofem_%s_disp.png", fnkey)) } // plot radial stresses if true { //if false { plt.Reset() for i, Pval := range Psel { plt.Plot(R_ana, Sr_ana[i], "'b-'") for k := 0; k < nips; k++ { for j := 0; j < nels; j++ { args := io.Sf("'%s%s'", colors[i], markers1[i]) if k > 1 { args = io.Sf("'k%s', ms=10", markers2[i]) } if k == 0 && j == 0 { args += io.Sf(", label='P=%g'", Pval) } plt.PlotOne(R[i][j][k], Sr[i][j][k], args) } } } plt.Gll("$r\\;\\mathrm{[mm]}$", "$\\sigma_r\\;\\mathrm{[MPa]}$", "leg_loc='lower right'") plt.AxisXrange(a, b) plt.SaveD("/tmp", io.Sf("gofem_%s_sr.png", fnkey)) } // plot tangential stresses if true { //if false { plt.Reset() for i, Pval := range Psel { plt.Plot(R_ana, St_ana[i], "'b-'") for k := 0; k < nips; k++ { for j := 0; j < nels; j++ { args := io.Sf("'%s%s'", colors[i], markers1[i]) if k > 1 { args = io.Sf("'k%s', ms=10", markers2[i]) } if k == 0 && j == 0 { args += io.Sf(", label='P=%g'", Pval) } plt.PlotOne(R[i][j][k], St[i][j][k], args) } } } plt.Gll("$r\\;\\mathrm{[mm]}$", "$\\sigma_t\\;\\mathrm{[MPa]}$", "leg_loc='upper left'") plt.SaveD("/tmp", io.Sf("gofem_%s_st.png", fnkey)) } }
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σ) } } }
// Start starts handling of results given a simulation input file func Start(simfnpath string, stageIdx, regionIdx int) { // fem structure Analysis = fem.NewFEM(simfnpath, "", false, false, true, false, false, 0) Dom = Analysis.Domains[regionIdx] Sum = Analysis.Summary // set stage err := Analysis.SetStage(stageIdx) if err != nil { chk.Panic("cannot set stage:\n%v", err) } // initialise solution vectors err = Analysis.ZeroStage(stageIdx, true) if err != nil { chk.Panic("cannot initialise solution vectors:\n%v", err) } // clear previous data Ipoints = make([]*fem.OutIpData, 0) Cid2ips = make([][]int, len(Dom.Msh.Cells)) Ipkey2ips = make(map[string][]int) Ipkeys = make(map[string]bool) Planes = make(map[string]*PlaneData) Results = make(map[string]Points) TimeInds = make([]int, 0) Times = make([]float64, 0) Splots = make([]*SplotDat, 0) // bins m := Dom.Msh δ := TolC * 2 xi := []float64{m.Xmin - δ, m.Ymin - δ} xf := []float64{m.Xmax + δ, m.Ymax + δ} if m.Ndim == 3 { xi = append(xi, m.Zmin-δ) xf = append(xf, m.Zmax+δ) } err = NodBins.Init(xi, xf, Ndiv) if err != nil { chk.Panic("cannot initialise bins for nodes: %v", err) } err = IpsBins.Init(xi, xf, Ndiv) if err != nil { chk.Panic("cannot initialise bins for integration points: %v", err) } // add nodes to bins for _, nod := range Dom.Nodes { err := NodBins.Append(nod.Vert.C, nod.Vert.Id) if err != nil { return } } // to find limits ndim := Dom.Msh.Ndim IpsMin = make([]float64, ndim) IpsMax = make([]float64, ndim) first := true // add integration points to slice of ips and to bins for cid, ele := range Dom.Cid2elem { if ele == nil { continue } dat := ele.OutIpsData() nip := len(dat) ids := make([]int, nip) for i, d := range dat { // add to bins ipid := len(Ipoints) ids[i] = ipid Ipoints = append(Ipoints, d) err = IpsBins.Append(d.X, ipid) if err != nil { chk.Panic("cannot append to bins of integration points: %v", err) } // set auxiliary map vals := d.Calc(Dom.Sol) for key, _ := range vals { utl.StrIntsMapAppend(&Ipkey2ips, key, ipid) Ipkeys[key] = true } // limits if first { for j := 0; j < ndim; j++ { IpsMin[j] = d.X[j] IpsMax[j] = d.X[j] } first = false } else { for j := 0; j < ndim; j++ { IpsMin[j] = utl.Min(IpsMin[j], d.X[j]) IpsMax[j] = utl.Max(IpsMax[j], d.X[j]) } } } Cid2ips[cid] = ids } }
// NewData allocates and initialises a new FEM data structure func NewData(filename, fnkey string, cpu int) *FemData { // load opt data var o FemData buf, err := io.ReadFile("od-" + fnkey + ".json") if err != nil { chk.Panic("cannot load opt data:\n%v", err) } err = json.Unmarshal(buf, &o.Opt) if err != nil { chk.Panic("cannot unmarshal opt data:\n%v", err) } o.Opt.CalcDerived() // load FEM data o.Analysis = fem.NewFEM(filename, io.Sf("cpu%d", cpu), false, false, false, false, false, cpu) o.Reg = o.Analysis.Sim.Regions[0] o.Dom = o.Analysis.Domains[0] // required vertices for _, vtag := range o.Opt.ReqVtags { verts := o.Dom.Msh.VertTag2verts[vtag] for _, vert := range verts { o.ReqVids = append(o.ReqVids, vert.Id) } } // groups o.Ncells = len(o.Dom.Msh.Cells) o.Cid2xid = make([]int, o.Ncells) if o.Opt.Groups { o.Nareas = len(o.Dom.Msh.CellTag2cells) for tag, cells := range o.Dom.Msh.CellTag2cells { xid := -tag - 1 for _, cell := range cells { o.Cid2xid[cell.Id] = xid } } } else { // all cells o.Nareas = o.Ncells for i, _ := range o.Dom.Msh.Cells { o.Cid2xid[i] = i } } // vertex to track deflection o.VidU = -1 // allvertices if o.Opt.VtagU < 0 { verts := o.Dom.Msh.VertTag2verts[o.Opt.VtagU] if len(verts) != 1 { chk.Panic("cannot set vertex to track deflection: verts = %v", verts) } o.VidU = verts[0].Id } // compute max weight o.Analysis.SetStage(0) for _, elem := range o.Dom.Elems { ele := elem.(*fem.ElastRod) o.MaxWeight += ele.Mdl.Rho * ele.Mdl.A * ele.L } return &o }