From 71caff1d2b2bc4c898115ea8a50d7014792d30dc Mon Sep 17 00:00:00 2001 From: Dave Goodwin Date: Tue, 2 Nov 2004 10:23:29 +0000 Subject: [PATCH] re-added file --- Cantera/src/ImplicitChem.cpp | 88 ++++++++++++++++++++++++++ Cantera/src/ImplicitChem.h | 117 +++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100755 Cantera/src/ImplicitChem.cpp create mode 100755 Cantera/src/ImplicitChem.h diff --git a/Cantera/src/ImplicitChem.cpp b/Cantera/src/ImplicitChem.cpp new file mode 100755 index 000000000..ea2760aa0 --- /dev/null +++ b/Cantera/src/ImplicitChem.cpp @@ -0,0 +1,88 @@ +/** + * @file Reactor.cpp + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ImplicitChem.h" +#include "CVode.h" + +namespace Cantera { + + ImplicitChem::ImplicitChem(Kinetics& kin, ThermoPhase& therm) + : FuncEval(), m_kin(&kin), m_thermo(&therm), m_integ(0), + m_atol(1.e-15), m_rtol(1.e-7), m_maxstep(0.0), m_energy(false) + { + m_integ = new CVodeInt; + //m_mix = &kin.phase(); + m_wt = m_thermo->molecularWeights(); + + // use backward differencing, with a full Jacobian computed + // numerically, and use a Newton linear iterator + m_integ->setMethod(BDF_Method); + m_integ->setProblemType(DENSE + NOJAC); + m_integ->setIterator(Newton_Iter); + m_nsp = m_thermo->nSpecies(); + } + + // overloaded method of FuncEval. Called by the integrator to + // get the initial conditions. + void ImplicitChem::getInitialConditions(double t0, size_t leny, double* y) + { + m_thermo->getMassFractions(y); + m_h0 = m_thermo->enthalpy_mass(); + m_rho = m_thermo->density(); + m_press = m_thermo->pressure(); + } + + + /** + * Must be called before calling method 'advance' + */ + void ImplicitChem::initialize(doublereal t0) { + m_integ->setTolerances(m_rtol, m_atol); + // m_integ->setMaxStep(m_maxstep); + m_integ->initialize(t0, *this); + } + + + void ImplicitChem::updateState(doublereal* y) { + m_thermo->setMassFractions(y); + if (m_energy) { + doublereal delta, temp = m_thermo->temperature(); + do { + delta = -(m_thermo->enthalpy_mass() - m_h0)/m_thermo->cp_mass(); + temp += delta; + m_thermo->setTemperature(temp); + } + while (fabs(delta) > 1.e-7); + } + m_thermo->setPressure(m_press); + } + + /** + * Called by the integrator to evaluate ydot given y at time 'time'. + */ + void ImplicitChem::eval(doublereal time, doublereal* y, doublereal* ydot) + { + updateState(y); // synchronize the mixture state with y + m_thermo->setPressure(m_press); + m_kin->getNetProductionRates(ydot); // "omega dot" + int k; + for (k = 0; k < m_nsp; k++) { + ydot[k] *= m_wt[k]/m_rho; + } + } + +} diff --git a/Cantera/src/ImplicitChem.h b/Cantera/src/ImplicitChem.h new file mode 100755 index 000000000..e20d4f8b9 --- /dev/null +++ b/Cantera/src/ImplicitChem.h @@ -0,0 +1,117 @@ +/** + * @file ImplicitChem.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_IMPCHEM_H +#define CT_IMPCHEM_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "FuncEval.h" +#include "CVode.h" +#include "Kinetics.h" +#include "ThermoPhase.h" + +namespace Cantera { + + /** + * Advances the composition of an associated phase object in time + * by implicitly integrating + * \f[ + * \dot Y_k = \frac{\omega_k}{\rho} + * \f] + */ + class ImplicitChem : public FuncEval { + + public: + + /** + * Constructor. + */ + ImplicitChem(Kinetics& kin, ThermoPhase& therm); + + + /** + * Destructor. Deletes the integrator. + */ + virtual ~ImplicitChem(){ delete m_integ; } + + + /** + * Overloads the virtual function + * declared in FuncEval. + */ + virtual void initialize(doublereal t0 = 0.0); + + void adiabatic() { + m_energy = true; + } + + void isothermal() { + m_energy = false; + } + + /** + * Integrate from t0 to t1. The integrator is reinitialized + * first. + */ + void integrate(doublereal t0, doublereal t1) { + m_integ->reinitialize(t0, *this); + m_integ->setMaxStepSize(t1 - t0); + m_rho = m_thermo->density(); + m_integ->integrate(t1); + updateState(m_integ->solution()); + } + + /** + * Integrate from t0 to t1 without reinitializing the + * integrator. + */ + void integrate0(doublereal t0, doublereal t1) { + m_integ->integrate(t1); + updateState(m_integ->solution()); + } + + // overloaded methods of class FuncEval + virtual int neq() { return m_nsp; } + virtual void eval(doublereal t, doublereal* y, doublereal* ydot); + virtual void getInitialConditions(doublereal t0, size_t leny, + doublereal* y); + + + protected: + + /** + * Set the mixture to a state consistent with solution + * vector y. + */ + void updateState(doublereal* y); + + //Kinetics::phase_t* m_mix; + Kinetics* m_kin; + ThermoPhase* m_thermo; + int m_nsp; + Integrator* m_integ; // pointer to integrator + doublereal m_atol, m_rtol; // tolerances + doublereal m_maxstep; // max step size + array_fp m_wt; + doublereal m_rho; + bool m_energy; + doublereal m_h0; + doublereal m_press; + + private: + + }; +} + +#endif