This is the analytical solution of the following differential equation: Spalding equation (1953) gives the mass evaporation rate dm/dt = - pi * d * density * D_AB * Sh * ln(1 + BM) as also in "A compararive study of numerical models for Eulerian-Lagrangian simulations of
turbulent evaporating sprays" D.I. Kolaitis, M.A. Founti J. Heat and Fluid Flow (2006) This is the same equation as used by Miller/Bellan in: "Direct numerical simulation of a confined three-dimensional gar mixing layer with one
evaporating hydrocarbon-droplet-laden stream" J. Fluid Mech. (1999) but they have rearranged it in the form of: dm/dt = - Sh / (3 * Sc) * m / tau * ln(1+BM) using particle-relaxation time tau. For detais of the analytical solution contact t.weg.nosp@m.mann.nosp@m.@aia..nosp@m.rwth.nosp@m.-aach.nosp@m.en.d.nosp@m.e
The heat balance equation for a droplet was given by Faeth 1983 to be (tp1-tp0)/dt = (pi * dp1 * Nu * km * (T_f - tp1) + dm1 * LH_ev)/(mp1 * cp) again this is the same equation as used by Miller/Bellan in: "Direct numerical simulation of a confined three-dimensional gar mixing layer with one
evaporating hydrocarbon-droplet-laden stream" J. Fluid Mech. (1999) but they have rearranged it in the form of: dT/dt = Nu / (3 * Pr) * cp_F/cp_L * 1/tau_p * (T_f - T_p) + dm/m * L_ev/cp_L For detais of the analytical solution contact t.weg.nosp@m.mann.nosp@m.@aia..nosp@m.rwth.nosp@m.-aach.nosp@m.en.d.nosp@m.e
NOTE: the type of differential equation changes for Nu -> 0 and is merely: dT/dt = dm/m * L_ev/cp_L
507 {
508
509
510
512 ASSERT(dt > 0, "Timestep < 0");
513
514
517 mTerm(1, AT_,
"Nan input values for evaporation!");
518 }
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
542 } else {
545 }
546
547
548 if(m_diameter <= s_backPtr->m_sizeLimit) {
554 return;
555 }
556
558
561 return;
562 }
563
565 ASSERT(volume > 0, "Invalid volume!");
566
567 static constexpr MFloat convEvap = 1E-10;
569
572
576
577
579
580 static constexpr MBool belanHarstad =
true;
581 if(belanHarstad) {
582
583
584
586
588
589
590
592
593
595
596
598
599 do {
601
602
603 if(m_diameter <= s_backPtr->m_sizeLimit) {
610 break;
611 }
612
613
615
616
617
618
619 MFloat viscosity_fluid =
s_backPtr->m_material->dynViscosityFun(T_bndry);
620 if(viscosity_fluid < 0) {
621 viscosity_fluid = numeric_limits<MFloat>::epsilon();
622 }
623
624
625 MFloat diffusionC =
s_backPtr->m_material->diffusionCoefficient(T_bndry);
626 ASSERT(diffusionC > 0, "ERROR: Invalid diffusion coefficient.");
627
628
629
631
632
633 MFloat lamda_fluid =
s_backPtr->m_material->airThermalConductivity(T_bndry);
634 if(lamda_fluid < 0) {
635 lamda_fluid = numeric_limits<MFloat>::epsilon();
636 }
637
638
639 const MFloat lamda_vap =
s_backPtr->m_material->thermalConductivity(T_bndry);
640
641
642 const MFloat viscosity_vap =
s_backPtr->m_material->dynamicViscosity(T_bndry);
643
644
645 const MFloat density_vap = p_fluid / (gasConstant_vap * T_bndry);
646
647
648
650
651
653
654
655
656
657
658
659
660 MFloat X_surf = p_Boil / p_fluid * exp(lH_ev / gasConstant_vap * (1.0 / T_Boil - 1.0 /
m_temperature));
661
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;
667 }
668
669
670 static constexpr MBool nonEquilibrium =
true;
672 if(nonEquilibrium) {
673
674
675
676
677
678
679
680
681
682
683
685 beta = 0.5 * Pr * Re_b;
686
687
688
691
692
693 X_surf = X_surf - (2.0 * beta * Lk_d);
694
695
696 if(X_surf < 0) {
697 X_surf = 1.0 - X_surfLimit;
698 }
699 }
700
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));
703
704
705 MFloat Y_surf = X_surf * molWeightRatio / (X_surf * molWeightRatio + (1.0 - X_surf));
706
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 <<
" "
711 }
712
713
714
715
716
717
718 MFloat BM = (Y_surf - Y_fluid) / (1.0 - Y_surf);
719 if(BM < MFloatEps) {
720
721
722 BM = 0;
723 }
724
725
726
727
728
729 MFloat Y_bndry = 2.0 / 3.0 * Y_surf + 1.0 / 3.0 * Y_fluid;
730
731 ASSERT(Y_bndry <= 1.0, "ERROR: Invalid fuel boundary layer mass concentration (>100%): " + to_string(Y_bndry));
732
733 if(std::isnan(Y_bndry)) {
734 cerr << "Y_surf " << Y_surf << " Y_f " << Y_fluid << endl;
735 }
736
737
738 MFloat X_bndry = -Y_bndry / (Y_bndry * molWeightRatio - Y_bndry - molWeightRatio);
739
740
741
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
746 << endl;
747 }
748
749 MFloat lamda_fluidVap =
POW2(1.0 + sqrt(lamda_fluid / lamda_vap) * pow(molWeightRatio, 0.25))
750 / sqrt(8.0 * (1.0 + 1 / molWeightRatio));
751
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;
756 }
757 ASSERT(!std::isnan(lamda_mix), "ERROR: lamda_mix is NaN!");
758
759
760 MFloat viscosity_vapFluid =
POW2(1.0 + sqrt(viscosity_vap / viscosity_fluid) * pow(1 / molWeightRatio, 0.25))
761 / sqrt(8.0 * (1.0 + molWeightRatio));
762
763 MFloat viscosity_fluidVap =
POW2(1.0 + sqrt(viscosity_fluid / viscosity_vap) * pow(molWeightRatio, 0.25))
764 / sqrt(8.0 * (1.0 + 1 / molWeightRatio));
765
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));
768
769 ASSERT(!std::isnan(viscosity_mix),
770 "ERROR: viscosity_mix is NaN!" + to_string(X_bndry) + " " + to_string(viscosity_vapFluid));
771
772
773
774
775
776
777
779
780
781
782
783
784
785
786
787
788
789
790
792
793
794
795
796
797 const MFloat Sh = 2.0 + 0.552 * sqrt(Re) * pow(Sc, 1.0 / 3.0);
798
799
800 ASSERT(!isnan(Sh), "Sh is nan!" + to_string(Re) + " " + to_string(Sc));
801
802
803
804
805 MFloat Nu = 2.0 + 0.552 * sqrt(Re) * pow(Pr, 1.0 / 3.0);
806
807
808 if(isnan(Nu)) cerr << " Re " << Re << " Pr " << Pr << endl;
809
810
811
812 if(nonEquilibrium) {
813 if(beta > MFloatEps) {
814 Nu = Nu * (beta / (exp(beta) - 1));
815 }
816#ifdef LPT_DEBUG
817 if(isnan(Nu)) cerr << "beta " << beta << endl;
818#endif
819 }
820
822
823
840 if(BM < MFloatEps) {
841 mass = oldMass;
842 } else {
843 A = -2.0 / 3.0 * density_mix * PI * diffusionC * Sh * log(1 + BM)
845
846 const MFloat B = pow(oldMass, 2.0 / 3.0);
847
848
849 if(isnan(B)) {
850 cerr << "oldMass " << oldMass << endl;
851 }
852 if(isnan(A)) {
853 cerr << "A " << A << " density_mix " << density_mix << " diffusion Coefficient " << diffusionC << " SH "
854 << Sh << " BM " << BM << endl;
855 }
856
857
858
859 if(fabs(A) > B) {
860 mass = 0.0;
861 } else {
862 mass = pow(B + A, 3.0 / 2.0);
863 }
864 }
865
866 ASSERT(!std::isnan(mass), "ERROR: Mass is NaN!");
867
868
869
870
871
872
873 m_dM = (oldMass - mass) / dt;
874
875 constexpr static MBool limitCondensation =
true;
876 if(limitCondensation &&
m_dM < 0) {
878 mass = oldMass;
879 }
880
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));
885
886
887 if(mass > 0) {
889
890
891 const MFloat reducedSheddedMass = oldSheddedMass -
m_dM * dt;
893
894 } else {
897 mass = 0.0;
902
903
904
905
906
907
908
909 break;
910 }
911 }
912
913
914
925 if(Nu > 100 * MFloatEps) {
927 PI * 0.5 * (
m_diameter + oldDiameter) * Nu * lamda_mix * dt / (mass * cp_liquid) / (
s_Pr *
s_Re);
929 T_fluid
930 -
m_dM * lH_ev / (Nu * lamda_mix * PI * 0.5 * (
m_diameter + oldDiameter)) * (
s_Re *
s_Pr * gammaMinusOne);
932 } else {
937
938 m_temperature = oldTemperature -
m_dM / (mass * cp_liquid) * lH_ev * dt * gammaMinusOne;
939 }
940
941#ifdef LPT_DEBUG
943 cerr <<
"m_diam " <<
m_diameter <<
" Nu " << Nu <<
" thCond " << lamda_mix << endl;
944 cerr <<
"m_t " <<
m_temperature <<
" oldT " << oldTemperature << endl;
946 <<
" " << viscosity_mix <<
" " <<
m_fluidDensity <<
" " << 2.0 + 0.552 * sqrt(Re) * pow(Pr, 1.0 / 3.0)
947 << endl;
948 TERM(-1);
949 }
950#endif
951
954 }
955
956 heatStep++;
957
958 }
while(abs(
m_temperature - previousTemp) > convEvap && heatStep < 100);
959
960 } else {
961
962 static MFloat dm_dt = (oldMass / dt) / 100000.0;
964 if(
m_dM * dt > oldMass) {
966 }
968 }
969
970
972 TERMM(-1, "Invalid temperature!");
973 }
974
975
978
979
980
982
983
985 "ERROR: m_heatFlux is NaN or inf! " + to_string(
m_temperature) +
" " + to_string(oldTemperature) +
" "
986 + to_string(volume));
987
990 }
991
992
994 }
995}
MFloat m_creationTime
creation time modifier
BitsetType::reference fullyEvaporated()
MFloat m_shedDiam
shedding diameter
MFloat sphericalVolume() const
Calculate the current volume.
MFloat m_temperature
temperature
MFloat sphericalMass() const
Calculate the current mass.
MFloat magRelVel(const MFloat *const velocity1, const MFloat *const velocity2) const
Calculate the magnitude of the relative velocity of the two given velocity vectors.
MFloat particleRe(const MFloat velocity, const MFloat density, const MFloat dynamicViscosity)
Calculate the particle reynoldsnumber.
void interpolateAllFluidVariables(const MInt cellId, const MFloat *const position, MFloat *const velocity, MFloat &density, MFloat &pressure, MFloat &temperature, MFloat &species, std::vector< MFloat > &weights)
constexpr Real POW3(const Real x)