예제 #1
0
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)
}
예제 #2
0
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
	}
}
예제 #3
0
파일: main.go 프로젝트: PaddySchmidt/gofem
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)
	}
}
예제 #4
0
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)
	}
}
예제 #5
0
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)
}
예제 #6
0
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)
}
예제 #7
0
파일: setandrunfem.go 프로젝트: cpmech/goga
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)
}
예제 #8
0
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))
	}
}
예제 #9
0
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σ)
		}
	}
}
예제 #10
0
파일: out.go 프로젝트: PaddySchmidt/gofem
// 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
	}
}
예제 #11
0
파일: femsim.go 프로젝트: cpmech/goga
// 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
}