예제 #1
0
파일: grid2d.go 프로젝트: yunpeng1/gosl
// fxy or z must be nil
func (g *Grid2D) Contour(dirout, fnkey string, fxy Cb_fxy, z []float64, nlevels int, show bool) {
	// write buffer
	var b bytes.Buffer
	io.Ff(&b, "from gosl import *\n")
	io.Ff(&b, "XYZ = array([")
	for j := 0; j < g.Ny; j++ {
		for i := 0; i < g.Nx; i++ {
			x := float64(i) * g.Dx
			y := float64(j) * g.Dy
			if fxy == nil {
				io.Ff(&b, "(%g, %g, %g),", x, y, z[i+j*g.Nx])
			} else {
				io.Ff(&b, "(%g, %g, %g),", x, y, fxy(x, y))
			}
		}
	}
	io.Ff(&b, "],dtype=float)\n")
	io.Ff(&b, "X = XYZ[:,0].reshape(%d,%d)\n", g.Ny, g.Nx)
	io.Ff(&b, "Y = XYZ[:,1].reshape(%d,%d)\n", g.Ny, g.Nx)
	io.Ff(&b, "Z = XYZ[:,2].reshape(%d,%d)\n", g.Ny, g.Nx)
	io.Ff(&b, "Contour(X,Y,Z, nlevels=%d)\n", nlevels)
	io.Ff(&b, "axis('equal')\n")
	io.Ff(&b, "show()\n")
	// save file
	io.WriteFileD(dirout, fnkey+".py", &b)
	if show {
		_, err := exec.Command("python", dirout+"/"+fnkey+".py").Output()
		if err != nil {
			chk.Panic("Grid2D:Draw failed when calling python\n%v", err)
		}
	}
}
예제 #2
0
파일: grid2d.go 프로젝트: yunpeng1/gosl
func (g *Grid2D) Draw(dirout, fnkey string, show bool) {
	// write buffer
	var b bytes.Buffer
	io.Ff(&b, "from gosl import *\n")
	io.Ff(&b, "XY = array([")
	for j := 0; j < g.Ny; j++ {
		for i := 0; i < g.Nx; i++ {
			x := float64(i) * g.Dx
			y := float64(j) * g.Dy
			io.Ff(&b, "(%g, %g),", x, y)
		}
	}
	io.Ff(&b, "],dtype=float)\n")
	io.Ff(&b, "L = %v\n", utl.IntPy(g.L))
	io.Ff(&b, "R = %v\n", utl.IntPy(g.R))
	io.Ff(&b, "B = %v\n", utl.IntPy(g.B))
	io.Ff(&b, "T = %v\n", utl.IntPy(g.T))
	io.Ff(&b, "plot(XY[:,0], XY[:,1], 'ko', clip_on=False)\n")
	io.Ff(&b, "plot(XY[L,0], XY[L,1], 'rs', ms=15, clip_on=False)\n")
	io.Ff(&b, "plot(XY[R,0], XY[R,1], 'bs', ms=15, clip_on=False)\n")
	io.Ff(&b, "plot(XY[B,0], XY[B,1], 'yo', ms=12, clip_on=False)\n")
	io.Ff(&b, "plot(XY[T,0], XY[T,1], 'go', ms=12, clip_on=False)\n")
	io.Ff(&b, "axis('equal')\n")
	io.Ff(&b, "grid()\n")
	io.Ff(&b, "show()\n")
	// save file
	io.WriteFileD(dirout, fnkey+".py", &b)
	if show {
		_, err := exec.Command("python", dirout+"/"+fnkey+".py").Output()
		if err != nil {
			chk.Panic("Grid2D:Draw failed when calling python\n%v", err)
		}
	}
}
예제 #3
0
func TestDiffusion1D(tst *testing.T) {

	//verbose()
	chk.PrintTitle("Test Diffusion 1D (cooling)")

	// solution parameters
	silent := false
	fixstp := true
	//fixstp := false
	//method := "FwEuler"
	method := "BwEuler"
	//method := "Dopri5"
	//method := "Radau5"
	//numjac := true
	numjac := false
	rtol := 1e-4
	atol := rtol

	// timestep
	t0, tf, dt := 0.0, 0.2, 0.03

	// problem data
	kx := 1.0 // conductivity
	N := 6    // number of nodes
	//Nb   := N + 2             // augmented system dimension
	xmax := 1.0               // length
	dx := xmax / float64(N-1) // spatial step size
	dxx := dx * dx
	mol := []float64{kx / dxx, -2.0 * kx / dxx, kx / dxx}

	// function
	fcn := func(f []float64, t float64, y []float64, args ...interface{}) error {
		for i := 0; i < N; i++ {
			f[i] = 0
			if i == 0 || i == N-1 {
				continue // skip presc node
			}
			for p, j := range []int{i - 1, i, i + 1} {
				if j < 0 {
					j = i + 1
				} //  left boundary
				if j == N {
					j = i - 1
				} //  right boundary
				f[i] += mol[p] * y[j]
			}
		}
		//io.Pfgrey("y = %v\n", y)
		//io.Pfcyan("f = %v\n", f)
		return nil
	}

	// Jacobian
	jac := func(dfdy *la.Triplet, t float64, y []float64, args ...interface{}) error {
		//chk.Panic("jac is not available")
		if dfdy.Max() == 0 {
			//dfdy.Init(Nb, Nb, 3*N)
			dfdy.Init(N, N, 3*N)
		}
		dfdy.Start()
		for i := 0; i < N; i++ {
			if i == 0 || i == N-1 {
				dfdy.Put(i, i, 0.0)
				continue
			}
			for p, j := range []int{i - 1, i, i + 1} {
				if j < 0 {
					j = i + 1
				} //  left boundary
				if j == N {
					j = i - 1
				} //  right boundary
				dfdy.Put(i, j, mol[p])
			}
		}
		return nil
	}

	// initial values
	x := utl.LinSpace(0.0, xmax, N)
	y := make([]float64, N)
	//y := make([]float64, Nb)
	for i := 0; i < N; i++ {
		y[i] = 4.0*x[i] - 4.0*x[i]*x[i]
	}

	// debug
	f0 := make([]float64, N)
	//f0 := make([]float64, Nb)
	fcn(f0, 0, y)
	if false {
		io.Pforan("y0 = %v\n", y)
		io.Pforan("f0 = %v\n", f0)
		var J la.Triplet
		jac(&J, 0, y)
		la.PrintMat("J", J.ToMatrix(nil).ToDense(), "%8.3f", false)
	}
	//chk.Panic("stop")

	/*
	   // constraints
	   var A la.Triplet
	   A.Init(2, N, 2)
	   A.Put(0,   0, 1.0)
	   A.Put(1, N-1, 1.0)
	   io.Pfcyan("A = %+v\n", A)
	   Am := A.ToMatrix(nil)
	   c  := make([]float64, 2)
	   la.SpMatVecMul(c, 1, Am, y) // c := Am*y
	   la.PrintMat("A", Am.ToDense(), "%3g", false)
	   io.Pfcyan("c = %v  ([0, 0] => consistent)\n", c)
	*/

	/*
	   // mass matrix
	   var M la.Triplet
	   M.Init(Nb, Nb, N + 4)
	   for i := 0; i < N; i++ {
	       M.Put(i, i, 1.0)
	   }
	   M.PutMatAndMatT(&A)
	   Mm := M.ToMatrix(nil)
	   la.PrintMat("M", Mm.ToDense(), "%3g", false)
	*/

	// output
	var b0, b1, b2 bytes.Buffer
	fmt.Fprintf(&b0, "from gosl import *\n")
	fmt.Fprintf(&b1, "T = array([")
	fmt.Fprintf(&b2, "U = array([")
	out := func(first bool, dt, t float64, y []float64, args ...interface{}) error {
		fmt.Fprintf(&b1, "%23.15E,", t)
		fmt.Fprintf(&b2, "[")
		for i := 0; i < N; i++ {
			fmt.Fprintf(&b2, "%23.15E,", y[i])
		}
		fmt.Fprintf(&b2, "],")
		return nil
	}
	defer func() {
		fmt.Fprintf(&b1, "])\n")
		fmt.Fprintf(&b2, "])\n")
		fmt.Fprintf(&b2, "X = linspace(0.0, %g, %d)\n", xmax, N)
		fmt.Fprintf(&b2, "tt, xx = meshgrid(T, X)\n")
		fmt.Fprintf(&b2, "ax = PlotSurf(tt, xx, vstack(transpose(U)), 't', 'x', 'u', 0.0, 1.0)\n")
		fmt.Fprintf(&b2, "ax.view_init(20.0, 30.0)\n")
		fmt.Fprintf(&b2, "show()\n")
		io.WriteFileD("/tmp/gosl", "plot_diffusion_1d.py", &b0, &b1, &b2)
	}()

	// ode solver
	var Jfcn Cb_jac
	var osol ODE
	if !numjac {
		Jfcn = jac
	}
	osol.Init(method, N, fcn, Jfcn, nil, out, silent)
	//osol.Init(method, Nb, fcn, Jfcn, &M, out, silent)
	osol.SetTol(atol, rtol)

	// constant Jacobian
	if method == "BwEuler" {
		osol.CteTg = true
		osol.Verbose = true
	}

	// run
	wallt0 := time.Now()
	if !fixstp {
		dt = tf - t0
	}
	osol.Solve(y, t0, tf, dt, fixstp)
	io.Pfmag("elapsed time = %v\n", time.Now().Sub(wallt0))
}
예제 #4
0
파일: topology.go 프로젝트: cpmech/goga
func tex_results(dirout, fnkey, title, label string, dat *FemData, A, B, C, D, E *goga.Solution, document, compact bool) {
	if len(A.Flt) != 10 {
		chk.Panic("tex_results works with len(Areas)==10 only\n")
		return
	}
	buf := new(bytes.Buffer)
	if document {
		io.Ff(buf, `\documentclass[a4paper]{article}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{booktabs}
\usepackage[margin=1.5cm,footskip=0.5cm]{geometry}

\title{GOGA Report}
\author{Dorival Pedroso}

\begin{document}

`)
	}
	io.Ff(buf, `\begin{table} \centering
\caption{%s}
`, title)
	if compact {
		io.Ff(buf, `\begin{tabular}[c]{cccccccc} \toprule
point & weight & deflection &  $A_0$ & $A_1$ & $A_2$ & $A_3$ & $A_4$   \\
      &        &            &  $A_5$ & $A_6$ & $A_7$ & $A_8$ & $A_9$   \\ \hline
`)
	} else {
		io.Ff(buf, `\begin{tabular}[c]{ccccccccccccc} \toprule
point & weight & deflection & $A_0$ & $A_1$ & $A_2$ & $A_3$ & $A_4$ & $A_5$ & $A_6$ & $A_7$ & $A_8$ & $A_9$ \\ \hline
`)
	}

	writeline := func(pt string, E []int, A []float64) {
		_, _, weight, deflection, _, _, _ := dat.RunFEM(E, A, 0, false)
		if compact {
			io.Ff(buf, "%s & $%.2f$ & $%.6f$ &  $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ \\\\\n", pt, weight, deflection, A[0], A[1], A[2], A[3], A[4])
			io.Ff(buf, "   &        &        &  $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ \\\\\n", A[5], A[6], A[7], A[8], A[9])
		} else {
			io.Ff(buf, "%s & $%.2f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ & $%.6f$ \\\\\n", pt, weight, deflection, A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[8], A[9])
		}
	}

	writeline("A", A.Int, A.Flt)
	writeline("B", B.Int, B.Flt)
	writeline("C", C.Int, C.Flt)
	writeline("D", D.Int, D.Flt)
	writeline("E", E.Int, E.Flt)

	io.Ff(buf, `
\bottomrule
\end{tabular}
\label{tab:%s}
\end{table}
`, label)
	if document {
		io.Ff(buf, ` \end{document}`)
	}

	tex := fnkey + ".tex"
	if document {
		io.WriteFileD(dirout, tex, buf)
		_, err := io.RunCmd(true, "pdflatex", "-interaction=batchmode", "-halt-on-error", "-output-directory=/tmp/goga/", tex)
		if err != nil {
			chk.Panic("%v", err)
		}
		io.PfBlue("file <%s/%s.pdf> generated\n", dirout, fnkey)
	} else {
		io.WriteFileVD(dirout, tex, buf)
	}
}
예제 #5
0
func main() {

	mpi.Start(false)
	defer func() {
		mpi.Stop(false)
	}()

	if mpi.Rank() == 0 {
		chk.PrintTitle("Test ODE 04b (MPI)")
		io.Pfcyan("Hairer-Wanner VII-p376 Transistor Amplifier (MPI)\n")
		io.Pfcyan("(from E Hairer's website, not the system in the book)\n")
	}
	if mpi.Size() != 3 {
		chk.Panic(">> error: this test requires 3 MPI processors\n")
		return
	}

	// RIGHT-HAND SIDE OF THE AMPLIFIER PROBLEM
	w := make([]float64, 8) // workspace
	fcn := func(f []float64, x float64, y []float64, args ...interface{}) error {
		d := args[0].(*HWtransData)
		UET := d.UE * math.Sin(d.W*x)
		FAC1 := d.BETA * (math.Exp((y[3]-y[2])/d.UF) - 1.0)
		FAC2 := d.BETA * (math.Exp((y[6]-y[5])/d.UF) - 1.0)
		la.VecFill(f, 0)
		switch mpi.Rank() {
		case 0:
			f[0] = y[0] / d.R9
		case 1:
			f[1] = (y[1]-d.UB)/d.R8 + d.ALPHA*FAC1
			f[2] = y[2]/d.R7 - FAC1
		case 2:
			f[3] = y[3]/d.R5 + (y[3]-d.UB)/d.R6 + (1.0-d.ALPHA)*FAC1
			f[4] = (y[4]-d.UB)/d.R4 + d.ALPHA*FAC2
			f[5] = y[5]/d.R3 - FAC2
			f[6] = y[6]/d.R1 + (y[6]-d.UB)/d.R2 + (1.0-d.ALPHA)*FAC2
			f[7] = (y[7] - UET) / d.R0
		}
		mpi.AllReduceSum(f, w)
		return nil
	}

	// JACOBIAN OF THE AMPLIFIER PROBLEM
	jac := func(dfdy *la.Triplet, x float64, y []float64, args ...interface{}) error {
		d := args[0].(*HWtransData)
		FAC14 := d.BETA * math.Exp((y[3]-y[2])/d.UF) / d.UF
		FAC27 := d.BETA * math.Exp((y[6]-y[5])/d.UF) / d.UF
		if dfdy.Max() == 0 {
			dfdy.Init(8, 8, 16)
		}
		NU := 2
		dfdy.Start()
		switch mpi.Rank() {
		case 0:
			dfdy.Put(2+0-NU, 0, 1.0/d.R9)
			dfdy.Put(2+1-NU, 1, 1.0/d.R8)
			dfdy.Put(1+2-NU, 2, -d.ALPHA*FAC14)
			dfdy.Put(0+3-NU, 3, d.ALPHA*FAC14)
			dfdy.Put(2+2-NU, 2, 1.0/d.R7+FAC14)
		case 1:
			dfdy.Put(1+3-NU, 3, -FAC14)
			dfdy.Put(2+3-NU, 3, 1.0/d.R5+1.0/d.R6+(1.0-d.ALPHA)*FAC14)
			dfdy.Put(3+2-NU, 2, -(1.0-d.ALPHA)*FAC14)
			dfdy.Put(2+4-NU, 4, 1.0/d.R4)
			dfdy.Put(1+5-NU, 5, -d.ALPHA*FAC27)
		case 2:
			dfdy.Put(0+6-NU, 6, d.ALPHA*FAC27)
			dfdy.Put(2+5-NU, 5, 1.0/d.R3+FAC27)
			dfdy.Put(1+6-NU, 6, -FAC27)
			dfdy.Put(2+6-NU, 6, 1.0/d.R1+1.0/d.R2+(1.0-d.ALPHA)*FAC27)
			dfdy.Put(3+5-NU, 5, -(1.0-d.ALPHA)*FAC27)
			dfdy.Put(2+7-NU, 7, 1.0/d.R0)
		}
		return nil
	}

	// MATRIX "M"
	c1, c2, c3, c4, c5 := 1.0e-6, 2.0e-6, 3.0e-6, 4.0e-6, 5.0e-6
	var M la.Triplet
	M.Init(8, 8, 14)
	M.Start()
	NU := 1
	switch mpi.Rank() {
	case 0:
		M.Put(1+0-NU, 0, -c5)
		M.Put(0+1-NU, 1, c5)
		M.Put(2+0-NU, 0, c5)
		M.Put(1+1-NU, 1, -c5)
		M.Put(1+2-NU, 2, -c4)
		M.Put(1+3-NU, 3, -c3)
	case 1:
		M.Put(0+4-NU, 4, c3)
		M.Put(2+3-NU, 3, c3)
		M.Put(1+4-NU, 4, -c3)
	case 2:
		M.Put(1+5-NU, 5, -c2)
		M.Put(1+6-NU, 6, -c1)
		M.Put(0+7-NU, 7, c1)
		M.Put(2+6-NU, 6, c1)
		M.Put(1+7-NU, 7, -c1)
	}

	// WRITE FILE FUNCTION
	idxstp := 1
	var b bytes.Buffer
	out := func(first bool, dx, x float64, y []float64, args ...interface{}) error {
		if mpi.Rank() == 0 {
			if first {
				fmt.Fprintf(&b, "%6s%23s%23s%23s%23s%23s%23s%23s%23s%23s\n", "ns", "x", "y0", "y1", "y2", "y3", "y4", "y5", "y6", "y7")
			}
			fmt.Fprintf(&b, "%6d%23.15E", idxstp, x)
			for j := 0; j < len(y); j++ {
				fmt.Fprintf(&b, "%23.15E", y[j])
			}
			fmt.Fprintf(&b, "\n")
			idxstp += 1
		}
		return nil
	}
	defer func() {
		if mpi.Rank() == 0 {
			io.WriteFileD("/tmp/gosl", "hwamplifierB.res", &b)
		}
	}()

	// INITIAL DATA
	D, xa, xb, ya := HWtransIni()

	// SET ODE SOLVER
	silent := false
	fixstp := false
	//method := "Dopri5"
	method := "Radau5"
	ndim := len(ya)
	//numjac := true
	numjac := false
	var osol ode.ODE

	osol.Pll = true

	if numjac {
		osol.Init(method, ndim, fcn, nil, &M, out, silent)
	} else {
		osol.Init(method, ndim, fcn, jac, &M, out, silent)
	}
	osol.IniH = 1.0e-6 // initial step size

	// SET TOLERANCES
	atol, rtol := 1e-11, 1e-5
	osol.SetTol(atol, rtol)

	// RUN
	t0 := time.Now()
	if fixstp {
		osol.Solve(ya, xa, xb, 0.01, fixstp, &D)
	} else {
		osol.Solve(ya, xa, xb, xb-xa, fixstp, &D)
	}
	if mpi.Rank() == 0 {
		io.Pfmag("elapsed time = %v\n", time.Now().Sub(t0))
	}
}
예제 #6
0
파일: auxiliary.go 프로젝트: yunpeng1/gosl
// work/correctness analysis
func WcAnalysis(dirout, fnkey, method string, fcn Cb_fcn, jac Cb_jac, M *la.Triplet, ycfcn Cb_ycorr, ya []float64, xa, xb float64,
	orders []float64, show bool) {

	// structure holding error data
	type RmsErr struct {
		value float64
		count int
	}

	// output function => calculate error indicator
	ndim := len(ya)
	yc := make([]float64, ndim)
	out := func(first bool, dx, x float64, y []float64, args ...interface{}) error {
		ycfcn(yc, x)
		for i := 0; i < ndim; i++ {
			args[0].(*RmsErr).value += math.Pow(math.Abs(y[i]-yc[i])/(1.0+y[i]), 2.0)
		}
		args[0].(*RmsErr).count += 1
		return nil
	}

	// initialise ode
	var o Solver
	o.Init(method, ndim, fcn, jac, M, out, true)
	o.PredCtrl = true

	// for python script
	var b0, b1, b2, b3 bytes.Buffer
	io.Ff(&b0, "from gosl import *\n")
	io.Ff(&b0, "tols = array([")
	io.Ff(&b1, "errs = array([")
	io.Ff(&b2, "nfev = array([")

	// run for a number of tolerances
	nt := 13
	tols := make([]float64, nt)
	for i := 1; i < nt+1; i++ {
		tols[i-1] = math.Pow(10.0, -float64(i))
	}
	io.Pf("tols = %v\n", tols)
	y := make([]float64, ndim)
	for i, tol := range tols {

		// set tolerances
		o.Atol, o.Rtol = tol, tol
		//o.Atol, o.Rtol = 1.0e-9, tol
		o.NmaxSS = 10000

		// run
		copy(y, ya)
		var re RmsErr
		o.Solve(y, xa, xb, xb-xa, false, &re)
		re.value = math.Sqrt(re.value / float64(re.count))
		io.Pf("tol = %e  =>  err = %e  =>  feval = %d\n", tol, re.value, o.nfeval)

		// python script
		if i == len(tols)-1 {
			io.Ff(&b0, "%g", tol)
			io.Ff(&b1, "%g", re.value)
			io.Ff(&b2, "%d", o.nfeval)
		} else {
			io.Ff(&b0, "%g,", tol)
			io.Ff(&b1, "%g,", re.value)
			io.Ff(&b2, "%d,", o.nfeval)
		}
	}
	io.Ff(&b0, "])\n")
	io.Ff(&b1, "])\n")
	io.Ff(&b2, "], dtype=float)\n")

	// python script
	io.Ff(&b3, "X, Y = -log10(errs), log10(nfev)\n")
	io.Ff(&b3, "plot(X, Y, clip_on=0)\n")
	if len(orders) > 0 {
		io.Ff(&b3, "dX = X[-1] - X[0]\n")
	}
	for _, ord := range orders {
		io.Ff(&b3, "plot([X[0], X[0]+dX], [Y[0], Y[0] + dX/float(%g)], 'k--', clip_on=0)\n", ord)
	}
	io.Ff(&b3, "Gll('correctness = -log10(error)', 'work = log10(nfev)', leg=0)\n")
	io.Ff(&b3, "show()\n")

	// write file
	fnpath := io.Sf("%s/%s_wc.py", dirout, fnkey)
	io.WriteFileD(dirout, fnkey+"_wc.py", &b0, &b1, &b2, &b3)

	// run script
	if show {
		_, err := exec.Command("python", fnpath).Output()
		if err != nil {
			chk.Panic("failed when calling python %s\n%v", fnpath, err)
		}
	}
}
예제 #7
0
파일: report.go 프로젝트: cpmech/goga
// Generate generates report
func (o *TexReport) Generate() {

	// functions
	o.col4 = "error"
	o.col5 = io.Sf("histogram ($N_{samples}=%d$)", o.nsamples)
	addHeader := o.normalTableHeader
	addRow := o.oneNormalAddRow
	switch o.Type {
	case 1:
		o.col4 = "objective"
	case 2:
		o.col5 = "spread"
		addRow = o.twoAddRow
	case 3:
		addRow = o.multiAddRow
	case 4:
		addHeader = o.compactTableHeader
		addRow = o.oneCompactAddRow
	}

	// number of rows per table
	nRowPerTab := o.NRowPerTab
	if nRowPerTab < 1 {
		nRowPerTab = len(o.Opts)
	}
	if o.RefLabel == "" {
		o.RefLabel = o.Fnkey
	}

	// input and xres tables
	o.inputHeader()
	o.xResHeader()

	// add rows
	idxtab := 0
	contd := ""
	for i, opt := range o.Opts {
		if i%nRowPerTab == 0 {
			if i > 0 {
				o.tableFooter(idxtab) // end previous table
				io.Ff(o.buf, "\n\n\n")
				contd = " (contd.)"
				idxtab++
			}
			addHeader(contd) // begin new table
		} else {
			if i > 0 {
				if o.Type != 4 {
					io.Ff(o.buf, "\\hline\n")
				}
				//io.Ff(o.bxres, "\n\\hline\n")
				io.Ff(o.buf, "\n")
			}
		}
		addRow(opt)
		o.inputRow(opt)
		o.xResRow(opt)
	}

	// close tables
	o.inputFooter()
	io.Ff(o.binp, "\n\n\n")
	o.xResFooter()
	o.tableFooter(idxtab) // end previous table
	io.Ff(o.buf, "\n\n\n")

	// write table
	tex := o.Fnkey + ".tex"
	io.WriteFileVD(o.DirOut, tex, o.buf, o.binp, o.bxres)

	// generate PDF
	if o.RunPDF {
		header := new(bytes.Buffer)
		footer := new(bytes.Buffer)
		str := ""
		if o.UseGeom {
			str = `\usepackage[margin=1.5cm,footskip=0.5cm]{geometry}`
		}
		io.Ff(header, `\documentclass[a4paper]{article}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{booktabs}
%s

\title{GOGA Report}
\author{Dorival Pedroso}

\begin{document}
`, str)
		io.Ff(footer, `
\end{document}`)

		// write temporary TeX file
		tex = "tmp_" + tex
		io.WriteFileD(o.DirOut, tex, header, o.buf, o.binp, o.bxres, footer)

		// run pdflatex
		_, err := io.RunCmd(false, "pdflatex", "-interaction=batchmode", "-halt-on-error", "-output-directory="+o.DirOut, tex)
		if err != nil {
			io.PfRed("pdflatex failed: %v\n", err)
			return
		}
		io.PfBlue("file <%s/tmp_%s.pdf> generated\n", o.DirOut, o.Fnkey)
	}
}
예제 #8
0
// plot results corresponding to one run
func Plot(dirout, fnkey, method string, bres *bytes.Buffer, ycps []int, ndim int, ycfcn Cb_ycorr, xa, xb float64,
	withdx, show bool, extra string) {

	// save file with results
	os.MkdirAll(dirout, 0777)
	if bres != nil {
		io.WriteFileD(dirout, fnkey+".res", bres)
	}

	// new python script
	var b bytes.Buffer
	fmt.Fprintf(&b, "from gosl import *\n")
	fmt.Fprintf(&b, "d = Read('%s/%s.res')\n", dirout, fnkey)

	// closed-form solution
	var xc []float64
	if ycfcn != nil {
		np := 101
		dx := (xb - xa) / float64(np-1)
		fmt.Fprintf(&b, "yc = array([\n")
		xc = make([]float64, np)
		yc := make([]float64, ndim)
		for i := 0; i < np; i++ {
			xc[i] = xa + dx*float64(i)
			ycfcn(yc, xc[i])
			fmt.Fprintf(&b, "[")
			for j := 0; j < ndim; j++ {
				if j == ndim-1 {
					fmt.Fprintf(&b, "%g", yc[j])
				} else {
					fmt.Fprintf(&b, "%g,", yc[j])
				}
			}
			if i == np-1 {
				fmt.Fprintf(&b, "]")
			} else {
				fmt.Fprintf(&b, "],\n")
			}
		}
		fmt.Fprintf(&b, "])\n")
		fmt.Fprintf(&b, "xc = array([")
		for i := 0; i < np; i++ {
			if i == np-1 {
				fmt.Fprintf(&b, "%g", xc[i])
			} else {
				fmt.Fprintf(&b, "%g,", xc[i])
			}
		}
		fmt.Fprintf(&b, "])\n")
	}

	// number of subplots
	nplt := len(ycps)
	if withdx {
		nplt += 1
	}

	// plot
	for i, cp := range ycps {
		fmt.Fprintf(&b, "subplot(%d,1,%d)\n", nplt, i+1)
		if ycfcn != nil {
			fmt.Fprintf(&b, "plot(xc, yc[:,%d], 'y-', lw=6, clip_on=0, label='solution')\n", cp)
		}
		fmt.Fprintf(&b, "plot(d['x'], d['y%d'], 'b-', marker='.', lw=1, clip_on=0, label='%s')\n", cp, method)
		fmt.Fprintf(&b, "Gll('x', 'y%d')\n", cp)
	}
	if withdx {
		fmt.Fprintf(&b, "subplot(%d,1,%d)\n", nplt, len(ycps)+1)
		fmt.Fprintf(&b, "plot(d['x'], d['dx'], 'b-', marker='.', lw=1, clip_on=0, label='%s')\n", method)
		fmt.Fprintf(&b, "gca().set_yscale('log')\n")
		fmt.Fprintf(&b, "Gll('x', 'step size')\n")
	}
	fmt.Fprintf(&b, extra)
	fmt.Fprintf(&b, "show()\n")

	// write file
	fn := fmt.Sprintf("%s/%s.py", dirout, fnkey)
	io.WriteFile(fn, &b)

	// run script
	if show {
		_, err := exec.Command("python", fn).Output()
		if err != nil {
			chk.Panic("failed when calling python %s\n%v", fn, err)
		}
	}
}