Loading...
Searching...
No Matches
bEqn.H
Go to the documentation of this file.
1if (ign.ignited())
2{
3 // progress variable
4 // ~~~~~~~~~~~~~~~~~
5 volScalarField c("c", scalar(1) - b);
6
7 // Unburnt gas density
8 // ~~~~~~~~~~~~~~~~~~~
9 volScalarField rhou(thermo.rhou());
10
11 // Calculate flame normal etc.
12 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
13
14 volVectorField n("n", fvc::grad(b));
15
16 volScalarField mgb(mag(n));
17
18 dimensionedScalar dMgb = 1.0e-3*
19 (b*c*mgb)().weightedAverage(mesh.V())
20 /((b*c)().weightedAverage(mesh.V()) + SMALL)
21 + dimensionedScalar("ddMgb", mgb.dimensions(), SMALL);
22
23 mgb += dMgb;
24
25 surfaceVectorField SfHat(mesh.Sf()/mesh.magSf());
26 surfaceVectorField nfVec(fvc::interpolate(n));
27 nfVec += SfHat*(fvc::snGrad(b) - (SfHat & nfVec));
28 nfVec /= (mag(nfVec) + dMgb);
29 surfaceScalarField nf((mesh.Sf() & nfVec));
30 n /= mgb;
31
32
33 #include "StCorr.H"
34
35 // Calculate turbulent flame speed flux
36 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 surfaceScalarField phiSt("phiSt", fvc::interpolate(rhou*StCorr*Su*Xi)*nf);
38
39 scalar StCoNum = max
40 (
41 mesh.surfaceInterpolation::deltaCoeffs()
42 *mag(phiSt)/(fvc::interpolate(rho)*mesh.magSf())
43 ).value()*runTime.deltaTValue();
44
45 Info<< "Max St-Courant Number = " << StCoNum << endl;
46
47 // Create b equation
48 // ~~~~~~~~~~~~~~~~~
49 fvScalarMatrix bEqn
50 (
51 fvm::ddt(rho, b)
52 + mvConvection->fvmDiv(phi, b)
53 + fvm::div(phiSt, b)
54 - fvm::Sp(fvc::div(phiSt), b)
55 - fvm::laplacian(turbulence->alphaEff(), b)
56 ==
58 );
59
60
61 // Add ignition cell contribution to b-equation
62 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63 #include "ignite.H"
64
65
66 // Solve for b
67 // ~~~~~~~~~~~
68 bEqn.relax();
69
70 fvOptions.constrain(bEqn);
71
72 bEqn.solve();
73
74 fvOptions.correct(b);
75
76 Info<< "min(b) = " << min(b).value() << endl;
77
78
79 // Calculate coefficients for Gulder's flame speed correlation
80 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81
82 volScalarField up(uPrimeCoef*sqrt((2.0/3.0)*turbulence->k()));
83 //volScalarField up(sqrt(mag(diag(n * n) & diag(turbulence->r()))));
84
85 volScalarField epsilon(pow(uPrimeCoef, 3)*turbulence->epsilon());
86
87 volScalarField tauEta(sqrt(thermo.muu()/(rhou*epsilon)));
88
89 volScalarField Reta
90 (
91 up
92 / (
93 sqrt(epsilon*tauEta)
94 + dimensionedScalar("1e-8", up.dimensions(), 1e-8)
95 )
96 );
97
98 //volScalarField l = 0.337*k*sqrt(k)/epsilon;
99 //Reta *= max((l - dimensionedScalar("dl", dimLength, 1.5e-3))/l, 0.0);
100
101 // Calculate Xi flux
102 // ~~~~~~~~~~~~~~~~~
103 surfaceScalarField phiXi
104 (
105 phiSt
106 - fvc::interpolate(fvc::laplacian(turbulence->alphaEff(), b)/mgb)*nf
107 + fvc::interpolate(rho)*fvc::interpolate(Su*(1.0/Xi - Xi))*nf
108 );
109
110
111 // Calculate mean and turbulent strain rates
112 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113
114 volVectorField Ut(U + Su*Xi*n);
115 volScalarField sigmat((n & n)*fvc::div(Ut) - (n & fvc::grad(Ut) & n));
116
117 volScalarField sigmas
118 (
119 ((n & n)*fvc::div(U) - (n & fvc::grad(U) & n))/Xi
120 + (
121 (n & n)*fvc::div(Su*n)
122 - (n & fvc::grad(Su*n) & n)
123 )*(Xi + scalar(1))/(2*Xi)
124 );
125
126
127 // Calculate the unstrained laminar flame speed
128 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129 volScalarField Su0(unstrainedLaminarFlameSpeed()());
130
131
132 // Calculate the laminar flame speed in equilibrium with the applied strain
133 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134 volScalarField SuInf(Su0*max(scalar(1) - sigmas/sigmaExt, scalar(0.01)));
135
136 if (SuModel == "unstrained")
137 {
138 Su == Su0;
139 }
140 else if (SuModel == "equilibrium")
141 {
142 Su == SuInf;
143 }
144 else if (SuModel == "transport")
145 {
146 // Solve for the strained laminar flame speed
147 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
148
149 volScalarField Rc
150 (
151 (sigmas*SuInf*(Su0 - SuInf) + sqr(SuMin)*sigmaExt)
152 /(sqr(Su0 - SuInf) + sqr(SuMin))
153 );
154
155 fvScalarMatrix SuEqn
156 (
157 fvm::ddt(rho, Su)
158 + fvm::div(phi + phiXi, Su, "div(phiXi,Su)")
159 - fvm::Sp(fvc::div(phiXi), Su)
160 ==
161 - fvm::SuSp(-rho*Rc*Su0/Su, Su)
162 - fvm::SuSp(rho*(sigmas + Rc), Su)
163 + fvOptions(rho, Su)
164 );
165
166 SuEqn.relax();
167
168 fvOptions.constrain(SuEqn);
169
170 SuEqn.solve();
171
172 fvOptions.correct(Su);
173
174 Su.clamp_range(SuMin, SuMax);
175 }
176 else
177 {
178 FatalError
179 << args.executable() << " : Unknown Su model " << SuModel
180 << abort(FatalError);
181 }
182
183
184 // Calculate Xi according to the selected flame wrinkling model
185 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
186
187 if (XiModel == "fixed")
188 {
189 // Do nothing, Xi is fixed!
190 }
191 else if (XiModel == "algebraic")
192 {
193 // Simple algebraic model for Xi based on Gulders correlation
194 // with a linear correction function to give a plausible profile for Xi
195 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
196 Xi == scalar(1) +
197 (scalar(1) + (2*XiShapeCoef)*(scalar(0.5) - b))
198 *XiCoef*sqrt(up/(Su + SuMin))*Reta;
199 }
200 else if (XiModel == "transport")
201 {
202 // Calculate Xi transport coefficients based on Gulders correlation
203 // and DNS data for the rate of generation
204 // with a linear correction function to give a plausible profile for Xi
205 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
206
207 volScalarField XiEqStar
208 (
209 scalar(1.001) + XiCoef*sqrt(up/(Su + SuMin))*Reta
210 );
211
212 volScalarField XiEq
213 (
214 scalar(1.001)
215 + (
216 scalar(1)
217 + (2*XiShapeCoef)
218 *(scalar(0.5) - clamp(b, zero_one{}))
219 )*(XiEqStar - scalar(1.001))
220 );
221
222 volScalarField Gstar(0.28/tauEta);
223 volScalarField R(Gstar*XiEqStar/(XiEqStar - scalar(1)));
224 volScalarField G(R*(XiEq - scalar(1.001))/XiEq);
225
226 //R *= (Gstar + 2*mag(devSymm(fvc::grad(U))))/Gstar;
227
228 // Solve for the flame wrinkling
229 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
230 fvScalarMatrix XiEqn
231 (
232 fvm::ddt(rho, Xi)
233 + fvm::div(phi + phiXi, Xi, "div(phiXi,Xi)")
234 - fvm::Sp(fvc::div(phiXi), Xi)
235 ==
236 rho*R
237 - fvm::Sp(rho*(R - G), Xi)
238 - fvm::Sp
239 (
240 rho*max
241 (
242 sigmat - sigmas,
243 dimensionedScalar(sigmat.dimensions(), Zero)
244 ),
245 Xi
246 )
247 + fvOptions(rho, Xi)
248 );
249
250 XiEqn.relax();
251
252 fvOptions.constrain(XiEqn);
253
254 XiEqn.solve();
255
256 fvOptions.correct(Xi);
257
258 // Correct boundedness of Xi
259 // ~~~~~~~~~~~~~~~~~~~~~~~~~
260 Xi.max(1.0);
261 Info<< "max(Xi) = " << max(Xi).value() << endl;
262 Info<< "max(XiEq) = " << max(XiEq).value() << endl;
263 }
264 else
265 {
266 FatalError
267 << args.executable() << " : Unknown Xi model " << XiModel
268 << abort(FatalError);
269 }
270
271 Info<< "Combustion progress = "
272 << 100*(scalar(1) - b)().weightedAverage(mesh.V()).value() << "%"
273 << endl;
274
275 St = Xi*Su;
276}
#define R(A, B, C, D, E, F, K, M)
dimensionedScalar StCorr("StCorr", dimless, 1.0)
label n
tmp< fv::convectionScheme< scalar > > mvConvection(fv::convectionScheme< scalar >::New(mesh, fields, phi, mesh.divScheme("div(phi,Yi_h)")))
fv::options & fvOptions
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
U
Definition pEqn.H:72
dynamicFvMesh & mesh
engineTime & runTime
scalar epsilon
compressible::turbulenceModel & turbulence
zeroField Su
Definition alphaSuSp.H:1
Foam::argList args(argc, argv)
Info<< "Creating the unstrained laminar flame speed\n"<< endl;autoPtr< laminarFlameSpeed > unstrainedLaminarFlameSpeed(laminarFlameSpeed::New(thermo))
volScalarField & b
volScalarField & e