EulerImplicit.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "EulerImplicit.H"
31#include "simpleMatrix.H"
32#include "Reaction.H"
33
34// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35
36template<class ChemistryModel>
38(
40)
41:
42 chemistrySolver<ChemistryModel>(thermo),
43 coeffsDict_(this->subDict("EulerImplicitCoeffs")),
44 cTauChem_(coeffsDict_.get<scalar>("cTauChem")),
45 eqRateLimiter_(coeffsDict_.get<Switch>("equilibriumRateLimiter")),
46 cTp_(this->nEqns())
47{}
48
49
50// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
51
52template<class ChemistryModel>
54{}
55
56
57// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
58
59template<class ChemistryModel>
61(
62 const label index,
63 const scalar pr,
64 const scalar pf,
65 const scalar corr,
66 const label lRef,
67 const label rRef,
68 const scalar p,
69 const scalar T,
71) const
72{
74 this->reactions_[index];
75
76 forAll(R.lhs(), s)
77 {
78 const label si = R.lhs()[s].index;
79 const scalar sl = R.lhs()[s].stoichCoeff;
80 RR[si][rRef] -= sl*pr*corr;
81 RR[si][lRef] += sl*pf*corr;
82 }
83
84 forAll(R.rhs(), s)
85 {
86 const label si = R.rhs()[s].index;
87 const scalar sr = R.rhs()[s].stoichCoeff;
88 RR[si][lRef] -= sr*pf*corr;
89 RR[si][rRef] += sr*pr*corr;
90 }
91}
92
93
94template<class ChemistryModel>
96(
97 scalarField& c,
98 scalar& T,
99 scalar& p,
100 scalar& deltaT,
101 scalar& subDeltaT
102) const
103{
104 const label nSpecie = this->nSpecie();
106
107 for (label i=0; i<nSpecie; i++)
108 {
109 c[i] = max(0, c[i]);
110 }
111
112 // Calculate the absolute enthalpy
113 const scalar cTot = sum(c);
114 typename ChemistryModel::thermoType mixture
115 (
116 (this->specieThermo_[0].W()*c[0])*this->specieThermo_[0]
117 );
118 for (label i=1; i<nSpecie; i++)
119 {
120 mixture += (this->specieThermo_[i].W()*c[i])*this->specieThermo_[i];
121 }
122 const scalar ha = mixture.Ha(p, T);
123 const scalar deltaTEst = min(deltaT, subDeltaT);
124
125 forAll(this->reactions(), i)
126 {
127 scalar pf, cf, pr, cr;
128 label lRef, rRef;
129
130 const scalar omegai =
131 this->omegaI(i, c, T, p, pf, cf, lRef, pr, cr, rRef);
132
133 scalar corr = 1;
134 if (eqRateLimiter_)
135 {
136 if (omegai < 0)
137 {
138 corr = 1/(1 + pr*deltaTEst);
139 }
140 else
141 {
142 corr = 1/(1 + pf*deltaTEst);
143 }
144 }
145
146 updateRRInReactionI(i, pr, pf, corr, lRef, rRef, p, T, RR);
147 }
148
149 // Calculate the stable/accurate time-step
150 scalar tMin = GREAT;
151
152 for (label i=0; i<nSpecie; i++)
153 {
154 scalar d = 0;
155 for (label j=0; j<nSpecie; j++)
156 {
157 d -= RR(i, j)*c[j];
158 }
159
160 if (d < -SMALL)
161 {
162 tMin = min(tMin, -(c[i] + SMALL)/d);
163 }
164 else
165 {
166 d = max(d, SMALL);
167 const scalar cm = max(cTot - c[i], 1e-5);
168 tMin = min(tMin, cm/d);
169 }
170 }
171
172 subDeltaT = cTauChem_*tMin;
173 deltaT = min(deltaT, subDeltaT);
174
175 // Add the diagonal and source contributions from the time-derivative
176 for (label i=0; i<nSpecie; i++)
177 {
178 RR(i, i) += 1/deltaT;
179 RR.source()[i] = c[i]/deltaT;
180 }
181
182 // Solve for the new composition
183 c = RR.LUsolve();
184
185 // Limit the composition
186 for (label i=0; i<nSpecie; i++)
187 {
188 c[i] = max(0, c[i]);
189 }
190
191 // Update the temperature
192 mixture = (this->specieThermo_[0].W()*c[0])*this->specieThermo_[0];
193 for (label i=1; i<nSpecie; i++)
194 {
195 mixture += (this->specieThermo_[i].W()*c[i])*this->specieThermo_[i];
196 }
197 T = mixture.THa(ha, p, T);
198}
199
200
201// ************************************************************************* //
#define R(A, B, C, D, E, F, K, M)
Macros for easy insertion into run-time selection tables.
ReactionThermo reactionThermo
Thermo type.
An Euler implicit solver for chemistry.
Definition: EulerImplicit.H:58
void updateRRInReactionI(const label index, const scalar pr, const scalar pf, const scalar corr, const label lRef, const label rRef, const scalar p, const scalar T, simpleMatrix< scalar > &RR) const
Definition: EulerImplicit.C:61
virtual ~EulerImplicit()
Destructor.
Definition: EulerImplicit.C:53
Simple extension of ReactionThermo to handle reaction kinetics in addition to the equilibrium thermod...
Definition: Reaction.H:73
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:78
An abstract base class for solving chemistry.
A simple square matrix solver with scalar coefficients.
Definition: simpleMatrix.H:67
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
volScalarField & p
const volScalarField & T
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
label nSpecie
CEqn solve()
volScalarField & e
Definition: createFields.H:11
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333