44 const auto nan = std::numeric_limits<MFloat>::quiet_NaN();
46 for(
MInt i = 0; i < nDim; i++) {
48 m_oldFluidVel[i] = nan;
67 hasCollided() =
false;
68 hadWallColl() =
false;
70 for(
MInt i = 0; i < nDim; i++) {
71 ASSERT(!isnan(m_fluidVel[i]),
"");
72 m_oldFluidVel[i] = m_fluidVel[i];
74 ASSERT(m_fluidDensity > 0,
"");
75 m_oldFluidDensity = m_fluidDensity;
86 mTerm(1, AT_,
"coupling of invalid particle?");
89 if(!s_backPtr->m_heatCoupling && !s_backPtr->m_evaporation) {
91 m_redistWeight.clear();
92 interpolateVelocityAndDensity(m_cellId, m_position.data(), m_fluidVel.data(), m_fluidDensity, m_redistWeight);
96 for(
MInt i = 0; i < nDim; i++) {
97 ASSERT(!isnan(m_oldFluidVel[i]),
"");
99 ASSERT(m_oldFluidDensity > 0,
"");
103 if((s_backPtr->m_heatCoupling && std::isnan(m_heatFlux)) || (s_backPtr->m_massCoupling && std::isnan(m_dM))) {
104 cerr <<
"Invalid energy equation!" << m_partId <<
" " << m_position[0] <<
" " << m_position[1] <<
" "
105 << m_position[2] << endl;
107 for(
MInt i = 0; i < nDim; i++) {
108 if(std::isnan(m_accel[i])) {
109 cerr <<
"Invalid motion equation!" << m_partId <<
" " << m_position[0] <<
" " << m_position[1] <<
" "
110 << m_position[2] << endl;
114 if(std::isnan(m_velocity[i])) {
115 cerr <<
"Invalid motion equation2!" << m_partId <<
" " << m_position[0] <<
" " << m_position[1] <<
" "
116 << m_position[2] <<
" " << m_densityRatio <<
" " << hadWallColl() << endl;
122 if(s_backPtr->m_momentumCoupling) momentumCoupling();
123 if(s_backPtr->m_heatCoupling) heatCoupling();
124 if(s_backPtr->m_massCoupling) massCoupling();
132 if(m_creationTime > s_backPtr->m_timeStep) {
133 cerr <<
"Limiting creation time from " << m_creationTime <<
" to " << s_backPtr->m_timeStep - MFloatEps << endl;
134 m_creationTime = s_backPtr->m_timeStep - MFloatEps;
137 const MFloat relT = (s_backPtr->m_timeStep - m_creationTime) / s_backPtr->m_timeStep;
139 if(m_dM < 0 || relT < 0 || relT > 1) {
140 cerr << m_creationTime <<
" " << m_partId <<
" " << m_dM <<
" " << relT <<
" " << s_backPtr->m_timeStep << endl;
141 mTerm(1, AT_
"Invalid mass flux");
145 const MFloat massFlux = -m_noParticles * m_dM * relT;
147 s_backPtr->m_sumEvapMass -= (massFlux * s_backPtr->m_timeStep);
149 if(!s_backPtr->m_couplingRedist) {
150 s_backPtr->a_massFlux(m_cellId) += massFlux;
152 for(
MInt n = 0; n < (signed)m_neighborList.size(); n++) {
153 s_backPtr->a_massFlux(m_neighborList[n]) += m_redistWeight.at(n) * massFlux;
165 const MFloat relT = (s_backPtr->m_timeStep - m_creationTime) / s_backPtr->m_timeStep;
170 (s_backPtr->m_evaporation) ? m_dM * relT * s_backPtr->m_timeStep + sphericalMass() : sphericalMass();
172 array<MFloat, nDim> force{};
173 array<MFloat, 3> evapMom{F0, F0, F0};
175 for(
MInt i = 0; i < nDim; i++) {
177 const MFloat invDensityRatio = (abs(m_densityRatio) <= MFloatEps) ? 1.0 : 1.0 / m_densityRatio;
178 force[i] = m_noParticles * mass * (m_accel[i] - ((1.0 - invDensityRatio) * s_Frm[i])) * relT;
182 if(s_backPtr->m_evaporation) evapMom[i] = -m_noParticles * m_dM * m_velocity[i] * relT;
187 const MFloat work = std::inner_product(force.begin(), force.end(), m_oldVel.begin(), 0.0);
190 if(!s_backPtr->m_couplingRedist) {
191 for(
MInt i = 0; i < nDim; i++) {
192 s_backPtr->a_momentumFlux(m_cellId, i) += (force[i] + evapMom[i]);
194 s_backPtr->a_workFlux(m_cellId) += work;
197 ASSERT(m_redistWeight.size() == m_neighborList.size(),
198 "Invalid " + to_string(m_redistWeight.size()) +
"!=" + to_string(m_neighborList.size()));
199 for(
MInt n = 0; n < (signed)m_neighborList.size(); n++) {
201 for(
MInt i = 0; i < nDim; i++) {
202 s_backPtr->a_momentumFlux(m_neighborList[n], i) += m_redistWeight.at(n) * (force[i] + evapMom[i]);
204 s_backPtr->a_workFlux(m_neighborList[n]) += m_redistWeight.at(n) * work;
216 const MFloat relT = (s_backPtr->m_timeStep - m_creationTime) / s_backPtr->m_timeStep;
220 for(
MInt i = 0; i < nDim; i++) {
221 velMagSquared +=
POW2(m_oldVel[i]);
225 const MFloat energySource = m_noParticles * (m_heatFlux - 0.5 * m_dM * velMagSquared);
227 if(s_backPtr->m_couplingRedist) {
228 for(
MInt n = 0; n < (signed)m_neighborList.size(); n++) {
230 s_backPtr->a_heatFlux(m_neighborList[n]) += m_redistWeight.at(n) * energySource * relT;
233 s_backPtr->a_heatFlux(m_cellId) += energySource * relT;
240 const MFloat dt = s_backPtr->m_timeStep - m_creationTime;
241 ASSERT(dt > 0,
"Timestep < 0");
244 m_oldPos = m_position;
245 m_oldVel = m_velocity;
246 m_oldAccel = m_accel;
247 m_oldCellId = m_cellId;
250 MLong debugPartId = -1;
251 if(m_partId == debugPartId) {
252 cerr <<
"BT " << m_velocity[0] <<
" " << m_velocity[1] <<
" " << m_velocity[2] << endl;
257 for(
MInt i = 0; i < nDim; i++) {
258 m_accel[i] = s_Frm[i];
259 m_oldAccel[i] = s_Frm[i];
265 for(
MInt i = 0; i < nDim; i++) {
266 ASSERT(!isnan(m_oldFluidVel[i]),
"");
268 ASSERT(m_oldFluidDensity > 0,
"");
272 const MFloat invDensityRatio =
273 1.0 / (
static_cast<MFloat>(ceil(s_backPtr->m_material->density(m_temperature) / m_oldFluidDensity * 1E9)) / 1E9);
275 m_densityRatio = 1 / invDensityRatio;
278 array<MFloat, nDim> predictedPos{};
279 array<MFloat, nDim> predictedVel{};
282 for(
MInt i = 0; i < nDim; i++) {
283 predictedVel[i] = m_oldVel[i] + dt * m_oldAccel[i];
284 predictedPos[i] = m_oldPos[i] + dt * m_oldVel[i] * s_lengthFactor + 0.5 * dt * dt * m_oldAccel[i] * s_lengthFactor;
288 if(m_partId == debugPartId) {
289 cerr <<
"PT " << m_velocity[0] <<
" " << m_velocity[1] <<
" " << m_velocity[2] << endl;
295 const MInt predictedCellId = s_backPtr->grid().findContainingLeafCell(&predictedPos[0], m_cellId);
297 if(predictedCellId < 0 || m_cellId < 0) {
304 ASSERT(m_cellId > -1,
"Invalid cell!");
305 ASSERT(predictedCellId > -1,
"Invalid predicetd cell!");
306 ASSERT(s_backPtr->c_isLeafCell(predictedCellId),
"Invalid cell!");
307 ASSERT(predictedCellId > -1,
"Invalid cell!");
309 array<MFloat, nDim> fluidVel{};
311 vector<MFloat> predictedWeights(0);
312 interpolateVelocityAndDensity(predictedCellId, predictedPos.data(), fluidVel.data(), fluidDensity, predictedWeights);
314 const MFloat T = s_backPtr->a_fluidTemperature(m_cellId);
316 MFloat fluidViscosity = s_backPtr->m_material->dynViscosityFun(T);
319 if(s_backPtr->m_dragModelType == 0) {
320 for(
MInt i = 0; i < nDim; i++) {
321 m_velocity[i] = predictedVel[i];
322 m_position[i] = predictedPos[i];
323 m_accel[i] = m_oldAccel[i];
326 switch(s_backPtr->m_motionEquationType) {
337 const MFloat relVel_old = magRelVel(&m_oldFluidVel[0], &m_oldVel[0]);
338 const MFloat relVel = magRelVel(&fluidVel[0], &predictedVel[0]);
342 cerr <<
"relVel " << fluidVel[0] <<
" " << fluidVel[1] <<
" " << fluidVel[2] <<
" " << predictedVel[0] <<
" "
343 << predictedVel[1] <<
" " << predictedVel[2] <<
" " << predictedCellId << endl;
344 mTerm(1, AT_,
"Invalid relative velocity!");
349 const MFloat DC_old = dragFactor(particleRe(relVel_old, m_oldFluidDensity, fluidViscosity) * s_Re) / s_Re
350 * fParticleRelTime(fluidViscosity);
352 const MFloat DC = dragFactor(particleRe(relVel, fluidDensity, fluidViscosity) * s_Re) / s_Re
353 * fParticleRelTime(fluidViscosity);
357 array<MFloat, nDim> avgFlowVel{};
358 for(
MInt i = 0; i < nDim; i++) {
359 avgFlowVel[i] = 0.5 * (m_oldFluidVel[i] + fluidVel[i]);
361 const MFloat avgDC = s_backPtr->m_motionEquationType == 0 ? DC_old : 0.5 * (DC_old + DC);
364 for(
MInt i = 0; i < nDim; i++) {
366 avgFlowVel[i] + (1.0 - invDensityRatio) * s_Frm[i] / avgDC
367 + exp(-avgDC * dt) * (m_oldVel[i] - avgFlowVel[i] + (invDensityRatio - 1.0) * s_Frm[i] / avgDC);
369 m_accel[i] = (m_velocity[i] - m_oldVel[i]) / dt;
371 m_position[i] = m_oldPos[i] + 0.5 * (m_oldVel[i] + m_velocity[i]) * dt * s_lengthFactor;
378 const MFloat relVel = magRelVel(&fluidVel[0], &predictedVel[0]);
380 const MFloat Rep = particleRe(relVel, m_oldFluidDensity, fluidViscosity) * s_Re;
382 const MFloat CD = dragFactor(Rep) / s_Re * fParticleRelTime(fluidViscosity);
384 for(
MInt i = 0; i < nDim; i++) {
385 m_accel[i] = CD * (fluidVel[i] - predictedVel[i]) + (1.0 - invDensityRatio) * s_Frm[i];
386 m_velocity[i] = m_oldVel[i] + dt * F1B2 * (m_accel[i] + m_oldAccel[i]);
387 m_position[i] = m_oldPos[i] + dt * F1B2 * (m_velocity[i] + m_oldVel[i]) * s_lengthFactor;
393 for(
MInt i = 0; i < nDim; i++) {
394 m_position[i] = m_oldPos[i] + 0.5 * dt * (fluidVel[i] + m_oldVel[i]) * s_lengthFactor;
395 m_velocity[i] = fluidVel[i];
396 m_accel[i] = (m_velocity[i] - m_oldVel[i]) / dt;
401 mTerm(1, AT_,
"Unknown particle corrector equation type!");
407 if(m_partId == debugPartId) {
408 cerr <<
"AT " << m_velocity[0] <<
" " << m_velocity[1] <<
" " << m_velocity[2] << endl;
413 checkCellChange(&m_oldPos[0]);
416 for(
MInt i = 0; i < nDim; i++) {
417 if(std::isnan(m_accel[i])) {
418 cerr <<
"Nan acc. for " << s_backPtr->domainId() <<
" " << m_partId <<
" " << m_position[0] <<
" "
419 << m_position[1] <<
" " << m_position[nDim - 1] <<
" " << s_backPtr->a_isValidCell(m_cellId) <<
" "
420 << m_oldPos[0] <<
" " << m_oldPos[1] <<
" " << m_oldPos[nDim - 1] <<
" " << m_creationTime <<
" "
421 << fluidVel[0] <<
" " << fluidVel[1] <<
" " << fluidVel[nDim - 1] << fluidDensity <<
" " << T <<
" "
422 << fluidViscosity <<
" " << m_oldVel[0] <<
" " << m_oldVel[1] <<
" " << m_oldVel[nDim - 1] << endl;
437 switch(s_backPtr->m_dragModelType) {
447 result = 1.0 + 0.15 * pow(partRe, 0.687);
451 result = 1.0 + 0.17 * pow(partRe, 0.632) + 1.0e-6 * pow(partRe, 2.25);
461 result = 0.424 * partRe / 24.0;
462 }
else if(partRe <= 0.1) {
467 result = 1.0 + pow(partRe, 2.0 / 3.0) / 6.0;
474 result = 0.44 * partRe / 24.0;
476 result = 1.0 + 0.15 * pow(partRe, 0.687);
479 const MFloat fluidFractionUnlimited = 1 - s_backPtr->a_volumeFraction(m_cellId);
480 const MFloat fluidFraction = fluidFractionUnlimited < 0.1 ? 0.1 : fluidFractionUnlimited;
481 result *= pow(fluidFraction, -2.65) * (fluidFraction -
POW2(fluidFraction));
487 const MFloat fluidFractionUnlimited = 1 - s_backPtr->a_volumeFraction(m_cellId);
488 const MFloat fluidFraction = fluidFractionUnlimited < 0.1 ? 0.1 : fluidFractionUnlimited;
489 result = pow(fluidFraction, -2.65) + 1.0 / 6.0 * pow(partRe, 2.0 / 3.0) * pow(fluidFraction, -1.78);
495 result = std::max(1.83 * partRe / 24, 0.1);
499 mTerm(1, AT_,
"Unknown particle drag method");
511 const MFloat dt = s_backPtr->m_timeStep - m_creationTime;
512 ASSERT(dt > 0,
"Timestep < 0");
515 if(isnan(m_dM) || isnan(m_diameter) || isnan(m_temperature)) {
516 cerr <<
globalTimeStep <<
" " << m_dM <<
" " << m_diameter <<
" " << m_temperature << endl;
517 mTerm(1, AT_,
"Nan input values for evaporation!");
535 m_redistWeight.clear();
539 if(!s_backPtr->m_massCoupling) {
540 interpolateAllFluidVariables(m_cellId, m_position.data(), m_fluidVel.data(), m_fluidDensity, p_fluid, T_fluid,
543 interpolateAllFluidVariables(m_cellId, m_position.data(), m_fluidVel.data(), m_fluidDensity, p_fluid, T_fluid,
544 Y_fluid, m_redistWeight);
548 if(m_diameter <= s_backPtr->m_sizeLimit) {
549 m_dM = sphericalMass() / dt;
552 fullyEvaporated() =
true;
564 const MFloat volume = sphericalVolume();
565 ASSERT(volume > 0,
"Invalid volume!");
567 static constexpr MFloat convEvap = 1E-10;
568 const MFloat oldDiameter = m_diameter;
570 MFloat previousTemp = m_temperature;
573 const MFloat oldMass = sphericalMass();
574 const MFloat oldTemperature = m_temperature;
575 const MFloat oldSheddedMass = 1.0 / 6.0 * PI * s_backPtr->m_material->density(m_temperature) *
POW3(m_shedDiam);
578 const MFloat cp_liquid = s_backPtr->m_material->cp(m_temperature);
580 static constexpr MBool belanHarstad =
true;
585 const MFloat T_Boil = s_backPtr->m_material->boilingPoint();
587 const MFloat p_Boil = s_backPtr->m_material->bpRefPressure();
591 const MFloat gasConstant_vap = s_backPtr->m_material->gasConstant();
594 const MFloat molWeightRatio = s_backPtr->m_material->molWeightRatio();
597 const MFloat gammaMinusOne = s_backPtr->m_material->gammaMinusOne();
600 previousTemp = m_temperature;
603 if(m_diameter <= s_backPtr->m_sizeLimit) {
606 m_temperature = oldTemperature;
608 fullyEvaporated() =
true;
614 const MFloat T_bndry = 2.0 / 3.0 * m_temperature + 1.0 / 3.0 * T_fluid;
619 MFloat viscosity_fluid = s_backPtr->m_material->dynViscosityFun(T_bndry);
620 if(viscosity_fluid < 0) {
621 viscosity_fluid = numeric_limits<MFloat>::epsilon();
625 MFloat diffusionC = s_backPtr->m_material->diffusionCoefficient(T_bndry);
626 ASSERT(diffusionC > 0,
"ERROR: Invalid diffusion coefficient.");
630 MFloat lH_ev = s_backPtr->m_material->latentHeatEvap(m_temperature);
633 MFloat lamda_fluid = s_backPtr->m_material->airThermalConductivity(T_bndry);
634 if(lamda_fluid < 0) {
635 lamda_fluid = numeric_limits<MFloat>::epsilon();
639 const MFloat lamda_vap = s_backPtr->m_material->thermalConductivity(T_bndry);
642 const MFloat viscosity_vap = s_backPtr->m_material->dynamicViscosity(T_bndry);
645 const MFloat density_vap = p_fluid / (gasConstant_vap * T_bndry);
649 const MFloat Sc = viscosity_fluid / (m_fluidDensity * diffusionC) * s_Sc;
652 const MFloat Pr = s_backPtr->m_material->airPrandtl(T_bndry) * s_Pr;
660 MFloat X_surf = p_Boil / p_fluid * exp(lH_ev / gasConstant_vap * (1.0 / T_Boil - 1.0 / m_temperature));
662 static constexpr MFloat X_surfLimit = 0.99999;
663 if(X_surf > X_surfLimit) {
664 X_surf = X_surfLimit;
665 }
else if(X_surf < 0) {
666 X_surf = 1.0 - X_surfLimit;
670 static constexpr MBool nonEquilibrium =
true;
684 const MFloat Re_b = m_dM / (PI * viscosity_fluid * m_diameter) * s_Re;
685 beta = 0.5 * Pr * Re_b;
690 viscosity_fluid * sqrt(2.0 * PI * m_temperature * gasConstant_vap) / (Sc * p_fluid * m_diameter * s_Re);
693 X_surf = X_surf - (2.0 * beta * Lk_d);
697 X_surf = 1.0 - X_surfLimit;
701 ASSERT(X_surf <= 1.0,
"ERROR: Invalid corrected fuel surface mole concentration (>100%): " + to_string(X_surf));
702 ASSERT(X_surf >= 0.0,
"ERROR: Invalid corrected fuel surface mole concentration (<0%): " + to_string(X_surf));
705 MFloat Y_surf = X_surf * molWeightRatio / (X_surf * molWeightRatio + (1.0 - X_surf));
707 ASSERT(Y_surf <= 1.0,
"ERROR: Invalid fuel surface mass concentration (>100%): " + to_string(Y_surf));
708 if(std::isnan(Y_surf)) {
709 cerr <<
"X_surf " << X_surf <<
" m_temperature " << m_temperature <<
" " << p_fluid << m_partId <<
" "
710 << m_position[0] <<
" " << m_position[1] <<
" " << m_position[2] << endl;
718 MFloat BM = (Y_surf - Y_fluid) / (1.0 - Y_surf);
729 MFloat Y_bndry = 2.0 / 3.0 * Y_surf + 1.0 / 3.0 * Y_fluid;
731 ASSERT(Y_bndry <= 1.0,
"ERROR: Invalid fuel boundary layer mass concentration (>100%): " + to_string(Y_bndry));
733 if(std::isnan(Y_bndry)) {
734 cerr <<
"Y_surf " << Y_surf <<
" Y_f " << Y_fluid << endl;
738 MFloat X_bndry = -Y_bndry / (Y_bndry * molWeightRatio - Y_bndry - molWeightRatio);
742 MFloat lamda_vapFluid =
POW2(1.0 + sqrt(lamda_vap / lamda_fluid) * pow(1 / molWeightRatio, 0.25))
743 / sqrt(8.0 * (1.0 + molWeightRatio));
744 if(isnan(lamda_vapFluid)) {
745 cerr <<
"lamda_vap " << lamda_vap <<
" lamda_fluid " << lamda_fluid <<
" lamda_vapFluid " << lamda_vapFluid
749 MFloat lamda_fluidVap =
POW2(1.0 + sqrt(lamda_fluid / lamda_vap) * pow(molWeightRatio, 0.25))
750 / sqrt(8.0 * (1.0 + 1 / molWeightRatio));
752 MFloat lamda_mix = X_bndry * lamda_vap / (X_bndry + (1.0 - X_bndry) * lamda_vapFluid)
753 + (1.0 - X_bndry) * lamda_fluid / (X_bndry * lamda_fluidVap + (1.0 - X_bndry));
754 if(isnan(lamda_mix)) {
755 cerr <<
"X_bndry " << X_bndry <<
" lamda_vap " << lamda_vap <<
" lamda_vapFluid " << lamda_vapFluid << endl;
757 ASSERT(!std::isnan(lamda_mix),
"ERROR: lamda_mix is NaN!");
760 MFloat viscosity_vapFluid =
POW2(1.0 + sqrt(viscosity_vap / viscosity_fluid) * pow(1 / molWeightRatio, 0.25))
761 / sqrt(8.0 * (1.0 + molWeightRatio));
763 MFloat viscosity_fluidVap =
POW2(1.0 + sqrt(viscosity_fluid / viscosity_vap) * pow(molWeightRatio, 0.25))
764 / sqrt(8.0 * (1.0 + 1 / molWeightRatio));
766 MFloat viscosity_mix = X_bndry * viscosity_vap / (X_bndry + (1.0 - X_bndry) * viscosity_vapFluid)
767 + (1.0 - X_bndry) * viscosity_fluid / (X_bndry * viscosity_fluidVap + (1.0 - X_bndry));
769 ASSERT(!std::isnan(viscosity_mix),
770 "ERROR: viscosity_mix is NaN!" + to_string(X_bndry) +
" " + to_string(viscosity_vapFluid));
778 const MFloat density_mix = Y_bndry * density_vap + (1.0 - Y_bndry) * m_fluidDensity;
791 MFloat Re = particleRe(m_fluidDensity, magRelVel(m_fluidVel.data(), &m_velocity[0]), viscosity_mix) * s_Re;
797 const MFloat Sh = 2.0 + 0.552 * sqrt(Re) * pow(Sc, 1.0 / 3.0);
800 ASSERT(!isnan(Sh),
"Sh is nan!" + to_string(Re) +
" " + to_string(Sc));
805 MFloat Nu = 2.0 + 0.552 * sqrt(Re) * pow(Pr, 1.0 / 3.0);
808 if(isnan(Nu)) cerr <<
" Re " << Re <<
" Pr " << Pr << endl;
813 if(beta > MFloatEps) {
814 Nu = Nu * (beta / (exp(beta) - 1));
817 if(isnan(Nu)) cerr <<
"beta " << beta << endl;
824 if(s_backPtr->m_evaporation) {
843 A = -2.0 / 3.0 * density_mix * PI * diffusionC * Sh * log(1 + BM)
844 * pow(6.0 / (PI * s_backPtr->m_material->density(m_temperature)), 1.0 / 3.0) * dt / (s_Sc * s_Re);
846 const MFloat B = pow(oldMass, 2.0 / 3.0);
850 cerr <<
"oldMass " << oldMass << endl;
853 cerr <<
"A " << A <<
" density_mix " << density_mix <<
" diffusion Coefficient " << diffusionC <<
" SH "
854 << Sh <<
" BM " << BM << endl;
862 mass = pow(B + A, 3.0 / 2.0);
866 ASSERT(!std::isnan(mass),
"ERROR: Mass is NaN!");
873 m_dM = (oldMass - mass) / dt;
875 constexpr static MBool limitCondensation =
true;
876 if(limitCondensation && m_dM < 0) {
881 ASSERT(!std::isnan(m_dM),
"ERROR: Evaporation rate is NaN!");
882 ASSERT(mass - oldMass <= 0 || abs(mass) < numeric_limits<MFloat>::epsilon(),
883 "ERROR: droplets are increasing in size due to condensation! m_dM " + to_string(m_dM) +
" oldMass "
884 + to_string(oldMass) +
" mass " + to_string(mass));
888 m_diameter = pow(mass / s_backPtr->m_material->density(m_temperature) * 6.0 / PI, 1.0 / 3.0);
891 const MFloat reducedSheddedMass = oldSheddedMass - m_dM * dt;
892 m_shedDiam = pow(reducedSheddedMass / s_backPtr->m_material->density(m_temperature) * 6.0 / PI, 1.0 / 3.0);
899 fullyEvaporated() =
true;
900 m_temperature = oldTemperature;
925 if(Nu > 100 * MFloatEps) {
927 PI * 0.5 * (m_diameter + oldDiameter) * Nu * lamda_mix * dt / (mass * cp_liquid) / (s_Pr * s_Re);
930 - m_dM * lH_ev / (Nu * lamda_mix * PI * 0.5 * (m_diameter + oldDiameter)) * (s_Re * s_Pr * gammaMinusOne);
931 m_temperature = c2 + (oldTemperature - c2) * exp(-c1);
938 m_temperature = oldTemperature - m_dM / (mass * cp_liquid) * lH_ev * dt * gammaMinusOne;
942 if(std::isnan(m_temperature)) {
943 cerr <<
"m_diam " << m_diameter <<
" Nu " << Nu <<
" thCond " << lamda_mix << endl;
944 cerr <<
"m_t " << m_temperature <<
" oldT " << oldTemperature << endl;
945 cerr <<
" Re " << Re <<
" Pr " << Pr <<
" " << T_bndry <<
" " << magRelVel(m_fluidVel.data(), &m_velocity[0])
946 <<
" " << viscosity_mix <<
" " << m_fluidDensity <<
" " << 2.0 + 0.552 * sqrt(Re) * pow(Pr, 1.0 / 3.0)
952 if(m_temperature < 0) {
953 m_temperature = MFloatEps;
958 }
while(abs(m_temperature - previousTemp) > convEvap && heatStep < 100);
962 static MFloat dm_dt = (oldMass / dt) / 100000.0;
964 if(m_dM * dt > oldMass) {
967 m_diameter = pow((oldMass - m_dM * dt) / s_backPtr->m_material->density(m_temperature) * 6.0 / PI, 1.0 / 3.0);
971 if(m_temperature < 0) {
972 TERMM(-1,
"Invalid temperature!");
976 if(s_backPtr->m_heatCoupling) {
977 const MFloat mass = sphericalMass();
981 m_heatFlux = mass * cp_liquid * (m_temperature - oldTemperature) / dt * 1 / s_backPtr->m_material->gammaMinusOne();
984 ASSERT(!std::isnan(m_heatFlux) && !std::isinf(m_heatFlux),
985 "ERROR: m_heatFlux is NaN or inf! " + to_string(m_temperature) +
" " + to_string(oldTemperature) +
" "
986 + to_string(volume));
988 if(s_backPtr->m_evaporation) {
989 m_heatFlux -= (m_dM * cp_liquid * m_temperature * 1 / s_backPtr->m_material->gammaMinusOne());
993 ASSERT(!std::isnan(m_heatFlux) && !std::isinf(m_heatFlux),
"ERROR: m_heatFlux is NaN or inf!");
void motionEquation() override
LPTSpherical()
constructor of spherical particles, used to invalidate values when debugging!
void coupling() override
single particle coupling terms
void momentumCoupling()
add the momentum flux from the particle to the cell/all surrounding cells
void advanceParticle() override
advance to new timeStep
void heatCoupling()
add the heat flux from the particle to the cell/all surrounding cells
void energyEquation() override
MFloat dragFactor(const MFloat partRe)
Calculate drag factor of the current particle for the given particle Reynolds number....
void massCoupling()
add the mass flux from the particle to the cell/all surrounding cells
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW3(const Real x)
constexpr Real POW2(const Real x)