50 #include <boost/array.hpp> 51 #include <boost/numeric/odeint.hpp> 52 #include <boost/range/numeric.hpp> 55 extern "C"{
void dsteqr_(
char &,
int *,
double *,
double *,
double *,
int *,
double *,
int *); }
73 typedef std::vector< double > state_type;
74 typedef runge_kutta_cash_karp54< state_type > error_stepper_type;
75 typedef controlled_runge_kutta< error_stepper_type > controlled_stepper_type;
145 int mOrder[6] = {0, 1, 2, 3, 4, 5};
146 double mom[2*nNodes], we[nNodes], vi[nNodes], sgBA[2*nNodes], sgCO2[2*nNodes], sc[2*nNodes];
147 double L_l, L_g, CO2_l, CO2_g, T, Lm, c1;
148 double rhoPolySurrgate;
153 double Catalyst_1, CE_A0, CE_A1, CE_B, CE_B2,
154 CE_I0, CE_I1, CE_I2, CE_PBA, CE_Breac,
155 CE_Areac0, CE_Areac1, CE_Ireac0, CE_Ireac1,
156 CE_Ireac2, Bulk, R_1, R_1_mass, R_1_temp, R_1_vol;
200 }
else if (y[1]<0.87) {
201 Rx=-2.027*y[1]+2.013;
210 modena_inputs_set(inputs_kinetics,
CE_A0_Pos, CE_A0);
211 modena_inputs_set(inputs_kinetics,
CE_A1_Pos, CE_A1);
212 modena_inputs_set(inputs_kinetics,
CE_B_Pos, CE_B);
213 modena_inputs_set(inputs_kinetics,
CE_B2_Pos, CE_B2);
214 modena_inputs_set(inputs_kinetics,
CE_I0_Pos, CE_I0);
215 modena_inputs_set(inputs_kinetics,
CE_I1_Pos, CE_I1);
216 modena_inputs_set(inputs_kinetics,
CE_I2_Pos, CE_I2);
217 modena_inputs_set(inputs_kinetics,
CE_PBA_Pos, CE_PBA);
218 modena_inputs_set(inputs_kinetics,
CE_Breac_Pos, CE_Breac);
219 modena_inputs_set(inputs_kinetics,
CE_Areac0_Pos, CE_Areac0);
220 modena_inputs_set(inputs_kinetics,
CE_Areac1_Pos, CE_Areac1);
221 modena_inputs_set(inputs_kinetics,
CE_Ireac0_Pos, CE_Ireac0);
222 modena_inputs_set(inputs_kinetics,
CE_Ireac1_Pos, CE_Ireac1);
223 modena_inputs_set(inputs_kinetics,
CE_Ireac2_Pos, CE_Ireac2);
224 modena_inputs_set(inputs_kinetics,
Bulk_Pos, Bulk);
225 modena_inputs_set(inputs_kinetics,
R_1_Pos, R_1);
226 modena_inputs_set(inputs_kinetics,
R_1_mass_Pos, R_1_mass);
227 modena_inputs_set(inputs_kinetics, R_1_temp_Pos, (T-273.15));
228 modena_inputs_set(inputs_kinetics, R_1_vol_Pos, R_1_vol);
231 int ret_kinetics =
modena_model_call(kinetics, inputs_kinetics, outputs_kinetics);
234 if(modena_error_occurred())
236 modena_inputs_destroy (inputs_kinetics);
237 modena_outputs_destroy (outputs_kinetics);
239 cout <<
"Modena Error:" << (modena_error()) << endl;
261 dydt[29] = modena_outputs_get(outputs_kinetics, source_R_1_temp_Pos);
262 dydt[30] = modena_outputs_get(outputs_kinetics, source_R_1_vol_Pos);
265 dydt[0] = -dydt[15]/(
W_0/1000);
269 dydt[1] = -(dydt[12] + dydt[13])/(
OH_0)*1000;
283 modena_inputs_set(inputs_den, T_denpos, T);
284 modena_inputs_set(inputs_den, XOH_denpos, XOH);
287 int ret_den =
modena_model_call (density_reaction_mixturemodel, inputs_den, outputs_den);
291 modena_inputs_destroy (inputs_den);
292 modena_outputs_destroy (outputs_den);
297 rhoPolySurrgate = modena_outputs_get(outputs_den, 0);
308 modena_inputs_set(inputs_den, T_denpos, T);
310 int ret_den =
modena_model_call (density_reaction_mixturemodel, inputs_den, outputs_den);
313 modena_inputs_destroy (inputs_den);
314 modena_outputs_destroy (outputs_den);
318 rhoPolySurrgate = modena_outputs_get(outputs_den, 0);
325 dydt[0] =
A_W*exp(-
E_W/(
RR*y[2]))*(1-y[0]);
341 dydt[0]=dydt[0]/(1+y[3]*rhoPolySurrgate/
rhoBL);
342 dydt[1]=dydt[1]/(1+y[3]*rhoPolySurrgate/
rhoBL);
347 if (apparentViscosity)
349 double shearRate = 0.05;
354 modena_inputs_set(inputs_rheo,
m0_rheopos, mom[0]);
355 modena_inputs_set(inputs_rheo,
m1_rheopos, mom[1]);
359 if(modena_error_occurred())
361 modena_inputs_destroy (inputs_rheo);
362 modena_outputs_destroy (outputs_rheo);
364 cout <<
"Modena Error: " << (modena_error()) << endl;
366 double mu_app = modena_outputs_get(outputs_rheo, 0);
380 if (realizabilityCheck)
382 cout <<
"----Step 1----" << endl;
383 cout <<
"moments before check realizability: " << endl;
387 cout <<
"----Step 2----" << endl;
388 cout <<
"check positivity" << endl;
391 double initial_mom[2*nNodes];
392 int nMoms = 2*nNodes;
395 for (
int i = 0; i < 2*nNodes; i++)
399 mom[i] = initial_mom[i];
407 cout <<
"----Step 3----" << endl;
408 cout <<
"first Hankel-Hadamard check" << endl;
410 cout <<
"Hankel-Hadamard check (0:realizable, 1:unrealizable) --> " << realizable << endl;
416 cout <<
"----Step 4----" << endl;
417 cout <<
"McGrawCorrection" << endl;
419 cout <<
"moments after McGrawCorrection: " << endl;
423 cout <<
"----Step 5----" << endl;
424 cout <<
"second Hankel-Hadamard check" << endl;
426 cout <<
"Hankel-Hadamard check (0:realizable, 1:unrealizable) --> " << realizable << endl;
430 cout <<
"----Step 6----" << endl;
431 cout <<
"WrightCorrection" << endl;
433 cout <<
"moments after WrightCorrection: " << endl;
440 PDA(we, vi, mom, nNodes);
449 double c_1 = L_l*rhoPolySurrgate*1000.0/
M_B;
450 double c_2 = CO2_l*rhoPolySurrgate*1000.0/
M_CO2;
452 if (bubbleMode ==
"two nodes")
454 double radiusGrowthBA[nNodes],
455 radiusGrowthCO2[nNodes],
456 volumeGrowthBA[nNodes],
457 volumeGrowthCO2[nNodes],
459 int ret_bblgr1[nNodes], ret_bblgr2[nNodes];
460 for (
int i = 0; i < nNodes; i++)
464 modena_inputs_set(inputs_bblgr1, Tbblgr1pos, T);
465 modena_inputs_set(inputs_bblgr1, Rbblgr1pos, nodeRadii[i]);
467 modena_inputs_set(inputs_bblgr1, c_1bblgr1pos, c_1);
468 modena_inputs_set(inputs_bblgr1, p_1bblgr1pos, p_1);
471 radiusGrowthBA[i] = modena_outputs_get(outputs_bblgr1, 0);
473 modena_inputs_set(inputs_bblgr2, Tbblgr2pos, T);
474 modena_inputs_set(inputs_bblgr2, Rbblgr2pos, nodeRadii[i]);
476 modena_inputs_set(inputs_bblgr2, c_2bblgr2pos, c_2);
477 modena_inputs_set(inputs_bblgr2, p_2bblgr2pos, p_2);
481 radiusGrowthCO2[i] = modena_outputs_get(outputs_bblgr2, 0);
484 if(modena_error_occurred())
486 cout << modena_error() << endl;
488 volumeGrowthBA[i] = (radiusGrowthBA[i]*
RR*T)/(p_1);
489 volumeGrowthCO2[i] = (radiusGrowthCO2[i]*
RR*T)/(p_2);
491 if (volumeGrowthBA[i] < 0.0 || radiusGrowthBA[i] < 0.0 ||
L0 < 1.0e-8 || y[1] > X_gel)
493 volumeGrowthBA[i] = 0.0;
495 if (volumeGrowthCO2[i] < 0.0 || radiusGrowthCO2[i] < 0.0 ||
W_0 < 1.0e-8 || y[1] > X_gel)
497 volumeGrowthCO2[i] = 0.0;
501 growthSource(sgBA, sgCO2, we, vi, nNodes, mOrder, CO2_l, L_l, T, volumeGrowthBA, volumeGrowthCO2);
503 else if (bubbleMode ==
"mean radius")
508 modena_inputs_set(inputs_bblgr1, Tbblgr1pos, T);
509 modena_inputs_set(inputs_bblgr1, Rbblgr1pos, R);
511 modena_inputs_set(inputs_bblgr1, c_1bblgr1pos, c_1);
512 modena_inputs_set(inputs_bblgr1, p_1bblgr1pos, p_1);
514 modena_inputs_set(inputs_bblgr2, Tbblgr2pos, T);
515 modena_inputs_set(inputs_bblgr2, Rbblgr2pos, R);
517 modena_inputs_set(inputs_bblgr2, c_2bblgr2pos, c_2);
518 modena_inputs_set(inputs_bblgr2, p_2bblgr2pos, p_2);
526 double dVdt_1[nNodes], dVdt_2[nNodes];
527 for (
int i = 0; i < nNodes; i++)
532 G1 = modena_outputs_get(outputs_bblgr1, 0);
533 G2 = modena_outputs_get(outputs_bblgr2, 0);
534 dVdt_1[0] = (G1*
RR*T)/(p_1);
535 if (dVdt_1[0] < 0.0 || G1 < 0.0 ||
L0<1e-8 || y[1]>X_gel)
539 dVdt_1[1] = dVdt_1[0];
540 dVdt_2[0] = (G2*
RR*T)/(p_2);
541 if (dVdt_2[0] < 0.0 || G2 < 0.0 ||
W_0<1e-8 || y[1]>X_gel)
545 dVdt_2[1] = dVdt_2[0];
547 growthSource(sgBA, sgCO2, we, vi, nNodes, mOrder, CO2_l, L_l, T, dVdt_1, dVdt_2);
551 cerr <<
"Invalid choice of bubbleMode!" << endl;
557 dydt[3] = -sgBA[1]*(p_1/(
RR*y[2]))*(
M_B/1000.0)*(1.0/rhoPolySurrgate);
558 dydt[4] = sgBA[1]*(p_1/(
RR*y[2]))*(
M_B/1000.0)*(1.0/rhoPolySurrgate);
559 dydt[6] = sgCO2[1]*(p_2/(
RR*y[2]))*(
M_CO2/1000.0)*(1.0/rhoPolySurrgate);
560 dydt[5] = -sgCO2[1]*(p_2/(
RR*y[2]))*(
M_CO2/1000.0)*(1.0/rhoPolySurrgate) +\
561 W_0*dydt[0]*(
M_CO2/1000.0)*(1.0/rhoPolySurrgate);
563 dydt[7] = sgBA[0] + sgCO2[0] + sc[0];
564 dydt[8] = sgBA[1] + sgCO2[1] + sc[1];
565 dydt[9] = sgBA[2] + sgCO2[2] + sc[2];
566 dydt[10] = sgBA[3] + sgCO2[3] + sc[3];
570 (-
DH_W*
W_0)/(rhoPolySurrgate*C_TOT)*dydt[0]+\
571 lambda/C_TOT*dydt[3];
578 int main(
int argc,
char **argv)
596 double pBA, pCO2, bubble_radius, rho_foam;
614 y[15] = max(
W_0*1e-3,0.0);
632 runge_kutta4< state_type > stepper;
635 file.open(
"resultsKinetics.txt");
636 file.setf(ios::scientific | ios::showpoint);
638 cout.setf(ios::fixed | ios::showpoint);
640 file << setw(12) <<
"t" << setw(12) <<
"Catalyst_1" 641 << setw(12) <<
"CE_A0" 642 << setw(12) <<
"CE_A1" 643 << setw(12) <<
"CE_B" 644 << setw(12) <<
"CE_B2" 645 << setw(12) <<
"CE_I0" 646 << setw(12) <<
"CE_I1" 647 << setw(12) <<
"CE_I2" 648 << setw(12) <<
"CE_PBA" 649 << setw(12) <<
"CE_Breac" 650 << setw(12) <<
"CE_Areac0" 651 << setw(12) <<
"CE_Areac1" 652 << setw(12) <<
"CE_Ireac0" 653 << setw(12) <<
"CE_Ireac1" 654 << setw(12) <<
"CE_Ireac2" 657 for(
double t=0.0 ; t<
tend ; t+=
dt )
659 cout <<
"Time = " << t << endl;
662 file << setw(12) << t <<
" " << setw(12) << y[11] <<
" " << setw(12) << y[12] <<
" " << setw(12) << y[13] <<
" " 663 << setw(12) << y[14] <<
" " << setw(12) << y[15] <<
" " << setw(12) << y[16] <<
" " 664 << setw(12) << y[17] <<
" " << setw(12) << y[18] <<
" " << setw(12) << y[19] <<
" " 665 << setw(12) << y[20] <<
" " << setw(12) << y[21] <<
" " << setw(12) << y[22] <<
" " 666 << setw(12) << y[23] <<
" " << setw(12) << y[24] <<
" " << setw(12) << y[25] <<
" " 676 rho_foam=
rhoPoly*(1.0 - (y[8]/(1.0+y[8])));
677 file2.open(
"after_foaming.txt");
678 file2.setf(ios::scientific | ios::showpoint);
679 file2 << setw(24) <<
"#foam_density" 680 << setw(24) <<
"mean_cell_diameter" 681 << setw(24) <<
"pressure1" 682 << setw(24) <<
"pressure2" 684 file2 << setw(24) << rho_foam
685 << setw(24) << 2*bubble_radius
size_t source_CE_Ireac2_Pos
memory allocation for outputs of kinetics surrogate model
Source terms due to the bubble growth.
size_t source_CE_PBA_Pos
memory allocation for outputs of kinetics surrogate model
size_t source_CE_A1_Pos
memory allocation for outputs of kinetics surrogate model
size_t m0_rheopos
memory allocation for the moment of order zero as the input of rheology surrogate model ...
double E_W
activation energy for the blowing reaction, J/mol
Calculate difference table for the moments realizability check.
double C_BL
Specific heat of the physical blowing agent in liquid phase, J/kg K.
checks for moments realizability
real(dp) polyol1_ini
initial concentration of polyol 1
size_t CE_I2_Pos
memory allocation for inputs of kinetics surrogate model
size_t source_CE_Breac_Pos
memory allocation for outputs of kinetics surrogate model
double NN
correlated to number of initial bubbles in m^3
size_t source_Bulk_Pos
memory allocation for outputs of kinetics surrogate model
size_t modena_model_inputs_argPos(const modena_model_t *self, const char *name)
Function determining position of an argument in the input vector.
double rel_err
relative error
double abs_err
absolute error
size_t source_CE_Areac0_Pos
memory allocation for outputs of kinetics surrogate model
int HankelHadamard(const double *m, int nNodes)
Hankel-Hadamard function.
double OH_0
Initial concentration of polyol OH groups in the mixutre, mol/m3.
real(dp), dimension(:), allocatable y
state variables
real(dp) amine_ini
initial concentration of amine
Source term due to the bubble coalescence.
size_t CE_Ireac0_Pos
memory allocation for inputs of kinetics surrogate model
size_t CE_PBA_Pos
memory allocation for inputs of kinetics surrogate model
size_t CE_Breac_Pos
memory allocation for inputs of kinetics surrogate model
void printMoms(const double *m, int nNodes)
prints moments
void growthSource(double *, double *, double *, double *, int &, int *, double &, double &, double &, double *, double *)
double sig
correlated to variance of initial distribution
size_t R_1_mass_Pos
memory allocation for inputs of kinetics surrogate model
void WrightCorrection(double *m, int nNodes)
size_t source_CE_I1_Pos
memory allocation for outputs of kinetics surrogate model
real(dp) isocyanate2_ini
initial concentration of isocyanate 2
bool momentsPositivite(const double *moments, int &nNodes)
size_t Catalyst_1_Pos
memory allocation for inputs of kinetics surrogate model
void coalescenceSource(double *, double *, double *, int &, int *, double &)
size_t source_CE_B_Pos
memory allocation for outputs of kinetics surrogate model
int denMod
density mode, 1 = modena, 2 = constant
double C_BG
Specific heat of the physical blowing agent in gas phase, J/kg K.
real(dp) isocyanate3_ini
initial concentration of isocyanate 3
size_t CE_Areac1_Pos
memory allocation for inputs of kinetics surrogate model
double partialPressureCO2(const state_type &y)
partial pressure of CO2
size_t CE_I1_Pos
memory allocation for inputs of kinetics surrogate model
controlled_stepper_type controlled_stepper
double surfaceTension
required for the computation of partial pressure
size_t temp_rheopos
memory allocation for the temperature as the input of rheology surrogate model
write the results into text files
size_t source_CE_Ireac1_Pos
memory allocation for outputs of kinetics surrogate model
void QmomKinetics(const state_type &y, state_type &dydt, double t)
This is to calculate the RHD of all the ODEs.
double M_CO2
Molecular mass of carbon dioxide, kg/kmol.
Product Difference Algorithm.
size_t CE_Ireac2_Pos
memory allocation for inputs of kinetics surrogate model
double W_0
Initial concentration of water in the mixture, mol/m3.
size_t source_CE_A0_Pos
memory allocation for outputs of kinetics surrogate model
size_t CE_Areac0_Pos
memory allocation for inputs of kinetics surrogate model
size_t source_CE_I2_Pos
memory allocation for outputs of kinetics surrogate model
double init_size
initial mean bubble diameter, m
int modena_model_call(modena_model_t *self, modena_inputs_t *inputs, modena_outputs_t *outputs)
Function calling the surrogate model and checking for errors.
double RR
ideal gas constant, J/mol K
size_t m1_rheopos
memory allocation for the moment of order one as the input of rheology surrogate model ...
double DH_OH
Reaction heat for the gelling reaction, J/mol.
size_t source_CE_I0_Pos
memory allocation for outputs of kinetics surrogate model
double Pr
initial/final pressure of the mixture, Pa
size_t CE_I0_Pos
memory allocation for inputs of kinetics surrogate model
size_t source_R_1_mass_Pos
memory allocation for outputs of kinetics surrogate model
size_t source_CE_Ireac0_Pos
memory allocation for outputs of kinetics surrogate model
double dpdt[2]
This is used to compute the partial pressures.
double C_TOT
Total specifc heat of the mixture.
double bubbleRadius(const double m0, const double m1)
radius of bubbles based on the moments
int main(int argc, char *argv[])
Reads parameters. Creates struts and walls. Saves foam morphology to a file.
double air_g
air weight fraction
size_t conv_rheopos
memory allocation for the conversion as the input of rheology surrogate model
double rhoPoly
density of the liquid polymer, kg/m3
size_t source_Catalyst_1_Pos
memory allocation for outputs of kinetics surrogate model
void modena_model_destroy(modena_model_t *self)
Function deallocating the memory allocated for the surrogate model.
allocate memory for the surrogate models
void write_kinetics(const state_type &y, const double t)
double nodeRadius(const double &v)
radius of bubbles at each node
bool dilution
use dilution effect
double rhoBL
density of the blowing agent, kg/m3
double C_CO2
CO2 specific heat, J/kg K.
size_t R_1_Pos
memory allocation for inputs of kinetics surrogate model
real(dp) polyol2_ini
initial concentration of polyol 2
double NCO_0
Initial concentration of isocianate NCO groups in the mixutre, mol/m3.
void mom_init(double *, double &, int &, double &, double &)
double M_B
Molecular mass of blowing agent, kg/kmol.
reads the inputs from input files.
Converts moments based on the unit volume of foam.
double partialPressureBA(const state_type &y)
partial pressure of the physical blowing agent
Maximum soluble physical blowing agent in the liquid mixture.
Wright corrections for moments realizability.
size_t Bulk_Pos
memory allocation for inputs of kinetics surrogate model
All the experimental data required for the source terms calculations.
double Temp0
initial temperature, K
size_t source_CE_Areac1_Pos
memory allocation for outputs of kinetics surrogate model
double M_air
Molecular weight of air, kg/kmol.
size_t kineticTime_Pos
memory allocation for inputs of kinetics surrogate model
double L0
Initial weight fraction of blowing agent in the liquid, -.
size_t CE_A1_Pos
memory allocation for inputs of kinetics surrogate model
size_t CE_B_Pos
memory allocation for inputs of kinetics surrogate model
functions related to the calculations of partial pressures
int kinMod
kinetics model, 1 = Baser, 2 = Baser with R(x)
void PDA(double *, double *, double *, int &)
real(dp) isocyanate1_ini
initial concentration of isocyanate 1
size_t shear_rheopos
memory allocation for the shear rate as the input of rheology surrogate model
size_t source_CE_B2_Pos
memory allocation for outputs of kinetics surrogate model
size_t CE_B2_Pos
memory allocation for inputs of kinetics surrogate model
double A_OH
pre-exponential factor for the gelling reaction, 1/s
Calcualte the determinant of an n by n matrix.
void McGrawCorrection(double *moments, int nNodes)
McGraw correction algorithm.
instantiate the surrogate models:
double pOld[2]
This is to hold the old pressure values during the partial pressure calculations. ...
void modena_model_argPos_check(const modena_model_t *self)
Function checking that the user has queried all input positions.
double DH_W
Reaction heat for the blowing reaction, J/mol.
size_t CE_Ireac1_Pos
memory allocation for inputs of kinetics surrogate model
double A_W
pre-exponential factor for the blowing reaction, 1/s
real(dp) catalyst
concentration of catalyst
size_t CE_A0_Pos
memory allocation for inputs of kinetics surrogate model
double E_OH
activation energy for the gelling reaction, J/mol
void ddtpartialPressure(const state_type &y, const double t, const double dt, double *dpdt, double *pOld, const double p_1, const double p_2, const double R)
time derivative of partial pressure
McGraw correction algorithm.
size_t source_R_1_Pos
memory allocation for outputs of kinetics surrogate model