32 if(solver().domainId() == 0) {
33 cerr <<
"Allocating Post-processing LPT data!" << endl;
37 mAlloc(m_particleCV, m_sprayDataSize, 2 + nDim,
"m_particleCV", F0, AT_);
38 mAlloc(m_particlePen, m_sprayDataSize, 19,
"m_particlePen", F0, AT_);
39 mAlloc(m_sprayStat, m_sprayDataSize, 5,
"m_sprayStat", F0, AT_);
40 mAlloc(m_sprayTimes, m_sprayDataSize, 3,
"m_sprayTimes", F0, AT_);
42 if(solver().m_sprayModel ==
nullptr)
return;
45 mAlloc(m_injectionData, this->m_sprayWriteInterval, 15,
"m_injectionData", F0, AT_);
46 mAlloc(m_cInjData, this->m_sprayWriteInterval + 1, nDim + 5,
"m_cInjData", F0, AT_);
48 if(!solver().isActive())
return;
50 array<MFloat, nDim + 5> loadedVariables = {};
52 if(solver().m_restartFile && solver().domainId() == 0) {
54 stringstream filename;
57 filename << solver().restartDir() <<
"injSums";
58 readFile.open(filename.str(), ios_base::in);
63 readFile.open(filename.str(), ios_base::in);
65 mTerm(1, AT_,
"Error reading injection file!");
70 std::ifstream src(filename.str(), std::ios::binary);
71 std::ofstream dst(backupName, std::ios::binary);
74 readFile.seekg(-1, ios_base::end);
80 readFile.seekg(-2, ios::cur);
81 readFile.seekg(-1, ios::cur);
84 readFile.seekg(-2, std::ios::cur);
87 getline(readFile, lastLine);
89 mTerm(1, AT_,
"Wrong injection file-format!");
91 stringstream ss(lastLine);
97 for(
MInt i = 0; i < nDim + 5; i++) {
98 ss >> loadedVariables[i];
99 cerr <<
"Loaded injected Data " << i <<
" is " << loadedVariables[i] << endl;
102 cerr <<
"Searching correct line in injection data-file for " <<
globalTimeStep <<
" from last output " << timeStep
106 readFile.seekg(-2, std::ios::cur);
107 readFile.seekg(-1, std::ios::cur);
109 const MInt oldPos = readFile.tellg();
111 readFile.seekg(-2, std::ios::cur);
115 getline(readFile, lastLine2);
116 const MInt newPos = readFile.tellg();
117 const MInt difPos = -(newPos - oldPos);
118 readFile.seekg(difPos, std::ios::cur);
122 for(
MInt i = 0; i < nDim + 5; i++) {
123 ss >> loadedVariables[i];
124 cerr <<
"Loaded injected Data " << i <<
" is " << loadedVariables[i] << endl;
128 for(
MInt i = 0; i < nDim + 5; i++) {
129 loadedVariables[i] = 0;
137 filename << solver().restartDir() <<
"injSums_" <<
globalTimeStep;
138 readFile.open(filename.str(), ios_base::in);
140 mTerm(1, AT_,
"Error reading injection file!");
142 readFile.seekg(-1, ios_base::end);
146 readFile.seekg(-2, ios::cur);
147 readFile.seekg(-1, ios::cur);
150 readFile.seekg(-2, std::ios::cur);
153 getline(readFile, lastLine2);
155 mTerm(1, AT_,
"Wrong injection file-format!");
157 stringstream ss2(lastLine2);
160 for(
MInt i = 0; i < nDim + 5; i++) {
161 ss2 >> loadedVariables[i];
162 if(solver().domainId() == 0) {
163 cerr <<
"Loaded injected Data " << i <<
" is " << loadedVariables[i] << endl;
167 cerr <<
"Correct Timestep count not be found at the end of in any of the injSums files!"
168 <<
"Either trunkate the files of implement version which checks through all lines!" << endl;
173 for(
MInt i = 0; i < nDim + 5; i++) {
174 m_cInjData[this->m_sprayWriteInterval][i] = loadedVariables[i];
178 if(solver().m_restartFile) {
179 MPI_Allreduce(MPI_IN_PLACE, &(m_cInjData[0][0]), (nDim + 5) * (this->m_sprayWriteInterval + 1), MPI_DOUBLE, MPI_MAX,
180 solver().mpiComm(), AT_,
"INPLACE",
"m_cInjData");
197 MFloat partMomentum[nDim] = {};
198 for(
MInt i = 0; i < nDim; i++) {
201 for(
MInt id = 0;
id < solver().a_noParticles(); ++
id) {
202 if(solver().m_partList[
id].isInvalid())
continue;
203 MFloat mass = solver().m_partList[
id].sphericalMass() * solver().m_partList[
id].m_noParticles;
206 solver().m_material->cp() / solver().m_material->gammaMinusOne() * mass * solver().m_partList[
id].m_temperature;
208 for(
MInt i = 0; i < nDim; i++) {
209 partMomentum[i] += (mass * solver().m_partList[
id].m_velocity[i]);
210 velMagSquared +=
POW2(solver().m_partList[
id].m_velocity[i]);
212 partE += 0.5 * mass * velMagSquared;
214 m_particleCV[m_sprayDataStep][0] = partMass;
215 m_particleCV[m_sprayDataStep][1] = partE;
216 for(
MInt i = 0; i < nDim; i++) {
217 m_particleCV[m_sprayDataStep][2 + i] = partMomentum[i];
237 const MInt noPen = 4;
238 array<array<MFloat, noPen>, nDim + 1> maxLiqPen{};
240 const MFloat massFracLimit = 0.90;
241 const MFloat LVFlimit = 0.025;
242 const MInt refLvl = 10;
245 static constexpr MInt nPlanes = 3;
247 static constexpr MFloat yPlaneBorder = 0.001333;
249 static constexpr MFloat yPlanes[nPlanes] = {0.2, 0.3333, 0.46667};
251 vector<MFloat> width(nPlanes);
252 for(
MInt n = 0; n < nPlanes; n++) {
263 for(
MInt id = 0;
id < solver().a_noParticles(); ++
id) {
264 array<MFloat, nDim + 1> distance{};
265 for(
MInt i = 0; i < nDim; i++) {
266 distance[i] = abs(solver().m_partList[
id].m_position[i] - solver().m_spawnCoord[i]);
269 distance[nDim] = sqrt(
POW2(distance[0]) +
POW2(distance[1]) +
POW2(distance[2]));
272 for(
MInt i = 0; i < nDim + 1; i++) {
273 assignLarger(maxLiqPen[i][0], distance[i]);
276 for(
MInt i = 0; i < nPlanes; i++) {
277 if(fabs(distance[1] - yPlanes[i]) < yPlaneBorder) {
278 assignLarger(width[i], distance[0]);
279 assignLarger(width[i], distance[2]);
282 const MInt cellId = solver().m_partList[
id].m_cellId;
283 if(cellId < 0)
continue;
284 if(solver().a_volumeFraction(cellId) > LVFlimit) {
285 for(
MInt i = 0; i < nDim + 1; i++) {
286 assignLarger(maxLiqPen[i][1], distance[i]);
291 for(
MInt cellId = 0; cellId < solver().noInternalCells(); cellId++) {
292 const MFloat massFraction =
293 solver().a_volumeFraction(cellId) * solver().m_material->density() / solver().a_fluidDensity(cellId);
294 array<MFloat, nDim + 1> distance{};
296 if(massFraction > massFracLimit) {
297 array<MFloat, nDim> cellCoordinate{};
298 for(
MInt i = 0; i < nDim; i++) {
299 cellCoordinate[i] = solver().c_coordinate(cellId, i);
300 distance[i] = abs(cellCoordinate[i] - solver().m_spawnCoord[i]);
302 distance[nDim] = sqrt(
POW2(distance[0]) +
POW2(distance[1]) +
POW2(distance[2]));
304 for(
MInt i = 0; i < nDim + 1; i++) {
305 assignLarger(maxLiqPen[i][2], distance[i]);
308 if(solver().a_level(cellId) == refLvl) {
309 solver().reduceData(cellId, &solver().a_volumeFraction(0), 1);
310 if(solver().a_volumeFraction(cellId) > LVFlimit) {
311 array<MFloat, nDim> cellCoordinate{};
312 for(
MInt i = 0; i < nDim; i++) {
313 cellCoordinate[i] = solver().c_coordinate(cellId, i);
314 distance[i] = abs(cellCoordinate[i] - solver().m_spawnCoord[i]);
316 distance[nDim] = sqrt(
POW2(distance[0]) +
POW2(distance[1]) +
POW2(distance[2]));
318 for(
MInt i = 0; i < nDim + 1; i++) {
319 assignLarger(maxLiqPen[i][3], distance[i]);
327 for(
MInt n = 0; n < noPen; n++) {
328 for(
MInt i = 0; i < nDim + 1; i++) {
329 m_particlePen[m_sprayDataStep][it++] = maxLiqPen[i][n];
333 for(
MInt n = 0; n < nPlanes; n++) {
334 m_particlePen[m_sprayDataStep][it++] = width[n];
338 mTerm(1, AT_,
"PP: Penetration-Storage not matching!");
352 const MInt noPart = solver().a_noParticles();
354 MLong noDroplets = 0;
358 for(
MInt id = 0;
id < noPart; ++
id) {
359 noDroplets += solver().m_partList[
id].m_noParticles;
360 diameter += solver().m_partList[
id].m_noParticles * solver().m_partList[
id].m_diameter;
361 surfaceArea += solver().m_partList[
id].m_noParticles *
POW2(solver().m_partList[
id].m_diameter);
362 volume += solver().m_partList[
id].m_noParticles *
POW3(solver().m_partList[
id].m_diameter);
369 m_sprayStat[m_sprayDataStep][0] = noPart;
370 m_sprayStat[m_sprayDataStep][1] = noDroplets;
371 m_sprayStat[m_sprayDataStep][2] = diameter;
372 m_sprayStat[m_sprayDataStep][3] = surfaceArea;
373 m_sprayStat[m_sprayDataStep][4] = volume;
382 if(solver().m_sprayModel ==
nullptr) {
386 if(!solver().isActive()) {
387 solver().m_injData.clear();
391 const MInt injectorCellId = solver().injectorCellId();
395 for(
auto it = solver().m_injData.begin(); it != solver().m_injData.end(); it++) {
396 const MInt timeStep = it->first;
397 if(solver().domainId() == 0) {
398 m_injectionData[count][0] = timeStep;
400 m_injectionData[count][0] = 0.0;
403 for(
MInt i = 0; i < 14; i++) {
404 const MFloat data = (it->second)[i];
405 m_injectionData[count][i + 1] = data;
411 MPI_Allreduce(MPI_IN_PLACE, &(m_injectionData[0][0]), 15 * this->m_sprayWriteInterval, MPI_DOUBLE, MPI_SUM,
412 solver().mpiComm(), AT_,
"INPLACE",
"m_injectionData");
414 MPI_Allreduce(MPI_IN_PLACE, &(m_cInjData[0][0]), (nDim + 5) * (this->m_sprayWriteInterval + 1), MPI_DOUBLE, MPI_MAX,
415 solver().mpiComm(), AT_,
"INPLACE",
"m_cInjData");
417 if(injectorCellId > -1) {
419 for(
MInt i = 0; i < nDim + 5; i++) {
420 m_cInjData[0][i] = m_cInjData[this->m_sprayWriteInterval][i];
423 for(
auto it = solver().m_injData.begin(); it != solver().m_injData.end(); it++) {
426 for(
MInt i = 0; i < nDim + 5; i++) {
427 m_cInjData[count][i] += m_injectionData[count][7 + i];
432 for(
MInt i = 0; i < nDim + 5; i++) {
433 m_cInjData[count][i] = m_cInjData[count - 1][i];
437 for(
MInt i = 0; i < nDim + 5; i++) {
438 m_cInjData[this->m_sprayWriteInterval][i] = m_cInjData[count][i];
442 for(
MInt id = 0;
id < this->m_sprayWriteInterval + 1;
id++) {
443 for(
MInt j = 0; j < nDim + 5; j++) {
444 m_cInjData[
id][j] = 0;
449 solver().m_injData.clear();
461 m_LPTSolutionInterval =
462 Context::getSolverProperty<MInt>(
"particleSolutionInterval", m_postprocessingId, AT_, &m_LPTSolutionInterval);
464 m_writeParLog = Context::getSolverProperty<MBool>(
"writeParLog", m_postprocessingId, AT_, &m_writeParLog);
465 if(m_writeParLog) initParticleLog();
478 if(!solver().isActive())
return;
480 solver().crankAngleSolutionOutput();
482 if(m_writeParLog &&
globalTimeStep % m_parLogInterval == 0) writeParticleLog();
484 if((m_LPTSolutionInterval > 0 &&
globalTimeStep % m_LPTSolutionInterval == 0) || this->m_finalTimeStep
485 || this->m_forceOutput) {
486 if(solver().domainId() == 0) {
487 cerr <<
"Writing particle File @" <<
globalTimeStep <<
"(" << solver().m_time <<
")... ";
489 solver().writePartData();
491 if(solver().m_collisions > 0) {
492 solver().writeCollData();
495 if(solver().domainId() == 0) {
496 cerr <<
" done. " << endl;
507 if(solver().m_restart && m_writeParLog) m_parLogApp =
true;
510 Context::getSolverProperty<MInt>(
"particleLogInterval", m_postprocessingId, AT_, &m_parLogInterval);
512 if(solver().domainId() == 0) {
513 std::ofstream parLog;
515 parLog.open(
"particle.log", ios::app);
517 parLog.open(
"particle.log");
518 const MString columns[9] = {
"x",
"y",
"z",
"vel_x",
"vel_y",
"vel_z",
"Re",
"C_D"};
519 parLog << std::setw(5) <<
"t"
521 for(
auto& i : columns) {
522 parLog << std::setw(15) << i <<
"\t";
538 if(solver().globalNoParticles() > 1) {
539 m_writeParLog =
false;
540 std::cerr <<
"writing particle.log is currently only implemented for single particles!" << std::endl;
544 if(solver().m_partList.size() < 1)
return;
547 std::ofstream parLog;
550 parLog.open(
"particle.log", std::ios::app);
554 parLog << std::setw(10) << std::setprecision(12) << i <<
"\t";
557 parLog << std::setw(10) << i <<
"\t";
561 const MFloat fluidViscosity = solver().m_material->dynViscosityFun(T);
567 parLog << std::setw(10) << ReP <<
"\t";
568 parLog << std::setw(10) << CD <<
"\t" << std::endl;
581 if(solver().domainId() == 0) {
583 Plog.open(
"ParticleStatistics.log", ios::app);
584 Plog << std::setw(5) <<
"t"
585 <<
"\t" << std::setw(10) <<
"VpRMS"
586 <<
"\t" << std::setw(10) <<
"AverageReP"
587 <<
"\t" << std::setw(10) <<
"EkinP" << endl;
604 if((m_LPTSolutionInterval > 0 &&
globalTimeStep % m_LPTSolutionInterval == 0) || this->m_finalTimeStep
605 || this->m_forceOutput) {
606 const MInt globalNoPart = solver().globalNoParticles();
608 MFloat VelmagnitudeSqSum = F0;
612 const MFloat T = solver().a_fluidTemperature(part.m_cellId);
613 const MFloat fluidViscosity = solver().m_material->dynViscosityFun(T);
614 const MFloat relVel = part.magRelVel(&part.m_oldFluidVel[0], &part.m_oldVel[0]);
616 RePSum += part.particleRe(relVel, part.m_oldFluidDensity, fluidViscosity) * part.s_Re;
618 MFloat VelmagnitudeSq = F0;
619 for(
MInt j = 0; j < nDim; j++) {
620 VelmagnitudeSq +=
POW2(part.m_velocity[j]);
622 VelmagnitudeSqSum += VelmagnitudeSq;
624 EkinSum += part.sphericalMass() * VelmagnitudeSq;
627 MPI_Allreduce(MPI_IN_PLACE, &RePSum, 1, MPI_DOUBLE, MPI_SUM, solver().mpiComm(), AT_,
"INPLACE",
"RePsum");
629 MFloat AverageReP = RePSum / globalNoPart;
631 MPI_Allreduce(MPI_IN_PLACE, &VelmagnitudeSqSum, 1, MPI_DOUBLE, MPI_SUM, solver().mpiComm(), AT_,
"INPLACE",
634 MFloat VpRMS = sqrt(VelmagnitudeSqSum / globalNoPart);
636 MPI_Allreduce(MPI_IN_PLACE, &EkinSum, 1, MPI_DOUBLE, MPI_SUM, solver().mpiComm(), AT_,
"INPLACE",
"EkinSum");
638 MFloat EkinP = 0.5 * EkinSum;
640 if(solver().domainId() == 0) {
642 Plog.open(
"ParticleStatistics.log", ios::app);
643 Plog << std::setw(5) <<
globalTimeStep <<
"\t" << std::setw(10) << VpRMS <<
"\t" << std::setw(10) << AverageReP
644 <<
"\t" << std::setw(10) << EkinP << endl;
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
std::array< MFloat, nDim > m_position
std::array< MFloat, nDim > m_velocity
std::array< MFloat, nDim > m_oldVel
particle velocity of the last time step
std::array< MFloat, nDim > m_oldFluidVel
fluid velocity of the last time step
MFloat m_oldFluidDensity
old fluid density
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.
MFloat dragFactor(const MFloat partRe)
Calculate drag factor of the current particle for the given particle Reynolds number....
void initParticleStatistics() override
init function for LPT particle statistics file
void parcelStatistics()
computes parcel statistics
void writeLPTSolutionFile() override
base function which is called every time-Step in postprocessInSolve
void initParticleLog()
initialize particle.log
void computeParticleStatistics() override
compute average quantites of particle phase average particle Reynolds number ReP the root mean square...
void particleMass()
computes conervation variables (mass/momentum/energy!)
void initSprayData() override
init arrays
void particlePenetration()
calculate vertical and horizontal penetration from given coordinate
PostProcessingLPT(MInt postprocessingId_, PostData< nDim > *data, SolverType *ppSolver_)
void initLPTSolutionFile() override
init function for LPT particle solution file
void writeParticleLog()
write particle Log file, containing particle position and velocity at timestep t
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW3(const Real x)
constexpr Real POW2(const Real x)
std::basic_string< char > MString
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce