libridc-0.2
implicit.h
Go to the documentation of this file.
1 #include "ridc.h"
2 #include <stdio.h>
3 #include "mkl.h" // MKL Standard Lib
4 #include "mkl_lapacke.h" // MKL LAPACK
5 
6 #ifndef _IMPLICIT_H_
7 #define _IMPLICIT_H_
8 
9 using namespace std;
10 
11 class ImplicitMKL : public ODE {
12 public:
13  ImplicitMKL(int my_neq, int my_nt, double my_ti, double my_tf, double my_dt) {
14  neq = my_neq;
15  nt = my_nt;
16  ti = my_ti;
17  tf = my_tf;
18  dt = my_dt;
19  }
20 
21  void rhs(double t, double *u, double *f) {
28  for (int i =0; i<neq; i++) {
29  f[i]=-(i+1)*t*u[i];
30  }
31  }
32 
33  void step(double t, double * u, double * unew) {
41  double tnew = t + dt;
42 
43  double NEWTON_TOL = 1.0e-14;
44  int NEWTON_MAXSTEP = 1000;
45 
46  double * J;
47  double * stepsize;
48  double * uguess;
49 
50  stepsize = new double[neq];
51  uguess = new double[neq];
52 
53  J = new double[neq*neq];
54 
55  // set initial condition
56  for (int i=0; i<neq; i++) {
57  uguess[i] = u[i];
58  }
59 
60  double maxstepsize;
61 
62  int counter=0;
63  int * pivot = new int[neq];
64 
65  while (1) {
66 
67  // create rhs
68  newt(tnew,u,uguess,stepsize);
69 
70  // compute numerical Jacobian
71  jac(tnew,uguess,J);
72 
73  // blas linear solve
74  LAPACKE_dgesv(LAPACK_ROW_MAJOR, (lapack_int) neq,
75  (lapack_int) 1, J, neq,pivot,stepsize,1);
76 
77  // check for convergence
78  maxstepsize = 0.0;
79  for (int i = 0; i<neq; i++) {
80  uguess[i] = uguess[i] - stepsize[i];
81  if (std::abs(stepsize[i])>maxstepsize) {
82  maxstepsize = std::abs(stepsize[i]);
83  }
84  }
85 
86  // if update sufficiently small enough
87  if ( maxstepsize < NEWTON_TOL) {
88  break;
89  }
90 
91  counter++;
92  //error if too many steps
93  if (counter > NEWTON_MAXSTEP) {
94  fprintf(stderr,"max Newton iterations reached\n");
95  exit(42);
96  }
97  } // end Newton iteration
98 
99  for (int i=0; i<neq; i++) {
100  unew[i] = uguess[i];
101  }
102 
103  delete [] pivot;
104  delete [] uguess;
105  delete [] stepsize;
106  delete [] J;
107 
108  }
109 
110  private:
111  void newt(double t, double *uprev, double *uguess,
112  double *g){
122  rhs(t,uguess,g);
123  for (int i =0; i<neq; i++) {
124  g[i] = uguess[i]-uprev[i]-dt*g[i];
125  }
126  }
127 
128  void jac(double t, double *u, double *J){
138  double d = 1e-5; // numerical Jacobian approximation
139  double *u1;
140  double *f1;
141  double *f;
142 
143 
144  // need to allocate memory
145  u1 = new double[neq];
146  f1 = new double[neq];
147  f = new double[neq];
148 
149  // note, instead of using newt, use rhs for efficiency
150  rhs(t,u,f);
151 
152  for (int i = 0; i<neq; i++) {
153  for (int j = 0; j<neq; j++) {
154  u1[j] = u[j];
155  }
156  u1[i] = u1[i] + d;
157 
158  rhs(t,u1,f1);
159 
160  for (int j = 0; j<neq; j++) {
161  J[j*neq+i] = -dt*(f1[j]-f[j])/d;
162  }
163  J[i*neq+i] = 1.0+J[i*neq+i];
164  }
165 
166  // need to delete memory
167  delete [] u1;
168  delete [] f1;
169  delete [] f;
170  }
171 
172 };
173 
174 
175 
176 
177 
178 
179 #endif // _IMPLICIT_H_
ImplicitMKL(int my_neq, int my_nt, double my_ti, double my_tf, double my_dt)
Definition: implicit.h:13
void newt(double t, double *uprev, double *uguess, double *g)
Definition: implicit.h:111
header file containing explanation of functions for the RIDC integrator
Definition: ridc.h:17
void rhs(double t, double *u, double *f)
Definition: implicit.h:21
void newt(double t, double *uprev, double *Kguess, double *g, PARAMETER param, BUTCHER rk)
Definition: brusselator.cpp:32
void jac(double t, double *uprev, double *Kguess, double *J, PARAMETER param, BUTCHER rk)
Definition: brusselator.cpp:70
void step(double t, double *u, double *unew)
Definition: implicit.h:33
void rhs(double t, double *u, PARAMETER param, double *f)
Definition: brusselator.cpp:9
void jac(double t, double *u, double *J)
Definition: implicit.h:128