Cantera  2.0
ResidJacEval.cpp
Go to the documentation of this file.
1 /**
2  * @file ResidJacEval.cpp
3  */
4 
5 /*
6  * Copyright 2004 Sandia Corporation. Under the terms of Contract
7  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
8  * retains certain rights in this software.
9  * See file License.txt for licensing information.
10  */
11 
12 #include "cantera/base/ct_defs.h"
15 
16 #include <iostream>
17 #include <vector>
18 
19 using namespace std;
20 
21 namespace Cantera
22 {
23 //====================================================================================================================
24 
25 ResidJacEval::ResidJacEval(doublereal atol) :
26  ResidEval(),
27  m_atol(atol)
28 {
29 }
30 //====================================================================================================================
31 // Copy Constructor for the %ResidJacEval object
32 /*
33  */
35  ResidEval()
36 {
37  *this = operator=(right);
38 }
39 //====================================================================================================================
41 {
42 }
43 //====================================================================================================================
45 {
46  if (this == &right) {
47  return *this;
48  }
49 
50  ResidEval::operator=(right);
51 
52  m_atol = right.m_atol;
53  neq_ = right.neq_;
54 
55  return *this;
56 }
57 //====================================================================================================================
58 // Duplication routine for objects which inherit from %ResidJacEval
59 /*
60  * This virtual routine can be used to duplicate %ResidJacEval objects
61  * inherited from %ResidJacEval even if the application only has
62  * a pointer to %ResidJacEval to work with.
63  *
64  * These routines are basically wrappers around the derived copy
65  * constructor.
66  */
68 {
69  ResidJacEval* ff = new ResidJacEval(*this);
70  return ff;
71 }
72 //====================================================================================================================
74 {
75  return neq_;
76 }
77 //====================================================================================================================
78 // Set a global value of the absolute tolerance
79 /*
80  * @param atol Value of atol
81  */
82 void ResidJacEval::setAtol(doublereal atol)
83 {
84  m_atol = atol;
85  if (m_atol <= 0.0) {
86  throw CanteraError("ResidJacEval::setAtol",
87  "atol must be greater than zero");
88  }
89 }
90 //====================================================================================================================
91 //! Fill in the initial conditions
92 /*!
93  * Values for both the solution and the value of ydot may be provided.
94  *
95  * @param t0 Time (input)
96  * @param y Solution vector (output)
97  * @param ydot Rate of change of solution vector. (output)
98  */
100 getInitialConditions(doublereal t0, doublereal* const y, doublereal* const ydot)
101 {
102  for (int i = 0; i < neq_; i++) {
103  y[i] = 0.0;
104  }
105  if (ydot) {
106  for (int i = 0; i < neq_; i++) {
107  ydot[i] = 0.0;
108  }
109  }
110  return 1;
111 }
112 //====================================================================================================================
113 // This function may be used to create output at various points in the execution of an application.
114 /*
115  *
116  * @param ifunc identity of the call
117  * 0 Initial call
118  * 1 Called at the end of every successful time step
119  * -1 Called at the end of every unsuccessful time step
120  * 2 Called at the end of every call to integrateRJE()
121  *
122  * @param t Time (input)
123  * @param delta_t The current value of the time step (input)
124  * @param y Solution vector (input, do not modify)
125  * @param ydot Rate of change of solution vector. (input)
126  */
127 void ResidJacEval::
128 user_out2(const int ifunc, const doublereal t, const doublereal deltaT,
129  const doublereal* y, const doublereal* ydot)
130 {
131 }
132 
133 //====================================================================================================================
134 // This function may be used to create output at various points in the execution of an application.
135 /*
136  * This routine calls user_out2().
137  *
138  * @param ifunc identity of the call
139  * @param t Time (input)
140  * @param y Solution vector (input, do not modify)
141  * @param ydot Rate of change of solution vector. (input)
142  */
143 void ResidJacEval::
144 user_out(const int ifunc, const doublereal t,
145  const doublereal* y, const doublereal* ydot)
146 {
147  user_out2(ifunc, t, 0.0, y, ydot);
148 }
149 //====================================================================================================================
150 //! Evaluate the time tracking equations, if any
151 /*!
152  * Evaluate time integrated quantities that are calculated at the
153  * end of every successful time step. This call is made once at the end of every successful
154  * time step that advances the time. It's also made once at the start of the time stepping.
155  *
156  * @param t Time (input)
157  * @param delta_t The current value of the time step (input)
158  * @param y Solution vector (input, do not modify)
159  * @param ydot Rate of change of solution vector. (input, do not modify)
160  */
161 int ResidJacEval::
162 evalTimeTrackingEqns(const doublereal t, const doublereal delta_t, const doublereal* y,
163  const doublereal* ydot)
164 {
165  return 1;
166 }
167 //====================================================================================================================
168 // Return a vector of delta y's for calculation of the numerical Jacobian
169 /*
170  * There is a default algorithm provided.
171  *
172  * delta_y[i] = atol[i] + 1.0E-6 ysoln[i]
173  * delta_y[i] = atol[i] + MAX(1.0E-6 ysoln[i] * 0.01 * solnWeights[i])
174  *
175  * @param t Time (input)
176  * @param y Solution vector (input, do not modify)
177  * @param ydot Rate of change of solution vector. (input, do not modify)
178  * @param delta_y Value of the delta to be used in calculating the numerical jacobian
179  * @param solnWeights Value of the solution weights that are used in determining convergence (default = 0)
180  *
181  * @return Returns a flag to indicate that operation is successful.
182  * 1 Means a successful operation
183  * 0 Means an unsuccessful operation
184  */
185 int ResidJacEval::
186 calcDeltaSolnVariables(const doublereal t, const doublereal* const ySoln,
187  const doublereal* const ySolnDot, doublereal* const deltaYSoln,
188  const doublereal* const solnWeights)
189 {
190  if (!solnWeights) {
191  for (int i = 0; i < neq_; i++) {
192  deltaYSoln[i] = m_atol + fabs(1.0E-6 * ySoln[i]);
193  }
194  } else {
195  for (int i = 0; i < neq_; i++) {
196  deltaYSoln[i] = std::max(1.0E-2 * solnWeights[i], 1.0E-6 * fabs(ySoln[i]));
197  }
198  }
199  return 1;
200 }
201 //====================================================================================================================
202 // Returns a vector of column scale factors that can be used to column scale Jacobians.
203 /*
204  * Default to yScales[] = 1.0
205  *
206  * @param t Time (input)
207  * @param y Solution vector (input, do not modify)
208  * @param y_old Old Solution vector (input, do not modify)
209  * @param yScales Value of the column scales
210  */
211 void ResidJacEval::
212 calcSolnScales(const doublereal t, const doublereal* const ysoln, const doublereal* const ysolnOld,
213  doublereal* const ysolnScales)
214 {
215  if (ysolnScales) {
216  if (ysolnScales[0] == 0.0) {
217  for (int i = 0; i < neq_; i++) {
218  ysolnScales[i] = 1.0;
219  }
220  }
221  }
222 }
223 //====================================================================================================================
224 // Filter the solution predictions
225 /*
226  * Codes might provide a predicted step change. This routine filters the predicted
227  * solution vector eliminating illegal directions.
228  *
229  * @param t Time (input)
230  * @param y Solution vector (input, output)
231  * @param step Proposed step in the solution that will be cropped
232  */
233 doublereal ResidJacEval::filterNewStep(doublereal t, const doublereal* const ybase, doublereal* const step)
234 {
235  return 0.0;
236 }
237 //====================================================================================================================
238 // Filter the solution predictions
239 /*
240  * Codes might provide a predicted solution vector. This routine filters the predicted
241  * solution vector.
242  *
243  * @param t Time (input)
244  * @param y Solution vector (input, output)
245  */
246 doublereal ResidJacEval::filterSolnPrediction(doublereal t, doublereal* const y)
247 {
248  return 0.0;
249 }
250 //====================================================================================================================
251 // Evaluate any stopping criteria other than a final time limit
252 /*
253  * If we are to stop the time integration for any reason other than reaching a final time limit, tout,
254  * provide a test here. This call is made at the end of every successful time step iteration
255  *
256  * @return If true, the the time stepping is stopped. If false, then time stepping is stopped if t >= tout
257  * Defaults to false.
258  *
259  * @param t Time (input)
260  * @param delta_t The current value of the time step (input)
261  * @param y Solution vector (input, do not modify)
262  * @param ydot Rate of change of solution vector. (input, do not modify)
263  */
264 bool ResidJacEval::
265 evalStoppingCritera(const doublereal t,
266  const doublereal delta_t,
267  const doublereal* const y,
268  const doublereal* const ydot)
269 {
270  return false;
271 }
272 //====================================================================================================================
273 // Multiply the matrix by another matrix that leads to better conditioning
274 /*
275  * Provide a left sided matrix that will multiply the current jacobian, after scaling
276  * and lead to a better conditioned system.
277  * This routine is called just before the matrix is factored.
278  *
279  * Original Problem:
280  * J delta_x = - Resid
281  *
282  * New problem:
283  * M (J delta_x) = - M Resid
284  *
285  * @param matrix Pointer to the current jacobian (if zero, it's already been factored)
286  * @param nrows offsets for the matrix
287  * @param rhs residual vector. This also needs to be lhs multiplied by M
288  */
289 int ResidJacEval::
290 matrixConditioning(doublereal* const matrix, const int nrows, doublereal* const rhs)
291 {
292  return 1;
293 }
294 //====================================================================================================================
295 // Evaluate the residual function
296 /*
297  * @param t Time (input)
298  * @param delta_t The current value of the time step (input)
299  * @param y Solution vector (input, do not modify)
300  * @param ydot Rate of change of solution vector. (input, do not modify)
301  * @param resid Value of the residual that is computed (output)
302  * @param evalType Type of the residual being computed (defaults to Base_ResidEval)
303  * @param id_x Index of the variable that is being numerically differenced to find
304  * the jacobian (defaults to -1, which indicates that no variable is being
305  * differenced or that the residual doesn't take this issue into account)
306  * @param delta_x Value of the delta used in the numerical differencing
307  */
308 int ResidJacEval::
309 evalResidNJ(const doublereal t, const doublereal deltaT, const doublereal* y,
310  const doublereal* ydot, doublereal* const resid, const ResidEval_Type_Enum evalType,
311  const int id_x, const doublereal delta_x)
312 {
313  throw CanteraError("ResidJacEval::evalResidNJ()", "Not implemented\n");
314  return 1;
315 }
316 //====================================================================================================================
317 int ResidJacEval::eval(const doublereal t, const doublereal* const y, const doublereal* const ydot,
318  doublereal* const r)
319 {
320  double deltaT = -1.0;
321  int flag = evalResidNJ(t, deltaT, y, ydot, r);
322  return flag;
323 }
324 //====================================================================================================================
325 // Calculate an analytical jacobian and the residual at the current time and values.
326 /*
327  * Only called if the jacFormation method is set to analytical
328  *
329  * @param t Time (input)
330  * @param delta_t The current value of the time step (input)
331  * @param y Solution vector (input, do not modify)
332  * @param ydot Rate of change of solution vector. (input, do not modify)
333  * @param J Reference to the SquareMatrix object to be calculated (output)
334  * @param resid Value of the residual that is computed (output)
335  */
336 int ResidJacEval::
337 evalJacobian(const doublereal t, const doublereal delta_t, doublereal cj,
338  const doublereal* const y,
339  const doublereal* const ydot,
340  GeneralMatrix& J,
341  doublereal* const resid)
342 {
343  doublereal* const* jac_colPts = J.colPts();
344  return evalJacobianDP(t, delta_t, cj, y, ydot, jac_colPts, resid);
345 }
346 //====================================================================================================================
347 // Calculate an analytical jacobian and the residual at the current time and values.
348 /*
349  * Only called if the jacFormation method is set to analytical
350  *
351  * @param t Time (input)
352  * @param delta_t The current value of the time step (input)
353  * @param c_j The current value of the coefficient of the time derivative
354  * @param y Solution vector (input, do not modify)
355  * @param ydot Rate of change of solution vector. (input, do not modify)
356  * @param jac_colPts Reference to the SquareMatrix object to be calculated (output)
357  * @param resid Value of the residual that is computed (output)
358  */
359 int ResidJacEval::
360 evalJacobianDP(const doublereal t, const doublereal delta_t,
361  const doublereal c_j,
362  const doublereal* const y,
363  const doublereal* const ydot,
364  doublereal* const* jac_colPts,
365  doublereal* const resid)
366 {
367  throw CanteraError("ResidJacEval::evalJacobianDP()", "Not implemented\n");
368  return 1;
369 }
370 //====================================================================================================================
371 
372 }