26 sootModel(nsoot_, nucl_, grow_, oxid_, coag_) {
28 if (nsoot_ < 3 || nsoot_ > 8)
29 throw runtime_error(
"MOMIC requires 3-8 moments");
34 throw runtime_error(
"MOMIC coagulation requires FM or CONTINUUM or HM");
39 for (
size_t k=0; k<
nsoot; k++)
44 Mp6 = vector<double>(22, 0.0);
45 Mq6 = vector<double>(30, 0.0);
46 np = {4,4,7,10,13,16,19,22};
47 nq = {12,12,15,18,21,24,27,30};
69 sootModel(nsoot_, Nmech, Gmech, Omech, Cmech) {
71 if (nsoot_ < 3 || nsoot_ > 8)
72 throw runtime_error(
"MOMIC requires 3-8 moments");
77 throw runtime_error(
"MOMIC coagulation requires FM or CONTINUUM or HM");
82 for (
size_t k=0; k<
nsoot; k++)
87 Mp6 = vector<double>(22, 0.0);
88 Mq6 = vector<double>(30, 0.0);
89 np = {4,4,7,10,13,16,19,22};
90 nq = {12,12,15,18,21,24,27,30};
110 for (
size_t k=0; k<
nsoot; k++)
131 vector<double> Mnuc(
Nmom, 0);
135 for (
size_t i=0; i<
Nmom; i++)
136 Mnuc[i] = pow(m_nuc, i)*Jnuc;
141 vector<double> Mcnd(
Nmom, 0);
147 vector<double> Mcnd_C(
Nmom, 0);
148 vector<double> Mcnd_FM(
Nmom, 0);
158 for (
size_t k=1, kk=(k-1)*3; k<
Nmom; k++)
159 Mcnd_C[k] =
double(k)*Kc*nDimer*mDimer* (
172 for (
size_t k=1; k<
Nmom; k++)
173 Mcnd_FM[k] =
double(k)*Kfm*nDimer*mDimer*
g_grid(k);
177 for (
size_t k=1; k<
Nmom; k++)
178 Mcnd[k] = Mcnd_FM[k]*Mcnd_C[k] / (Mcnd_FM[k]+Mcnd_C[k]);
183 vector<double> Mgrw(
Nmom, 0);
187 for (
size_t k=1; k<
Nmom; k++)
192 vector<double> Moxi(
Nmom, 0);
195 for (
size_t k=1; k<
Nmom; k++)
200 vector<double> Mcoa(
Nmom, 0);
207 for (
size_t i=0; i<
Nmom; i++)
212 vector<double> nucl_gasSources((
size_t)
gasSp::size, 0.0);
213 vector<double> grow_gasSources((
size_t)
gasSp::size, 0.0);
214 vector<double> oxid_gasSources((
size_t)
gasSp::size, 0.0);
221 sources.
gasSources[sp] = nucl_gasSources[sp] + grow_gasSources[sp] + oxid_gasSources[sp];
242 const double sigL = 3.0;
243 const double mavg = 1.0E-21;
249 M[1] = M[0] * mavg * exp(0.5 * pow(sigL,2.0));
252 M[2] = M[0] * pow(mavg,2) * exp(0.5 * 4 * pow(sigL,2.0));
261 for (
size_t i=0; i<
Nmom; i++)
267 }
while (
Nmom>3 && zeros);
299 double f0, f1, f2, f3;
304 f0 = 2.*(
Mq6[xi+0] *
Mq6[yi+2] +
307 f1 = 2.*(
Mq6[xi+0] *
Mq6[yi+5] +
308 2.*
Mq6[xi+1] *
Mq6[yi+4] +
312 f2 = 2.*(
Mq6[xi+0] *
Mq6[yi+8] +
313 2.*
Mq6[xi+1] *
Mq6[yi+7] +
315 2.*
Mq6[xi+3] *
Mq6[yi+5] +
316 2.*
Mq6[xi+4] *
Mq6[yi+4] );
319 f3 = 2.*(
Mq6[xi+0] *
Mq6[yi+11] +
320 2.*
Mq6[xi+1] *
Mq6[yi+10] +
322 3.*
Mq6[xi+3] *
Mq6[yi+8] +
323 6.*
Mq6[xi+4] *
Mq6[yi+7] +
324 3.*
Mq6[xi+5] *
Mq6[yi+6] );
328 f0 =
Mq6[xi+0] *
Mq6[yi+2] +
329 2.*
Mq6[xi+1] *
Mq6[yi+1] +
332 f1 =
Mq6[xi+0] *
Mq6[yi+5] +
333 2.*
Mq6[xi+1] *
Mq6[yi+4] +
336 2.*
Mq6[xi+4] *
Mq6[yi+1] +
340 f2 =
Mq6[xi+0] *
Mq6[yi+8] +
341 2.*
Mq6[xi+1] *
Mq6[yi+7] +
343 2.*
Mq6[xi+3] *
Mq6[yi+5] +
344 4.*
Mq6[xi+4] *
Mq6[yi+4] +
345 2.*
Mq6[xi+5] *
Mq6[yi+3] +
347 2.*
Mq6[xi+7] *
Mq6[yi+1] +
351 f3 =
Mq6[xi+0] *
Mq6[yi+11] +
352 2.*
Mq6[xi+1] *
Mq6[yi+10] +
354 3.*
Mq6[xi+3] *
Mq6[yi+8] +
355 6.*
Mq6[xi+4] *
Mq6[yi+7] +
356 3.*
Mq6[xi+5] *
Mq6[yi+6] +
357 3.*
Mq6[xi+6] *
Mq6[yi+5] +
358 6.*
Mq6[xi+7] *
Mq6[yi+4] +
359 3.*
Mq6[xi+8] *
Mq6[yi+3] +
361 2.*
Mq6[xi+10] *
Mq6[yi+1] +
369 fhalf = pow(f0,5./16.) * pow(f1,15./16.) * pow(f2, -5./16.) * pow(f3, 1./16.);
371 fhalf = pow(f0, 3./8.) * pow(f1, 3./4.) * pow(f2, -1./8.);
373 fhalf = pow(f0, 1./2.) * pow(f1, 1./2.);
403 double g0, g1, g2, g3;
447 ghalf = pow(g0,5./16.) * pow(g1,15./16.) * pow(g2, -5./16.) * pow(g3, 1./16.);
449 ghalf = pow(g0, 3./8.) * pow(g1, 3./4.) * pow(g2, -1./8.);
451 ghalf = pow(g0, 1./2.) * pow(g1, 1./2.);
468 if (M[0] <= 0.0)
return vector<double>(
Nmom, 0.0);
470 vector<double> Rates_C(
Nmom, 0.0);
471 vector<double> Rates_FM(
Nmom, 0.0);
472 vector<double> Rates(
Nmom, 0.0);
481 for (
size_t r=0; r<
Nmom; r++) {
484 Rates_FM[r] = -0.5*Kfm*
f_grid(0,0);
486 for (
size_t k=1; k<=r-1; k++)
488 Rates_FM[r] *= 0.5*Kfm;
502 for (
size_t r=0; r<
Nmom; r++) {
509 for (
size_t k=1; k<=r-1; k++) {
514 2.0*
Mp6[kk+2]*
Mp6[rk+2] +
516 Kcp*(
Mp6[kk+0]*
Mp6[rk+3] +
521 Rates_C[r] *= 0.5*Kc;
528 for (
size_t r=0; r<
Nmom; r++) {
531 Rates[r] = Rates_FM[r];
533 Rates[r] = Rates_C[r];
535 Rates[r] = Rates_FM[r]*Rates_C[r] / (Rates_FM[r]+Rates_C[r]);
581 double Ifm1 = Kfm*
g_grid(1);
585 return Ifm1*Ic1/(Ifm1 + Ic1);
615 for (
int k=0; k<
Nmom; k++)
620 for (
int j=1; j<
Nmom; j++)
621 for (
int i=0; i<
Nmom-j; i++)
649 int kend = (r >= 0) ?
Nmom : 3;
650 for(
int k=1; k<kend; k++) {
652 coef *= (r-k)/
double(k+1);
655 double value = pow(10., l10Mr);
656 return isfinite(value) ? value : 0.0;
679 for(
size_t i=0, p=-4; i<
np[
Nmom]; i++, p+=2)
683 for(
size_t i=0, q=-3; i<
nq[
Nmom]; i++, q+=2)
698 mD26 = pow(mDimer, 2./6.);
699 mDn26 = pow(mDimer, -2./6.);
700 mDn46 = pow(mDimer, -4./6.);
702 mDn36 = pow(mDimer, -3./6.);
703 mDn16 = pow(mDimer, -1./6.);
704 mD16 = pow(mDimer, 1./6.);
705 mD36 = pow(mDimer, 3./6.);
706 mD56 = pow(mDimer, 5./6.);
707 mD76 = pow(mDimer, 7./6.);
708 mD96 = pow(mDimer, 9./6.);
709 mD116 = pow(mDimer, 11./6.);
710 mD136 = pow(mDimer, 13./6.);
711 mD156 = pow(mDimer, 15./6.);
712 mD176 = pow(mDimer, 17./6.);
713 mD196 = pow(mDimer, 19./6.);
double binomial_coefficient(unsigned r, unsigned k)
virtual double getKcp(const state &state) const
coagulationMech mechType
identity of the type of coagulation (child)
virtual double getKfm(const state &state) const
virtual double getKc(const state &state) const
void getGrowthGasRates(const double &msootDotGrow, std::vector< double > &gasSourcesGrow) const
virtual double getGrowthSootRate(const state &state) const =0
growthMech mechType
identity of the type of growth (child)
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
size_t Nmom
number of soot moments (may decrese from downselectIfNeeded)
std::vector< double > Mq6
arrays holding fractional moments M_{q/6} where q is negative (FM)
double Mr(const double r)
double mDn36
mDimer^{-3/6}, etc.; for free molecular
std::vector< double > MOMICCoagulationRates(const state &state, std::vector< double > &M)
void set_diffTable(const std::vector< double > &M)
virtual double pahSootCollisionRatePerDimer(const state &state, const double mDimer)
void set_fractional_moments_Mp6_Mq6()
std::vector< double > Mp6
arrays holding fractional moments M_{p/6} where p is posiitive (Continuum)
std::vector< size_t > np
# of Mp6 entries needed based on Nmom; if Nmom=3, then np[3] is # Mp6 entries to fill
std::vector< std::vector< double > > diffTable
set in set_diffTable, used in Mr
void downselectIfNeeded(std::vector< double > &M)
virtual void setSourceTerms(state &state)
double f_grid(int x, int y)
double mDn46
mDimer^{-4/6}, etc.; for continuum
std::vector< size_t > nq
# of Mq6 entries needed based on Nmom; if Nmom=3, then nq[3] is # Mq6 entries to fill
sootModel_MOMIC(size_t nsoot_, nucleationModel *nucl_, growthModel *grow_, oxidationModel *oxid_, coagulationModel *coag_)
coagulationModel * coag
pointer to coagulation mechanism
psdMech psdMechType
one of MONO, LOGN, QMOM, MOMIC, SECT, etc.
sourceTerms sources
struct containing soot, gas, and pah source terms vectors
nucleationModel * nucl
pointer to nucleation mechanism
growthModel * grow
pointer to growth mechanism
size_t nsoot
# of soot variables: moments or sections
oxidationModel * oxid
pointer to oxidation mechanism
std::vector< double > sootVar
soot variables (moments or # in sections>
double cMin
soot min num carbon atoms (dynamic for PAH nucleation)
const double rhoSoot
soot particle density
const double Na
Avogadro's constant: #/kmol.
const std::vector< double > gasSpMW
(kg/kmol); make sure the order corresponds to the gasSp enum
std::vector< double > pahSources
kg/m3*s
std::vector< double > gasSources
kg/m3*s
std::vector< double > sootSources
kg^r/m3*s (moments), or #/m3*s (sections)