3#include "cantera/base/ct_defs.h"
14#include <highfive/highfive.hpp>
18using soot::sootModel, soot::state, soot::gasSp, soot::gasSpMapIS, soot::gasSpMapES;
19using HighFive::File, HighFive::Group, HighFive::DataSet;
23int Func_kinsol(N_Vector varsKS, N_Vector fvec,
void *user_data);
24int rhsf_cvode(realtype t, N_Vector varsCV, N_Vector dvarsdtCV,
void *user_data);
46 const bool _doEnergyEqn,
47 const bool _isFlamelet,
49 const size_t _ngrd,
const double _L,
double _P,
50 shared_ptr<Cantera::Solution> csol,
52 const vector<double> &_yLbc,
const vector<double> &_yRbc,
53 const double _TLbc,
const double _TRbc,
54 shared_ptr<sootModel> _SM,
55 shared_ptr<state> _SMstate) :
56 isPremixed(_isPremixed),
57 isFlamelet(_isFlamelet),
58 doEnergyEqn(_doEnergyEqn),
73 if(_isPremixed && _isFlamelet)
74 throw runtime_error(
"Cannot set both premixed and flamelet");
75 if(_isFlamelet && _L!=1.0)
76 throw runtime_error(
"flamelet should have L=1");
81 kin = csol->kinetics();
82 trn = csol->transport();
89 y = vector<vector<double> >(
ngrd, vector<double>(
nsp, 0.0));
104 for(
size_t k=0; k<
nsp; k++)
105 hspLbc[k] *=
TLbc*Cantera::GasConstant/
gas->molecularWeight(k);
112 for(
size_t k=0; k<
nsp; k++)
113 hspRbc[k] *=
TRbc*Cantera::GasConstant/
gas->molecularWeight(k);
127 for(
int i=1; i<
nsoot; i++)
129 sootScales = {1E20, 1.8E-3, 3.4E-26, 6.3E-49, 1.2E-71, 2.2E-94, 4E-117, 7.4E-140};
133 flux_y = vector<vector<double> >(
ngrd+1, vector<double>(
nsp, 0.0));
142 radProps = make_shared<rad_planck_mean>();
150 isp =
gas->speciesIndex(
"H2O");
151 double xH2O =
yLbc[isp];
152 isp =
gas->speciesIndex(
"CO2");
153 double xCO2 =
yLbc[isp];
154 isp =
gas->speciesIndex(
"CO");
155 double xCO =
yLbc[isp];
156 radProps = make_shared<rad_rcslw>(4,
TLbc,
P, fvsoot, xH2O, xCO2, xCO);
159 radProps = make_shared<rad_planck_mean>();
166 double xH2O, xCO2, xCO, xCH4;
169 isp =
gas->speciesIndex(
"H2O");
171 isp =
gas->speciesIndex(
"CO2");
173 isp =
gas->speciesIndex(
"CO");
175 isp =
gas->speciesIndex(
"CH4");
188 fh5 = make_shared<File>(
"data.h5", File::Truncate);
210 for (
size_t i=1; i<
ngrd; i++)
211 x[i] =
x[i-1] + (
dx[i-1]+
dx[i])/2;
218 double dx1 =
L*Lfrac/n1;
219 for(
int i=0; i<n1; i++)
223 double dx2 =
L*(1.0-Lfrac)/n2;
224 for(
int i=n1; i<
ngrd; i++)
228 for (
size_t i=1; i<
ngrd; i++)
229 x[i] =
x[i-1] + (
dx[i-1]+
dx[i])/2;
249 for(
size_t i=0; i<
ngrd-1; i++) {
271 for(
int i=0; i<
ngrd; i++)
272 mixf[i] =
strm->getMixtureFraction(&
y[i][0]);
273 mixfLbc =
strm->getMixtureFraction(&
yLbc[0]);
274 mixfRbc =
strm->getMixtureFraction(&
yRbc[0]);
277 vector<double> rho(
ngrd);
278 vector<double> h(
ngrd);
279 for(
int i=0; i<
ngrd; i++) {
280 gas->setState_TPY(
T[i],
P, &
y[i][0]);
281 rho[i] =
gas->density();
282 h[i] =
gas->enthalpy_mass();
286 double rhoLbc =
gas->density();
288 double rhoRbc =
gas->density();
292 vector<double> field;
293 vector<vector<double>> field2;
295 Group grp =
fh5->createGroup(gname);
297 grp.createAttribute<
string>(
"caseType",
isPremixed ?
"premixed" : (
isFlamelet ?
"flamelet" :
"diffusion"));
299 grp.createAttribute<
string>(
"timeType", timeType);
301 field =
x; field.insert(field.begin(), 0.0); field.push_back(
L);
302 DataSet dset = grp.createDataSet(
"x", field);
303 dset.createAttribute<
string>(
"units",
"m");
304 dset.createAttribute<
string>(
"note",
"grid cell positions");
307 field = mixf; field.insert(field.begin(), mixfLbc); field.push_back(mixfRbc);
308 dset = grp.createDataSet(
"mixf", field);
309 dset.createAttribute<
string>(
"units",
"--");
313 dset = grp.createDataSet(
"T", field);
314 dset.createAttribute<
string>(
"units",
"K");
316 field = h; field.insert(field.begin(),
hLbc); field.push_back(
isPremixed ? h.back() :
hRbc);
317 dset = grp.createDataSet(
"h", field);
318 dset.createAttribute<
string>(
"units",
"J/kg");
320 field = rho; field.insert(field.begin(), rhoLbc); field.push_back(
isPremixed ? rho.back() : rhoRbc);
321 dset = grp.createDataSet(
"rho", field);
322 dset.createAttribute<
string>(
"units",
"kg/m3");
324 field2 =
y; field2.insert(field2.begin(),
yLbc); field2.push_back(
isPremixed ?
y.back() :
yRbc);
325 dset = grp.createDataSet(
"y", field2);
326 dset.createAttribute<
string>(
"units",
"--");
327 dset.createAttribute<
string>(
"note",
"mass fractions");
328 dset.createAttribute<vector<string>>(
"species names",
gas->speciesNames());
331 vector<double> sootBC(
nsoot, 0.0);
333 dset = grp.createDataSet(
"soot", field2);
334 dset.createAttribute<
string>(
"units",
"mass moment: kg^k/m3");
354 for(
int i=0; i<
ngrd; i++)
355 mixf[i] =
strm->getMixtureFraction(&
y[i][0]);
356 mixfLbc =
strm->getMixtureFraction(&
yLbc[0]);
357 mixfRbc =
strm->getMixtureFraction(&
yRbc[0]);
360 vector<double> rho(
ngrd);
361 vector<double> h(
ngrd);
362 for(
int i=0; i<
ngrd; i++) {
363 gas->setState_TPY(
T[i],
P, &
y[i][0]);
364 rho[i] =
gas->density();
365 h[i] =
gas->enthalpy_mass();
368 double rhoLbc =
gas->density();
370 double rhoRbc =
gas->density();
374 ofstream ofile(fname.c_str());
376 cerr <<
"\n\n***************** ERROR OPENING FILE " << fname << endl << endl;
380 ofile <<
"# L (m) = " <<
L << endl;
381 ofile <<
"# P (Pa) = " <<
P << endl;
385 ofile << setw(15) <<
"00" << j++ <<
"_x";
386 if(!
isPremixed) ofile << setw(13) <<
"00" << j++ <<
"_mixf";
387 ofile << setw(16) <<
"00" << j++ <<
"_T";
388 ofile << setw(16) <<
"00" << j++ <<
"_h";
389 ofile << setw(10) <<
"00" << j++ <<
"_density";
390 for(
int k=0; k<
nsp; k++) {
391 stringstream ss; ss << setfill(
'0') << setw(3) << j++ <<
"_" <<
gas->speciesName(k);
392 ofile << setw(19) << ss.str();
395 for(
int u=0; u<
nsoot; u++) {
396 stringstream yy; yy << setfill(
'0') << setw(3) << j++ <<
"_" <<
"M"<<u;
397 ofile << setw(19) << yy.str();
401 ofile << setprecision(10);
404 ofile << setw(19) << 0;
406 ofile << setw(19) <<
TLbc;
407 ofile << setw(19) <<
hLbc;
408 ofile << setw(19) << rhoLbc;
409 for(
int k=0; k<
nsp; k++)
410 ofile << setw(19) <<
yLbc[k];
412 for(
int k=0; k<
nsoot; k++)
413 ofile << setw(19) << 0;
416 for(
int i=0; i<
ngrd; i++) {
418 ofile << setw(19) <<
x[i];
420 ofile << setw(19) <<
T[i];
421 ofile << setw(19) << h[i];
422 ofile << setw(19) << rho[i];
423 for(
int k=0; k<
nsp; k++)
424 ofile << setw(19) <<
y[i][k];
426 for(
int k=0; k<
nsoot; k++)
427 ofile << setw(19) <<
sootvars[i][k];
433 ofile << setw(19) <<
L;
434 ofile << setw(19) <<
T.back();
435 ofile << setw(19) << h.back();
436 ofile << setw(19) << rho.back();
437 for(
int k=0; k<
nsp; k++)
438 ofile << setw(19) <<
y.back()[k];
440 for(
int k=0; k<
nsoot; k++)
441 ofile << setw(19) <<
sootvars.back()[k];
446 ofile << setw(19) <<
L;
447 ofile << setw(19) << mixfRbc;
448 ofile << setw(19) <<
TRbc;
449 ofile << setw(19) <<
hRbc;
450 ofile << setw(19) << rhoRbc;
451 for(
int k=0; k<
nsp; k++)
452 ofile << setw(19) <<
yRbc[k];
454 for(
int k=0; k<
nsoot; k++)
455 ofile << setw(19) << 0.0;
487 if (icType ==
"linear") {
489 double hLbc =
gas->enthalpy_mass();
491 double hRbc =
gas->enthalpy_mass();
492 for(
int i=0; i<
ngrd; i++) {
493 for(
int k=0; k<
nsp; k++)
496 gas->setMassFractions(&
y[i][0]);
497 gas->setState_HP(h,
P);
504 else if (icType ==
"equilibrium") {
506 for(
int i=0; i<
ngrd; i++) {
507 gas->setState_TPY(
T[i],
P, &
y[i][0]);
508 gas->equilibrate(
"HP");
509 gas->getMassFractions(&
y[i][0]);
516 else if (icType ==
"stored") {
525 else if (icType ==
"premixed") {
527 gas->setMassFractions(&
yLbc[0]);
529 gas->equilibrate(
"HP");
530 for(
int i=0; i<
ngrd; i++) {
531 gas->getMassFractions(&
y[i][0]);
532 T[i] =
gas->temperature();
536 for(
int i=0; i<
ngrd; i++) {
538 gas->equilibrate(
"TP");
539 gas->getMassFractions(&
y[i][0]);
540 T[i] =
gas->temperature();
594 vector<double> D(
ngrd);
595 vector<double> density(
ngrd);
596 vector<double> nu;
if(
doSoot) nu.resize(
ngrd);
597 vector<double> h(
ngrd);
598 for(
int i=0; i<
ngrd; i++) {
599 gas->setMassFractions_NoNorm(&
y[i][0]);
600 gas->setState_TP(
T[i],
P);
601 density[i] =
gas->density();
602 D[i] =
trn->thermalConductivity()/(density[i]*
gas->cp_mass());
603 h[i] =
gas->enthalpy_mass();
604 if(
doSoot) nu[i] =
trn->viscosity()/density[i];
609 vector<double> D_f(
ngrd+1);
610 vector<double> density_f(
ngrd+1);
611 vector<double> nu_f;
if(
doSoot) nu_f.resize(
ngrd+1);
612 vector<double> T_f;
if(
doSoot) T_f.resize(
ngrd+1);
615 density_f[0] =
gas->density();
616 D_f[0] =
trn->thermalConductivity()/(density_f[0]*
gas->cp_mass());
618 nu_f[0] =
trn->viscosity()/density_f[0];
624 density_f.back() =
gas->density();
625 D_f.back() =
trn->thermalConductivity()/(density_f.back()*
gas->cp_mass());
627 nu_f.back() =
trn->viscosity()/density_f.back();
640 for(
int i=1, im=0; i<
ngrd; i++, im++) {
641 density_f[i] = density[im]*
fl[im] + density[i]*
fr[im];
642 D_f[i] = D[im] *
fl[im] + D[i] *
fr[im];
644 nu_f[i] = nu[im]*
fl[im] + nu[i]*
fr[im];
645 T_f[i] =
T[im] *
fl[im] +
T[i] *
fr[im];
651 for(
int k=0; k<
nsp; k++) {
657 flux_y[0][k] = -density_f[0] *D_f[0] *(
y[0][k]-
yLbc[k]) *2/
dx[0];
660 for(
int i=1; i<
ngrd; i++) {
661 flux_y[i][k] = -density_f[i]*D_f[i]*(
y[i][k]-
y[i-1][k])*2/(
dx[i-1]+
dx[i]);
668 for(
int i=1; i<
ngrd; i++) {
669 flux_h[i] = -density_f[i]*D_f[i]*(h[i]-h[i-1])*2/(
dx[i-1]+
dx[i]);
673 flux_h.back() = -density_f.back()*D_f.back()*(
hRbc-h.back())*2/
dx.back();
680 vector<double> hsp(
nsp);
681 gas->getEnthalpy_RT(&hsp[0]);
682 for(
size_t k=0; k<
nsp; k++){
683 hsp[k] *=
TLbc*Cantera::GasConstant/
gas->molecularWeight(k);
693 for(
int k=0; k<
nsoot; k++) {
698 (T_f.back()-
T.back())/
dx.back()*2;
704 for(
int i=1; i<
ngrd; i++) {
705 flux_soot[i][k] = 0.556*nu_f[i]*(
T[i]-
T[i-1])/T_f[i]*2/(
dx[i-1]+
dx[i]);
742 vector<vector<double>> D(
ngrd, vector<double> (
nsp,0.0));
743 vector<double> density(
ngrd);
744 vector<double> M(
ngrd);
745 vector<double> tcond(
ngrd);
746 vector<double> nu;
if(
doSoot) nu.resize(
ngrd);
747 for(
int i=0; i<
ngrd; i++) {
748 gas->setMassFractions_NoNorm(&
y[i][0]);
749 gas->setState_TP(
T[i],
P);
750 density[i] =
gas->density();
751 M[i] =
gas->meanMolecularWeight();
752 trn->getMixDiffCoeffs(&D[i][0]);
753 tcond[i] =
trn->thermalConductivity();
755 nu[i] =
trn->viscosity()/density[i];
760 vector<vector<double>> D_f(
ngrd+1, vector<double> (
nsp,0.0));
761 vector<vector<double>> y_f(
ngrd+1, vector<double> (
nsp,0.0));
762 vector<double> density_f(
ngrd+1);
763 vector<double> M_f(
ngrd+1);
764 vector<double> T_f(
ngrd+1);
765 vector<double> tcond_f(
ngrd+1);
766 vector<double> nu_f;
if(
doSoot) nu_f.resize(
ngrd+1);
769 density_f[0] =
gas->density();
770 M_f[0] =
gas->meanMolecularWeight();
771 trn->getMixDiffCoeffs(&D_f[0][0]);
772 tcond_f[0] =
trn->thermalConductivity();
773 if(
doSoot) nu_f[0] =
trn->viscosity()/density_f[0];
779 density_f.back() =
gas->density();
780 M_f.back() =
gas->meanMolecularWeight();
781 trn->getMixDiffCoeffs(&(D_f.back()[0]));
782 tcond_f.back() =
trn->thermalConductivity();
786 nu_f.back() =
trn->viscosity()/density_f.back();
794 for(
int k=0; k<
nsp; k++) {
802 for (
int i=1, im=0; i<
ngrd; i++, im++) {
803 density_f[i] = density[im]*
fl[im] + density[i]*
fr[im];
804 T_f[i] =
T[im] *
fl[im] +
T[i] *
fr[im];
805 tcond_f[i] = tcond[im] *
fl[im] + tcond[i] *
fr[im];
806 M_f[i] = M[im] *
fl[im] + M[i] *
fr[im];
808 nu_f[i] = nu[im] *
fl[im] + nu[i] *
fr[im];
809 for(
int k=0; k<
nsp; k++) {
810 D_f[i][k] = D[im][k] *
fl[im] + D[i][k] *
fr[im];
811 y_f[i][k] =
y[im][k] *
fl[im] +
y[i][k] *
fr[im];
825 for(
int k=0; k<
nsp; k++)
829 for(
int k=0; k<
nsp; k++) {
830 flux_y[0][k] = -density_f[0]*D_f[0][k]*(
y[0][k]-
yLbc[k])*2/
dx[0]
831 -density_f[0]*D_f[0][k]*y_f[0][k]*(M[0]-M_f[0])*2/
dx[0]/M_f[0];
834 for(
int k=0; k<
nsp; k++) {
835 flux_y[0][k] -= y_f[0][k]*jstar;
842 for(
int k=0; k<
nsp; k++)
846 for(
int k=0; k<
nsp; k++) {
848 -density_f.back()*D_f.back()[k]*y_f.back()[k]*(M_f.back()-M[
ngrd-1])*2/
dx.back()/M_f.back();
851 for(
int k=0; k<
nsp; k++) {
858 for (
int i=1; i<
ngrd; i++) {
860 for(
int k=0; k<
nsp; k++) {
861 flux_y[i][k] = -density_f[i]*D_f[i][k]*(
y[i][k]-
y[i-1][k])*2/(
dx[i-1]+
dx[i])
862 -density_f[i]*D_f[i][k]*y_f[i][k]*(M[i]-M[i-1])*2/(
dx[i-1]+
dx[i])/M_f[i];
865 for(
int k=0; k<
nsp; k++) {
866 flux_y[i][k] -= y_f[i][k]*jstar;
875 flux_h[0] = -tcond_f[0]*(
T[0]-T_f[0])*2/
dx[0];
876 flux_h.back() = -tcond_f.back()*(T_f.back()-
T.back())*2/
dx.back();
877 for(
int i=1; i<
ngrd; i++)
878 flux_h[i] = -tcond_f[i]*(
T[i]-
T[i-1])*2/(
dx[i-1]+
dx[i]);
882 vector<double> hsp(
nsp);
885 gas->getEnthalpy_RT(&hsp[0]);
886 for(
size_t k=0; k<
nsp; k++)
889 gas->setState_TPY(T_f.back(),
P, &(y_f.back()[0]));
890 gas->getEnthalpy_RT(&hsp[0]);
891 for(
size_t k=0; k<
nsp; k++)
892 flux_h.back() +=
flux_y.back()[k]*hsp[k]*T_f.back()*Cantera::GasConstant/
gas->molecularWeight(k);
894 for(
size_t i=1; i<
ngrd; i++) {
895 gas->setState_TP(T_f[i],
P);
896 gas->getEnthalpy_RT(&hsp[0]);
897 for(
size_t k=0; k<
nsp; k++)
898 flux_h[i] +=
flux_y[i][k]*hsp[k]*T_f[i]*Cantera::GasConstant/
gas->molecularWeight(k);
904 for(
int k=0; k<
nsoot; k++) {
909 (T_f.back()-
T.back())/
dx.back()*2;
910 for(
int i=1; i<
ngrd; i++) {
918 for(
int i=1; i<
ngrd; i++) {
919 flux_soot[i][k] = -0.556*nu_f[i]*(
T[i]-
T[i-1])/T_f[i]*2/(
dx[i-1]+
dx[i]);
946 vector<double> vars(
nvarA);
948 for(
size_t i=0; i<
ngrd; i++) {
949 for(
size_t k=0; k<
nsp; k++)
950 vars[
Ia(i,k)] =
y[i][k];
962 vector<double> scales_v(
nvarA, 1.0);
963 vector<double> scales_f(
nvarA, 1.0);
964 vector<double> constraints(
nvarA, 0.0);
966 for(
int i=0; i<
nvarA; i++) {
967 scales_v[i] = vars[i] < 1E-3 ? 1E-3 : vars[i];
968 scales_f[i] = vars[i] < 1E-3 ? 1E-3 : vars[i];
976 solver_kinsol s_kin(
this,
nvarA, scales_v, scales_f, constraints, mu, ml, ftol, stol);
985 for(
s=0.0;
s<=1.0;
s+=0.01) {
986 cout << endl <<
"s = " <<
s; cout.flush();
992 for(
size_t i=0; i<
ngrd; i++) {
993 for(
size_t k=0; k<
nsp; k++)
994 y[i][k] = vars[
Ia(i,k)];
1012 for(
size_t i=0; i<
ngrd; i++) {
1013 for(
size_t k=0; k<
nsp; k++)
1014 y[i][k] = vars[
Ia(i,k)];
1025 vector<double> Q(
ngrd);
1028 vector<double> rr(
nsp);
1030 for(
size_t i=0; i<
ngrd; i++) {
1031 gas->setMassFractions_NoNorm(&
y[i][0]);
1032 gas->setState_TP(
T[i],
P);
1033 kin->getNetProductionRates(&rr[0]);
1034 for(
size_t k=0; k<
nsp; k++)
1036 - rr[k]*
gas->molecularWeight(k)*
dx[i];
1047 for(
size_t i=0; i<
nvarA; i++)
1048 F[i] = F[i] + (
s-1.0)*
F0[i];
1065 ignis *flm =
static_cast<ignis *
>(user_data);
1067 double *vars = N_VGetArrayPointer(varsKS);
1068 double *F = N_VGetArrayPointer(fvec);
1070 int rv = flm->
Func(vars, F);
1084 vector<double> kabs, awts;
1085 double fvsoot = 0.0;
1086 double xH2O, xCO2, xCO, xCH4;
1089 for(
int i=0; i<
ngrd; i++) {
1090 isp =
gas->speciesIndex(
"H2O");
1091 xH2O =
y[i][isp]/
gas->molecularWeight(isp)*
gas->meanMolecularWeight();
1092 isp =
gas->speciesIndex(
"CO2");
1093 xCO2 =
y[i][isp]/
gas->molecularWeight(isp)*
gas->meanMolecularWeight();
1094 isp =
gas->speciesIndex(
"CO");
1095 xCO =
y[i][isp]/
gas->molecularWeight(isp)*
gas->meanMolecularWeight();
1096 isp =
gas->speciesIndex(
"CH4");
1097 xCH4 =
y[i][isp]/
gas->molecularWeight(isp)*
gas->meanMolecularWeight();
1098 radProps->get_k_a(kabs, awts,
T[i],
P, fvsoot, xH2O, xCO2, xCO, xCH4);
1101 for(
int j=0; j<nGGa; j++)
1102 Q[i] += -4.0*rad::sigma*kabs[j]*(awts[j]*pow(
T[i],4.0)
1123 const double Tmin,
const double Tmax) {
1126 vector<double> vars(
nvarA);
1128 for(
size_t i=0; i<
ngrd; i++) {
1129 for(
size_t k=0; k<
nsp; k++)
1130 vars[
Ia(i,k)] =
y[i][k];
1142 vector<double> atol(
nvarA, 1.0);
1144 for(
int i=0; i<
nvarA; i++)
1166 double tend = nTauRun * tau;
1168 double dt = tend/nSteps;
1169 dT = Tmax==Tmin ? 0.0 : (Tmax-(Tmin+0.1))/nSteps;
1173 for(
int istep=1; istep<=nSteps; istep++, t+=dt) {
1175 if(doWriteTime &&
dT <= 0.0) {
1178 ss <<
"X_" <<
chi0 <<
"U_" << setfill(
'0') << setw(3) <<
isave++;
1180 ss <<
"L_" <<
L <<
"U_" << setfill(
'0') << setw(3) <<
isave++;
1181 string fname = ss.str();
1189 for(
size_t i=0; i<
ngrd; i++) {
1190 for(
size_t k=0; k<
nsp; k++)
1191 y[i][k] = vars[
Ia(i,k)];
1196 gas->setState_TP(
T[i],
P);
1219 for(
size_t i=0; i<
ngrd; i++) {
1220 for(
size_t k=0; k<
nsp; k++)
1221 y[i][k] = vars[
Ia(i,k)];
1237 vector<double> rr(
nsp);
1238 vector<double> Q(
ngrd);
1241 vector<double> yPAH;
if(
doSoot) yPAH.resize(6,0.0);
1243 vector<double> yGasForSM;
if(
doSoot) yGasForSM.resize( (
size_t)gasSp::size );
1245 for(
size_t i=0; i<
ngrd; i++) {
1246 gas->setMassFractions_NoNorm(&
y[i][0]);
1247 gas->setState_TP(
T[i],
P);
1248 kin->getNetProductionRates(&rr[0]);
1249 double rho =
gas->density();
1250 double mu =
trn->viscosity();
1252 for(
size_t kSootGases=0; kSootGases<(size_t)gasSp::size; kSootGases++) {
1253 size_t kgas =
gas->speciesIndex(gasSpMapIS[kSootGases]);
1254 yGasForSM[kSootGases] = (kgas != Cantera::npos) ?
y[i][kgas] : 0.0;
1259 for(
size_t k=0; k<
nsp; k++)
1261 rr[k]*
gas->molecularWeight(k)/rho;
1270 for(
size_t kSootGases=0; kSootGases<(size_t)gasSp::size; kSootGases++) {
1271 size_t kgas =
gas->speciesIndex(gasSpMapIS[kSootGases]);
1272 if(kgas != Cantera::npos)
1273 dvarsdt[
Ia(i,kgas)] +=
SM->sources.gasSources[kSootGases];
1278 double cp =
gas->cp_mass();
1279 vector<double> hsp(
nsp);
1280 gas->getEnthalpy_RT(&hsp[0]);
1281 for(
size_t k=0; k<
nsp; k++)
1282 hsp[k] *=
T[i]*Cantera::GasConstant/
gas->molecularWeight(k);
1283 double sum_hkdykdt = 0.0;
1284 for(
size_t k=0; k<
nsp; k++)
1285 sum_hkdykdt += hsp[k]*dvarsdt[
Ia(i,k)];
1291 dvarsdt[
Ia(i,
nvar-1)] = 0.0;
1294 double TmaxLocal = *max_element(
T.begin(),
T.end());
1296 cout << endl <<
isave <<
" " << TmaxLocal <<
" " <<
Ttarget <<
" ";
1297 stringstream ss; ss <<
"L_" <<
L <<
"U_" << setfill(
'0') << setw(3) <<
isave++;
1298 string fname = ss.str();
1321 for(
size_t i=0; i<
ngrd; i++) {
1322 for(
size_t k=0; k<
nsp; k++)
1323 y[i][k] = vars[
Ia(i,k)];
1339 vector<vector<double> > rr(
ngrd, vector<double>(
nsp));
1340 vector<double> rho(
ngrd);
1341 vector<double> mu;
if(
doSoot) mu.resize(
ngrd);
1344 vector<double> yPAH;
if(
doSoot) yPAH.resize(6,0.0);
1345 vector<double> yGasForSM;
if(
doSoot) yGasForSM.resize( (
size_t)gasSp::size );
1347 vector<double> cp(
ngrd);
1348 vector<vector<double> > hsp(
ngrd, vector<double>(
nsp));
1349 vector<double> hsprrSum(
ngrd, 0.0);
1351 for(
size_t i=0; i<
ngrd; i++) {
1355 gas->setMassFractions_NoNorm(&
y[i][0]);
1356 gas->setState_TP(
T[i],
P);
1360 kin->getNetProductionRates(&rr[i][0]);
1361 for(
size_t k=0; k<
nsp; k++)
1362 rr[i][k] *=
gas->molecularWeight(k);
1366 gas->getEnthalpy_RT(&hsp[i][0]);
1367 for(
size_t k=0; k<
nsp; k++) {
1368 hsp[i][k] *=
T[i]*Cantera::GasConstant/
gas->molecularWeight(k);
1369 hsprrSum[i] += hsp[i][k] * rr[i][k];
1374 rho[i] =
gas->density();
1375 cp[i] =
gas->cp_mass();
1377 mu[i] =
trn->viscosity();
1378 D[i] =
trn->thermalConductivity()/(rho[i]*cp[i]);
1379 for (
size_t k=0; k<
nsoot; k++)
1386 vector<double> d2ydz2(
ngrd);
1387 vector<double> yy(
ngrd);
1388 for(
size_t k=0; k<
nsp; k++) {
1389 for(
size_t i=0; i<
ngrd; i++)
1392 for(
size_t i=0; i<
ngrd; i++)
1393 dvarsdt[
Ia(i,k)] = 0.5*
chi[i]*d2ydz2[i] + rr[i][k]/rho[i];
1398 vector<double> d2Tdz2(
ngrd);
1401 vector<double> dTdz(
ngrd);
1404 vector<double> dcpdz(
ngrd);
1407 vector<double> dydzdhdzSum(
ngrd, 0.0);
1408 vector<double> dykdz(
ngrd);
1409 vector<double> dhkdz(
ngrd);
1410 vector<double> hh(
ngrd);
1411 for(
size_t k=0; k<
nsp; k++) {
1412 for(
size_t i=0; i<
ngrd; i++) {
1418 for(
size_t i=0; i<
ngrd; i++)
1419 dydzdhdzSum[i] += dykdz[i]*dhkdz[i];
1422 vector<double> Q(
ngrd);
1425 for(
size_t i=0; i<
ngrd; i++) {
1426 dvarsdt[
Ia(i,
nvar-1)] = -hsprrSum[i]/(cp[i]*rho[i]) + 0.5*
chi[i]*
1427 (d2Tdz2[i] + (dTdz[i]*dcpdz[i] + dydzdhdzSum[i])/cp[i]);
1440 double LeS = 1000.0;
1442 vector<double> d2sdz2(
ngrd);
1443 vector<double> ss(
ngrd);
1444 for(
size_t k=0; k<
nsoot; k++) {
1445 for(
size_t i=0; i<
ngrd; i++)
1448 for(
size_t i=0; i<
ngrd; i++)
1449 dvarsdt[
Ia(i,k+
nsp)] = 0.5*
chi[i]*d2sdz2[i]/LeS;
1453 vector<double> C(
ngrd);
1454 vector<double> B(
ngrd);
1455 vector<double> rhoBD(
ngrd);
1456 vector<double> muB_T(
ngrd);
1459 for (
int i=0; i<
ngrd; i++) {
1460 B[i] = sqrt(
chi[i]/(2*D[i]));
1461 rhoBD[i] = rho[i]*B[i]*D[i];
1462 muB_T[i] = mu[i]*B[i]/
T[i];
1465 vector<double> drhoDBdz(
ngrd);
1468 vector<double> dmuB_Tdz(
ngrd);
1471 for (
int i=0; i<
ngrd; i++) {
1472 C[i] = 0.556*mu[i]/(rho[i]*
T[i])* B[i]*B[i]*dTdz[i]-
1473 B[i]/rho[i]*drhoDBdz[i];
1474 for(
size_t kSootGases=0; kSootGases<(size_t)gasSp::size; kSootGases++) {
1475 size_t kgas =
gas->speciesIndex(gasSpMapIS[kSootGases]);
1476 yGasForSM[kSootGases] = (kgas != Cantera::npos) ?
y[i][kgas] : 0.0;
1480 for (
int k=0; k<
nsoot; k++) {
1481 S = 0.556*(
sootvars[i][k]/rho[i])/rho[i]* (B[i]*dTdz[i]*dmuB_Tdz[i]+ B[i]*B[i]*mu[i]/
T[i]*d2Tdz2[i])+
1482 SM->sources.sootSources[k]/rho[i];
1495 dvarsdt[
Ia(i,
nsp+k)] += S;
1498 for(
size_t kSootGases=0; kSootGases<(size_t)gasSp::size; kSootGases++) {
1499 size_t kgas =
gas->speciesIndex(gasSpMapIS[kSootGases]);
1500 if(kgas != Cantera::npos)
1501 dvarsdt[
Ia(i,kgas)] +=
SM->sources.gasSources[kSootGases];
1510 double TmaxLocal = *max_element(
T.begin(),
T.end());
1512 cout << endl <<
isave <<
" " << TmaxLocal <<
" " <<
Ttarget <<
" ";
1513 stringstream ss; ss <<
"X_" <<
chi0 <<
"U_" << setfill(
'0') << setw(3) <<
isave++;
1514 string fname = ss.str();
1539 const vector<double> &v, vector<double> &dvdx) {
1542 double vfR = v[0]*
fl[0]+v[1]*
fr[0];
1543 dvdx[0] = (vfR-vfL)/
dx[0];
1545 for(
size_t i=1; i<
ngrd-1; i++) {
1547 vfR = v[i]*
fl[i]+v[i+1]*
fr[i];
1548 dvdx[i] = (vfR-vfL)/
dx[i];
1569 const vector<double> &v, vector<double> &d2vdx2) {
1571 double dvdxL = (v[0]-vL) /
dx[0]*2;
1572 double dvdxR = (v[1]-v[0])/(
dx[0]+
dx[1])*2;
1573 d2vdx2[0] = (dvdxR - dvdxL)/
dx[0];
1575 for(
size_t i=1; i<
ngrd-1; i++) {
1577 dvdxR = (v[i+1]-v[i])/(
dx[i]+
dx[i+1])*2;
1578 d2vdx2[i] = (dvdxR - dvdxL)/
dx[i];
1595 float tt1, tt2, lnx, sgn;
1596 sgn = (x < 0) ? -1.0f : 1.0f;
1598 x = (1 - x)*(1 + x);
1601 tt1 = 2/(M_PI*0.147) + 0.5f * lnx;
1602 tt2 = 1/(0.147) * lnx;
1604 return(sgn*sqrtf(-tt1 + sqrtf(tt1*tt1 - tt2)));
1622 for(
size_t i=0; i<
ngrd; i++) {
1638int rhsf_cvode(realtype t, N_Vector varsCV, N_Vector dvarsdtCV,
void *user_data) {
1639 ignis *flm =
static_cast<ignis *
>(user_data);
1641 double *vars = N_VGetArrayPointer(varsCV);
1642 double *dvarsdt = N_VGetArrayPointer(dvarsdtCV);
1648 rv = flm->
rhsf(vars, dvarsdt);
std::vector< double > dx
grid spacing (m), nonuniform is fine
std::vector< double > T
temperature (K)
size_t nsp
number of gas species
std::vector< double > F0
for homotopy approaches
bool doRadiation
radiation flag
std::vector< std::vector< double > > flux_soot
species fluxes: [I(igrid, ksoot)]
double hRbc
h boundary values: left and right (as needed)
size_t ngrd
number of interior grid points
double TRbc
T boundary values: left and right (as needed)
double hscale
scaling value for enthalpy (for solvers)
std::vector< double > hspRbc
species enthalpies on right boundary
size_t Ia(size_t i, size_t k)
std::vector< double > awts_sur
awts for surroundings
std::shared_ptr< Cantera::Kinetics > kin
Cantera kinetics object.
std::vector< double > fl
fractions for interpolation
double s
homotopy variable
std::shared_ptr< Cantera::ThermoPhase > gas
Cantera thermo object.
void writeFile(const std::string fname)
bool doLe1
true if doing unity Lewis numbers (default false)
std::vector< double > yRbc
y boundary values: left and right (as needed)
double cpRbc
cp boundary values: left and right (as needed)
bool isFlamelet
true for laminar flamelet (mixture fraction coordinate)
std::vector< double > sootScales
scaling value for soot variables (for solvers)
std::shared_ptr< streams > strm
streams object (mixture fraction, etc.)
std::vector< double > fr
fractions for interpolation
bool doEnergyEqn
for premixed flames: can solve energy equation or set T profile
double Tscale
scaling value for temperature (for solvers)
size_t nvar
number of transported variables at each grid point
void setDerivative2(const double vL, const double vR, const std::vector< double > &v, std::vector< double > &d2vdx2)
int rhsf_flamelet(const double *vars, double *dvarsdt)
std::vector< std::vector< double > > sootstore
stored soot variables
double dT
delta T increment for unsteady cases
void writeFileHdf5(const std::string gname, const std::string timeType)
std::vector< double > x
grid position values (m)
std::shared_ptr< HighFive::File > fh5
hdf5 file pointer
std::vector< std::vector< double > > flux_y
species fluxes: [I(igrid, ksp)] I(igrid,ksp) maps 2D onto 1D
int Func(const double *vars, double *F)
std::shared_ptr< Cantera::Transport > trn
Cantera transport object.
std::shared_ptr< soot::sootModel > SM
soot model
std::vector< double > hspLbc
species enthalpies on left boundary
std::vector< double > yLbc
double P
system pressure, uniform (Pa)
std::shared_ptr< linearInterp > LI
interpolator for specified temperature profiles
ignis(const bool _isPremixed, const bool _doEnergyEqn, const bool _isFlamelet, const bool _doSoot, const size_t _ngrd, const double _L, const double _P, std::shared_ptr< Cantera::Solution > csol, std::string _radType, const std::vector< double > &_yLbc, const std::vector< double > &_yRbc, const double _TLbc, const double _TRbc, std::shared_ptr< soot::sootModel > _SM, std::shared_ptr< soot::state > _SMstate)
std::vector< std::vector< double > > y
mass fractions: y[igrid][isp]
std::vector< std::vector< double > > ystore
stored mass fractions
void setDerivative(const double vL, const double vR, const std::vector< double > &v, std::vector< double > &dvdx)
std::vector< double > kabs_sur
kabs for surroundings
std::shared_ptr< rad > radProps
radiation object
double Ttarget
for unsteady cases, run until this max T instead of for a given time
std::vector< double > flux_h
species fluxes: [igrid]
void setChi(const double _chi0)
double mflux
premixed flame mass flux (kg/m2*s)
std::shared_ptr< soot::state > SMstate
holds state variables (gas and soot) for soot model
std::vector< std::vector< double > > sootvars
soot moments or sections; sootvars[igrid][isoot]
int isave
file counter for save during unsteady cases
void setIC(const std::string icType, const std::string fname="")
void setQrad(std::vector< double > &Q)
std::vector< double > vars0
for homotopy approaches
std::vector< double > chi
dissipation rate profile
std::vector< double > Tstore
stored temperature
int rhsf(const double *vars, double *dvarsdt)
void solveUnsteady(const double nTauRun, const int nsteps, const bool doWriteTime=true, const double Tmin=0, const double Tmax=0)
bool isPremixed
true of the case is a premixed flame, (only left boundary condition, constant mass flux through domai...
size_t nsoot
number of soot variables
std::string radType
radiation model name
double Pstore
stored system pressure (for initializing from stored state)
int integrate(std::vector< double > &y, const realtype dt)
int solve(int(*Func)(N_Vector, N_Vector, void *), std::vector< double > &y)
int rhsf_cvode(realtype t, N_Vector varsCV, N_Vector dvarsdtCV, void *user_data)
int Func_kinsol(N_Vector varsKS, N_Vector fvec, void *user_data)