Cantera  2.0
IDA_Solver.h
Go to the documentation of this file.
1 /**
2  * @file IDA_Solver.h
3  * Header file for class IDA_Solver
4  */
5 
6 // Copyright 2006 California Institute of Technology
7 
8 #ifndef CT_IDA_SOLVER_H
9 #define CT_IDA_SOLVER_H
10 
11 #include <vector>
12 
13 #include "DAE_Solver.h"
15 
16 #if HAS_SUNDIALS
17 
18 #if SUNDIALS_VERSION == 22
19 #include "nvector_serial.h"
20 #else
21 #include "sundials/sundials_nvector.h"
22 
23 // These constants are defined internally in the ida package, ida.c
24 #define IDA_NN 0
25 #define IDA_SS 1
26 #define IDA_SV 2
27 #define IDA_WF 3
28 
29 #endif
30 #if SUNDIALS_VERSION >= 24
31 #define REAL_WORKSPACE_SIZE 0
32 #endif
33 
34 namespace Cantera
35 {
36 
37 /**
38  * Exception thrown when a IDA error is encountered.
39  */
40 class IDA_Err : public CanteraError
41 {
42 public:
43  IDA_Err(std::string msg) : CanteraError("IDA_Solver", msg) {}
44 };
45 
46 
47 class ResidData; // forward reference
48 
49 class IDA_Solver : public DAE_Solver
50 {
51 public:
52 
53  //! Constructor.
54  /*!
55  * Default settings: dense jacobian, no user-supplied Jacobian function, Newton iteration.
56  *
57  * @param f Function that will supply the time dependent residual to be solved
58  */
59  IDA_Solver(ResidJacEval& f);
60 
61  virtual ~IDA_Solver();
62 
63  /**
64  * Set error tolerances. This version specifies a scalar
65  * relative tolerance, and a vector absolute tolerance.
66  */
67  virtual void setTolerances(doublereal reltol,
68  doublereal* abstol);
69 
70  /**
71  * Set error tolerances. This version specifies a scalar
72  * relative tolerance, and a scalar absolute tolerance.
73  */
74  virtual void setTolerances(doublereal reltol, doublereal abstol);
75 
76  virtual void setLinearSolverType(int solverType);
77 
78  //! Set up the problem to use a dense linear direct solver
79  virtual void setDenseLinearSolver();
80 
81  //! Set up the problem to use a band solver
82  /*!
83  * @param m_upper upper band width of the matrix
84  * @param m_lower lower band width of the matrix
85  */
86  virtual void setBandedLinearSolver(int m_upper, int m_lower);
87 
88  virtual void setMaxOrder(int n);
89 
90  //! Set the maximum number of time steps
91  /*!
92  * @param n input of maximum number of time steps
93  */
94  virtual void setMaxNumSteps(int n);
95 
96  //! Sset the initial step size
97  /*!
98  * @param h0 initial step size value
99  */
100  virtual void setInitialStepSize(doublereal h0);
101 
102  //! Set the stop time
103  /*!
104  * @param tstop the independent variable value past which the solution is not to proceed.
105  */
106  virtual void setStopTime(doublereal tstop);
107 
108  //! Get the current step size from IDA via a call
109  /*!
110  * @return Returns the current step size.
111  */
112  virtual double getCurrentStepFromIDA();
113 
114 
115  //! Set the form of the jacobian
116  /*!
117  *
118  * @param formJac Form of the jacobian
119  *
120  * 0 numerical jacobian
121  * 1 analytical jacobian given by the evalJacobianDP() function
122  */
123  virtual void setJacobianType(int formJac);
124 
125 
126  virtual void setMaxErrTestFailures(int n);
127 
128  //! Set the maximum number of nonlinear iterations on a timestep
129  /*!
130  * @param n Set the max iterations. The default is 4, which seems awefully low to me.
131  */
132  virtual void setMaxNonlinIterations(int n);
133 
134  //! Set the maximum number of nonlinear solver convergence failures
135  /*!
136  * @param n Value of nonlin failures. If value is exceeded, the calculation terminates.
137  */
138  virtual void setMaxNonlinConvFailures(int n);
139 
140 
141  virtual void inclAlgebraicInErrorTest(bool yesno);
142 
143  /**
144  * Get the value of a solver-specific output parameter.
145  */
146  virtual doublereal getOutputParameter(int flag) const;
147 
148  //! Calculate consistent value of the starting solution given the starting solution derivatives
149  /*!
150  * This method may be called if the initial conditions do not
151  * satisfy the residual equation F = 0. Given the derivatives
152  * of all variables, this method computes the initial y
153  * values.
154  */
155  virtual void correctInitial_Y_given_Yp(doublereal* y, doublereal* yp,
156  doublereal tout);
157 
158  //! Calculate consistent value of the algebraic constraints and derivatives at the start of the problem
159  /*!
160  * This method may be called if the initial conditions do not
161  * satisfy the residual equation F = 0. Given the initial
162  * values of all differential variables, it computes the
163  * initial values of all algebraic variables and the initial
164  * derivatives of all differential variables.
165  */
166  virtual void correctInitial_YaYp_given_Yd(doublereal* y, doublereal* yp, doublereal tout);
167 
168  //! Step the system to a final value of the time
169  /*!
170  * @param tout Final value of the time
171  *
172  * @return Returns the IDASolve() return flag
173  *
174  * The return values for IDASolve are described below.
175  * (The numerical return values are defined above in this file.)
176  * All unsuccessful returns give a negative return value.
177  *
178  * IDA_SUCCESS
179  * IDASolve succeeded and no roots were found.
180  *
181  * IDA_ROOT_RETURN: IDASolve succeeded, and found one or more roots.
182  * If nrtfn > 1, call IDAGetRootInfo to see which g_i were found
183  * to have a root at (*tret).
184  *
185  * IDA_TSTOP_RETURN:
186  * IDASolve returns computed results for the independent variable
187  * value tstop. That is, tstop was reached.
188  *
189  * IDA_MEM_NULL:
190  * The IDA_mem argument was NULL.
191  *
192  * IDA_ILL_INPUT:
193  * One of the inputs to IDASolve is illegal. This includes the
194  * situation when a component of the error weight vectors
195  * becomes < 0 during internal stepping. It also includes the
196  * situation where a root of one of the root functions was found
197  * both at t0 and very near t0. The ILL_INPUT flag
198  * will also be returned if the linear solver function IDA---
199  * (called by the user after calling IDACreate) failed to set one
200  * of the linear solver-related fields in ida_mem or if the linear
201  * solver's init routine failed. In any case, the user should see
202  * the printed error message for more details.
203  *
204  *
205  * IDA_TOO_MUCH_WORK:
206  * The solver took mxstep internal steps but could not reach tout.
207  * The default value for mxstep is MXSTEP_DEFAULT = 500.
208  *
209  * IDA_TOO_MUCH_ACC:
210  * The solver could not satisfy the accuracy demanded by the user
211  * for some internal step.
212  *
213  * IDA_ERR_FAIL:
214  * Error test failures occurred too many times (=MXETF = 10) during
215  * one internal step.
216  *
217  * IDA_CONV_FAIL:
218  * Convergence test failures occurred too many times (= MXNCF = 10)
219  * during one internal step.
220  *
221  * IDA_LSETUP_FAIL:
222  * The linear solver's setup routine failed
223  * in an unrecoverable manner.
224  *
225  * IDA_LSOLVE_FAIL:
226  * The linear solver's solve routine failed
227  * in an unrecoverable manner.
228  *
229  * IDA_CONSTR_FAIL:
230  * The inequality constraints were violated,
231  * and the solver was unable to recover.
232  *
233  * IDA_REP_RES_ERR:
234  * The user's residual function repeatedly returned a recoverable
235  * error flag, but the solver was unable to recover.
236  *
237  * IDA_RES_FAIL:
238  * The user's residual function returned a nonrecoverable error
239  * flag.
240  *
241  */
242  virtual int solve(doublereal tout);
243 
244  virtual doublereal step(doublereal tout);
245 
246  virtual void init(doublereal t0);
247 
248  //! the current value of solution component k.
249  /*!
250  * @param k index of the solution
251  */
252  virtual doublereal solution(int k) const;
253 
254  virtual const doublereal* solutionVector() const;
255 
256  //! the current value of the derivative of solution component k.
257  virtual doublereal derivative(int k) const;
258 
259  virtual const doublereal* derivativeVector() const;
260 
261  void* IDAMemory() {
262  return m_ida_mem;
263  }
264 
265 protected:
266 
267  //! Pointer to the IDA memory for the problem
268  void* m_ida_mem;
269 
270  //! Initial value of the time
271  doublereal m_t0;
272 
273  //! Current value of the solution vector
274  void* m_y;
275 
276  //! Current value of the derivative of the solution vector
277  void* m_ydot;
278  void* m_id;
279  void* m_constraints;
280  void* m_abstol;
281  int m_type;
282 
283 
284  int m_itol;
285  int m_iter;
286  doublereal m_reltol;
287  doublereal m_abstols;
288  int m_nabs;
289 
290  //! Maximum value of the timestep allowed
291  doublereal m_hmax;
292 
293  //! Minimum value of the timestep allowd
294  doublereal m_hmin;
295 
296  //! Value of the initial time step
297  doublereal m_h0;
298 
299  //! Maximum number of time steps allowed
300  int m_maxsteps;
301 
302  //! maximum time step order of the method
303  int m_maxord;
304 
305  //! Form of the jacobian
306  /*!
307  * 0 numerical jacobian created by ida
308  * 1 analytical jacobian. Must have populated the evalJacobianDP()
309  * function in the ResidJacEval class.
310  * 2 numerical jacobian formed by the ResidJacEval class (unimplemented)
311  */
312  int m_formJac;
313 
314  //! maximum time
315  doublereal m_tstop;
316 
317  //! Value of the previous, previous time
318  doublereal m_told_old;
319 
320  //! Value of the previous time
321  doublereal m_told;
322 
323  //! Value of the current time
324  doublereal m_tcurrent;
325 
326  //! Value of deltaT for the current step
327  doublereal m_deltat;
328 
329  //! maximum number of error test failures
330  int m_maxErrTestFails;
331 
332  //! Maximum number of nonlinear solver iterations at one solution
333  /*!
334  * If zero, this is the default of 4.
335  */
336  int m_maxNonlinIters;
337 
338  //! Maximum number of nonlinear convergence failures
339  int m_maxNonlinConvFails;
340 
341  //! If true, the algebraic variables don't contribute to error tolerances
342  int m_setSuppressAlg;
343 
344  ResidData* m_fdata;
345  int m_mupper;
346  int m_mlower;
347 };
348 
349 }
350 
351 #endif
352 #endif
353