38 size_t nv_old = oldmech.
nSpecies() + 4;
39 size_t nv_new = newmech.
nSpecies() + 4;
41 if (size_new < nv_new*points) {
43 "new solution array must have length "+
51 for (j = 0; j < points; j++)
52 for (n = 0; n < 4; n++) {
53 newSoln[nv_new*j + n] = oldSoln[nv_old*j + n];
61 for (
size_t k = 0; k < nsp0; k++) {
70 for (j = 0; j < points; j++) {
71 newSoln[nv_new*j + 4 + knew] = oldSoln[nv_old*j + 4 + k];
78 for (j = 0; j < points; j++) {
85 static void st_drawline()
87 writelog(
"\n-------------------------------------"
88 "------------------------------------------");
105 m_transport_option(-1)
129 m_nv = c_offset_Y + m_nsp;
132 m_do_species.resize(m_nsp,
true);
135 m_do_energy.resize(m_points,
false);
137 m_diff.resize(m_nsp*m_points);
138 m_multidiff.resize(m_nsp*m_nsp*m_points);
139 m_flux.
resize(m_nsp,m_points);
140 m_wdot.
resize(m_nsp,m_points, 0.0);
141 m_surfdot.resize(m_nsp, 0.0);
142 m_ybar.resize(m_nsp);
166 for (
size_t k = 0; k < m_nsp; k++) {
180 m_refiner->setActive(0,
false);
181 m_refiner->setActive(1,
false);
182 m_refiner->setActive(2,
false);
183 m_refiner->setActive(3,
false);
186 for (
size_t ng = 0; ng < m_points; ng++) {
187 gr.push_back(1.0*ng/m_points);
190 setID(
"stagnation flow");
200 m_rho.resize(m_points, 0.0);
201 m_wtm.resize(m_points, 0.0);
202 m_cp.resize(m_points, 0.0);
203 m_enth.resize(m_points, 0.0);
204 m_visc.resize(m_points, 0.0);
205 m_tcon.resize(m_points, 0.0);
207 if (m_transport_option == c_Mixav_Transport) {
208 m_diff.resize(m_nsp*m_points);
210 m_multidiff.resize(m_nsp*m_nsp*m_points);
211 m_diff.resize(m_nsp*m_points);
212 m_dthermal.
resize(m_nsp, m_points, 0.0);
214 m_flux.
resize(m_nsp,m_points);
215 m_wdot.
resize(m_nsp,m_points, 0.0);
216 m_do_energy.resize(m_points,
false);
218 m_fixedy.
resize(m_nsp, m_points);
219 m_fixedtemp.resize(m_points);
221 m_dz.resize(m_points-1);
222 m_z.resize(m_points);
226 void StFlow::setupGrid(
size_t n,
const doublereal* z)
232 for (j = 1; j < m_points; j++) {
234 m_dz[j-1] = m_z[j] - m_z[j-1];
245 m_do_soret = withSoret;
247 if (m_trans->
model() == cMulticomponent) {
248 m_transport_option = c_Multi_Transport;
249 m_multidiff.resize(m_nsp*m_nsp*m_points);
250 m_diff.resize(m_nsp*m_points);
251 m_dthermal.
resize(m_nsp, m_points, 0.0);
252 }
else if (m_trans->
model() == cMixtureAveraged) {
253 m_transport_option = c_Mixav_Transport;
254 m_diff.resize(m_nsp*m_points);
257 "Thermal diffusion (the Soret effect) "
258 "requires using a multicomponent transport model.");
260 throw CanteraError(
"setTransport",
"unknown transport model.");
264 void StFlow::enableSoret(
bool withSoret)
266 if (m_transport_option == c_Multi_Transport) {
267 m_do_soret = withSoret;
269 throw CanteraError(
"setTransport",
270 "Thermal diffusion (the Soret effect) "
271 "requires using a multicomponent transport model.");
283 const doublereal* yy = x + m_nv*j + c_offset_Y;
296 const doublereal* yyj = x + m_nv*j + c_offset_Y;
297 const doublereal* yyjp = x + m_nv*(j+1) + c_offset_Y;
298 for (
size_t k = 0; k < m_nsp; k++) {
299 m_ybar[k] = 0.5*(yyj[k] + yyjp[k]);
310 size_t nz = m_zfix.size();
311 bool e = m_do_energy[0];
312 for (j = 0; j < m_points; j++) {
316 zz = (z(j) - z(0))/(z(m_points - 1) - z(0));
320 for (k = 0; k < m_nsp; k++) {
343 doublereal* rg, integer* diagg, doublereal rdt)
359 doublereal* x = xg +
loc();
360 doublereal* rsd = rg +
loc();
361 integer* diag = diagg +
loc();
370 size_t jpt = (jg == 0) ? 0 : jg -
firstPoint();
371 jmin = std::max<size_t>(jpt, 1) - 1;
376 size_t j0 = std::max<size_t>(jmin, 1) - 1;
377 size_t j1 =
std::min(jmax+1,m_points-1);
405 doublereal sum, sum2, dtdzj;
407 for (j = jmin; j <= jmax; j++) {
422 rsd[index(c_offset_U,0)] =
423 -(rho_u(x,1) - rho_u(x,0))/m_dz[0]
424 -(density(1)*V(x,1) + density(0)*V(x,0));
431 rsd[index(c_offset_V,0)] = V(x,0);
432 rsd[index(c_offset_T,0)] = T(x,0);
433 rsd[index(c_offset_L,0)] = -rho_u(x,0);
439 for (k = 0; k < m_nsp; k++) {
441 rsd[index(c_offset_Y + k, 0)] =
442 -(m_flux(k,0) + rho_u(x,0)* Y(x,k,0));
444 rsd[index(c_offset_Y, 0)] = 1.0 - sum;
454 else if (j == m_points - 1) {
461 rsd[index(0,j)] = rho_u(x,j);
462 rsd[index(1,j)] = V(x,j);
463 rsd[index(2,j)] = T(x,j);
464 rsd[index(c_offset_L, j)] = lambda(x,j) - lambda(x,j-1);
465 diag[index(c_offset_L, j)] = 0;
466 doublereal sum = 0.0;
467 for (k = 0; k < m_nsp; k++) {
469 rsd[index(k+4,j)] = m_flux(k,j-1) + rho_u(x,j)*Y(x,k,j);
471 rsd[index(4,j)] = 1.0 - sum;
472 diag[index(4,j)] = 0;
496 rsd[index(c_offset_U,j)] =
497 -(rho_u(x,j+1) - rho_u(x,j))/m_dz[j]
498 -(density(j+1)*V(x,j+1) + density(j)*V(x,j));
501 diag[index(c_offset_U, j)] = 0;
510 rsd[index(c_offset_V,j)]
511 = (shear(x,j) - lambda(x,j) - rho_u(x,j)*dVdz(x,j)
512 - m_rho[j]*V(x,j)*V(x,j))/m_rho[j]
513 - rdt*(V(x,j) - V_prev(j));
514 diag[index(c_offset_V, j)] = 1;
525 doublereal convec, diffus;
526 for (k = 0; k < m_nsp; k++) {
527 convec = rho_u(x,j)*dYdz(x,k,j);
528 diffus = 2.0*(m_flux(k,j) - m_flux(k,j-1))
530 rsd[index(c_offset_Y + k, j)]
531 = (m_wt[k]*(wdot(k,j))
532 - convec - diffus)/m_rho[j]
533 - rdt*(Y(x,k,j) - Y_prev(k,j));
534 diag[index(c_offset_Y + k, j)] = 1;
542 if (m_do_energy[j]) {
553 for (k = 0; k < m_nsp; k++) {
554 flxk = 0.5*(m_flux(k,j-1) + m_flux(k,j));
555 sum += wdot(k,j)*h_RT[k];
556 sum2 += flxk*cp_R[k]/m_wt[k];
562 rsd[index(c_offset_T, j)] =
563 - m_cp[j]*rho_u(x,j)*dtdzj
564 - divHeatFlux(x,j) - sum - sum2;
565 rsd[index(c_offset_T, j)] /= (m_rho[j]*m_cp[j]);
567 rsd[index(c_offset_T, j)] -= rdt*(T(x,j) - T_prev(j));
568 diag[index(c_offset_T, j)] = 1;
573 if (!m_do_energy[j]) {
574 rsd[index(c_offset_T, j)] = T(x,j) -
T_fixed(j);
575 diag[index(c_offset_T, j)] = 0;
578 rsd[index(c_offset_L, j)] = lambda(x,j) - lambda(x,j-1);
579 diag[index(c_offset_L, j)] = 0;
592 if (m_transport_option == c_Mixav_Transport) {
593 for (
size_t j = j0; j < j1; j++) {
595 m_visc[j] = (m_dovisc ? m_trans->
viscosity() : 0.0);
599 }
else if (m_transport_option == c_Multi_Transport) {
600 doublereal sum, sumx, wtm, dz;
601 doublereal
eps = 1.0e-12;
602 for (
size_t m = j0; m < j1; m++) {
604 dz = m_z[m+1] - m_z[m];
607 m_visc[m] = (m_dovisc ? m_trans->
viscosity() : 0.0);
610 DATA_PTR(m_multidiff) + mindex(0,0,m));
612 for (
size_t k = 0; k < m_nsp; k++) {
615 for (
size_t j = 0; j < m_nsp; j++) {
617 sum += m_wt[j]*m_multidiff[mindex(k,j,m)]*
618 ((X(x,j,m+1) - X(x,j,m))/dz + eps);
619 sumx += (X(x,j,m+1) - X(x,j,m))/dz;
622 m_diff[k + m*m_nsp] = sum/(wtm*(sumx+
eps));
647 doublereal* rg, integer* diagg, doublereal rdt)
663 doublereal* x = xg +
loc();
664 doublereal* rsd = rg +
loc();
665 integer* diag = diagg +
loc();
673 size_t jpt = (jg == 0) ? 0 : jg -
firstPoint();
674 jmin = std::max<size_t>(jpt, 1) - 1;
679 size_t j0 = std::max<size_t>(jmin, 1) - 1;
680 size_t j1 =
std::min(jmax+1,m_points-1);
705 doublereal sum, sum2, dtdzj;
707 for (j = jmin; j <= jmax; j++) {
721 rsd[index(c_offset_U,0)] =
722 -(rho_u(x,1) - rho_u(x,0))/m_dz[0]
723 -(density(1)*V(x,1) + density(0)*V(x,0));
730 rsd[index(c_offset_V,0)] = V(x,0);
731 rsd[index(c_offset_T,0)] = T(x,0);
732 rsd[index(c_offset_L,0)] = -rho_u(x,0);
737 for (k = 0; k < m_nsp; k++) {
739 rsd[index(c_offset_Y + k, 0)] =
740 -(m_flux(k,0) + rho_u(x,0)* Y(x,k,0));
742 rsd[index(c_offset_Y, 0)] = 1.0 - sum;
752 else if (j == m_points - 1) {
760 rsd[index(0,j)] = rho_u(x,j) - rho_u(x,j-1);
761 rsd[index(1,j)] = V(x,j);
762 rsd[index(2,j)] = T(x,j) - T(x,j-1);
763 doublereal sum = 0.0;
764 rsd[index(c_offset_L, j)] = lambda(x,j) - lambda(x,j-1);
765 diag[index(c_offset_L, j)] = 0;
766 for (k = 0; k < m_nsp; k++) {
768 rsd[index(k+4,j)] = m_flux(k,j-1) + rho_u(x,j)*Y(x,k,j);
770 rsd[index(4,j)] = 1.0 - sum;
771 diag[index(4,j)] = 0;
784 if (grid(j) > m_zfixed) {
785 rsd[index(c_offset_U,j)] =
786 - (rho_u(x,j) - rho_u(x,j-1))/m_dz[j-1]
787 - (density(j-1)*V(x,j-1) + density(j)*V(x,j));
790 else if (grid(j) == m_zfixed) {
791 if (m_do_energy[j]) {
792 rsd[index(c_offset_U,j)] = (T(x,j) - m_tfixed);
794 rsd[index(c_offset_U,j)] = (rho_u(x,j)
797 }
else if (grid(j) < m_zfixed) {
798 rsd[index(c_offset_U,j)] =
799 - (rho_u(x,j+1) - rho_u(x,j))/m_dz[j]
800 - (density(j+1)*V(x,j+1) + density(j)*V(x,j));
803 diag[index(c_offset_U, j)] = 0;
811 rsd[index(c_offset_V,j)]
812 = (shear(x,j) - lambda(x,j) - rho_u(x,j)*dVdz(x,j)
813 - m_rho[j]*V(x,j)*V(x,j))/m_rho[j]
814 - rdt*(V(x,j) - V_prev(j));
815 diag[index(c_offset_V, j)] = 1;
826 doublereal convec, diffus;
827 for (k = 0; k < m_nsp; k++) {
828 convec = rho_u(x,j)*dYdz(x,k,j);
829 diffus = 2.0*(m_flux(k,j) - m_flux(k,j-1))
831 rsd[index(c_offset_Y + k, j)]
832 = (m_wt[k]*(wdot(k,j))
833 - convec - diffus)/m_rho[j]
834 - rdt*(Y(x,k,j) - Y_prev(k,j));
835 diag[index(c_offset_Y + k, j)] = 1;
843 if (m_do_energy[j]) {
854 for (k = 0; k < m_nsp; k++) {
855 flxk = 0.5*(m_flux(k,j-1) + m_flux(k,j));
856 sum += wdot(k,j)*h_RT[k];
857 sum2 += flxk*cp_R[k]/m_wt[k];
863 rsd[index(c_offset_T, j)] =
864 - m_cp[j]*rho_u(x,j)*dtdzj
865 - divHeatFlux(x,j) - sum - sum2;
866 rsd[index(c_offset_T, j)] /= (m_rho[j]*m_cp[j]);
868 rsd[index(c_offset_T, j)] -= rdt*(T(x,j) - T_prev(j));
869 diag[index(c_offset_T, j)] = 1;
873 rsd[index(c_offset_T, j)] = T(x,j) -
T_fixed(j);
874 diag[index(c_offset_T, j)] = 0;
877 rsd[index(c_offset_L, j)] = lambda(x,j) - lambda(x,j-1);
878 diag[index(c_offset_L, j)] = 0;
897 sprintf(buf,
" Pressure: %10.4g Pa \n", m_press);
899 for (i = 0; i < nn; i++) {
901 sprintf(buf,
"\n z ");
903 for (n = 0; n < 5; n++) {
908 for (j = 0; j < m_points; j++) {
909 sprintf(buf,
"\n %10.4g ",m_z[j]);
911 for (n = 0; n < 5; n++) {
912 sprintf(buf,
" %10.4g ",component(x, i*5+n,j));
918 size_t nrem = m_nv - 5*nn;
920 sprintf(buf,
"\n z ");
922 for (n = 0; n < nrem; n++) {
927 for (j = 0; j < m_points; j++) {
928 sprintf(buf,
"\n %10.4g ",m_z[j]);
930 for (n = 0; n < nrem; n++) {
931 sprintf(buf,
" %10.4g ",component(x, nn*5+n,j));
945 doublereal sum, wtm, rho, dz, gradlogT;
947 switch (m_transport_option) {
949 case c_Mixav_Transport:
950 case c_Multi_Transport:
951 for (j = j0; j < j1; j++) {
957 for (k = 0; k < m_nsp; k++) {
958 m_flux(k,j) = m_wt[k]*(rho*m_diff[k+m_nsp*j]/wtm);
959 m_flux(k,j) *= (X(x,k,j) - X(x,k,j+1))/dz;
963 for (k = 0; k < m_nsp; k++) {
964 m_flux(k,j) += sum*Y(x,k,j);
970 throw CanteraError(
"updateDiffFluxes",
"unknown transport model");
974 for (m = j0; m < j1; m++) {
975 gradlogT = 2.0 * (T(x,m+1) - T(x,m)) /
976 ((T(x,m+1) + T(x,m)) * (z(m+1) - z(m)));
977 for (k = 0; k < m_nsp; k++) {
978 m_flux(k,m) -= m_dthermal(k,m)*gradlogT;
997 if (n >= c_offset_Y && n < (c_offset_Y + m_nsp)) {
1006 size_t StFlow::componentIndex(
string name)
const
1012 }
else if (name==
"V") {
1014 }
else if (name==
"T") {
1016 }
else if (name==
"lambda") {
1019 for (
size_t n=4; n<m_nsp+4; n++) {
1030 void StFlow::restore(
const XML_Node& dom, doublereal* soln)
1033 vector<string> ignored;
1037 vector<XML_Node*> str;
1038 dom.getChildren(
"string",str);
1039 int nstr =
static_cast<int>(str.size());
1040 for (
int istr = 0; istr < nstr; istr++) {
1041 const XML_Node& nd = *str[istr];
1042 writelog(nd[
"title"]+
": "+nd.value()+
"\n");
1047 pp =
getFloat(dom,
"pressure",
"pressure");
1051 vector<XML_Node*> d;
1052 dom.child(
"grid_data").getChildren(
"floatArray",d);
1053 size_t nd = d.size();
1056 size_t n, np = 0, j, ks, k;
1058 bool readgrid =
false, wrote_header =
false;
1059 for (n = 0; n < nd; n++) {
1060 const XML_Node& fa = *d[n];
1072 throw CanteraError(
"StFlow::restore",
1073 "domain contains no grid points.");
1077 for (n = 0; n < nd; n++) {
1078 const XML_Node& fa = *d[n];
1083 if (x.size() == np) {
1084 for (j = 0; j < np; j++) {
1085 soln[index(0,j)] = x[j];
1090 }
else if (nm ==
"z") {
1092 }
else if (nm ==
"V") {
1094 if (x.size() == np) {
1095 for (j = 0; j < np; j++) {
1096 soln[index(1,j)] = x[j];
1101 }
else if (nm ==
"T") {
1103 if (x.size() == np) {
1104 for (j = 0; j < np; j++) {
1105 soln[index(2,j)] = x[j];
1114 for (
size_t jj = 0; jj < np; jj++) {
1115 zz[jj] = (grid(jj) - zmin())/(zmax() - zmin());
1121 }
else if (nm ==
"L") {
1123 if (x.size() == np) {
1124 for (j = 0; j < np; j++) {
1125 soln[index(3,j)] = x[j];
1132 if (x.size() == np) {
1135 for (j = 0; j < np; j++) {
1136 soln[index(k+4,j)] = x[j];
1140 ignored.push_back(nm);
1144 if (ignored.size() != 0) {
1147 size_t nn = ignored.size();
1148 for (
size_t n = 0; n < nn; n++) {
1153 for (ks = 0; ks < nsp; ks++) {
1154 if (did_species[ks] == 0) {
1155 if (!wrote_header) {
1156 writelog(
"Missing data for species:\n");
1157 wrote_header =
true;
1165 throw CanteraError(
"StFlow::restore",
"Data size error");
1185 XML_Node& gv = flow.addChild(
"grid_data");
1186 addFloat(flow,
"pressure", m_press,
"Pa",
"pressure");
1196 x.size(),
DATA_PTR(x),
"1/s",
"rate");
1204 for (k = 0; k < m_nsp; k++) {
1207 x.size(),
DATA_PTR(x),
"",
"massFraction",0.0,1.0);