MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
SprayModel< nDim > Class Template Reference

#include <lptspray.h>

Collaboration diagram for SprayModel< nDim >:
[legend]

Public Member Functions

 SprayModel ()
 
void init (LPT< nDim > *_particle)
 Spray model initialisation. More...
 
void injection (const MFloat dt)
 Perform a spray injection. More...
 
void secondaryBreakUp (const MFloat dt)
 Atomization of particles. More...
 
MFloat timeSinceSOI () const
 
MFloattimeSinceSOI ()
 
MFloat injectionDuration () const
 
MFloat injectionSpeed () const
 
MBool soonInjection (const MFloat time)
 
std::mt19937_64 & randomPrimBreakUp (const MInt calls)
 

Public Attributes

MFloatm_injData = nullptr
 
MBool m_broadcastInjected = true
 
MInt m_injStep = 0
 
MInt m_injStopTimeStep = -1
 
MInt m_injStartTimeStep = -1
 
MFloat m_injectionCrankAngle = -1
 
MFloat m_Strouhal = -99
 
MFloat m_initialCad = 0
 
std::mt19937_64 m_PRNGPrimBreakUp
 
MInt m_PRNGPrimBreakUpCount = 0
 
MLong m_spraySeed {}
 
MInt m_noRTsecBreakUp = 0
 
MInt m_noKHsecBreakUp = 0
 

Static Public Attributes

static constexpr MInt m_injDataSize = 11
 

Private Member Functions

MInt domainId () const
 
MInt solverId () const
 
MaterialState< nDim > & material () const
 
MFloat sphericalMass (const MFloat diameter, const MFloat temperature)
 
void readSprayProperties ()
 
void logDistributionFunction ()
 create log of distribution functions for plots and debugging More...
 
void updateInjectionRate ()
 Update injection rate. More...
 
void primaryBreakUp (const MFloat dt)
 Inject new particles from the injector exit. More...
 
void injectParticles (const MInt spawnParticlesCount, const MFloat *spawnCoord, const MFloat particleDiameter, const MFloat particleDensityRatio, const MFloat particleVelocity, const MFloat sprayConeAngle, const MFloat coneDiameter, std::function< MFloat(MInt)> holePositionAngle, std::function< MFloat(MInt)> injectorDiameter, std::function< MFloat(MInt)> holeNozzleAngle, const MBool hull, const MInt parcelSize, const MInt noInjectionHoles)
 Create new random particles using the provided options. More...
 
void injectParticles (const MInt spawnParticlesCount, const MFloat *spawnCoord, const MFloat particleDiameter, const MFloat particleDensityRatio, const MFloat particleVelocity, const MFloat sprayConeAngle, const MFloat coneDiameter, const MBool hull, const MFloat nozzleAngle, const MInt parcelSize, const MInt noInjectionHoles)
 
void initPRNG (const MInt seed, const MInt discard)
 
std::mt19937_64 & randomSecBreakUp ()
 

Private Attributes

MFloat m_currentInjectionRate = 0.0
 
MFloatTensor m_injectionRateList
 
MFloatTensor m_injectionTimings
 
MFloat m_primMinDropletSize = 5e-7
 
MFloat m_injDuration = 0.00055
 
MFloat m_injectorNozzleDiameter = 0.0
 
MFloat m_injectionSpeed = -1.0
 
MFloatm_injectorDiameter = nullptr
 
MFloatm_injectorOrificeAngle = nullptr
 
MFloatm_orificePositionAngle = nullptr
 
MFloat m_injectorOrficeSize {}
 
MFloat m_RosinRammlerMin = -1
 
MFloat m_RosinRammlerMean = -1
 
MFloat m_RosinRammlerMax = -1
 
MFloat m_RosinRammlerSpread = -1
 
MFloatm_needleLiftTime = nullptr
 
MFloat m_injectorDir [nDim] {}
 
MFloat m_injectionDistSigmaCoeff = 1.0
 
MInt m_partEmittDist = 0
 
MFloatm_sprayAngle = nullptr
 
MFloat m_sprayConeAngle = 0.0
 
MBool m_primRosinRammler = true
 
MFloat m_timeSinceSOI = 0.0
 
MFloat m_B0 = 0.61
 
MFloat m_B1 = 40
 
MFloat m_CRT = 0.1
 
MFloat m_CT = 1.0
 
MFloat m_weberLimitKH = 6
 
MFloat m_massLimit = 0.03
 
MFloat m_weberLimitRT = 300
 
MBool m_secBUDisplayMessage = false
 
MInt m_maxRTChildParcels = 3
 
MFloat m_Cbu = 20
 
MInt m_RTDiameterMode = 0
 
MFloat m_sprayAngleKH = 2
 
MBool m_activePrimaryBUp = true
 
MBool m_activeSecondaryBUp = false
 
MInt m_primBrkUpParcelSize = 1
 
MBool m_useNeedleLiftTime = false
 
MFloat m_angularGap = -1
 
MInt m_injectorType = 0
 
MBool m_multiHoleInjector = false
 
MBool m_singleHoleInjector = false
 
MBool m_hollowConeInjector = false
 
MBool m_predictivePRNG = true
 
MBool m_RTsecBreakUp = true
 
MBool m_KHsecBreakUp = true
 
MBool m_RTsecBreakUpLength = true
 
MPI_Comm m_primBUp
 
MInt m_maxNoPrimParcels = 1
 
MInt m_primParcelsPerInj = 1000000
 
std::mt19937_64 m_PRNGSecBU
 

Static Private Attributes

static LPT< nDim > * s_backPtr = nullptr
 
static MFloat s_lengthFactor {}
 

Detailed Description

template<MInt nDim>
class SprayModel< nDim >

Definition at line 21 of file lptspray.h.

Constructor & Destructor Documentation

◆ SprayModel()

template<MInt nDim>
SprayModel< nDim >::SprayModel ( )
inline

Definition at line 24 of file lptspray.h.

24{};

Member Function Documentation

◆ domainId()

template<MInt nDim>
MInt SprayModel< nDim >::domainId ( ) const
inlineprivate

Definition at line 69 of file lptspray.h.

69{ return s_backPtr->domainId(); }
static LPT< nDim > * s_backPtr
Definition: lptspray.h:66

◆ init()

template<MInt nDim>
void SprayModel< nDim >::init ( LPT< nDim > *  _particle)
Author
Sven Berger
Date
October 2015
Parameters
[in]spawnCellIdLocation at which particles are created.

Definition at line 29 of file lptspray.cpp.

29 {
30 m_log << " Initialising spray model" << endl;
31
32 s_backPtr = _particle;
33 s_lengthFactor = s_backPtr->m_partList[0].s_lengthFactor;
34
35 m_activePrimaryBUp = s_backPtr->m_activePrimaryBUp;
36 m_activeSecondaryBUp = s_backPtr->m_activeSecondaryBUp;
37
38 if(!s_backPtr->m_restart) {
39 s_backPtr->m_particleResiduum = 0.0;
40 }
41
42 // allocate spray data
43 mAlloc(m_needleLiftTime, 2, "needleLiftTime", AT_);
44 mAlloc(m_sprayAngle, 2, "m_sprayAngle", F0, AT_);
45 mAlloc(m_injData, m_injDataSize, "m_injData", AT_);
46
48
50}
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
Definition: alloc.h:173
MFloat * m_needleLiftTime
Definition: lptspray.h:132
static constexpr MInt m_injDataSize
Definition: lptspray.h:38
MBool m_activePrimaryBUp
Definition: lptspray.h:165
MFloat * m_sprayAngle
Definition: lptspray.h:143
void logDistributionFunction()
create log of distribution functions for plots and debugging
Definition: lptspray.cpp:1837
static MFloat s_lengthFactor
Definition: lptspray.h:67
MFloat * m_injData
Definition: lptspray.h:39
void readSprayProperties()
MBool m_activeSecondaryBUp
Definition: lptspray.h:166
InfoOutFile m_log

◆ initPRNG()

template<MInt nDim>
void SprayModel< nDim >::initPRNG ( const MInt  seed,
const MInt  discard 
)
inlineprivate

Definition at line 220 of file lptspray.h.

220 {
221 if(m_predictivePRNG) {
222 m_PRNGSecBU.seed(seed);
223 m_PRNGSecBU.discard(discard);
224 }
225 }
MBool m_predictivePRNG
Definition: lptspray.h:180
std::mt19937_64 m_PRNGSecBU
Definition: lptspray.h:191

◆ injection()

template<MInt nDim>
void SprayModel< nDim >::injection ( const MFloat  dt)
Author
Sven Berger
Date
November 2015

Definition at line 672 of file lptspray.cpp.

672 {
673 // injection has not started yet, this also means that zero particles should be present!
675 ASSERT(s_backPtr->a_noParticles() == 0, "");
676 if(domainId() == 0) {
677 cerr << "Before injection" << m_injectionCrankAngle << " "
679 }
680 for(MInt i = 0; i < m_injDataSize; i++) {
681 m_injData[i] = 0;
682 }
683 return;
684 }
685
686 m_timeSinceSOI += dt;
687
688
689 MBool endOfInjection = false;
690 if(m_injStopTimeStep > -1 && globalTimeStep > m_injStopTimeStep) endOfInjection = true;
691 if(m_timeSinceSOI > m_injDuration) endOfInjection = true;
692 if(m_injStartTimeStep > -1 && globalTimeStep < m_injStartTimeStep) endOfInjection = true;
693
694 // injection has already ended
695 if(endOfInjection) {
696 cerr0 << "After injection " << m_timeSinceSOI << " " << m_injDuration << endl;
697
698 for(MInt i = 0; i < m_injDataSize; i++) {
699 m_injData[i] = 0;
700 }
701 if(s_backPtr->m_spawnCellId > -1) {
703 }
704 return;
705 }
706
707
708 // injection location is on another domain
709 if(s_backPtr->m_spawnCellId < 0) {
710 ASSERT(s_backPtr->noDomains() > 1, "");
711
712 // receive injected particles instead
714 s_backPtr->recvInjected();
715 }
716 for(MInt i = 0; i < m_injDataSize; i++) {
717 m_injData[i] = 0;
718 }
719
720 } else {
721 // injection on this domain
722 ASSERT(domainId() == s_backPtr->m_spawnDomainId, "");
723
724 // update injection rate
726
727 // current number of particles
728 const MInt prevNo = s_backPtr->a_noParticles();
729
730 // inject new particles
731 primaryBreakUp(dt);
732
734 s_backPtr->broadcastInjected(prevNo);
735 }
736 }
737}
MFloat m_injectionCrankAngle
Definition: lptspray.h:60
MFloat m_Strouhal
Definition: lptspray.h:61
MFloat m_timeSinceSOI
Definition: lptspray.h:149
void primaryBreakUp(const MFloat dt)
Inject new particles from the injector exit.
Definition: lptspray.cpp:744
MFloat m_initialCad
Definition: lptspray.h:62
void updateInjectionRate()
Update injection rate.
Definition: lptspray.cpp:1658
MBool m_broadcastInjected
Definition: lptspray.h:41
MInt domainId() const
Definition: lptspray.h:69
MInt m_injStopTimeStep
Definition: lptspray.h:44
MInt m_injStartTimeStep
Definition: lptspray.h:45
MFloat m_injDuration
Definition: lptspray.h:96
MInt globalTimeStep
std::ostream cerr0
int32_t MInt
Definition: maiatypes.h:62
bool MBool
Definition: maiatypes.h:58
MFloat crankAngle(const MFloat time, const MFloat Strouhal, const MFloat offset, const MInt mode)
help-function for engine calculations which returns the crank-angle for a given time,...
Definition: maiamath.h:506

◆ injectionDuration()

template<MInt nDim>
MFloat SprayModel< nDim >::injectionDuration ( ) const
inline

Definition at line 35 of file lptspray.h.

35{ return m_injDuration; }

◆ injectionSpeed()

template<MInt nDim>
MFloat SprayModel< nDim >::injectionSpeed ( ) const
inline

Definition at line 36 of file lptspray.h.

36{ return m_injectionSpeed; }
MFloat m_injectionSpeed
Definition: lptspray.h:103

◆ injectParticles() [1/2]

template<MInt nDim>
void SprayModel< nDim >::injectParticles ( const MInt  spawnParticlesCount,
const MFloat spawnCoord,
const MFloat  particleDiameter,
const MFloat  particleDensityRatio,
const MFloat  particleVelocity,
const MFloat  sprayConeAngle,
const MFloat  coneDiameter,
const MBool  hull,
const MFloat  nozzleAngle,
const MInt  parcelSize,
const MInt  noInjectionHoles 
)
inlineprivate

Definition at line 203 of file lptspray.h.

206 {
207 std::function<MFloat(MInt)> dummyDefault = [&](MInt) { return -1.0; };
208 std::function<MFloat(MInt)> holeNozzleAngle = [&](MInt) { return nozzleAngle; };
209 ASSERT(noInjectionHoles == 1, "Incorrect function call!");
210
211 injectParticles(spawnParticlesCount, spawnCoord, particleDiameter, particleDensityRatio, particleVelocity,
212 sprayConeAngle, coneDiameter, dummyDefault, dummyDefault, holeNozzleAngle, hull, parcelSize,
213 noInjectionHoles);
214 }
void injectParticles(const MInt spawnParticlesCount, const MFloat *spawnCoord, const MFloat particleDiameter, const MFloat particleDensityRatio, const MFloat particleVelocity, const MFloat sprayConeAngle, const MFloat coneDiameter, std::function< MFloat(MInt)> holePositionAngle, std::function< MFloat(MInt)> injectorDiameter, std::function< MFloat(MInt)> holeNozzleAngle, const MBool hull, const MInt parcelSize, const MInt noInjectionHoles)
Create new random particles using the provided options.
Definition: lptspray.cpp:1696
double MFloat
Definition: maiatypes.h:52

◆ injectParticles() [2/2]

template<MInt nDim>
void SprayModel< nDim >::injectParticles ( const MInt  spawnParticlesCount,
const MFloat spawnCoord,
const MFloat  particleDiameter,
const MFloat  particleDensityRatio,
const MFloat  particleVelocity,
const MFloat  sprayConeAngle,
const MFloat  coneDiameter,
std::function< MFloat(MInt)>  holePositionAngle,
std::function< MFloat(MInt)>  injectorDiameter,
std::function< MFloat(MInt)>  holeNozzleAngle,
const MBool  hull,
const MInt  parcelSize,
const MInt  noInjectionHoles 
)
private
Author
Sven Berger, Tim Wegmann
Date
November 2015
Parameters
[in]spawnParticlesCountNumber of particles created in the given location.
[in]spawnCoordCoordinates of the location to spawn the particles in. (Note: Check if this is on the calling procs domain!!!)
[in]particleDiameterSize of the particles that get created.
[in]particleDensityRatioDensity ratio of the newly created particles.
[in]particleVelocityinitial velocity of the created particles.
[in]sprayConeAngleAngle of the cone in which particles are created
[in]coneDiameterintial diameter of the spray cone (0.0 for blob-injection)
[in]hullOnly create particles on the hull of the cone
[in]holeNozzleAngleOpening angle of the nozzle
[in]parcelSizeParcel size that is used for the newly created particles
[in]noInjectionHolesNumber of holes of the injector
[in]injectorDiameterDiameter of the injector.

Definition at line 1696 of file lptspray.cpp.

1702 {
1703 std::array<MFloat, nDim> spawnParticlesInitVelo;
1704 array<MFloat, 3> injectionLocation{};
1705 array<MFloat, 3> holeLocation{};
1706
1707 if(spawnParticlesCount > 0) {
1708 m_injStep++;
1709 }
1710
1711 if(particleDiameter < s_backPtr->m_sizeLimit) {
1712 cerr << "Inj. small particle " << particleDiameter << " " << s_backPtr->m_sizeLimit << endl;
1713 }
1714
1715 for(MInt i = 0; i < spawnParticlesCount; i++) {
1716 MInt randomShift = 1;
1718 randomShift = 0;
1720 randomVectorInCone(&spawnParticlesInitVelo[0], &m_injectorDir[0], particleVelocity, sprayConeAngle,
1722
1723 if(coneDiameter > numeric_limits<MFloat>::epsilon() && !hull) {
1724 // determine a random point within the injector orfice
1725 randomPointInCircle(&holeLocation[0], &m_injectorDir[0], coneDiameter, randomPrimBreakUp(2));
1726
1727 if(noInjectionHoles > 1) {
1728 // determine position of the hole
1729 pointOnCircle(&injectionLocation[0], &m_injectorDir[0], injectorDiameter(i), holePositionAngle(i));
1730 }
1731 } else if(hull) {
1733 randomVectorInCone(&spawnParticlesInitVelo[0], &m_injectorDir[0], particleVelocity, sprayConeAngle,
1735
1736 // determine a point just on the hull of the cone (like for a hollow-cone injector)
1737 // TODO labels:LPT make settable
1738 static constexpr MBool randomDist = false;
1739 if(randomDist) {
1740 randomPointOnCircle(&injectionLocation[0], &m_injectorDir[0], coneDiameter, randomPrimBreakUp(1),
1741 spawnParticlesCount, i);
1742 } else {
1743 // generate one particle per 1 deg
1744 const static MFloat angleBetween = 360.0 / spawnParticlesCount;
1745 const MFloat phi = (i * angleBetween + ((m_injStep - 1) % static_cast<MInt>(angleBetween))) / 180.0 * M_PI;
1746 pointOnCircle(&injectionLocation[0], &m_injectorDir[0], coneDiameter, phi);
1747 }
1748 }
1749 }
1750
1751 // rotate injection by the angle of the nozzle
1752 if(fabs(holeNozzleAngle(i)) > numeric_limits<MFloat>::epsilon()) {
1753 const MFloat holeAngleRad = -holeNozzleAngle(i) / 180 * M_PI;
1754 const MFloat absDist = maia::math::norm(injectionLocation);
1755
1756 array<MFloat, nDim> crossP{};
1757 array<MFloat, nDim> revInjLoc{};
1758 for(MInt j = 0; j < nDim; j++) {
1759 revInjLoc[j] = -injectionLocation[j] / absDist;
1760 }
1761
1762 maia::math::cross(&m_injectorDir[0], &revInjLoc[0], &crossP[0]);
1763
1764 // boundary basis at the injection location
1765 MFloatScratchSpace injLocBasis(nDim, nDim, FUN_, "R");
1766 for(MInt j = 0; j < nDim; j++) {
1767 injLocBasis(j, 0) = m_injectorDir[j];
1768 injLocBasis(j, 1) = revInjLoc[j];
1769 injLocBasis(j, 2) = crossP[j];
1770 }
1771
1772 // find inverse for reverse-tranformation
1773 MFloatScratchSpace inverse(nDim, nDim, AT_, "inverse");
1774 for(MInt j = 0; j < nDim; j++) {
1775 for(MInt k = 0; k < nDim; k++) {
1776 inverse(j, k) = injLocBasis(j, k);
1777 }
1778 }
1779
1780 maia::math::invert(&inverse(0, 0), 3, 3);
1781 // NOTE: inverse might not be normalized correctly, meaning that the magnitude is not conserved!
1782
1783 // rotation matrix around the z-axis in the injection location basis
1784 MFloatScratchSpace R(nDim, nDim, FUN_, "R");
1785 R.fill(0.0);
1786 R(2, 2) = 1.0;
1787 R(0, 0) = cos(holeAngleRad);
1788 R(1, 0) = sin(holeAngleRad);
1789 R(0, 1) = -sin(holeAngleRad);
1790 R(1, 1) = cos(holeAngleRad);
1791
1792 // global coordinate transformation is then found be B*R*B^-1
1793 MFloatScratchSpace result1(nDim, nDim, FUN_, "result1");
1794 MFloatScratchSpace result(nDim, nDim, FUN_, "result");
1795 MFloatScratchSpace tempV(nDim, FUN_, "tempV");
1796 for(MInt j = 0; j < nDim; j++) {
1797 tempV[j] = spawnParticlesInitVelo[j];
1798 }
1799
1800 maia::math::multiplyMatricesSq(injLocBasis, R, result1, nDim);
1801 maia::math::multiplyMatricesSq(result1, inverse, result, nDim);
1802 for(MInt j = 0; j < nDim; j++) {
1803 spawnParticlesInitVelo[j] = 0;
1804 for(MInt k = 0; k < nDim; k++) {
1805 spawnParticlesInitVelo[j] += result(j, k) * tempV[k];
1806 }
1807 }
1808
1809 // reset vector length and direction
1810 maia::math::normalize(&spawnParticlesInitVelo[0], nDim);
1811 // reverse sign if velocity has opposite direction to the injector direction
1812 if(scalarProduct(&spawnParticlesInitVelo[0], &m_injectorDir[0], nDim) < 0.0) {
1813 for(MInt j = 0; j < nDim; j++) {
1814 spawnParticlesInitVelo[j] *= -1;
1815 }
1816 }
1817 for(MInt j = 0; j < nDim; j++) {
1818 spawnParticlesInitVelo[j] *= particleVelocity;
1819 }
1820 }
1821 // final injection position = hole position + orifice position + injector center
1822 for(MInt j = 0; j < nDim; j++) {
1823 injectionLocation[j] += spawnCoord[j] + holeLocation[j];
1824 }
1825
1826 s_backPtr->addParticle(s_backPtr->m_spawnCellId, particleDiameter, particleDensityRatio, randomShift, 2,
1827 &spawnParticlesInitVelo[0], &injectionLocation[0], parcelSize);
1828 }
1829}
This class is a ScratchSpace.
Definition: scratch.h:758
MInt m_injStep
Definition: lptspray.h:43
MInt m_partEmittDist
Definition: lptspray.h:140
std::mt19937_64 & randomPrimBreakUp(const MInt calls)
Definition: lptspray.h:234
MFloat m_injectorDir[nDim]
Definition: lptspray.h:135
MFloat m_injectionDistSigmaCoeff
Definition: lptspray.h:137
MInt m_PRNGPrimBreakUpCount
Definition: lptspray.h:232
@ PART_EMITT_DIST_NONE
Definition: enums.h:348
T cos(const T a, const T b, const T x)
Cosine slope filter.
Definition: filter.h:125
MFloat scalarProduct(const MFloat *a, const MFloat *b, const MInt length)
Definition: lptlib.h:149
void randomPointInCircle(MFloat *vec, const MFloat *normalDirection, const MFloat diameter, std::mt19937_64 &PRNG)
Definition: lptlib.h:383
void randomPointOnCircle(MFloat *vec, const MFloat *normalDirection, const MFloat diameter, std::mt19937_64 &PRNG, const MInt circleSplit=1, const MInt splitNo=0)
Definition: lptlib.h:459
MInt randomVectorInCone(MFloat *vec, const MFloat *coneAxis, const MFloat length, const MFloat openingAngle, const MInt dist, std::mt19937_64 &PRNG, const MFloat distCoeff=0.0, const MFloat nozzleAngle=0.0)
Generate a random vector in a cone defined by its opening angle.
Definition: lptlib.h:252
void pointOnCircle(MFloat *vec, const MFloat *normalDirection, const MFloat diameter, MFloat phi)
Definition: lptlib.h:528
void cross(const T *const u, const T *const v, T *const c)
Definition: maiamath.h:101
void invert(MFloat *A, const MInt m, const MInt n)
Definition: maiamath.cpp:171
void normalize(std::array< T, N > &u)
Definition: maiamath.h:191
MFloat norm(const std::array< T, N > &u)
Definition: maiamath.h:148
MInt inverse(MFloat **a, MFloat **ainv, MInt n, const MFloat epsilon)
Definition: maiamath.h:587
void multiplyMatricesSq(MFloatScratchSpace &m1, MFloatScratchSpace &m2, MFloatScratchSpace &result, MInt dim)
Definition: maiamath.h:279

◆ logDistributionFunction()

template<MInt nDim>
void SprayModel< nDim >::logDistributionFunction
private
Author
Tim Wegmann
Date
January 2023

Definition at line 1837 of file lptspray.cpp.

1837 {
1838 if(domainId() != 0) return;
1839
1840 const MInt noDraws = 1000000;
1844
1845 std::mt19937_64 randomNumberGenerator;
1846 randomNumberGenerator.seed(m_spraySeed);
1847
1848 const MInt noBinns = 1000;
1849 MFloat binWidth = (maxValue - minValue) / noBinns;
1850 MIntScratchSpace binValue(noBinns, AT_, "binValue");
1851 binValue.fill(0);
1852
1853 for(MInt i = 0; i < noDraws; i++) {
1854 const MFloat drawValue = rosinRammler(minValue, meanValue, maxValue, m_RosinRammlerSpread, randomNumberGenerator);
1855 const MInt binId = std::floor((drawValue - minValue) / binWidth);
1856 binValue[binId]++;
1857 }
1858
1859 m_log << "IDSD Binning: " << endl;
1860 m_log << "Rosin-Rammler distribution: " << endl;
1861 m_log << "Min-value : " << minValue << endl;
1862 m_log << "Max-value : " << maxValue << endl;
1863 m_log << "Mean-value: " << meanValue << endl;
1864 m_log << "Spread : " << m_RosinRammlerSpread << endl;
1865 m_log << "Number-draws: " << noDraws << endl;
1866
1867 for(MInt i = 0; i < noBinns; i++) {
1868 m_log << minValue + i * binWidth << " " << binValue[i] << endl;
1869 }
1870
1871 minValue = 0.0;
1872 maxValue = 5 * meanValue;
1873 binWidth = (maxValue - minValue) / noBinns;
1874
1875 binValue.fill(0);
1876
1877 for(MInt i = 0; i < noDraws; i++) {
1878 const MFloat drawValue = NTDistribution(meanValue, randomNumberGenerator);
1879 const MInt binId = std::floor((drawValue - minValue) / binWidth);
1880 binValue[binId]++;
1881 }
1882
1883 m_log << "Nukiyama-Tanasawa distribution: " << endl;
1884 m_log << "Mean-value: " << meanValue << endl;
1885 for(MInt i = 0; i < noBinns; i++) {
1886 m_log << minValue + i * binWidth << " " << binValue[i] << endl;
1887 }
1888}
MLong m_spraySeed
Definition: lptspray.h:240
MFloat m_RosinRammlerSpread
Definition: lptspray.h:129
MFloat m_RosinRammlerMax
Definition: lptspray.h:124
MFloat m_RosinRammlerMean
Definition: lptspray.h:121
MFloat m_injectorNozzleDiameter
Definition: lptspray.h:100
MFloat m_RosinRammlerMin
Definition: lptspray.h:118
MFloat NTDistribution(const MFloat x_mean, std::mt19937_64 &PRNG)
Definition: lptlib.h:601
MFloat rosinRammler(const MFloat min, const MFloat mean, const MFloat max, const MFloat spread, std::mt19937_64 &PRNG)
Definition: lptlib.h:584

◆ material()

template<MInt nDim>
MaterialState< nDim > & SprayModel< nDim >::material ( ) const
inlineprivate

Definition at line 72 of file lptspray.h.

72{ return *s_backPtr->m_material; }

◆ primaryBreakUp()

template<MInt nDim>
void SprayModel< nDim >::primaryBreakUp ( const MFloat  dt)
private
Author
Sven Berger
Date
November 2015

Definition at line 744 of file lptspray.cpp.

744 {
745 TRACE();
746
747 ASSERT(domainId() == s_backPtr->m_spawnDomainId, "");
748 ASSERT(s_backPtr->m_spawnCellId > -1, "");
749
750 // invalidate injection data:
751 MInt noInjParticles = -1;
752 MInt noInjDroplets = -1;
753 MFloat injMass = NAN;
754 MFloat injParticleDiameter = NAN;
755 static MFloat lastD = -1;
756
757 // 1) ramp-up and other general injection parameters:
758
759 MFloat injectionProgress = m_timeSinceSOI / m_injDuration;
760
761
762 // the rampFactor is used to control/ramp the massflowrate and velocity
763 // during the injector opening and closing
764 // which linearly increases/decreases to the full injection velocity massflowrate
765 MFloat rampFactor = 1.0;
766 if(injectionProgress < m_needleLiftTime[0]) {
767 rampFactor = injectionProgress / m_needleLiftTime[0];
768 } else if(injectionProgress > (1 - m_needleLiftTime[1])) {
769 rampFactor = 1 - (injectionProgress - (1 - m_needleLiftTime[1])) / m_needleLiftTime[1];
770 }
771
772 // theoretically injected mass during this timestep
773 // current injection rate + left over mass from previous timestep
774 injMass = m_currentInjectionRate * rampFactor * dt + s_backPtr->m_particleResiduum;
775
776 // considering ramp-factor for parcel count
777 MInt noDroplets = mMax(1, (MInt)(m_primBrkUpParcelSize * rampFactor));
778
779 // 2) injector dependant injection parameters
780 // and injection of new particles
781 if(m_singleHoleInjector) { //(Spray A)
782
784 // droplet diameter distribution function
785
789
790 // mass of the smallest possible droplet
791 const MFloat minMass = sphericalMass(diameterMin, material().T());
792
793 noInjParticles = 0;
794 noInjDroplets = 0;
795
796 MFloat remainingMass = injMass;
797 injMass = 0;
798
799 while(remainingMass > minMass) {
800 if(lastD > 0) {
801 injParticleDiameter = lastD;
802 } else {
803 injParticleDiameter =
804 rosinRammler(diameterMin, diameterMean, diameterMax, m_RosinRammlerSpread, randomPrimBreakUp(1));
805 }
806
807 const MFloat particleMass = noDroplets * sphericalMass(injParticleDiameter, material().T());
808 const MFloat tempMass = remainingMass - particleMass;
809
810 // limit mass to be positive
811 if(tempMass < 0) {
812 lastD = injParticleDiameter;
813 s_backPtr->m_particleResiduum = remainingMass;
814 break;
815 }
816
817 // the initial cone diameter needs to be reduced by half of the droplet diameter
818 // since the droplet is supposed to be fully within the cone
819 const MFloat coneDiameter = m_injectorOrficeSize - 0.5 * injParticleDiameter;
820 lastD = -1;
821 injectParticles(1, s_backPtr->m_spawnCoord, injParticleDiameter, material().densityRatio(),
822 m_injectionSpeed * rampFactor, m_sprayConeAngle, coneDiameter, false, 0.0, noDroplets, 1);
823
824 noInjParticles++;
825 noInjDroplets += noDroplets;
826 injMass += particleMass;
827 remainingMass -= particleMass;
828 }
829
830 } else {
831 // blob-injection with all particles at the injector center
832
833 injParticleDiameter = m_injectorNozzleDiameter;
834 noInjDroplets = 1;
835
836 const MFloat initParticleMass = sphericalMass(injParticleDiameter, material().T());
837
838
839 MFloat noNewParticles = (m_currentInjectionRate * dt) / initParticleMass + s_backPtr->m_particleResiduum;
840 noInjParticles = floor(noNewParticles);
841
842 s_backPtr->m_particleResiduum = noNewParticles - noInjParticles;
843
844 injectParticles(noInjParticles, s_backPtr->m_spawnCoord, injParticleDiameter, material().densityRatio(),
845 m_injectionSpeed, m_sprayConeAngle, 0.0, false, 0.0, 1, 1);
846 }
847 } else if(m_hollowConeInjector) {
848 // hollow cone injector, such as the TMFB Injector
849 // This implementation of the hollow cone injector model of:
850 // Spray Modeling for Outwardly-Opening Hollow-Cone Injectors, Sim, Badra et al., SAE, 2016
851
852 // maximum number of parcels to be generated during this time step
853 const MInt parcelTargetNo = m_primParcelsPerInj / m_injDuration * dt;
854
855 // limit the number of parcels to be injected to maxNoPrimParcels
856 noInjParticles = std::min(parcelTargetNo, m_maxNoPrimParcels);
857
858 // injection velocity is scaled by this factor
859 const MFloat scaledInjectionV = rampFactor * m_injectionSpeed;
860
861 // thickness of the fluid flow within the angular gap
862 MFloat initialLiquidSheetThickness = NAN;
863
864 if(m_angularGap > -1) {
865 initialLiquidSheetThickness = max(m_angularGap * rampFactor, m_primMinDropletSize);
866 } else {
867 initialLiquidSheetThickness =
869 - sqrt(M_PI * POW2(m_injectorNozzleDiameter) * material().density() * scaledInjectionV
870 - 4.0 * m_currentInjectionRate * rampFactor)
871 / (2.0 * sqrt(M_PI) * sqrt(material().density() * scaledInjectionV)),
873 }
874
875 // initial particle size when considered as string like coneshaped
876 // starting from the injector angular gap
877 injParticleDiameter = 4.0 / M_PI * initialLiquidSheetThickness;
879 const MFloat diameterMin = injParticleDiameter / m_RosinRammlerMin;
880 const MFloat diameterMean = injParticleDiameter / m_RosinRammlerMean;
881 const MFloat diameterMax = injParticleDiameter / m_RosinRammlerMax;
882 injParticleDiameter =
883 rosinRammler(diameterMin, diameterMean, diameterMax, m_RosinRammlerSpread, randomPrimBreakUp(1));
884 }
885
886 // mass of a particle to be added
887 const MFloat initialDropletMass = sphericalMass(injParticleDiameter, material().T());
888
889 const MFloat newDroplets = injMass / initialDropletMass;
890
891 noInjDroplets = floor(newDroplets / noInjParticles);
892
893 if(noInjDroplets > 0) {
894 const MFloat injectorGapDiameter = m_injectorNozzleDiameter - 0.5 * injParticleDiameter;
895 s_backPtr->m_particleResiduum = (newDroplets - noInjParticles * noInjDroplets) * initialDropletMass;
896
897 injectParticles(noInjParticles, s_backPtr->m_spawnCoord, injParticleDiameter, material().densityRatio(),
898 scaledInjectionV, m_sprayConeAngle, injectorGapDiameter * s_lengthFactor, true, m_angularGap,
899 noInjDroplets, 1.0);
900
901 injMass = noInjParticles * noInjDroplets * initialDropletMass;
902
903 } else {
904 injMass = 0;
905 noInjParticles = 0;
906 }
907
908 } else if(m_multiHoleInjector) {
909 // injectors with multiple injection holes
910 // MULTIHOLE : ECN Spray-G
911 // MULTIHOLE_Opt : optimized 7-hole Spray-G
912 // MULTIHOLE_TME : 5-hole Injection of the TME
913
914 MInt noHoles = -1;
915 switch(m_injectorType) {
916 case MULTIHOLE: {
917 noHoles = 8;
918 break;
919 }
920 case MULTIHOLE_OPT: {
921 noHoles = 7;
922 break;
923 }
924 case MULTIHOLE_TME: {
925 noHoles = 5;
926 break;
927 }
928 default:
929 mTerm(1, AT_, "Unknown multi-hole injector-type!");
930 }
931
932 static constexpr MFloat C_a = 0.65;
933 // NOTE: Wehrfritz et. al. propose to use the nominal injector nozzle diameter!
934 // otherwise the area-coefficient of ~0.65 can be used
935
936 const MFloat initialConeAngle = m_sprayConeAngle;
937 // as in:
938 //"Validation of a comprehensive computational fluid dynamics methodology to predict the direct
939 // injection process of gasoline sprays using Spray G experimental data"
940 // Davide Paredi , Tommaso Lucchini , Gianluca D’Errico, Angelo Onorati,
941 // Lyle Pickett and Joshua Lacey
942 // International J of Engine Research 2020, Vol. 21(1) 199–216
943
944 ASSERT(m_primRosinRammler, "");
945
946 const MFloat effectiveDiam = sqrt(C_a) * m_injectorNozzleDiameter;
947 const MFloat diameterMin = effectiveDiam / m_RosinRammlerMin;
948 const MFloat diameterMean = effectiveDiam / m_RosinRammlerMean;
949 const MFloat diameterMax = effectiveDiam / m_RosinRammlerMax;
950
951 MFloat remainingMass = injMass;
952 const MFloat minMass = sphericalMass(diameterMin, material().T());
953
954 injMass = 0;
955 noInjParticles = 0;
956 noInjDroplets = 0;
957
958 std::function<MFloat(MInt)> holePosition = [&](MInt id) {
959 const MFloat angleDelta = 2 * M_PI / 8;
960 switch(m_injectorType) {
961 case MULTIHOLE: {
962 return (id * angleDelta);
963 }
964 case MULTIHOLE_OPT: {
965 // 0: x=0, z=-1
966 // 2: x=-1, z=0
967 // 4: x=0, z=1
968 // 6: x=1, z=0
969 if(id > 1) {
970 id = id + 1;
971 }
972 return id * angleDelta;
973 }
974 case MULTIHOLE_TME: {
975 return m_orificePositionAngle[id] / 180 * M_PI;
976 }
977 default:
978 mTerm(1, AT_, "Unknown multi-hole injector-type!");
979 }
980 };
981
982 std::function<MFloat(MInt)> injectorDiameter = [&](MInt id) {
983 switch(m_injectorType) {
984 case MULTIHOLE:
985 case MULTIHOLE_OPT: {
986 return m_injectorDiameter[0];
987 }
988 case MULTIHOLE_TME: {
989 return m_injectorDiameter[id + 1];
990 }
991 default:
992 mTerm(1, AT_, "Unknown multi-hole injector-type!");
993 }
994 };
995
996 // return angle [degree] of the hole orientation
997 std::function<MFloat(MInt)> holeAngle = [&](MInt id) {
998 switch(m_injectorType) {
999 case MULTIHOLE:
1000 case MULTIHOLE_OPT: {
1001 return 37.0;
1002 }
1003 case MULTIHOLE_TME: {
1004 return m_injectorOrificeAngle[id];
1005 }
1006 default:
1007 mTerm(1, AT_, "Unknown multi-hole injector-type!");
1008 }
1009 };
1010
1011 while(remainingMass > minMass) {
1012 if(lastD > 0) {
1013 injParticleDiameter = lastD;
1014 } else {
1015 injParticleDiameter =
1016 rosinRammler(diameterMin, diameterMean, diameterMax, m_RosinRammlerSpread, randomPrimBreakUp(1));
1017 }
1018
1019 const MFloat particleMass = noHoles * noDroplets * sphericalMass(injParticleDiameter, material().T());
1020
1021 const MFloat tempMass = remainingMass - particleMass;
1022
1023 if(tempMass < 0) {
1024 lastD = injParticleDiameter;
1025 s_backPtr->m_particleResiduum = remainingMass;
1026 break;
1027 }
1028
1029 lastD = -1;
1030 injectParticles(noHoles, s_backPtr->m_spawnCoord, injParticleDiameter, material().densityRatio(),
1031 m_injectionSpeed, initialConeAngle, m_injectorOrficeSize, holePosition, injectorDiameter,
1032 holeAngle, false, noDroplets, noHoles);
1033
1034 injMass += particleMass;
1035 noInjParticles += noHoles;
1036 noInjDroplets += noHoles * noDroplets;
1037 remainingMass -= particleMass;
1038 }
1039 }
1040
1041 // 3) store injection data for possible post-processing:
1043 m_injData[1] = injectionProgress;
1044 m_injData[2] = rampFactor;
1045 m_injData[3] = noInjParticles;
1046 m_injData[4] = noInjDroplets;
1047 m_injData[5] = injParticleDiameter;
1048 m_injData[6] = injMass;
1049
1050 array<MFloat, 3> injMomentum = {};
1051 for(MInt i = 0; i < 3; i++) {
1052 injMomentum[i] = 0;
1053 }
1054 MFloat injEnergy = 0;
1055 for(MInt i = 0; i < noInjParticles; i++) {
1056 const MInt id = s_backPtr->a_noParticles() - 1 - i;
1057 const MFloat mass = sphericalMass(s_backPtr->m_partList[id].m_diameter, s_backPtr->m_partList[id].m_temperature)
1058 * s_backPtr->m_partList[id].m_noParticles;
1059 MFloat velMagSquared = 0;
1060 for(MInt j = 0; j < nDim; j++) {
1061 injMomentum[j] += mass * s_backPtr->m_partList[id].m_velocity[j];
1062 velMagSquared += POW2(s_backPtr->m_partList[id].m_velocity[j]);
1063 }
1064 injEnergy += mass * s_backPtr->m_material->cp(s_backPtr->m_partList[id].m_temperature)
1065 * s_backPtr->m_partList[id].m_temperature * 1 / s_backPtr->m_material->gammaMinusOne();
1066 injEnergy += 0.5 * mass * velMagSquared;
1067 }
1068 m_injData[7] = injMomentum[0];
1069 m_injData[8] = injMomentum[1];
1070 m_injData[9] = injMomentum[2];
1071 m_injData[10] = injEnergy;
1072
1073 cerr << globalTimeStep << " " << m_timeSinceSOI << " injMass " << injMass << " injParticles " << noInjParticles
1074 << endl;
1075}
MInt m_primParcelsPerInj
Definition: lptspray.h:188
MFloat m_angularGap
Definition: lptspray.h:172
MFloat m_currentInjectionRate
Definition: lptspray.h:84
MFloat sphericalMass(const MFloat diameter, const MFloat temperature)
Definition: lptspray.h:74
MaterialState< nDim > & material() const
Definition: lptspray.h:72
MBool m_multiHoleInjector
Definition: lptspray.h:176
MInt m_primBrkUpParcelSize
Definition: lptspray.h:168
MFloat * m_orificePositionAngle
Definition: lptspray.h:112
MFloat * m_injectorOrificeAngle
Definition: lptspray.h:109
MInt m_maxNoPrimParcels
Definition: lptspray.h:187
MInt m_injectorType
Definition: lptspray.h:175
MFloat m_primMinDropletSize
Definition: lptspray.h:93
MBool m_singleHoleInjector
Definition: lptspray.h:177
MFloat m_injectorOrficeSize
Definition: lptspray.h:115
MBool m_hollowConeInjector
Definition: lptspray.h:178
MBool m_primRosinRammler
Definition: lptspray.h:147
MFloat m_sprayConeAngle
Definition: lptspray.h:144
MFloat * m_injectorDiameter
Definition: lptspray.h:106
@ MULTIHOLE_OPT
Definition: enums.h:361
@ MULTIHOLE
Definition: enums.h:361
@ MULTIHOLE_TME
Definition: enums.h:361
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
constexpr Real POW2(const Real x)
Definition: functions.h:119
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94
MInt id
Definition: maiatypes.h:71

◆ randomPrimBreakUp()

template<MInt nDim>
std::mt19937_64 & SprayModel< nDim >::randomPrimBreakUp ( const MInt  calls)
inline

Definition at line 234 of file lptspray.h.

234 {
235 ASSERT(domainId() == s_backPtr->m_spawnDomainId, "");
236 m_PRNGPrimBreakUpCount += calls;
237 return m_PRNGPrimBreakUp;
238 }
std::mt19937_64 m_PRNGPrimBreakUp
Definition: lptspray.h:231

◆ randomSecBreakUp()

template<MInt nDim>
std::mt19937_64 & SprayModel< nDim >::randomSecBreakUp ( )
inlineprivate

Definition at line 227 of file lptspray.h.

227{ return m_PRNGSecBU; }

◆ readSprayProperties()

template<MInt nDim>
void SprayModel< nDim >::readSprayProperties ( )
private

◆ secondaryBreakUp()

template<MInt nDim>
void SprayModel< nDim >::secondaryBreakUp ( const MFloat  dt)
Author
Sven Berger
Date
November 2015

Definition at line 1081 of file lptspray.cpp.

1081 {
1082 TRACE();
1083
1084 m_noRTsecBreakUp = 0;
1085 m_noKHsecBreakUp = 0;
1086
1087 if(!m_RTsecBreakUp && !m_KHsecBreakUp) return;
1088
1089 // use const to avoid breakup of particles which have just been created
1090 const MInt noPart = s_backPtr->a_noParticles();
1091
1092 // increase size of particle vector if necessary before joining next loop
1093 if(0.5 * s_backPtr->m_partList.capacity() < s_backPtr->a_noParticles()) {
1094 s_backPtr->m_partList.reserve(10 * s_backPtr->m_partList.capacity());
1095 }
1096
1097 // 0) Compute break-up length:
1098 // (usually used when no initial droplet size distribution (IDS) is available and
1099 // the blob method is used
1100 // Break-up length can be calculated by Levich theory according to Levich, 1962
1101
1102 const MFloat breakupLength =
1103 m_RTsecBreakUpLength ? m_Cbu * m_injectorNozzleDiameter * sqrt(material().ambientDensityRatio()) : 0;
1104
1105 // if(droplet.m_breakUpTime > 0.43839) {
1106 // reset for particles which have been affected significantly by tumble motion!
1107 // breakupLength = 0.0;
1108 //}
1109
1110
1111 ASSERT(m_injectorNozzleDiameter > 0, "ERROR: No valid nozzle diameter set.");
1112 ASSERT(breakupLength > -MFloatEps, "ERROR: Invalid breakup length.");
1113
1114 // 1) Loop over all particles and check for break-up
1115 for(MInt i = 0; i < noPart; i++) {
1116 auto& droplet = s_backPtr->m_partList.at(i);
1117
1118 if(droplet.firstStep()) continue;
1119 if(droplet.isInvalid()) continue;
1120 if(droplet.fullyEvaporated()) continue;
1121 ASSERT(!isnan(droplet.m_diameter), "Invalid diameter! ");
1122 if(droplet.m_diameter < s_backPtr->m_sizeLimit) continue;
1123 if(droplet.hadWallColl()) continue;
1124
1125 ASSERT(droplet.m_cellId > 0, "ERROR: Invalid cellId");
1126
1127 // increase breakup time
1128 droplet.m_breakUpTime += dt;
1129
1130 ASSERT(!isnan(droplet.m_shedDiam) && droplet.m_shedDiam > -MFloatEps, "");
1131
1132 // 2) Computations for Kelvin-Helmholtz Break up Model mainly based on:
1133 // "Modeling Spray Atomization with the Kelvin-Helmholtz/Rayleigh-Taylor Hibrid Model"
1134 // by Beale and Reitz, Atomization and Sprays (1999)
1135 // NOTE: in this case the radius and not the diameter is used as reference length!
1136
1137 MFloat liquidLength = MFloatMax;
1139 liquidLength = maia::math::distance(s_backPtr->m_spawnCoord, droplet.m_position);
1140 /*
1141 if(m_injectorType == MULTIHOLE) {
1142 const MFloat dist1 = maia::math::distance(s_backPtr->m_spawnCoord, droplet.m_position);
1143 const MFloat diff = POW2(dist1) - POW2(m_injectorDiameter);
1144 if(diff > 0) {
1145 liquidLength = sqrt(diff);
1146 } else {
1147 liquidLength = 0;
1148 }
1149 }
1150 */
1151 }
1152
1153 const MFloat dropRadius = 0.5 * droplet.m_diameter;
1154 const MFloat relV = droplet.magRelVel(&droplet.m_fluidVel[0], &droplet.m_velocity[0]);
1155
1156 //#ifdef LPT_DEBUG
1157 if(isnan(relV)) {
1158 cerr << droplet.m_fluidVel[0] << " " << droplet.m_fluidVel[1] << " " << droplet.m_fluidVel[nDim - 1] << endl;
1159 mTerm(1, AT_, "");
1160 }
1161 //#endif
1162
1163 // radius based particle Weber-number
1164 const MFloat We_l =
1165 droplet.WeberNumber(s_backPtr->m_material->density(droplet.m_temperature), pow(relV, 2), droplet.m_temperature)
1166 * droplet.s_We;
1167
1168 // if the weber number is to small the further calculated values are nan or inf
1169 if(We_l < m_weberLimitKH) continue;
1170
1171 // particle Reynolds number
1172 // factor 0.5 to convert from diameter to radius based
1173 const MFloat Re_l = 0.5
1174 * droplet.particleRe(material().density(droplet.m_temperature), relV,
1175 material().dynamicViscosity(droplet.m_temperature))
1176 * droplet.s_Re;
1177
1178 // gas Weber number
1179 const MFloat We_g = droplet.WeberNumber(droplet.m_fluidDensity, pow(relV, 2), droplet.m_temperature) * droplet.s_We;
1180 // Ohnesorge number
1181 const MFloat Z = sqrt(We_l) / Re_l;
1182 // Taylor number
1183 const MFloat T = Z * sqrt(We_g);
1184
1185 // Lamda_KH
1186 const MFloat KH_waveL = 9.02 * dropRadius * (1.0 + 0.45 * sqrt(Z)) * (1.0 + 0.4 * pow(T, 0.7))
1187 / pow(1.0 + 0.865 * pow(We_g, 1.67), 0.6);
1188
1189
1190 // Kelvin-Helmholtz reference diameter (thus factor 2.0)
1191 const MFloat KH_diameter = 2.0 * m_B0 * KH_waveL;
1192
1193 // ASSERT(KH_diameter > MFloatEps,
1194 // to_string(KH_diameter) + " surfWL " + to_string(KH_waveL));
1195 if(KH_diameter < 2 * MFloatEps) {
1196 cerr << KH_diameter << " d_KH " << dropRadius << " " << Z << " " << T << " " << We_g << " " << We_l << endl;
1197 }
1198
1199 // Omega_KH
1200 const MFloat KH_growthR = ((0.34 + 0.38 * pow(We_g, 1.5)) / ((1.0 + Z) * (1.0 + 1.4 * pow(T, 0.6))))
1201 * sqrt(material().spraySurfaceTension(droplet.m_temperature)
1202 / (material().density(droplet.m_temperature) * pow(dropRadius, 3)))
1203 * sqrt(1 / droplet.s_We);
1204
1205
1206 // tau_kH
1207 const MFloat KH_time = 3.726 * m_B1 * dropRadius / (KH_waveL * KH_growthR);
1208
1209 // const MFloat KH_speed = (droplet.m_diameter - KH_diameter) / KH_time;
1210
1211 // 3) prepare initialisation of new droplets
1212 // parent velocity magnitude
1213 const MFloat magVel = droplet.magVel();
1214 array<MFloat, nDim> parentTrajectory{};
1215 // get parent droplet direction
1216 for(MInt v = 0; v < nDim; v++) {
1217 parentTrajectory.at(v) = droplet.m_velocity.at(v) / magVel;
1218 }
1219
1220 // in case parent parcel is not moving
1221 if(magVel < MFloatEps) {
1222 // TODO labels:LPT,totest check if this exception is necessary!
1223 continue;
1224 /*
1225 // get direction from flow direction
1226 MFloat fluidVel = 0;
1227 for(MInt j = 0; j < nDim; j++) {
1228 fluidVel += POW2(s_backPtr->a_fluidVelocity(droplet.m_cellId, j));
1229 }
1230 fluidVel = sqrt(fluidVel);
1231
1232 for(MInt v = 0; v < nDim; v++) {
1233 parentTrajectory[v] = s_backPtr->a_fluidVelocity(droplet.m_cellId, v) / fluidVel;
1234 }
1235 */
1236 }
1237
1238 // magnitude of droplet acceleration
1239 MFloat drop_accel = 0.0;
1240 for(MInt dir = 0; dir < nDim; dir++) {
1241 drop_accel += POW2(droplet.m_accel.at(dir));
1242 }
1243 drop_accel = sqrt(drop_accel);
1244
1245 // storing some old droplet properties
1246 const MFloat oldMass = droplet.sphericalMass() * droplet.m_noParticles;
1247 vector<MFloat> oldMom(nDim);
1248 for(MInt n = 0; n < nDim; n++) {
1249 oldMom[n] = oldMass * droplet.m_velocity[n];
1250 }
1251 const MFloat oldDiameter = droplet.m_diameter;
1252
1253 // 4) Computations for Rayleigh-Taylor Break up Model mainly based on:
1254 // "Modeling Spray Atomization with the Kelvin-Helmholtz/Rayleigh-Taylor Hibrid Model"
1255 // by Beale and Reitz, Atomization and Sprays (1999)
1256 // or Baumgarten
1257
1258 // NOTE wavelength = 2 * PI * 1/ waveNumber(=K_RT)
1259 const MFloat RT_waveL =
1260 2.0 * PI
1261 * sqrt(3.0 * material().spraySurfaceTension(droplet.m_temperature)
1262 / (drop_accel * (material().density(droplet.m_temperature) - droplet.m_fluidDensity)))
1263 / sqrt(droplet.s_We);
1264
1265 // Omega_RT
1266 const MFloat RT_frequency =
1267 sqrt(2.0 / (3.0 * sqrt(3.0 * material().spraySurfaceTension(droplet.m_temperature)))
1268 * pow(drop_accel * (material().density(droplet.m_temperature) - droplet.m_fluidDensity), 3.0 / 2.0)
1269 / (material().density(droplet.m_temperature) + droplet.m_fluidDensity))
1270 * pow(droplet.s_We, 1 / 4);
1271
1272 const MFloat RT_time = m_CT / RT_frequency;
1273
1274 // NOTE: in this case its the diameter!
1275 const MFloat RT_diameter = m_CRT * RT_waveL;
1276
1277 ASSERT(RT_diameter > 0, "");
1278
1279 // const MFloat RT_speed = (droplet.m_diameter - RT_diameter) / RT_time;
1280
1281
1282 // 6) Rayleigh-Taylor break-up
1283 if(m_RTsecBreakUp && liquidLength >= breakupLength && droplet.m_breakUpTime >= RT_time
1284 && droplet.m_diameter > RT_diameter && We_l < m_weberLimitRT) {
1285 // choose RT child diameter version
1286 MFloat childDiameter = RT_diameter;
1287 if(m_RTDiameterMode == 2) {
1288 initPRNG(globalTimeStep, s_backPtr->c_globalId(droplet.m_cellId));
1289 const MFloat diameterMin = RT_diameter / m_RosinRammlerMin;
1290 const MFloat diameterMean = RT_diameter / m_RosinRammlerMean;
1291 const MFloat diameterMax = RT_diameter / m_RosinRammlerMax;
1292 childDiameter = rosinRammler(diameterMin, diameterMean, diameterMax, m_RosinRammlerSpread, randomSecBreakUp());
1293 if(droplet.m_diameter < childDiameter) {
1294 // no breakup
1295 continue;
1296 }
1297 } else if(m_RTDiameterMode == 1) {
1298 childDiameter = pow(oldDiameter, 2 / 3) * pow(RT_diameter, 1 / 3);
1299 }
1300
1301 if(m_maxRTChildParcels == 0) {
1302 // no child parcles are added, only the diameter and no-particles is changed
1303 auto noDroplets = static_cast<MInt>(droplet.m_noParticles * POW3(oldDiameter / childDiameter));
1304 // NOTE: casting obove means a runding down for all positive values
1305 // version below applies additiona round up for values above 0.75
1306
1307 // NOTE: applying rounding to avoid mass-losses!
1308 if(noDroplets > 0) {
1309 childDiameter = pow(6.0 / PI, 1.0 / 3.0)
1310 * pow(oldMass / (noDroplets * material().density(droplet.m_temperature)), 1.0 / 3.0);
1311 droplet.m_diameter = childDiameter;
1312 droplet.m_shedDiam = childDiameter;
1313 droplet.m_noParticles = noDroplets;
1314 droplet.m_breakUpTime = 0.0;
1316
1317 const MFloat newMass = sphericalMass(droplet.m_diameter, droplet.m_temperature) * droplet.m_noParticles;
1318 if(fabs(newMass - oldMass) > MFloatEps) {
1319 cerr << "Missing mass is RT-breakup " << oldMass << " " << newMass << endl;
1320 }
1321 }
1322
1323 } else {
1324 if(m_RTDiameterMode != 2) {
1325 initPRNG(globalTimeStep, s_backPtr->c_globalId(droplet.m_cellId));
1326 }
1327
1328 // calculate new number of droplets
1329 const MFloat dropletVolume = pow(droplet.m_diameter, 3.0);
1330 const MFloat dropletRTVolume = pow(childDiameter, 3.0);
1331
1332 MInt noBrokenUpDroplets = dropletVolume / dropletRTVolume;
1333
1334 // don't allow inconsequential breakup
1335 if(noBrokenUpDroplets == 1) {
1336 continue;
1337 }
1338 noBrokenUpDroplets *= droplet.m_noParticles;
1339
1340 // number of drops per new parcel
1341 auto dropsPerParcel = static_cast<MInt>(
1342 noBrokenUpDroplets > m_maxRTChildParcels ? floor(noBrokenUpDroplets / m_maxRTChildParcels) : 1);
1343
1344 // limit the number of new parcels
1345 MInt noNewParcels = noBrokenUpDroplets;
1346 if(dropsPerParcel > 1) {
1347 noNewParcels = m_maxRTChildParcels - 1;
1348 } else {
1349 --noNewParcels;
1350 }
1351
1352 const MFloat RT_dropletMass = sphericalMass(childDiameter, droplet.m_temperature);
1353 const MFloat parentMass = oldMass - dropsPerParcel * RT_dropletMass * noNewParcels;
1354 const MFloat parentDiam =
1355 pow(6.0 / PI, 1.0 / 3.0)
1356 * pow(parentMass / (dropsPerParcel * material().density(droplet.m_temperature)), 1.0 / 3.0);
1357
1358 ASSERT(parentMass > 0, "Invalid mass!");
1359 ASSERT(parentDiam > 0 && !isnan(parentDiam), "");
1360 ASSERT(dropsPerParcel > 0, "");
1361
1362 // Reset values
1363 droplet.m_diameter = parentDiam;
1364 droplet.m_shedDiam = parentDiam;
1365 droplet.m_noParticles = dropsPerParcel;
1366 droplet.m_breakUpTime = 0.0;
1368
1369#ifdef _OPENMP
1370#pragma omp critical
1371#endif
1373 cerr << "#################################################" << endl;
1374 cerr << "Break-Up type: RT" << endl;
1375 cerr << "parent diameter: " << droplet.m_diameter << endl;
1376 cerr << "Time: " << m_timeSinceSOI << endl;
1377 cerr << "old number of particles: " << droplet.m_noParticles << endl;
1378 cerr << "new particles/parcels: " << noNewParcels << endl;
1379 cerr << "parcel size: " << dropsPerParcel << endl;
1380 cerr << "Weber number: " << We_l << endl;
1381 cerr << "#################################################" << endl;
1382 }
1383
1384 MFloat sprayAngle = m_sprayAngle[0];
1386 // hollow cone injectors have a large spray angle because of the hollow cone
1387 // geometry the actual relevant spray angle is much smaller
1388 static constexpr MFloat angularGapAngle = 45.0;
1389 sprayAngle = m_sprayAngle[0] - 2 * angularGapAngle;
1390 }
1391
1392#ifdef LPT_DEBUG
1393 vector<MFloat> mom(nDim);
1394#endif
1395
1396 // create new droplets
1397 array<MFloat, nDim> childVelocity{};
1398 for(MInt s = 0; s < noNewParcels; s++) {
1399 randomVectorInCone(&childVelocity[0], &parentTrajectory[0], magVel, sprayAngle, m_partEmittDist,
1401
1402 const MInt childId = s_backPtr->addParticle(droplet.m_cellId, childDiameter, droplet.m_densityRatio, 0, 3,
1403 &childVelocity[0], &droplet.m_position[0], dropsPerParcel);
1404
1405 // set child temperature based on parent value
1406 s_backPtr->m_partList[childId].m_temperature = droplet.m_temperature;
1407 s_backPtr->m_partList[childId].m_heatFlux = 0.0;
1408 s_backPtr->m_partList[childId].m_dM = 0.0;
1409
1410
1411#ifdef LPT_DEBUG
1412 // check kin. energy conservation
1413 MFloat magVelChild = 0;
1414 for(MInt n = 0; n < nDim; n++) {
1415 magVelChild += POW2(childVelocity[n]);
1416 }
1417 magVelChild = sqrt(magVelChild);
1418 if(fabs(magVel - magVelChild) > MFloatEps) {
1419 cerr << "RT kin. energy loss: " << magVel << " " << magVelChild << endl;
1420 }
1421 for(MInt n = 0; n < nDim; n++) {
1422 mom[n] += sphericalMass(childDiameter, droplet.m_temperature) * dropsPerParcel * childVelocity[n];
1423 }
1424#endif
1425 }
1426
1427#ifdef LPT_DEBUG
1428 // check momentum conservation:
1429 for(MInt n = 0; n < nDim; n++) {
1430 mom[n] +=
1431 droplet.m_velocity[n] * sphericalMass(droplet.m_diameter, droplet.m_temperature) * droplet.m_noParticles;
1432
1433 if(fabs(oldMom[n] - mom[n]) > MFloatEps) {
1434 cerr << "RT momentum change: " << oldMom[n] << " " << mom[n] << endl;
1435 }
1436 }
1437
1438 // check conservation:
1439 const MFloat newMass = sphericalMass(droplet.m_diameter, droplet.m_temperature) * droplet.m_noParticles;
1440 MFloat childMass = 0;
1441 for(MInt n = 0; n < noNewParcels; n++) {
1442 const MInt id = s_backPtr->a_noParticles() - 1 - n;
1443 childMass += (sphericalMass(s_backPtr->m_partList[id].m_diameter, s_backPtr->m_partList[id].m_temperature)
1444 * s_backPtr->m_partList[id].m_noParticles);
1445 }
1446 const MFloat massLoss_RT = oldMass - newMass - childMass;
1447 if(fabs(massLoss_RT) > MFloatEps) {
1448 cerr << "RT Mass loss! Old " << oldMass << " parent " << newMass << " childs " << childMass << " diff "
1449 << massLoss_RT << endl;
1450 }
1451#endif
1452 }
1453 continue;
1454 }
1455
1456 // Kelvin-Helmholtz induced break-up
1457 // if((KH_speed >= RT_speed || liquidLength < breakupLength) && droplet.m_diameter >= KH_diameter && m_KHsecBreakUp)
1458 // {
1459 if(m_KHsecBreakUp && droplet.m_diameter > KH_diameter) {
1460 const MFloat KH_mass = sphericalMass(KH_diameter, droplet.m_temperature);
1461 if(KH_mass < MFloatEps) continue;
1462 // ASSERT(KH_mass > MFloatEps, to_string(KH_mass) + " KH_diameter:" + to_string(KH_diameter));
1463
1464 // Kelvin-Helmholtz induced mass stripping
1465 // NOTE: shedDiam is the diameter of the parent particle after undergoing KH-breakup!
1466 // i.e. the remaining mass in the parent!
1467 droplet.m_shedDiam -= (droplet.m_shedDiam - KH_diameter) / KH_time * dt;
1468
1469 // if the shed diameter is smaller than the KH diameter
1470 // no child parcel is added, the parent diameter is set to the KH-diameter
1471 // and the noParticles is set by mass conservation
1472 if(droplet.m_shedDiam < KH_diameter) {
1473 MInt noDroplets = floor(oldMass / KH_mass);
1474 if(noDroplets > 0) {
1475 const MFloat diameter = pow(6.0 / PI, 1.0 / 3.0)
1476 * pow(oldMass / (noDroplets * material().density(droplet.m_temperature)), 1.0 / 3.0);
1477 // fully transversion to KH-diameter
1478 // after applying rounding to avoid mass-losses!
1479 // droplet.m_breakUpTime = -dt;
1480 droplet.m_diameter = diameter;
1481 droplet.m_shedDiam = diameter;
1482 droplet.m_noParticles = noDroplets;
1484
1485 const MFloat newMass = sphericalMass(droplet.m_diameter, droplet.m_temperature) * droplet.m_noParticles;
1486 if(fabs(newMass - oldMass) > MFloatEps) {
1487 cerr << "Missing mass at KH-breakup 1 is " << oldMass << " " << newMass << endl;
1488 }
1489 continue;
1490 }
1491 }
1492
1493 // mass going into the particle = oldMass - mass remaining in the parant parcel
1494 const MFloat sheddedMass =
1495 oldMass - sphericalMass(droplet.m_shedDiam, droplet.m_temperature) * droplet.m_noParticles;
1496
1497 if(m_massLimit > sheddedMass / oldMass) {
1498 continue;
1499 }
1500
1501 MInt noSheddedOffDrops = floor(sheddedMass / KH_mass);
1502 if(noSheddedOffDrops <= 0) continue;
1503 const MFloat parentMass = oldMass - KH_mass * noSheddedOffDrops;
1504 ASSERT(parentMass > 0, "");
1505 // when reformulating the equations above, parentDiam is equal to the shedDiam!
1506 const MFloat parentDiam =
1507 pow(6.0 / PI * parentMass / (droplet.m_noParticles * material().density(droplet.m_temperature)), 1.0 / 3.0);
1508
1509 // adding additional child parcel
1510 // child parcel properties set as prescribed in
1511 //"Modeling Atomization Processes in High-Pressure Vaporizing Sprays"
1512 // R. Reitz , Atom.& Sprayz 3 (1987) 309-337
1513 initPRNG(globalTimeStep, s_backPtr->c_globalId(droplet.m_cellId));
1514
1515 // droplet.m_breakUpTime = -dt;
1516 droplet.m_diameter = parentDiam;
1517 droplet.m_shedDiam = parentDiam;
1518
1519 // different spray-angle versions
1520 MFloat angle = m_sprayAngle[0];
1521 if(m_sprayAngleKH > 1 && m_sprayAngleKH < 2.9) {
1522 angle = m_sprayAngle[0];
1523 if(liquidLength < breakupLength) {
1524 angle = m_sprayConeAngle;
1525 }
1526 } else if(m_sprayAngleKH > 0 && m_sprayAngleKH < 1) {
1527 angle = 2 * atan(m_sprayAngleKH * KH_growthR * KH_waveL / m_injectionSpeed);
1528 angle = min(m_sprayAngle[0], angle);
1529 } else if(m_sprayAngleKH > 2.9) {
1530 if(liquidLength < breakupLength) {
1531 angle = m_sprayAngle[0];
1532 } else {
1533 angle = m_sprayAngle[1];
1534 }
1535 }
1536
1537 if(angle < 0 || angle > 90) {
1538 cerr << "Large KH-spray angle : " << angle << endl;
1539 }
1540
1541 array<MFloat, nDim> childVelocity{};
1542 randomVectorInCone(&childVelocity[0], &parentTrajectory[0], magVel, angle, string2enum("PART_EMITT_DIST_NONE"),
1544
1545 // adding a single additional parcel with KH_diameter
1546 const MInt childId = s_backPtr->addParticle(droplet.m_cellId, KH_diameter, droplet.m_densityRatio, 0, 3,
1547 &childVelocity[0], &droplet.m_position[0], noSheddedOffDrops);
1548
1549 // set child temperature based on parent value
1550 s_backPtr->m_partList[childId].m_temperature = droplet.m_temperature;
1551 s_backPtr->m_partList[childId].m_heatFlux = 0.0;
1552 s_backPtr->m_partList[childId].m_dM = 0.0;
1553
1554
1556
1557#ifdef _OPENMP
1558#pragma omp critical
1559#endif
1561 cerr << "#################################################" << endl;
1562 cerr << "Break-Up type: KH" << endl;
1563 cerr << "parent diameter: " << droplet.m_diameter << " " << parentDiam << endl;
1564 cerr << "KH size: " << KH_diameter << endl;
1565 cerr << "KH time: " << KH_time << endl;
1566 cerr << "Time: " << m_timeSinceSOI << endl;
1567 cerr << "old #droplets: " << droplet.m_noParticles << endl;
1568 cerr << "# new droplets: " << noSheddedOffDrops << endl;
1569 cerr << "Weber number: " << We_l << endl;
1570 cerr << "#################################################" << endl;
1571 }
1572
1573 // apply velocity change to parent particle
1574 // under momentum and kin. energy conservation!
1575 /*
1576 vector<MFloat> childMom(nDim);
1577 for(MInt n = 0; n < nDim; n++){
1578 childMom[n] = sphericalMass(KH_diameter) * noSheddedOffDrops * childVelocity[n];
1579 droplet.m_velocity[n] = (oldMom[n] - childMom[n])
1580 / (sphericalMass(droplet.m_diameter) * droplet.m_noParticles);
1581 }
1582
1583 maia::math::normalize(&droplet.m_velocity[0], 3);
1584 for(MInt n = 0; i < nDim; n++){
1585 droplet.m_velocity[i] *= magVel;
1586 }
1587 */
1588
1589#ifdef LPT_DEBUG
1590 // check momentum conservation
1591 vector<MFloat> mom(nDim);
1592 for(MInt n = 0; n < nDim; n++) {
1593 mom[n] =
1594 droplet.m_velocity[n] * sphericalMass(droplet.m_diameter, droplet.m_temperature) * droplet.m_noParticles
1595 + sphericalMass(KH_diameter, droplet.m_temperature) * noSheddedOffDrops * childVelocity[n];
1596 if(fabs(oldMom[n] - mom[n]) > MFloatEps) {
1597 cerr << "KH momentum change: " << oldMom[n] << " " << mom[n] << " "
1598 << droplet.m_velocity[n] * sphericalMass(droplet.m_diameter, droplet.m_temperature)
1599 * droplet.m_noParticles
1600 << endl;
1601 }
1602 }
1603
1604 // check kin. energy conservation
1605 MFloat magVelChild = 0;
1606 for(MInt n = 0; n < nDim; n++) {
1607 magVelChild += POW2(childVelocity[n]);
1608 }
1609 magVelChild = sqrt(magVelChild);
1610 if(fabs(magVel - magVelChild) > MFloatEps) {
1611 cerr << "KH kin. energy loss: " << magVel << " " << magVelChild << endl;
1612 }
1613 MFloat magVelNew = droplet.magVel();
1614 if(fabs(magVel - magVelNew) > MFloatEps) {
1615 cerr << "KH kin. energy loss: " << magVel << " " << magVelNew << endl;
1616 }
1617 // check mass conservation
1618 const MFloat newMass = sphericalMass(droplet.m_diameter, droplet.m_temperature) * droplet.m_noParticles;
1619 const MInt childId = s_backPtr->a_noParticles() - 1;
1620 const MFloat childMass =
1621 sphericalMass(s_backPtr->m_partList[childId].m_diameter, s_backPtr->m_partList[childId].m_temperature)
1622 * s_backPtr->m_partList[childId].m_noParticles;
1623 const MFloat massLoss_KH = oldMass - newMass - childMass;
1624 if(fabs(massLoss_KH) > MFloatEps) {
1625 cerr << "KH Mass loss! Old " << oldMass << " parent " << newMass << " childs " << childMass << " diff "
1626 << massLoss_KH << endl;
1627 }
1628#endif
1629 } /*else if( m_KHsecBreakUp && KH_diameter > droplet.m_diameter &&
1630 droplet.m_breakUpTime > KH_time ) {
1631 //version by Reitz (1987)
1632 MFloat d_KH = 2 * mMin(
1633 pow(3 * PI * POW2(droplet.m_diameter) * relV / ( 2 * 4 * KH_growthR), 0.33),
1634 pow(3 * POW2(droplet.m_diameter) * KH_waveL / 16, 0.33));
1635
1636 auto noDroplets = static_cast<MInt>(droplet.m_noParticles *
1637 POW3(droplet.m_diameter) / POW3(d_KH));
1638 if(noDroplets > 0 ) {
1639 const MFloat diameter = pow(6.0 / PI, 1.0 / 3.0) *
1640 pow(oldMass / (noDroplets * material().density(droplet.m_temperature)), 1.0/ 3.0);
1641 //change droplet diameter
1642 droplet.m_breakUpTime = 0.0;
1643 droplet.m_diameter = diameter;
1644 droplet.m_shedDiam = diameter;
1645 droplet.m_noParticles = noDroplets;
1646 m_noKHsecBreakUp++;
1647 }
1648 }
1649 */
1650 }
1651}
std::mt19937_64 & randomSecBreakUp()
Definition: lptspray.h:227
MInt m_noRTsecBreakUp
Definition: lptspray.h:242
MFloat m_CRT
Definition: lptspray.h:154
MFloat m_CT
Definition: lptspray.h:155
MFloat m_weberLimitRT
Definition: lptspray.h:158
MBool m_secBUDisplayMessage
Definition: lptspray.h:159
MBool m_RTsecBreakUpLength
Definition: lptspray.h:183
MFloat m_sprayAngleKH
Definition: lptspray.h:163
MFloat m_weberLimitKH
Definition: lptspray.h:156
MFloat m_Cbu
Definition: lptspray.h:161
MInt m_RTDiameterMode
Definition: lptspray.h:162
MInt m_maxRTChildParcels
Definition: lptspray.h:160
MFloat m_B0
Definition: lptspray.h:152
MInt m_noKHsecBreakUp
Definition: lptspray.h:243
MBool m_KHsecBreakUp
Definition: lptspray.h:182
MFloat m_massLimit
Definition: lptspray.h:157
MBool m_RTsecBreakUp
Definition: lptspray.h:181
void initPRNG(const MInt seed, const MInt discard)
Definition: lptspray.h:220
MFloat m_B1
Definition: lptspray.h:153
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
Definition: enums.cpp:20
constexpr Real POW3(const Real x)
Definition: functions.h:123
MFloat distance(const MFloat *a, const MFloat *b)
Definition: maiamath.h:249

◆ solverId()

template<MInt nDim>
MInt SprayModel< nDim >::solverId ( ) const
inlineprivate

Definition at line 70 of file lptspray.h.

70{ return s_backPtr->solverId(); }

◆ soonInjection()

template<MInt nDim>
MBool SprayModel< nDim >::soonInjection ( const MFloat  time)
inline

Definition at line 47 of file lptspray.h.

47 {
49 return true;
50 }
51 if(m_injectionCrankAngle < 0) {
52 return true;
53 } else if(m_injectionCrankAngle > -1
55 return true;
56 }
57 return false;
58 }

◆ sphericalMass()

template<MInt nDim>
MFloat SprayModel< nDim >::sphericalMass ( const MFloat  diameter,
const MFloat  temperature 
)
inlineprivate

Definition at line 74 of file lptspray.h.

74 {
75 return 1.0 / 6.0 * PI * material().density(temperature) * POW3(diameter);
76 }

◆ timeSinceSOI() [1/2]

template<MInt nDim>
MFloat & SprayModel< nDim >::timeSinceSOI ( )
inline

Definition at line 33 of file lptspray.h.

33{ return m_timeSinceSOI; }

◆ timeSinceSOI() [2/2]

template<MInt nDim>
MFloat SprayModel< nDim >::timeSinceSOI ( ) const
inline

Definition at line 32 of file lptspray.h.

32{ return m_timeSinceSOI; }

◆ updateInjectionRate()

template<MInt nDim>
void SprayModel< nDim >::updateInjectionRate
private
Author
Piotr Duda, Sven Berger
Date
June 2016

Definition at line 1658 of file lptspray.cpp.

1658 {
1659 const MInt numInjections = m_injectionRateList.dim0();
1660 if(numInjections == 0) return;
1661
1664 } else {
1665 for(MInt i = 0; i <= numInjections; i++) {
1667 const MFloat t =
1670 break;
1671 }
1672 }
1673 }
1674}
MFloatTensor m_injectionTimings
Definition: lptspray.h:90
MFloatTensor m_injectionRateList
Definition: lptspray.h:87
size_type dim0() const
Return the size of dimension 0.
Definition: tensor.h:366

Member Data Documentation

◆ m_activePrimaryBUp

template<MInt nDim>
MBool SprayModel< nDim >::m_activePrimaryBUp = true
private

Definition at line 165 of file lptspray.h.

◆ m_activeSecondaryBUp

template<MInt nDim>
MBool SprayModel< nDim >::m_activeSecondaryBUp = false
private

Definition at line 166 of file lptspray.h.

◆ m_angularGap

template<MInt nDim>
MFloat SprayModel< nDim >::m_angularGap = -1
private

Definition at line 172 of file lptspray.h.

◆ m_B0

template<MInt nDim>
MFloat SprayModel< nDim >::m_B0 = 0.61
private

Definition at line 152 of file lptspray.h.

◆ m_B1

template<MInt nDim>
MFloat SprayModel< nDim >::m_B1 = 40
private

Definition at line 153 of file lptspray.h.

◆ m_broadcastInjected

template<MInt nDim>
MBool SprayModel< nDim >::m_broadcastInjected = true

Definition at line 41 of file lptspray.h.

◆ m_Cbu

template<MInt nDim>
MFloat SprayModel< nDim >::m_Cbu = 20
private

Definition at line 161 of file lptspray.h.

◆ m_CRT

template<MInt nDim>
MFloat SprayModel< nDim >::m_CRT = 0.1
private

Definition at line 154 of file lptspray.h.

◆ m_CT

template<MInt nDim>
MFloat SprayModel< nDim >::m_CT = 1.0
private

Definition at line 155 of file lptspray.h.

◆ m_currentInjectionRate

template<MInt nDim>
MFloat SprayModel< nDim >::m_currentInjectionRate = 0.0
private

Definition at line 84 of file lptspray.h.

◆ m_hollowConeInjector

template<MInt nDim>
MBool SprayModel< nDim >::m_hollowConeInjector = false
private

Definition at line 178 of file lptspray.h.

◆ m_initialCad

template<MInt nDim>
MFloat SprayModel< nDim >::m_initialCad = 0

Definition at line 62 of file lptspray.h.

◆ m_injData

template<MInt nDim>
MFloat* SprayModel< nDim >::m_injData = nullptr

Definition at line 39 of file lptspray.h.

◆ m_injDataSize

template<MInt nDim>
constexpr MInt SprayModel< nDim >::m_injDataSize = 11
staticconstexpr

Definition at line 38 of file lptspray.h.

◆ m_injDuration

template<MInt nDim>
MFloat SprayModel< nDim >::m_injDuration = 0.00055
private

Definition at line 96 of file lptspray.h.

◆ m_injectionCrankAngle

template<MInt nDim>
MFloat SprayModel< nDim >::m_injectionCrankAngle = -1

Definition at line 60 of file lptspray.h.

◆ m_injectionDistSigmaCoeff

template<MInt nDim>
MFloat SprayModel< nDim >::m_injectionDistSigmaCoeff = 1.0
private

Definition at line 137 of file lptspray.h.

◆ m_injectionRateList

template<MInt nDim>
MFloatTensor SprayModel< nDim >::m_injectionRateList
private

Definition at line 87 of file lptspray.h.

◆ m_injectionSpeed

template<MInt nDim>
MFloat SprayModel< nDim >::m_injectionSpeed = -1.0
private

Definition at line 103 of file lptspray.h.

◆ m_injectionTimings

template<MInt nDim>
MFloatTensor SprayModel< nDim >::m_injectionTimings
private

Definition at line 90 of file lptspray.h.

◆ m_injectorDiameter

template<MInt nDim>
MFloat* SprayModel< nDim >::m_injectorDiameter = nullptr
private

Definition at line 106 of file lptspray.h.

◆ m_injectorDir

template<MInt nDim>
MFloat SprayModel< nDim >::m_injectorDir[nDim] {}
private

Definition at line 135 of file lptspray.h.

◆ m_injectorNozzleDiameter

template<MInt nDim>
MFloat SprayModel< nDim >::m_injectorNozzleDiameter = 0.0
private

Definition at line 100 of file lptspray.h.

◆ m_injectorOrficeSize

template<MInt nDim>
MFloat SprayModel< nDim >::m_injectorOrficeSize {}
private

Definition at line 115 of file lptspray.h.

◆ m_injectorOrificeAngle

template<MInt nDim>
MFloat* SprayModel< nDim >::m_injectorOrificeAngle = nullptr
private

Definition at line 109 of file lptspray.h.

◆ m_injectorType

template<MInt nDim>
MInt SprayModel< nDim >::m_injectorType = 0
private

Definition at line 175 of file lptspray.h.

◆ m_injStartTimeStep

template<MInt nDim>
MInt SprayModel< nDim >::m_injStartTimeStep = -1

Definition at line 45 of file lptspray.h.

◆ m_injStep

template<MInt nDim>
MInt SprayModel< nDim >::m_injStep = 0

Definition at line 43 of file lptspray.h.

◆ m_injStopTimeStep

template<MInt nDim>
MInt SprayModel< nDim >::m_injStopTimeStep = -1

Definition at line 44 of file lptspray.h.

◆ m_KHsecBreakUp

template<MInt nDim>
MBool SprayModel< nDim >::m_KHsecBreakUp = true
private

Definition at line 182 of file lptspray.h.

◆ m_massLimit

template<MInt nDim>
MFloat SprayModel< nDim >::m_massLimit = 0.03
private

Definition at line 157 of file lptspray.h.

◆ m_maxNoPrimParcels

template<MInt nDim>
MInt SprayModel< nDim >::m_maxNoPrimParcels = 1
private

Definition at line 187 of file lptspray.h.

◆ m_maxRTChildParcels

template<MInt nDim>
MInt SprayModel< nDim >::m_maxRTChildParcels = 3
private

Definition at line 160 of file lptspray.h.

◆ m_multiHoleInjector

template<MInt nDim>
MBool SprayModel< nDim >::m_multiHoleInjector = false
private

Definition at line 176 of file lptspray.h.

◆ m_needleLiftTime

template<MInt nDim>
MFloat* SprayModel< nDim >::m_needleLiftTime = nullptr
private

Definition at line 132 of file lptspray.h.

◆ m_noKHsecBreakUp

template<MInt nDim>
MInt SprayModel< nDim >::m_noKHsecBreakUp = 0

Definition at line 243 of file lptspray.h.

◆ m_noRTsecBreakUp

template<MInt nDim>
MInt SprayModel< nDim >::m_noRTsecBreakUp = 0

Definition at line 242 of file lptspray.h.

◆ m_orificePositionAngle

template<MInt nDim>
MFloat* SprayModel< nDim >::m_orificePositionAngle = nullptr
private

Definition at line 112 of file lptspray.h.

◆ m_partEmittDist

template<MInt nDim>
MInt SprayModel< nDim >::m_partEmittDist = 0
private

Definition at line 140 of file lptspray.h.

◆ m_predictivePRNG

template<MInt nDim>
MBool SprayModel< nDim >::m_predictivePRNG = true
private

Definition at line 180 of file lptspray.h.

◆ m_primBrkUpParcelSize

template<MInt nDim>
MInt SprayModel< nDim >::m_primBrkUpParcelSize = 1
private

Definition at line 168 of file lptspray.h.

◆ m_primBUp

template<MInt nDim>
MPI_Comm SprayModel< nDim >::m_primBUp
private

Definition at line 185 of file lptspray.h.

◆ m_primMinDropletSize

template<MInt nDim>
MFloat SprayModel< nDim >::m_primMinDropletSize = 5e-7
private

Definition at line 93 of file lptspray.h.

◆ m_primParcelsPerInj

template<MInt nDim>
MInt SprayModel< nDim >::m_primParcelsPerInj = 1000000
private

Definition at line 188 of file lptspray.h.

◆ m_primRosinRammler

template<MInt nDim>
MBool SprayModel< nDim >::m_primRosinRammler = true
private

Definition at line 147 of file lptspray.h.

◆ m_PRNGPrimBreakUp

template<MInt nDim>
std::mt19937_64 SprayModel< nDim >::m_PRNGPrimBreakUp

Definition at line 231 of file lptspray.h.

◆ m_PRNGPrimBreakUpCount

template<MInt nDim>
MInt SprayModel< nDim >::m_PRNGPrimBreakUpCount = 0

Definition at line 232 of file lptspray.h.

◆ m_PRNGSecBU

template<MInt nDim>
std::mt19937_64 SprayModel< nDim >::m_PRNGSecBU
private

Definition at line 191 of file lptspray.h.

◆ m_RosinRammlerMax

template<MInt nDim>
MFloat SprayModel< nDim >::m_RosinRammlerMax = -1
private

Definition at line 124 of file lptspray.h.

◆ m_RosinRammlerMean

template<MInt nDim>
MFloat SprayModel< nDim >::m_RosinRammlerMean = -1
private

Definition at line 121 of file lptspray.h.

◆ m_RosinRammlerMin

template<MInt nDim>
MFloat SprayModel< nDim >::m_RosinRammlerMin = -1
private

Definition at line 118 of file lptspray.h.

◆ m_RosinRammlerSpread

template<MInt nDim>
MFloat SprayModel< nDim >::m_RosinRammlerSpread = -1
private

Definition at line 129 of file lptspray.h.

◆ m_RTDiameterMode

template<MInt nDim>
MInt SprayModel< nDim >::m_RTDiameterMode = 0
private

Definition at line 162 of file lptspray.h.

◆ m_RTsecBreakUp

template<MInt nDim>
MBool SprayModel< nDim >::m_RTsecBreakUp = true
private

Definition at line 181 of file lptspray.h.

◆ m_RTsecBreakUpLength

template<MInt nDim>
MBool SprayModel< nDim >::m_RTsecBreakUpLength = true
private

Definition at line 183 of file lptspray.h.

◆ m_secBUDisplayMessage

template<MInt nDim>
MBool SprayModel< nDim >::m_secBUDisplayMessage = false
private

Definition at line 159 of file lptspray.h.

◆ m_singleHoleInjector

template<MInt nDim>
MBool SprayModel< nDim >::m_singleHoleInjector = false
private

Definition at line 177 of file lptspray.h.

◆ m_sprayAngle

template<MInt nDim>
MFloat* SprayModel< nDim >::m_sprayAngle = nullptr
private

Definition at line 143 of file lptspray.h.

◆ m_sprayAngleKH

template<MInt nDim>
MFloat SprayModel< nDim >::m_sprayAngleKH = 2
private

Definition at line 163 of file lptspray.h.

◆ m_sprayConeAngle

template<MInt nDim>
MFloat SprayModel< nDim >::m_sprayConeAngle = 0.0
private

Definition at line 144 of file lptspray.h.

◆ m_spraySeed

template<MInt nDim>
MLong SprayModel< nDim >::m_spraySeed {}

Definition at line 240 of file lptspray.h.

◆ m_Strouhal

template<MInt nDim>
MFloat SprayModel< nDim >::m_Strouhal = -99

Definition at line 61 of file lptspray.h.

◆ m_timeSinceSOI

template<MInt nDim>
MFloat SprayModel< nDim >::m_timeSinceSOI = 0.0
private

Definition at line 149 of file lptspray.h.

◆ m_useNeedleLiftTime

template<MInt nDim>
MBool SprayModel< nDim >::m_useNeedleLiftTime = false
private

Definition at line 170 of file lptspray.h.

◆ m_weberLimitKH

template<MInt nDim>
MFloat SprayModel< nDim >::m_weberLimitKH = 6
private

Definition at line 156 of file lptspray.h.

◆ m_weberLimitRT

template<MInt nDim>
MFloat SprayModel< nDim >::m_weberLimitRT = 300
private

Definition at line 158 of file lptspray.h.

◆ s_backPtr

template<MInt nDim>
LPT< nDim > * SprayModel< nDim >::s_backPtr = nullptr
staticprivate

Definition at line 66 of file lptspray.h.

◆ s_lengthFactor

template<MInt nDim>
MFloat SprayModel< nDim >::s_lengthFactor {}
staticprivate

Definition at line 67 of file lptspray.h.


The documentation for this class was generated from the following files: