SootLib
Loading...
Searching...
No Matches
sootModel_SECT.cc
Go to the documentation of this file.
1#include "sootModel_SECT.h"
2
3using namespace std;
4using namespace soot;
5
20
22 nucleationModel *nucl_,
23 growthModel *grow_,
24 oxidationModel *oxid_,
25 coagulationModel *coag_,
26 double binGrowthFactor_,
27 int cMin_) :
28 sootModel(nsoot_, nucl_, grow_, oxid_, coag_),
29 binGrowthFactor(binGrowthFactor_) {
30
31 if (nsoot_ < 2)
32 throw runtime_error("SECT requires nsoot>1");
33
34 set_mBins(cMin_);
35
37
39 beta_DSi.resize(nsoot);
40}
41
56
58 nucleationMech Nmech,
59 growthMech Gmech,
60 oxidationMech Omech,
61 coagulationMech Cmech,
62 double binGrowthFactor_,
63 int cMin_) :
64 sootModel(nsoot_, Nmech, Gmech, Omech, Cmech),
65 binGrowthFactor(binGrowthFactor_) {
66
67 if (nsoot_ < 2)
68 throw runtime_error("SECT requires nsoot>1");
69
70 set_mBins(cMin_);
71
73
75 beta_DSi.resize(nsoot);
76}
77
85
86void sootModel_SECT::set_mBins(const int cMin_) {
87
88 mBins.resize(nsoot);
89 for (size_t k = 0; k < nsoot; k++)
90 mBins[k] = cMin_ * pow(binGrowthFactor, k) * gasSpMW[(size_t)gasSp::C] / Na;
91}
92
107
108double sootModel_SECT::pahSootCollisionRatePerDimer(const state &state, const double mDimer) {
109
110 //---------- compute beta_DSi; used here and in subsequent PAH condensation in setSourceTerms
111
112 size_t k;
113
114 for(k=0; k<nsoot; k++)
116
117 //---------- compute I_beta_DS
118
119 double I_beta_DS = 0.0;
120 double term1, term2;
121
122 k = 0; // 1st bin: loss via growth into 2nd
123 term1 = beta_DSi[k]*state.sootVar[k]/(mBins[k+1]-mBins[k]);
124 I_beta_DS -= term1*mBins[0];
125
126 for(k=1; k<nsoot-1; k++) { // interior bins: gain from k-1, lose to k+1
127 term2 = beta_DSi[k]*state.sootVar[k]/(mBins[k+1]-mBins[k]);
128 I_beta_DS += mBins[k] * (term1 - term2);
129 term1 = term2;
130 }
131
132 k = nsoot-1; // last bin: gain from 2nd to last + condensation inside
133 term2 = beta_DSi[k]*state.sootVar[k]/mBins[k];
134 I_beta_DS += mBins[k] * (term1 + term2);
135
136 return I_beta_DS;
137
138}
139
151
153
154 size_t k;
155 double term;
156
157 //---------- get chemical rates
158
159 double jNuc = nucl->getNucleationSootRate(state); // #/m3*s
160 double kGrw = grow->getGrowthSootRate(state); // kg/m2*s
161 double kOxi = oxid->getOxidationSootRate(state); // kg/m2*s
162
163 //----------- nucleation terms
164
165 vector<double> Snuc(nsoot, 0.0); // #/m3*s in each bin (only bin 0)
166
168 double mNuc = state.cMin*gasSpMW[(int)gasSp::C]/Na; // mass of a nucleated particle
169 Snuc[0] = jNuc * mNuc /mBins[0]; // kg_soot/m3*s (as carbon); \todo check that soot nucleation mass < mBins[1]
170 }
171
172 //----------- get area for growth, condensation and oxidation
173
174 vector<double> Am2m3(nsoot, 0); // m2 soot / m3 bulk volume
175 for (k = 0; k < nsoot; k++)
176 Am2m3[k] = M_PI*pow(6.*mBins[k]/(M_PI*rhoSoot), twothird)*state.sootVar[k];
177
178 //----------- growth terms: positive velocity through size domain
179
180 vector<double> Sgrw(nsoot, 0.0); // #/m3*s in each bin
181
183 k=0; // first bin
184 term = kGrw*Am2m3[k]/(mBins[k+1]-mBins[k]);
185 Sgrw[k] = -term;
186
187 for(k=1; k<nsoot-1; k++) { // loop up interior bins
188 Sgrw[k] = term;
189 term = kGrw*Am2m3[k]/(mBins[k+1]-mBins[k]);
190 Sgrw[k] -= term;
191 }
192
193 k=nsoot-1; // last bin
194 Sgrw[k] = term + kGrw*Am2m3[k]/mBins[k]; // growth into last bin from its smaller neighbor +
195 // growth inside last bin manifest as new particles in that bin
196 }
197 //----------- PAH condensation terms:
198 //----------- positive vel. through size domain: each bin has in/out except 1st (out) and last (in,gen)
199 //----------- beta_DSi is set in pahSootCollisionRatePerDimer called in nucl->getNucleationSootRate
200
201 vector<double> Scnd(nsoot, 0.0);
203
204 k=0; // first bin
205 term = beta_DSi[k] * state.sootVar[k] * nucl->DIMER.nDimer *
206 nucl->DIMER.mDimer / (mBins[k+1]-mBins[k]);
207 Scnd[k] = -term;
208
209 for(k=1; k<nsoot-1; k++) { // loop up interior bins
210 Scnd[k] = term;
211 term = beta_DSi[k] * state.sootVar[k] * nucl->DIMER.nDimer *
212 nucl->DIMER.mDimer / (mBins[k+1]-mBins[k]);
213 Scnd[k] -= term;
214 }
215
216 k=nsoot-1; // last bin
217 Scnd[k] = term + // growth into bin by neighbor + ... vvv
218 beta_DSi[k] * state.sootVar[k] * // growth inside last bin, manifest as new particles in that bin (rather that transport out)
220 }
221
222 //----------- oxidation terms: negative velocity through size domain
223
224 vector<double> Soxi(nsoot, 0.0); // #/m3*s in each bin
225
227 k=nsoot-1; // last bin
228 term = kOxi*Am2m3[k]/(mBins[k]-mBins[k-1]);
229 Soxi[k] = -term;
230
231 for(k=nsoot-2; k>0; k--) { // loop down interior bins
232 Soxi[k] = term;
233 term = kOxi*Am2m3[k]/(mBins[k]-mBins[k-1]);
234 Soxi[k] -= term;
235 }
236 k=0; // first bin
237 Soxi[k] = term - kOxi*Am2m3[k]/mBins[k]; // source from oxid of larger neighbor -
238 // oxidation inside first bin, manifest as fewer particles in that bin (rather than transport out)
239 }
240 //----------- coagulation terms
241
242
243 vector<double> Scoa(nsoot, 0.0); // #/m3*s in each bin
244
246 static const double ilnF = 1.0/log(binGrowthFactor); // factor for finding location
247 double K12;
248
249 for(size_t i=0; i<nsoot; i++) { // loop size i
250 for(size_t j=i; j<nsoot; j++) { // which collides with each size j >= i (loop over upper triang matrix inc diag)
251
252 //----------- loss: i,j collide to remove from bins i and j
253
255 term = K12*state.sootVar[i]*state.sootVar[j];
256 Scoa[i] -= term;
257 if (j>i) // account for terms below the diagonal taking advantage of symmetry
258 Scoa[j] -= term;
259
260 //----------- gain: mi + mj = mk --> bins floor(k) and ceil(k) gain so that mass, # conserved
261 //----------- mBins[0]*F^k = mBins[i] + mBins[j] --> k = int( log((mBins[i]+mBins[j])/mBins[0])/log(F) )
262
263 if (i==j) term *= 0.5;
264
265 size_t k = static_cast<size_t>(ilnF * log((mBins[i]+mBins[j])/mBins[0]));
266
267 if (k >= nsoot)
268 k=nsoot-1;
269 if (k == nsoot-1) // i+j into last bin, no splitting, conserve mass
270 Scoa[k] += term*(mBins[i]+mBins[j])/mBins[k];
271 else { // i+j between k and k+1, split to conserve # and mass
272 double Xk = (mBins[k+1] - (mBins[i] + mBins[j])) / (mBins[k+1] - mBins[k]); // fraction into bin k
273 Scoa[k] += Xk * term;
274 Scoa[k+1] += (1.0-Xk) * term;
275 }
276 }
277 }
278 }
279
280 //---------- combine to make soot source terms
281
282 for (size_t k=0; k<nsoot; k++)
283 sources.sootSources[k] = Snuc[k] + Sgrw[k] + Scnd[k] + Soxi[k] + Scoa[k]; // #/m3*s in bin k
284
285 //---------- set gas sources
286
287 double mdotN=0, mdotG=0, mdotO=0; // kg/m3*s from nuc, grow, cond, oxid
288 for(size_t k=0; k<nsoot; k++) {
289 mdotN += Snuc[k]*mBins[k];
290 mdotG += Sgrw[k]*mBins[k];
291 mdotO += Soxi[k]*mBins[k];
292 }
293
294 vector<double> nucl_gasSources((size_t)gasSp::size, 0.0);
295 vector<double> grow_gasSources((size_t)gasSp::size, 0.0);
296 vector<double> oxid_gasSources((size_t)gasSp::size, 0.0);
297
298 nucl->getNucleationGasRates(mdotN, nucl_gasSources);
299 grow->getGrowthGasRates( mdotG, grow_gasSources);
300 oxid->getOxidationGasRates( mdotO, oxid_gasSources);
301
302 for (size_t sp=0; sp<(size_t)gasSp::size; sp++)
303 sources.gasSources[sp] = nucl_gasSources[sp] + grow_gasSources[sp] + oxid_gasSources[sp];
304
305 //---------- set PAH source terms
306
308 sources.pahSources = nucl->nucleationPahRxnRates; // includes both nucleation and condensation
309}
310
316
318
319 double M0;
320 for (size_t k=0; k<nsoot; k++)
321 M0 += state.sootVar[k];
322 return M0;
323}
324
330
332
333 double M1;
334 for (size_t k=0; k<nsoot; k++)
335 M1 += state.sootVar[k] * mBins[k];
336 return M1;
337}
coagulationMech mechType
identity of the type of coagulation (child)
virtual double getCoagulationSootRate(const state &state, double m1, double m2) const =0
void getGrowthGasRates(const double &msootDotGrow, std::vector< double > &gasSourcesGrow) const
Definition: growthModel.cc:16
virtual double getGrowthSootRate(const state &state) const =0
growthMech mechType
identity of the type of growth (child)
Definition: growthModel.h:24
std::vector< double > nucleationPahRxnRates
mole ratios for PAH gas species rate coupling
void getNucleationGasRates(const double &msootDotNucl, std::vector< double > &gasSourcesNucl) const
dimerStruct DIMER
used for PAH nucleation only
nucleationMech mechType
identity of the type of nucleation (child)
virtual double getNucleationSootRate(state &state)=0
void getOxidationGasRates(const double &msootDotOxid, std::vector< double > &gasSourcesOxid) const
oxidationMech mechType
identity of the type of oxidation (child)
virtual double getOxidationSootRate(const state &state) const =0
double binGrowthFactor
F^0, F^1, F^2, ... (set F here, F=2, say)
void set_mBins(const int cMin_)
virtual void setSourceTerms(state &state)
sootModel_SECT(size_t nsoot_, nucleationModel *nucl_, growthModel *grow_, oxidationModel *oxid_, coagulationModel *coag_, double binGrowthFactor_=2.0, int cMin_=100)
std::vector< double > beta_DSi
store beta_dimer_soot_i for PAH nuc to avoid double computing
virtual double get_M1_sectional(const state &state)
virtual double pahSootCollisionRatePerDimer(const state &state, const double mDimer)
virtual double get_M0_sectional(const state &state)
std::vector< double > mBins
mass in sections for the sectional model
Definition: sootModel.h:41
coagulationModel * coag
pointer to coagulation mechanism
Definition: sootModel.h:33
psdMech psdMechType
one of MONO, LOGN, QMOM, MOMIC, SECT, etc.
Definition: sootModel.h:37
sourceTerms sources
struct containing soot, gas, and pah source terms vectors
Definition: sootModel.h:42
nucleationModel * nucl
pointer to nucleation mechanism
Definition: sootModel.h:30
growthModel * grow
pointer to growth mechanism
Definition: sootModel.h:31
size_t nsoot
# of soot variables: moments or sections
Definition: sootModel.h:28
oxidationModel * oxid
pointer to oxidation mechanism
Definition: sootModel.h:32
std::vector< double > sootVar
soot variables (moments or # in sections>
Definition: state.h:32
double cMin
soot min num carbon atoms (dynamic for PAH nucleation)
Definition: state.h:36
Definition: sootDefs.h:11
oxidationMech
Definition: sootDefs.h:33
const double rhoSoot
soot particle density
Definition: sootDefs.h:21
coagulationMech
Definition: sootDefs.h:34
growthMech
Definition: sootDefs.h:32
nucleationMech
Definition: sootDefs.h:31
const double twothird
Definition: sootDefs.h:25
const double Na
Avogadro's constant: #/kmol.
Definition: sootDefs.h:15
const std::vector< double > gasSpMW
(kg/kmol); make sure the order corresponds to the gasSp enum
Definition: sootDefs.h:74
std::vector< double > pahSources
kg/m3*s
Definition: sootDefs.h:143
std::vector< double > gasSources
kg/m3*s
Definition: sootDefs.h:142
std::vector< double > sootSources
kg^r/m3*s (moments), or #/m3*s (sections)
Definition: sootDefs.h:141