Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2925_AutoDiffForDynamicalModels/AutoDiffForDynamicalModelsTest/TestCvodes.cs @ 16245

Last change on this file since 16245 was 16245, checked in by gkronber, 6 years ago

#2925 worked on integration of CVODES library

File size: 8.2 KB
Line 
1using System;
2using HeuristicLab.Problems.DynamicalSystemsModelling;
3using Microsoft.VisualStudio.TestTools.UnitTesting;
4
5namespace AutoDiffForDynamicalModelsTest {
6  [TestClass]
7  public class TestCvodes {
8    [TestMethod]
9    public unsafe void TestCvodesMethod() {
10      // test vectors
11      var arr = new double[] { 3.14, 2.71 };
12      var vec = Problem.N_VMake_Serial(2, arr);
13      Problem.N_VDestroy_Serial(vec);
14
15      vec = Problem.N_VNew_Serial(10);
16
17      unsafe {
18        int* content = (int*)*(int*)vec.ToPointer();
19        long length = *content;
20        Console.WriteLine(*content);
21        int own_data = *(content + 2);
22        Console.WriteLine(own_data);
23        double* data = (double*)*(content + 3);
24        double data0 = *data;
25      }
26      Problem.N_VConst_Serial(2.0, vec);
27      Problem.N_VPrint_Serial(vec);
28      Assert.AreEqual(20, Problem.N_VL1Norm_Serial(vec));
29      Problem.N_VDestroy_Serial(vec);
30
31
32      // linear oscillator
33      int numberOfEquations = 2;
34      var y = Problem.N_VNew_Serial(numberOfEquations);
35      // y must be initialized before calling CVodeInit
36      // Problem.N_VConst_Serial(100.0, y);
37      Problem.NV_Set_Ith_S(y, 0, 0.5); // x
38      Problem.NV_Set_Ith_S(y, 1, 1);  // v
39
40      var cvode_mem = Problem.CVodeCreate(Problem.MultistepMethod.CV_ADAMS, Problem.NonlinearSolverIteration.CV_FUNCTIONAL);
41
42      var flag = Problem.CVodeInit(cvode_mem, F, 0.0, y);
43      Assert.AreEqual(Problem.CV_SUCCESS, flag);
44
45      flag = Problem.CVodeSStolerances(cvode_mem, 1E-4, 1.0);
46      Assert.AreEqual(Problem.CV_SUCCESS, flag);
47
48      var A = Problem.SUNDenseMatrix(numberOfEquations, numberOfEquations);
49      Assert.AreNotSame(A, IntPtr.Zero);
50
51
52      var linearSolver = Problem.SUNDenseLinearSolver(y, A);
53      Assert.AreNotSame(linearSolver, IntPtr.Zero);
54
55      flag = Problem.CVDlsSetLinearSolver(cvode_mem, linearSolver, A);
56      Assert.AreEqual(Problem.CV_SUCCESS, flag);
57
58      // flag = Problem.CVDlsSetJacFn(cvode_mem, JacF);
59      // Assert.AreEqual(Problem.CV_SUCCESS, flag);
60
61      // var ns = 1; // number of parameters
62      // var p = new double[1]; // set as user-data
63      // var yS0 = Problem.N_VCloneVectorArray_Serial(ns, y); // clone the output vector for each parameter, TODO: free
64      // for(int i=0;i<ns;i++) {
65      //
66      // }
67
68
69      var q = Problem.N_VNew_Serial(1);
70      Problem.NV_Set_Ith_S(q, 0, 0.0);
71      flag = Problem.CVodeQuadInit(cvode_mem, FQ, q);
72      Assert.AreEqual(Problem.CV_SUCCESS, flag);
73
74
75      int steps = 10;
76      flag = Problem.CVodeAdjInit(cvode_mem, steps, Problem.CV_HERMITE);
77      Assert.AreEqual(Problem.CV_SUCCESS, flag);
78
79      /* step by step forward integration
80      double t = 0.0;
81      double tout = 0.1; // first output time
82      int nout = 100; // number of output times
83      for (int iout = 0; iout < nout; iout++) {
84        flag = Problem.CVode(cvode_mem, tout, y, ref t, Problem.CV_NORMAL);
85        Assert.AreEqual(Problem.CV_SUCCESS, flag);
86        Console.WriteLine("{0} {1} {2}", t, Problem.NV_Get_Ith_S(y, 0), Problem.NV_Get_Ith_S(y, 1));
87        // Problem.N_VPrint_Serial(y);
88        tout += 0.1;
89      }
90      */
91
92      // complete forward integration
93      double tout = 100.0; // last time
94      double time = 0.0;
95      int ncheck = 0; // number of checkpoints
96      flag = Problem.CVodeF(cvode_mem, tout, y, ref time, Problem.CV_NORMAL, ref ncheck);
97      Assert.AreEqual(Problem.CV_SUCCESS, flag);
98
99      long numSteps = 0;
100      flag = Problem.CVodeGetNumSteps(cvode_mem, ref numSteps);
101      Assert.AreEqual(Problem.CV_SUCCESS, flag);
102
103      var yB = Problem.N_VNew_Serial(numberOfEquations);
104      Problem.N_VConst_Serial(0.0, yB);
105
106      int numberOfParameters = 2;
107      var qB = Problem.N_VNew_Serial(numberOfParameters);
108      Problem.N_VConst_Serial(0.0, qB);
109
110      int indexB = 0;
111      flag = Problem.CVodeCreateB(cvode_mem, Problem.MultistepMethod.CV_BDF, Problem.NonlinearSolverIteration.CV_NEWTON, ref indexB);
112      Assert.AreEqual(Problem.CV_SUCCESS, flag);
113
114      var TB1 = tout;
115      flag = Problem.CVodeInitB(cvode_mem, indexB, FB, TB1, yB);
116      Assert.AreEqual(Problem.CV_SUCCESS, flag);
117
118      var relTolB = 1E-6;
119      var absTolB = 1E-8;
120      flag = Problem.CVodeSStolerancesB(cvode_mem, indexB, relTolB, absTolB);
121      Assert.AreEqual(Problem.CV_SUCCESS, flag);
122
123      var AB = Problem.SUNDenseMatrix(numberOfEquations, numberOfEquations);
124      Assert.AreNotSame(linearSolver, IntPtr.Zero);
125
126      var lsB = Problem.SUNDenseLinearSolver(yB, AB);
127      Assert.AreNotSame(linearSolver, IntPtr.Zero);
128
129      flag = Problem.CVDlsSetLinearSolverB(cvode_mem, indexB, lsB, AB);
130      Assert.AreEqual(Problem.CV_SUCCESS, flag);
131
132      flag = Problem.CVDlsSetJacFnB(cvode_mem, indexB, JacFB);
133      Assert.AreEqual(Problem.CV_SUCCESS, flag);
134
135      flag = Problem.CVodeQuadInitB(cvode_mem, indexB, FQB, qB);
136      Assert.AreEqual(Problem.CV_SUCCESS, flag);
137
138      /* First get results at t = TBout1 */
139
140      /* Call CVodeB to integrate the backward ODE problem. */
141      var tBackOut = 50.0;
142      flag = Problem.CVodeB(cvode_mem, tBackOut, Problem.CV_NORMAL);
143      Assert.AreEqual(Problem.CV_SUCCESS, flag);
144
145      /* Call CVodeGetB to get yB of the backward ODE problem. */
146      flag = Problem.CVodeGetB(cvode_mem, indexB, ref time, yB);
147      Assert.AreEqual(Problem.CV_SUCCESS, flag);
148
149      /* Call CVodeGetAdjY to get the interpolated value of the forward solution
150         y during a backward integration. */
151      flag = Problem.CVodeGetAdjY(cvode_mem, tBackOut, y);
152      Assert.AreEqual(Problem.CV_SUCCESS, flag);
153
154      /* Then at t = T0 */
155
156      double t0 = 0.0;
157      flag = Problem.CVodeB(cvode_mem, t0, Problem.CV_NORMAL);
158      Assert.AreEqual(Problem.CV_SUCCESS, flag);
159
160      long nstB = 0;
161      Problem.CVodeGetNumSteps(Problem.CVodeGetAdjCVodeBmem(cvode_mem, indexB), ref nstB);
162
163      flag = Problem.CVodeGetB(cvode_mem, indexB, ref time, yB);
164      Assert.AreEqual(Problem.CV_SUCCESS, flag);
165
166
167      flag = Problem.CVodeGetQuadB(cvode_mem, indexB, ref time, qB);
168      Assert.AreEqual(Problem.CV_SUCCESS, flag);
169
170      flag = Problem.CVodeGetAdjY(cvode_mem, t0, y);
171      Assert.AreEqual(Problem.CV_SUCCESS, flag);
172
173      Problem.N_VDestroy_Serial(y);
174      Problem.CVodeFree(cvode_mem);
175      Problem.SUNLinSolFree(linearSolver);
176      Problem.SUNMatDestroy(A);
177    }
178
179
180    private int JacF(double t, IntPtr y, IntPtr fy, IntPtr Jac, IntPtr user_data, IntPtr tmp1, IntPtr tmp2, IntPtr tmp3) {
181      throw new NotImplementedException();
182      return 0;
183    }
184
185    private int JacFB(double t, IntPtr y, IntPtr yB, IntPtr fyB, IntPtr Jac, IntPtr user_data, IntPtr tmp1, IntPtr tmp2, IntPtr tmp3) {
186      throw new NotImplementedException();
187      return 0;
188    }
189
190    public static int F(
191      double t, // realtype
192      IntPtr y, // N_Vector
193      IntPtr ydot, // N_Vector
194      IntPtr user_data) {
195
196      Problem.NV_Set_Ith_S(ydot, 0, Problem.NV_Get_Ith_S(y, 1));
197      Problem.NV_Set_Ith_S(ydot, 1, -0.3 * Problem.NV_Get_Ith_S(y, 0));
198      return 0;
199      ;
200    }
201    public static int FB(
202        double t, // realtype
203        IntPtr y, // N_Vector
204        IntPtr yB, // N_Vector
205        IntPtr yBdot, // N_Vector
206        IntPtr user_data) {
207
208      // y' = f(y,p)
209
210      // yB = λ
211      // λ' = -(∂f / ∂y)^T λ - (∂g / ∂y)
212      // the goal is to find dG/dp where G = integrate( g(y,t,p), t=0, t=T) )
213
214      // for F above:
215      // ∂f / ∂ =
216      //  0.0 1.0
217      // -0.3 0.0
218
219      // we have no g!?
220      // therefore λ' =
221      // λ1' = 0.3 λ2 - 0.0
222      // λ2' = 1.0 λ1 - 0.0
223
224      Problem.NV_Set_Ith_S(yBdot, 0, 0.3 * Problem.NV_Get_Ith_S(yB, 1));
225      Problem.NV_Set_Ith_S(yBdot, 1, Problem.NV_Get_Ith_S(yB, 0));
226
227      return 0;
228      ;
229    }
230
231    private int FQ(double t, IntPtr y, IntPtr yQdot, IntPtr user_data) {
232      // TODO: squared error
233      Problem.NV_Set_Ith_S(yQdot, 0, Problem.NV_Get_Ith_S(y, 2));
234      return 0;
235    }
236
237
238    private int FQB(double t, IntPtr y, IntPtr yB, IntPtr qBdot, IntPtr user_data) {
239      throw new NotImplementedException();
240    }
241  }
242}
Note: See TracBrowser for help on using the repository browser.