33 template<
class ThermoType>
40 log_(this->lookupOrDefault(
"log", false)),
41 cpuLoad_(this->lookupOrDefault(
"cpuLoad", false)),
44 this->
found(
"jacobian")
45 ? jacobianTypeNames_.
read(this->lookup(
"jacobian"))
52 specieThermos_(mixture_.specieThermos()),
53 reactions_(
thermo.species(), specieThermos_, this->
mesh(), *this),
67 mechRed_(*mechRedPtr_),
69 tabulation_(*tabulationPtr_)
81 "RR." + Yvf_[fieldi].
name(),
93 Info<<
"chemistryModel: Number of species = " << nSpecie_
123 cpuSolveFile_ =
logFile(
"cpu_solve.out");
130 template<
class ThermoType>
137 template<
class ThermoType>
150 Y_[sToc_[i]] =
max(YTp[i], 0);
157 Y_[i] =
max(YTp[i], 0);
161 const scalar
T = YTp[nSpecie_];
162 const scalar
p = YTp[nSpecie_ + 1];
166 for (
label i=0; i<Y_.size(); i++)
168 rhoM += Y_[i]/specieThermos_[i].rho(
p,
T);
173 for (
label i=0; i<Y_.size(); i ++)
175 c_[i] = rhoM/specieThermos_[i].W()*Y_[i];
182 if (!mechRed_.reactionDisabled(ri))
184 reactions_[ri].dNdtByV
199 for (
label i=0; i<nSpecie_; i++)
201 const scalar WiByrhoM = specieThermos_[sToc(i)].W()/rhoM;
202 scalar& dYidt = dYTpdt[i];
210 for (
label i=0; i<Y_.size(); i++)
212 CpM += Y_[i]*specieThermos_[i].Cp(
p,
T);
216 scalar& dTdt = dYTpdt[nSpecie_];
217 for (
label i=0; i<nSpecie_; i++)
219 dTdt -= dYTpdt[i]*specieThermos_[sToc(i)].ha(
p,
T);
224 scalar& dpdt = dYTpdt[nSpecie_ + 1];
229 template<
class ThermoType>
243 Y_[sToc_[i]] =
max(YTp[i], 0);
250 Y_[i] =
max(YTp[i], 0);
254 const scalar
T = YTp[nSpecie_];
255 const scalar
p = YTp[nSpecie_ + 1];
259 for (
label i=0; i<Y_.size(); i++)
261 v[i] = 1/specieThermos_[i].rho(
p,
T);
264 for (
label i=0; i<Y_.size(); i++)
271 for (
label i=0; i<Y_.size(); i ++)
273 c_[i] = rhoM/specieThermos_[i].W()*Y_[i];
278 for (
label i=0; i<nSpecie_; i++)
280 const scalar rhoMByWi = rhoM/specieThermos_[sToc(i)].W();
281 switch (jacobianType_)
283 case jacobianType::fast:
285 dcdY(i, i) = rhoMByWi;
288 case jacobianType::exact:
289 for (
label j=0; j<nSpecie_; j++)
292 rhoMByWi*((i == j) - rhoM*v[sToc(j)]*Y_[sToc(i)]);
300 for (
label i=0; i<Y_.size(); i++)
302 alphavM += Y_[i]*rhoM*v[i]*specieThermos_[i].alphav(
p,
T);
308 for (
label i=0; i<nSpecie_ + 2; i++)
310 for (
label j=0; j<nSpecie_ + 2; j++)
312 ddNdtByVdcTp[i][j] = 0;
317 if (!mechRed_.reactionDisabled(ri))
319 reactions_[ri].ddNdtByVdcTp
338 for (
label i=0; i<nSpecie_; i++)
340 const scalar WiByrhoM = specieThermos_[sToc(i)].W()/rhoM;
341 scalar& dYidt = dYTpdt[i];
344 for (
label j=0; j<nSpecie_; j++)
346 scalar ddNidtByVdYj = 0;
347 switch (jacobianType_)
349 case jacobianType::fast:
351 const scalar ddNidtByVdcj = ddNdtByVdcTp(i, j);
352 ddNidtByVdYj = ddNidtByVdcj*dcdY(j, j);
355 case jacobianType::exact:
358 const scalar ddNidtByVdck = ddNdtByVdcTp(i,
k);
359 ddNidtByVdYj += ddNidtByVdck*dcdY(
k, j);
364 scalar& ddYidtdYj = J(i, j);
365 ddYidtdYj = WiByrhoM*ddNidtByVdYj + rhoM*v[sToc(j)]*dYidt;
368 scalar ddNidtByVdT = ddNdtByVdcTp(i, nSpecie_);
369 for (
label j=0; j<nSpecie_; j++)
371 const scalar ddNidtByVdcj = ddNdtByVdcTp(i, j);
372 ddNidtByVdT -= ddNidtByVdcj*c_[sToc(j)]*alphavM;
375 scalar& ddYidtdT = J(i, nSpecie_);
376 ddYidtdT = WiByrhoM*ddNidtByVdT + alphavM*dYidt;
378 scalar& ddYidtdp = J(i, nSpecie_ + 1);
386 scalar CpM = 0, dCpMdT = 0;
387 for (
label i=0; i<Y_.size(); i++)
389 Cp[i] = specieThermos_[i].Cp(
p,
T);
391 dCpMdT += Y_[i]*specieThermos_[i].dCpdT(
p,
T);
396 scalar& dTdt = dYTpdt[nSpecie_];
397 for (
label i=0; i<nSpecie_; i++)
399 ha[sToc(i)] = specieThermos_[sToc(i)].ha(
p,
T);
400 dTdt -= dYTpdt[i]*
ha[sToc(i)];
405 scalar& dpdt = dYTpdt[nSpecie_ + 1];
409 for (
label i=0; i<nSpecie_; i++)
411 scalar& ddTdtdYi = J(nSpecie_, i);
413 for (
label j=0; j<nSpecie_; j++)
415 const scalar ddYjdtdYi = J(j, i);
416 ddTdtdYi -= ddYjdtdYi*
ha[sToc(j)];
418 ddTdtdYi -=
Cp[sToc(i)]*dTdt;
423 scalar& ddTdtdT = J(nSpecie_, nSpecie_);
425 for (
label i=0; i<nSpecie_; i++)
427 const scalar dYidt = dYTpdt[i];
428 const scalar ddYidtdT = J(i, nSpecie_);
429 ddTdtdT -= dYidt*
Cp[sToc(i)] + ddYidtdT*
ha[sToc(i)];
431 ddTdtdT -= dTdt*dCpMdT;
435 scalar& ddTdtdp = J(nSpecie_, nSpecie_ + 1);
439 for (
label i=0; i<nSpecie_ + 2; i++)
441 scalar& ddpdtdYiTp = J(nSpecie_ + 1, i);
447 template<
class ThermoType>
451 const label reactioni
457 "RR:" + reactions_[reactioni].
name(),
463 if (!this->chemistry_ || mechRed_.reactionDisabled(reactioni))
474 reactionEvaluationScope scope(*
this);
480 const scalar
rho = rhovf[celli];
481 const scalar
T = Tvf[celli];
482 const scalar
p = pvf[celli];
484 for (
label i=0; i<nSpecie_; i++)
486 const scalar Yi = Yvf_[i][celli];
487 c_[i] =
rho*Yi/specieThermos_[i].W();
490 scalar omegaf, omegar;
508 template<
class ThermoType>
512 const label reactioni
516 for (
label i=0; i<nSpecie_; i++)
523 "RR:" + reactions_[reactioni].
name() +
":" + Yvf_[i].
name(),
530 if (!this->chemistry_ || mechRed_.reactionDisabled(reactioni))
543 reactionEvaluationScope scope(*
this);
549 const scalar
rho = rhovf[celli];
550 const scalar
T = Tvf[celli];
551 const scalar
p = pvf[celli];
553 for (
label i=0; i<nSpecie_; i++)
555 const scalar Yi = Yvf_[i][celli];
556 c_[i] =
rho*Yi/specieThermos_[i].W();
573 for (
label i=0; i<nSpecie_; i++)
575 RR[i][celli] = dNdtByV[i]*specieThermos_[i].W();
583 template<
class ThermoType>
586 if (!this->chemistry_)
599 reactionEvaluationScope scope(*
this);
603 const scalar
rho = rhovf[celli];
604 const scalar
T = Tvf[celli];
605 const scalar
p = pvf[celli];
607 for (
label i=0; i<nSpecie_; i++)
609 const scalar Yi = Yvf_[i][celli];
610 c_[i] =
rho*Yi/specieThermos_[i].W();
617 if (!mechRed_.reactionDisabled(ri))
619 reactions_[ri].dNdtByV
633 for (
label i=0; i<mechRed_.nActiveSpecies(); i++)
635 RR_[sToc(i)][celli] = dNdtByV[i]*specieThermos_[sToc(i)].W();
641 template<
class ThermoType>
642 template<
class DeltaTType>
645 const DeltaTType& deltaT
655 scalar totalSolveCpuTime = 0;
657 if (!this->chemistry_)
663 this->
mesh().template lookupObject<volScalarField>
665 this->
thermo().phasePropertyName(
"rho")
671 reactionEvaluationScope scope(*
this);
680 scalar deltaTMin = great;
687 const scalar
rho0 = rho0vf[celli];
689 scalar
p = p0vf[celli];
690 scalar
T = T0vf[celli];
692 for (
label i=0; i<nSpecie_; i++)
694 Y_[i] =
Y0[i] = Yvf_[i].oldTime()[celli];
697 for (
label i=0; i<nSpecie_; i++)
699 phiq[i] = Yvf_[i].oldTime()[celli];
703 phiq[
nSpecie() + 2] = deltaT[celli];
706 scalar timeLeft = deltaT[celli];
714 if (tabulation_.retrieve(phiq, Rphiq))
733 for (
label i=0; i<nSpecie_; i++)
735 c_[i] =
rho0*Y_[i]/specieThermos_[i].W();
739 mechRed_.reduceMechanism(
p,
T, c_, cTos_, sToc_, celli);
742 sY_.setSize(nSpecie_);
743 for (
label i=0; i<nSpecie_; i++)
745 sY_[i] = Y_[sToc(i)];
756 while (timeLeft > small)
758 scalar dt = timeLeft;
772 for (
label i=0; i<mechRed_.nActiveSpecies(); i++)
774 Y_[sToc_[i]] = sY_[i];
779 solve(
p,
T, Y_, celli, dt, deltaTChem_[celli]);
791 if (tabulation_.tabulates())
797 Rphiq[Rphiq.
size()-3] =
T;
798 Rphiq[Rphiq.
size()-2] =
p;
799 Rphiq[Rphiq.
size()-1] = deltaT[celli];
805 mechRed_.nActiveSpecies(),
816 setNSpecie(mechRed_.nSpecie());
819 deltaTMin =
min(deltaTChem_[celli], deltaTMin);
820 deltaTChem_[celli] =
min(deltaTChem_[celli], deltaTChemMax_);
824 for (
label i=0; i<nSpecie_; i++)
826 RR_[i][celli] =
rho0*(Y_[i] -
Y0[i])/deltaT[celli];
838 << this->time().userTimeValue()
839 <<
" " << totalSolveCpuTime <<
endl;
843 tabulation_.update();
854 template<
class ThermoType>
869 template<
class ThermoType>
875 return this->solve<scalarField>(deltaT);
879 template<
class ThermoType>
890 extrapolatedCalculatedFvPatchScalarField::typeName
895 if (!this->chemistry_)
897 ttc.
ref().correctBoundaryConditions();
907 reactionEvaluationScope scope(*
this);
911 const scalar
rho = rhovf[celli];
912 const scalar
T = Tvf[celli];
913 const scalar
p = pvf[celli];
915 for (
label i=0; i<nSpecie_; i++)
917 c_[i] =
rho*Yvf_[i][celli]/specieThermos_[i].W();
937 scalar sumW = 0, sumWRateByCTot = 0;
941 scalar omegaf, omegar;
942 R.omega(
p,
T, c_, celli, omegaf, omegar);
947 wf +=
R.rhs()[
s].stoichCoeff*omegaf;
950 sumWRateByCTot +=
sqr(wf);
955 wr +=
R.lhs()[
s].stoichCoeff*omegar;
958 sumWRateByCTot +=
sqr(wr);
962 sumWRateByCTot == 0 ? vGreat : sumW/sumWRateByCTot*
sum(c_);
965 ttc.
ref().correctBoundaryConditions();
970 template<
class ThermoType>
984 if (!this->chemistry_)
989 reactionEvaluationScope scope(*
this);
997 const scalar hi = specieThermos_[i].hf();
998 Qdot[celli] -= hi*RR_[i][celli];
scalar Cp(const scalar p, const scalar T) const
scalar ha(const scalar p, const scalar T) const
#define forAll(list, i)
Loop across all elements in list.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
static tmp< DimensionedField< Type, GeoMesh, PrimitiveField > > New(const word &name, const Mesh &mesh, const dimensionSet &, const PrimitiveField< Type > &)
Return a temporary field constructed from name, mesh,.
Generic GeometricField class.
static tmp< GeometricField< Type, GeoMesh, PrimitiveField > > New(const word &name, const Internal &, const PtrList< Patch > &, const HashPtrTable< Source > &=HashPtrTable< Source >())
Return a temporary field constructed from name,.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
const Time & time() const
Return time.
void size(const label)
Override size to be inconsistent with allocated storage.
const Field0Type & oldTime() const
Return the old-time field.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Simple extension of ThermoType to handle reaction kinetics in addition to the equilibrium thermodynam...
const fluidMulticomponentThermo & thermo() const
Return const access to the thermo.
jacobianType
Enumeration for the type of Jacobian to be calculated by the.
const fvMesh & mesh() const
Return const access to the mesh.
virtual const fvMesh & mesh() const =0
Return const access to the mesh.
virtual const volScalarField & T() const =0
Temperature [K].
Extends base chemistry model by adding a thermo package, and ODE functions. Introduces chemistry equa...
virtual tmp< volScalarField::Internal > reactionRR(const label reactioni) const
Return the rate of reactioni [kmol/m^3/s].
virtual void jacobian(const scalar t, const scalarField &YTp, const label li, scalarField &dYTpdt, scalarSquareMatrix &J) const
Calculate the ODE jacobian.
virtual tmp< volScalarField > tc() const
Return the chemical time scale.
virtual void derivatives(const scalar t, const scalarField &YTp, const label li, scalarField &dYTpdt) const
Calculate the ODE derivatives.
virtual label nReaction() const
The number of reactions.
virtual ~chemistryModel()
Destructor.
virtual PtrList< volScalarField::Internal > specieReactionRR(const label reactioni) const
Return reaction rates of the species in reactioni [kg/m^3/s].
virtual tmp< volScalarField > Qdot() const
Return the heat release rate [kg/m/s^3].
virtual void calculate()
Calculates the reaction rates.
An abstract class for methods of chemical mechanism reduction.
An abstract class for chemistry tabulation.
Starts timing CPU usage and return elapsed time from start.
double cpuTimeIncrement() const
Return CPU time (in seconds) since last call to cpuTimeIncrement()
const fileName & name() const
Return the dictionary name.
Base-class for multi-component fluid thermodynamic properties.
virtual const volScalarField & p() const =0
Pressure [Pa].
Foam::multicomponentMixture.
void setSpecieInactive(const label speciei) const
Set specie inactive.
virtual void syncSpeciesActive() const =0
Synchronise the specie active flags.
Extends base chemistry model adding an ODESystem and the reduction maps needed for tabulation.
autoPtr< OFstream > logFile(const word &name) const
Create and return a TDAC log file of the given name.
friend class chemistryModel
virtual void resetCpuTime()
Reset the CPU time (dummy)
virtual void cpuTimeIncrement(const label celli)
Cache the CPU time increment for celli (dummy)
static optionalCpuLoad & New(const word &name, const polyMesh &mesh, const bool loadBalancing)
Construct from polyMesh if loadBalancing is true.
A class for managing temporary objects.
T & ref() const
Return non-const reference or generate a fatal error.
Templated form of IOobject providing type information for file reading and header type checking.
bool headerOk()
Read header (uses typeGlobalFile to find file) and check.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
autoPtr< CompressibleMomentumTransportModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const viscosity &viscosity)
const dimensionedScalar RR
Universal gas constant: default SI units: [J/kmol/K].
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
const dimensionSet dimEnergy
Ostream & endl(Ostream &os)
Add newline and flush stream.
void T(LagrangianPatchField< Type > &f, const LagrangianPatchField< Type > &f1)
To & dynamicCast(From &r)
Reference type cast template function,.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
const dimensionSet dimTime
const dimensionSet dimVolume
const dimensionSet dimMoles
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
static scalar R(const scalar a, const scalar x)
void sqr(LagrangianPatchField< typename outerProduct< Type, Type >::type > &f, const LagrangianPatchField< Type > &f1)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
const dimensionSet dimMass
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
SolverPerformance< Type > solve(fvMatrix< Type > &, const word &)
Solve returning the solution statistics given convergence tolerance.
scalarList Y0(nSpecie, 0.0)
fluidMulticomponentThermo & thermo