Пример #1
0
func main() {

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

	if mpi.Rank() == 0 {
		chk.PrintTitle("Test ODE 02b")
		io.Pfcyan("Hairer-Wanner VII-p5 Eq.(1.5) Van der Pol's Equation (MPI)\n")
	}
	if mpi.Size() != 2 {
		chk.Panic(">> error: this test requires 2 MPI processors\n")
		return
	}

	eps := 1.0e-6
	w := make([]float64, 2) // workspace
	fcn := func(f []float64, x float64, y []float64, args ...interface{}) error {
		f[0], f[1] = 0, 0
		switch mpi.Rank() {
		case 0:
			f[0] = y[1]
		case 1:
			f[1] = ((1.0-y[0]*y[0])*y[1] - y[0]) / eps
		}
		// join all f
		mpi.AllReduceSum(f, w)
		return nil
	}
	jac := func(dfdy *la.Triplet, x float64, y []float64, args ...interface{}) error {
		if dfdy.Max() == 0 {
			dfdy.Init(2, 2, 4)
		}
		dfdy.Start()
		if false { // per column
			switch mpi.Rank() {
			case 0:
				dfdy.Put(0, 0, 0.0)
				dfdy.Put(1, 0, (-2.0*y[0]*y[1]-1.0)/eps)
			case 1:
				dfdy.Put(0, 1, 1.0)
				dfdy.Put(1, 1, (1.0-y[0]*y[0])/eps)
			}
		} else { // per row
			switch mpi.Rank() {
			case 0:
				dfdy.Put(0, 0, 0.0)
				dfdy.Put(0, 1, 1.0)
			case 1:
				dfdy.Put(1, 0, (-2.0*y[0]*y[1]-1.0)/eps)
				dfdy.Put(1, 1, (1.0-y[0]*y[0])/eps)
			}
		}
		return nil
	}

	// data
	silent := false
	fixstp := false
	//method := "Dopri5"
	method := "Radau5"
	xa, xb := 0.0, 2.0
	ya := []float64{2.0, -0.6}
	ndim := len(ya)

	// output
	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, "%23s %23s %23s %23s\n", "dx", "x", "y0", "y1")
			}
			fmt.Fprintf(&b, "%23.15E %23.15E %23.15E %23.15E\n", dx, x, y[0], y[1])
		}
		return nil
	}
	defer func() {
		if mpi.Rank() == 0 {
			extra := "d2 = Read('data/vdpol_radau5_for.dat')\n" +
				"subplot(3,1,1)\n" +
				"plot(d2['x'],d2['y0'],'k+',label='res',ms=10)\n" +
				"subplot(3,1,2)\n" +
				"plot(d2['x'],d2['y1'],'k+',label='res',ms=10)\n"
			ode.Plot("/tmp/gosl", "vdpolB", method, &b, []int{0, 1}, ndim, nil, xa, xb, true, false, extra)
		}
	}()

	// one run
	var o ode.ODE
	o.Distr = true
	//numjac := true
	numjac := false
	if numjac {
		o.Init(method, ndim, fcn, nil, nil, out, silent)
	} else {
		o.Init(method, ndim, fcn, jac, nil, out, silent)
	}

	// tolerances and initial step size
	rtol := 1e-4
	atol := rtol
	o.SetTol(atol, rtol)
	o.IniH = 1.0e-4

	//o.NmaxSS = 2

	y := make([]float64, ndim)
	copy(y, ya)
	t0 := time.Now()
	if fixstp {
		o.Solve(y, xa, xb, 0.05, fixstp)
	} else {
		o.Solve(y, xa, xb, xb-xa, fixstp)
	}
	if mpi.Rank() == 0 {
		io.Pfmag("elapsed time = %v\n", time.Now().Sub(t0))
	}
}
Пример #2
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))
}
Пример #3
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))
	}
}
Пример #4
0
// Hairer-Wanner VII-p5 Eq.(1.5) Van der Pol's Equation
func TestODE02a(tst *testing.T) {

	//verbose()
	chk.PrintTitle("Test ODE 02a")
	io.Pfcyan("Hairer-Wanner VII-p5 Eq.(1.5) Van der Pol's Equation\n")

	eps := 1.0e-6
	fcn := func(f []float64, x float64, y []float64, args ...interface{}) error {
		f[0] = y[1]
		f[1] = ((1.0-y[0]*y[0])*y[1] - y[0]) / eps
		return nil
	}
	jac := func(dfdy *la.Triplet, x float64, y []float64, args ...interface{}) error {
		if dfdy.Max() == 0 {
			dfdy.Init(2, 2, 4)
		}
		dfdy.Start()
		dfdy.Put(0, 0, 0.0)
		dfdy.Put(0, 1, 1.0)
		dfdy.Put(1, 0, (-2.0*y[0]*y[1]-1.0)/eps)
		dfdy.Put(1, 1, (1.0-y[0]*y[0])/eps)
		return nil
	}

	// data
	silent := false
	fixstp := false
	//method := "Dopri5"
	method := "Radau5"
	xa, xb := 0.0, 2.0
	ya := []float64{2.0, -0.6}
	ndim := len(ya)

	// output
	var b bytes.Buffer
	out := func(first bool, dx, x float64, y []float64, args ...interface{}) error {
		if first {
			fmt.Fprintf(&b, "%23s %23s %23s %23s\n", "dx", "x", "y0", "y1")
		}
		fmt.Fprintf(&b, "%23.15E %23.15E %23.15E %23.15E\n", dx, x, y[0], y[1])
		return nil
	}
	defer func() {
		extra := "d2 = Read('data/vdpol_radau5_for.dat')\n" +
			"subplot(3,1,1)\n" +
			"plot(d2['x'],d2['y0'],'k+',label='res',ms=10)\n" +
			"subplot(3,1,2)\n" +
			"plot(d2['x'],d2['y1'],'k+',label='res',ms=10)\n"
		Plot("/tmp/gosl", "vdpolA", method, &b, []int{0, 1}, ndim, nil, xa, xb, true, false, extra)
	}()

	// one run
	var o ODE
	numjac := true
	if numjac {
		o.Init(method, ndim, fcn, nil, nil, out, silent)
	} else {
		o.Init(method, ndim, fcn, jac, nil, out, silent)
	}

	// tolerances and initial step size
	rtol := 1e-4
	atol := rtol
	o.SetTol(atol, rtol)
	o.IniH = 1.0e-4

	//o.NmaxSS = 2

	y := make([]float64, ndim)
	copy(y, ya)
	t0 := time.Now()
	if fixstp {
		o.Solve(y, xa, xb, 0.05, fixstp)
	} else {
		o.Solve(y, xa, xb, xb-xa, fixstp)
	}
	io.Pfmag("elapsed time = %v\n", time.Now().Sub(t0))
}
Пример #5
0
func main() {

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

	if mpi.Rank() == 0 {
		chk.PrintTitle("ode04: Hairer-Wanner VII-p376 Transistor Amplifier\n")
	}
	if mpi.Size() != 3 {
		chk.Panic(">> error: this test requires 3 MPI processors\n")
		return
	}

	// data
	UE, UB, UF, ALPHA, BETA := 0.1, 6.0, 0.026, 0.99, 1.0e-6
	R0, R1, R2, R3, R4, R5 := 1000.0, 9000.0, 9000.0, 9000.0, 9000.0, 9000.0
	R6, R7, R8, R9 := 9000.0, 9000.0, 9000.0, 9000.0
	W := 2.0 * 3.141592654 * 100.0

	// initial values
	xa := 0.0
	ya := []float64{0.0,
		UB,
		UB / (R6/R5 + 1.0),
		UB / (R6/R5 + 1.0),
		UB,
		UB / (R2/R1 + 1.0),
		UB / (R2/R1 + 1.0),
		0.0}

	// endpoint of integration
	xb := 0.05
	//xb = 0.0123 // OK
	//xb = 0.01235 // !OK

	// right-hand side of the amplifier problem
	w := make([]float64, 8) // workspace
	fcn := func(f []float64, dx, x float64, y []float64, args ...interface{}) error {
		UET := UE * math.Sin(W*x)
		FAC1 := BETA * (math.Exp((y[3]-y[2])/UF) - 1.0)
		FAC2 := BETA * (math.Exp((y[6]-y[5])/UF) - 1.0)
		la.VecFill(f, 0)
		switch mpi.Rank() {
		case 0:
			f[0] = y[0] / R9
		case 1:
			f[1] = (y[1]-UB)/R8 + ALPHA*FAC1
			f[2] = y[2]/R7 - FAC1
		case 2:
			f[3] = y[3]/R5 + (y[3]-UB)/R6 + (1.0-ALPHA)*FAC1
			f[4] = (y[4]-UB)/R4 + ALPHA*FAC2
			f[5] = y[5]/R3 - FAC2
			f[6] = y[6]/R1 + (y[6]-UB)/R2 + (1.0-ALPHA)*FAC2
			f[7] = (y[7] - UET) / R0
		}
		mpi.AllReduceSum(f, w)
		return nil
	}

	// Jacobian of the amplifier problem
	jac := func(dfdy *la.Triplet, dx, x float64, y []float64, args ...interface{}) error {
		FAC14 := BETA * math.Exp((y[3]-y[2])/UF) / UF
		FAC27 := BETA * math.Exp((y[6]-y[5])/UF) / 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/R9)
			dfdy.Put(2+1-NU, 1, 1.0/R8)
			dfdy.Put(1+2-NU, 2, -ALPHA*FAC14)
			dfdy.Put(0+3-NU, 3, ALPHA*FAC14)
			dfdy.Put(2+2-NU, 2, 1.0/R7+FAC14)
		case 1:
			dfdy.Put(1+3-NU, 3, -FAC14)
			dfdy.Put(2+3-NU, 3, 1.0/R5+1.0/R6+(1.0-ALPHA)*FAC14)
			dfdy.Put(3+2-NU, 2, -(1.0-ALPHA)*FAC14)
			dfdy.Put(2+4-NU, 4, 1.0/R4)
			dfdy.Put(1+5-NU, 5, -ALPHA*FAC27)
		case 2:
			dfdy.Put(0+6-NU, 6, ALPHA*FAC27)
			dfdy.Put(2+5-NU, 5, 1.0/R3+FAC27)
			dfdy.Put(1+6-NU, 6, -FAC27)
			dfdy.Put(2+6-NU, 6, 1.0/R1+1.0/R2+(1.0-ALPHA)*FAC27)
			dfdy.Put(3+5-NU, 5, -(1.0-ALPHA)*FAC27)
			dfdy.Put(2+7-NU, 7, 1.0/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)
	}

	// flags
	silent := false
	fixstp := false
	//method := "Dopri5"
	method := "Radau5"
	ndim := len(ya)
	numjac := false

	// structure to hold numerical results
	res := ode.Results{Method: method}

	// ODE solver
	var osol ode.Solver
	osol.Pll = true

	// solve problem
	if numjac {
		osol.Init(method, ndim, fcn, nil, &M, ode.SimpleOutput, silent)
	} else {
		osol.Init(method, ndim, fcn, jac, &M, ode.SimpleOutput, 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, &res)
	} else {
		osol.Solve(ya, xa, xb, xb-xa, fixstp, &res)
	}

	// plot
	if mpi.Rank() == 0 {
		io.Pfmag("elapsed time = %v\n", time.Now().Sub(t0))
		plt.SetForEps(2.0, 400)
		args := "'b-', marker='.', lw=1, clip_on=0"
		ode.Plot("/tmp/gosl/ode", "hwamplifier_mpi.eps", &res, nil, xa, xb, "", args, func() {
			_, T, err := io.ReadTable("data/radau5_hwamplifier.dat")
			if err != nil {
				chk.Panic("%v", err)
			}
			for j := 0; j < ndim; j++ {
				plt.Subplot(ndim+1, 1, j+1)
				plt.Plot(T["x"], T[io.Sf("y%d", j)], "'k+',label='reference',ms=10")
			}
		})
	}
}
Пример #6
0
func main() {

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

	if mpi.Rank() == 0 {
		chk.PrintTitle("ode02: Hairer-Wanner VII-p5 Eq.(1.5) Van der Pol's Equation")
	}
	if mpi.Size() != 2 {
		chk.Panic(">> error: this test requires 2 MPI processors\n")
		return
	}

	eps := 1.0e-6
	w := make([]float64, 2) // workspace
	fcn := func(f []float64, dx, x float64, y []float64, args ...interface{}) error {
		f[0], f[1] = 0, 0
		switch mpi.Rank() {
		case 0:
			f[0] = y[1]
		case 1:
			f[1] = ((1.0-y[0]*y[0])*y[1] - y[0]) / eps
		}
		// join all f
		mpi.AllReduceSum(f, w)
		return nil
	}
	jac := func(dfdy *la.Triplet, dx, x float64, y []float64, args ...interface{}) error {
		if dfdy.Max() == 0 {
			dfdy.Init(2, 2, 4)
		}
		dfdy.Start()
		if false { // per column
			switch mpi.Rank() {
			case 0:
				dfdy.Put(0, 0, 0.0)
				dfdy.Put(1, 0, (-2.0*y[0]*y[1]-1.0)/eps)
			case 1:
				dfdy.Put(0, 1, 1.0)
				dfdy.Put(1, 1, (1.0-y[0]*y[0])/eps)
			}
		} else { // per row
			switch mpi.Rank() {
			case 0:
				dfdy.Put(0, 0, 0.0)
				dfdy.Put(0, 1, 1.0)
			case 1:
				dfdy.Put(1, 0, (-2.0*y[0]*y[1]-1.0)/eps)
				dfdy.Put(1, 1, (1.0-y[0]*y[0])/eps)
			}
		}
		return nil
	}

	// method and flags
	silent := false
	fixstp := false
	//method := "Dopri5"
	method := "Radau5"
	numjac := false
	xa, xb := 0.0, 2.0
	ya := []float64{2.0, -0.6}
	ndim := len(ya)

	// structure to hold numerical results
	res := ode.Results{Method: method}

	// allocate ODE object
	var o ode.Solver
	o.Distr = true
	if numjac {
		o.Init(method, ndim, fcn, nil, nil, ode.SimpleOutput, silent)
	} else {
		o.Init(method, ndim, fcn, jac, nil, ode.SimpleOutput, silent)
	}

	// tolerances and initial step size
	rtol := 1e-4
	atol := rtol
	o.IniH = 1.0e-4
	o.SetTol(atol, rtol)
	//o.NmaxSS = 2

	// solve problem
	y := make([]float64, ndim)
	copy(y, ya)
	t0 := time.Now()
	if fixstp {
		o.Solve(y, xa, xb, 0.05, fixstp, &res)
	} else {
		o.Solve(y, xa, xb, xb-xa, fixstp, &res)
	}

	// plot
	if mpi.Rank() == 0 {
		io.Pfmag("elapsed time = %v\n", time.Now().Sub(t0))
		plt.SetForEps(1.5, 400)
		args := "'b-', marker='.', lw=1, ms=4, clip_on=0"
		ode.Plot("/tmp/gosl/ode", "vdpolA_mpi.eps", &res, nil, xa, xb, "", args, func() {
			_, T, err := io.ReadTable("data/vdpol_radau5_for.dat")
			if err != nil {
				chk.Panic("%v", err)
			}
			plt.Subplot(3, 1, 1)
			plt.Plot(T["x"], T["y0"], "'k+',label='reference',ms=7")
			plt.Subplot(3, 1, 2)
			plt.Plot(T["x"], T["y1"], "'k+',label='reference',ms=7")
		})
	}
}
Пример #7
0
// Hairer-Wanner VII-p5 Eq.(1.5) Van der Pol's Equation
func Test_ode02(tst *testing.T) {

	//verbose()
	chk.PrintTitle("ode02: Hairer-Wanner VII-p5 Eq.(1.5) Van der Pol's Equation")

	// problem definition
	eps := 1.0e-6
	fcn := func(f []float64, dx, x float64, y []float64, args ...interface{}) error {
		f[0] = y[1]
		f[1] = ((1.0-y[0]*y[0])*y[1] - y[0]) / eps
		return nil
	}
	jac := func(dfdy *la.Triplet, dx, x float64, y []float64, args ...interface{}) error {
		if dfdy.Max() == 0 {
			dfdy.Init(2, 2, 4)
		}
		dfdy.Start()
		dfdy.Put(0, 0, 0.0)
		dfdy.Put(0, 1, 1.0)
		dfdy.Put(1, 0, (-2.0*y[0]*y[1]-1.0)/eps)
		dfdy.Put(1, 1, (1.0-y[0]*y[0])/eps)
		return nil
	}

	// method and flags
	silent := false
	fixstp := false
	//method := "Dopri5"
	method := "Radau5"
	numjac := false
	xa, xb := 0.0, 2.0
	ya := []float64{2.0, -0.6}
	ndim := len(ya)

	// structure to hold numerical results
	res := Results{Method: method}

	// allocate ODE object
	var o Solver
	if numjac {
		o.Init(method, ndim, fcn, nil, nil, SimpleOutput, silent)
	} else {
		o.Init(method, ndim, fcn, jac, nil, SimpleOutput, silent)
	}

	// tolerances and initial step size
	rtol := 1e-4
	atol := rtol
	o.IniH = 1.0e-4
	o.SetTol(atol, rtol)
	//o.NmaxSS = 2

	// solve problem
	y := make([]float64, ndim)
	copy(y, ya)
	t0 := time.Now()
	if fixstp {
		o.Solve(y, xa, xb, 0.05, fixstp, &res)
	} else {
		o.Solve(y, xa, xb, xb-xa, fixstp, &res)
	}
	io.Pfmag("elapsed time = %v\n", time.Now().Sub(t0))

	// plot
	if chk.Verbose {
		plt.SetForEps(1.5, 400)
		args := "'b-', marker='.', lw=1, ms=4, clip_on=0"
		Plot("/tmp/gosl/ode", "vdpolA.eps", &res, nil, xa, xb, "", args, func() {
			_, T, err := io.ReadTable("data/vdpol_radau5_for.dat")
			if err != nil {
				chk.Panic("%v", err)
			}
			plt.Subplot(3, 1, 1)
			plt.Plot(T["x"], T["y0"], "'k+',label='reference',ms=7")
			plt.Subplot(3, 1, 2)
			plt.Plot(T["x"], T["y1"], "'k+',label='reference',ms=7")
		})
	}
}