cantera/src/numerics/ResidJacEval.cpp
2012-05-24 16:29:29 +00:00

372 lines
15 KiB
C++

/**
* @file ResidJacEval.cpp
*/
/*
* Copyright 2004 Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
* retains certain rights in this software.
* See file License.txt for licensing information.
*/
#include "cantera/base/ct_defs.h"
#include "cantera/numerics/ctlapack.h"
#include "cantera/numerics/ResidJacEval.h"
#include <iostream>
#include <vector>
using namespace std;
namespace Cantera
{
//====================================================================================================================
ResidJacEval::ResidJacEval(doublereal atol) :
ResidEval(),
m_atol(atol)
{
}
//====================================================================================================================
// Copy Constructor for the %ResidJacEval object
/*
*/
ResidJacEval::ResidJacEval(const ResidJacEval& right) :
ResidEval()
{
*this = operator=(right);
}
//====================================================================================================================
ResidJacEval::~ResidJacEval()
{
}
//====================================================================================================================
ResidJacEval& ResidJacEval::operator=(const ResidJacEval& right)
{
if (this == &right) {
return *this;
}
ResidEval::operator=(right);
m_atol = right.m_atol;
neq_ = right.neq_;
return *this;
}
//====================================================================================================================
// Duplication routine for objects which inherit from %ResidJacEval
/*
* This virtual routine can be used to duplicate %ResidJacEval objects
* inherited from %ResidJacEval even if the application only has
* a pointer to %ResidJacEval to work with.
*
* These routines are basically wrappers around the derived copy
* constructor.
*/
ResidJacEval* ResidJacEval::duplMyselfAsResidJacEval() const
{
ResidJacEval* ff = new ResidJacEval(*this);
return ff;
}
//====================================================================================================================
int ResidJacEval::nEquations() const
{
return neq_;
}
//====================================================================================================================
// Set a global value of the absolute tolerance
/*
* @param atol Value of atol
*/
void ResidJacEval::setAtol(doublereal atol)
{
m_atol = atol;
if (m_atol <= 0.0) {
throw CanteraError("ResidJacEval::setAtol",
"atol must be greater than zero");
}
}
//====================================================================================================================
//! Fill in the initial conditions
/*!
* Values for both the solution and the value of ydot may be provided.
*
* @param t0 Time (input)
* @param y Solution vector (output)
* @param ydot Rate of change of solution vector. (output)
*/
int ResidJacEval::
getInitialConditions(doublereal t0, doublereal* const y, doublereal* const ydot)
{
for (int i = 0; i < neq_; i++) {
y[i] = 0.0;
}
if (ydot) {
for (int i = 0; i < neq_; i++) {
ydot[i] = 0.0;
}
}
return 1;
}
//====================================================================================================================
// This function may be used to create output at various points in the execution of an application.
/*
*
* @param ifunc identity of the call
* 0 Initial call
* 1 Called at the end of every successful time step
* -1 Called at the end of every unsuccessful time step
* 2 Called at the end of every call to integrateRJE()
*
* @param t Time (input)
* @param delta_t The current value of the time step (input)
* @param y Solution vector (input, do not modify)
* @param ydot Rate of change of solution vector. (input)
*/
void ResidJacEval::
user_out2(const int ifunc, const doublereal t, const doublereal deltaT,
const doublereal* y, const doublereal* ydot)
{
}
//====================================================================================================================
// This function may be used to create output at various points in the execution of an application.
/*
* This routine calls user_out2().
*
* @param ifunc identity of the call
* @param t Time (input)
* @param y Solution vector (input, do not modify)
* @param ydot Rate of change of solution vector. (input)
*/
void ResidJacEval::
user_out(const int ifunc, const doublereal t,
const doublereal* y, const doublereal* ydot)
{
user_out2(ifunc, t, 0.0, y, ydot);
}
//====================================================================================================================
//! Evaluate the time tracking equations, if any
/*!
* Evaluate time integrated quantities that are calculated at the
* end of every successful time step. This call is made once at the end of every successful
* time step that advances the time. It's also made once at the start of the time stepping.
*
* @param t Time (input)
* @param delta_t The current value of the time step (input)
* @param y Solution vector (input, do not modify)
* @param ydot Rate of change of solution vector. (input, do not modify)
*/
int ResidJacEval::
evalTimeTrackingEqns(const doublereal t, const doublereal delta_t, const doublereal* y,
const doublereal* ydot)
{
return 1;
}
//====================================================================================================================
// Return a vector of delta y's for calculation of the numerical Jacobian
/*
* There is a default algorithm provided.
*
* delta_y[i] = atol[i] + 1.0E-6 ysoln[i]
* delta_y[i] = atol[i] + MAX(1.0E-6 ysoln[i] * 0.01 * solnWeights[i])
*
* @param t Time (input)
* @param y Solution vector (input, do not modify)
* @param ydot Rate of change of solution vector. (input, do not modify)
* @param delta_y Value of the delta to be used in calculating the numerical jacobian
* @param solnWeights Value of the solution weights that are used in determining convergence (default = 0)
*
* @return Returns a flag to indicate that operation is successful.
* 1 Means a successful operation
* 0 Means an unsuccessful operation
*/
int ResidJacEval::
calcDeltaSolnVariables(const doublereal t, const doublereal* const ySoln,
const doublereal* const ySolnDot, doublereal* const deltaYSoln,
const doublereal* const solnWeights)
{
if (!solnWeights) {
for (int i = 0; i < neq_; i++) {
deltaYSoln[i] = m_atol + fabs(1.0E-6 * ySoln[i]);
}
} else {
for (int i = 0; i < neq_; i++) {
deltaYSoln[i] = std::max(1.0E-2 * solnWeights[i], 1.0E-6 * fabs(ySoln[i]));
}
}
return 1;
}
//====================================================================================================================
// Returns a vector of column scale factors that can be used to column scale Jacobians.
/*
* Default to yScales[] = 1.0
*
* @param t Time (input)
* @param y Solution vector (input, do not modify)
* @param y_old Old Solution vector (input, do not modify)
* @param yScales Value of the column scales
*/
void ResidJacEval::
calcSolnScales(const doublereal t, const doublereal* const ysoln, const doublereal* const ysolnOld,
doublereal* const ysolnScales)
{
if (ysolnScales) {
if (ysolnScales[0] == 0.0) {
for (int i = 0; i < neq_; i++) {
ysolnScales[i] = 1.0;
}
}
}
}
//====================================================================================================================
// Filter the solution predictions
/*
* Codes might provide a predicted step change. This routine filters the predicted
* solution vector eliminating illegal directions.
*
* @param t Time (input)
* @param y Solution vector (input, output)
* @param step Proposed step in the solution that will be cropped
*/
doublereal ResidJacEval::filterNewStep(doublereal t, const doublereal* const ybase, doublereal* const step)
{
return 0.0;
}
//====================================================================================================================
// Filter the solution predictions
/*
* Codes might provide a predicted solution vector. This routine filters the predicted
* solution vector.
*
* @param t Time (input)
* @param y Solution vector (input, output)
*/
doublereal ResidJacEval::filterSolnPrediction(doublereal t, doublereal* const y)
{
return 0.0;
}
//====================================================================================================================
// Evaluate any stopping criteria other than a final time limit
/*
* If we are to stop the time integration for any reason other than reaching a final time limit, tout,
* provide a test here. This call is made at the end of every successful time step iteration
*
* @return If true, the the time stepping is stopped. If false, then time stepping is stopped if t >= tout
* Defaults to false.
*
* @param t Time (input)
* @param delta_t The current value of the time step (input)
* @param y Solution vector (input, do not modify)
* @param ydot Rate of change of solution vector. (input, do not modify)
*/
bool ResidJacEval::
evalStoppingCritera(const doublereal t,
const doublereal delta_t,
const doublereal* const y,
const doublereal* const ydot)
{
return false;
}
//====================================================================================================================
// Multiply the matrix by another matrix that leads to better conditioning
/*
* Provide a left sided matrix that will multiply the current jacobian, after scaling
* and lead to a better conditioned system.
* This routine is called just before the matrix is factored.
*
* Original Problem:
* J delta_x = - Resid
*
* New problem:
* M (J delta_x) = - M Resid
*
* @param matrix Pointer to the current jacobian (if zero, it's already been factored)
* @param nrows offsets for the matrix
* @param rhs residual vector. This also needs to be lhs multiplied by M
*/
int ResidJacEval::
matrixConditioning(doublereal* const matrix, const int nrows, doublereal* const rhs)
{
return 1;
}
//====================================================================================================================
// Evaluate the residual function
/*
* @param t Time (input)
* @param delta_t The current value of the time step (input)
* @param y Solution vector (input, do not modify)
* @param ydot Rate of change of solution vector. (input, do not modify)
* @param resid Value of the residual that is computed (output)
* @param evalType Type of the residual being computed (defaults to Base_ResidEval)
* @param id_x Index of the variable that is being numerically differenced to find
* the jacobian (defaults to -1, which indicates that no variable is being
* differenced or that the residual doesn't take this issue into account)
* @param delta_x Value of the delta used in the numerical differencing
*/
int ResidJacEval::
evalResidNJ(const doublereal t, const doublereal deltaT, const doublereal* y,
const doublereal* ydot, doublereal* const resid, const ResidEval_Type_Enum evalType,
const int id_x, const doublereal delta_x)
{
throw CanteraError("ResidJacEval::evalResidNJ()", "Not implemented\n");
return 1;
}
//====================================================================================================================
int ResidJacEval::eval(const doublereal t, const doublereal* const y, const doublereal* const ydot,
doublereal* const r)
{
double deltaT = -1.0;
int flag = evalResidNJ(t, deltaT, y, ydot, r);
return flag;
}
//====================================================================================================================
// Calculate an analytical jacobian and the residual at the current time and values.
/*
* Only called if the jacFormation method is set to analytical
*
* @param t Time (input)
* @param delta_t The current value of the time step (input)
* @param y Solution vector (input, do not modify)
* @param ydot Rate of change of solution vector. (input, do not modify)
* @param J Reference to the SquareMatrix object to be calculated (output)
* @param resid Value of the residual that is computed (output)
*/
int ResidJacEval::
evalJacobian(const doublereal t, const doublereal delta_t, doublereal cj,
const doublereal* const y,
const doublereal* const ydot,
GeneralMatrix& J,
doublereal* const resid)
{
doublereal* const* jac_colPts = J.colPts();
return evalJacobianDP(t, delta_t, cj, y, ydot, jac_colPts, resid);
}
//====================================================================================================================
// Calculate an analytical jacobian and the residual at the current time and values.
/*
* Only called if the jacFormation method is set to analytical
*
* @param t Time (input)
* @param delta_t The current value of the time step (input)
* @param c_j The current value of the coefficient of the time derivative
* @param y Solution vector (input, do not modify)
* @param ydot Rate of change of solution vector. (input, do not modify)
* @param jac_colPts Reference to the SquareMatrix object to be calculated (output)
* @param resid Value of the residual that is computed (output)
*/
int ResidJacEval::
evalJacobianDP(const doublereal t, const doublereal delta_t,
const doublereal c_j,
const doublereal* const y,
const doublereal* const ydot,
doublereal* const* jac_colPts,
doublereal* const resid)
{
throw CanteraError("ResidJacEval::evalJacobianDP()", "Not implemented\n");
return 1;
}
//====================================================================================================================
}