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)) } }
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)) }
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)) } }
// 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)) }
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") } }) } }
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") }) } }
// 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") }) } }