13template <MInt nDim,
class SysEqn>
23template <MInt nDim,
class SysEqn>
26template <MInt nDim,
class SysEqn>
32 solver().m_skewness = this->m_skewness;
33 solver().m_kurtosis = this->m_kurtosis;
34 solver().m_activeMeanVars = this->m_activeMeanVars;
42template <MInt nDim,
class SysEqn>
46 m_pointData->setInputOutputProperties();
50template <MInt nDim,
class SysEqn>
52 if(!isActive())
return;
53 m_pointData->save(m_finalTimeStep);
56template <MInt nDim,
class SysEqn>
60 m_surfaceData->setInputOutputProperties();
61 m_surfaceData->init();
64template <MInt nDim,
class SysEqn>
66 if(!isActive())
return;
67 m_surfaceData->save(m_finalTimeStep);
70template <MInt nDim,
class SysEqn>
74 m_volumeData->setInputOutputProperties();
78template <MInt nDim,
class SysEqn>
80 if(!isActive())
return;
81 m_volumeData->save(m_finalTimeStep);
84template <MInt nDim,
class SysEqn>
90 solver().m_movingAvgInterval = this->m_movingAverageInterval;
93template <MInt nDim,
class SysEqn>
99 solver().m_averageVorticity = this->m_averageVorticity;
100 solver().m_averageSpeedOfSound = this->m_averageSpeedOfSound;
104template <MInt nDim,
class SysEqn>
108 if(!solver().grid().isActive())
return;
110 if(m_postprocessFileName !=
"") {
111 m_log <<
" ^ * probe line for file " << m_postprocessFileName << endl;
113 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) postData().loadMeanFile(m_postprocessFileName);
116 for(
MInt t = m_averageStartTimestep; t <= m_averageStopTimestep; t += m_averageInterval) {
117 solver().loadSampleVariables(t);
123template <MInt nDim,
class SysEqn>
133 MInt noVars = m_noVariables;
134 if(m_postData->isMeanFile()) {
135 noVars = m_postData->fileNoVars();
139 stringstream fileName;
140 fileName << solver().outputDir() <<
"probeLines_" << step << ParallelIo::fileExt();
144 for(
MInt probeLineId = 0; probeLineId < m_noProbeLines; probeLineId++) {
145 stringstream varNameBase;
146 varNameBase <<
"line_" << probeLineId;
147 string coordName = varNameBase.str() +
"_coordinates";
149 parallelIo.defineArray(PIO_FLOAT, coordName, m_globalNoProbeLineIds[probeLineId]);
150 parallelIo.setAttribute(probeLineId,
"lineId", coordName);
152 varNameBase <<
"_var_";
153 for(
MInt varId = 0; varId < noVars; varId++) {
154 stringstream varName;
155 varName << varNameBase.str() << varId;
156 parallelIo.defineArray(PIO_FLOAT, varName.str(), m_globalNoProbeLineIds[probeLineId]);
157 parallelIo.setAttribute(probeLineId,
"lineId", varName.str());
161 for(
MInt probeLineId = 0; probeLineId < m_noProbeLines; probeLineId++) {
162 if(m_probeLineDirection[probeLineId] < 0 || m_probeLineDirection[probeLineId] >= nDim) {
166 m_log <<
" ^ * probe line timestep " <<
globalTimeStep <<
" for line #" << probeLineId << endl;
168 MInt noIds = m_noProbeLineIds[probeLineId];
175 const MFloat* cellVars = 0;
178 for(
MInt i = 0; i < m_noProbeLineIds[probeLineId]; i++) {
179 probeId = m_probeLineIds[probeLineId][i];
181 for(
MInt varId = 0; varId < noVars; varId++) {
182 vars[i * noVars + varId] = cellVars[varId];
186 parallelIo.setOffset(m_noProbeLineIds[probeLineId], m_probeLineOffsets[probeLineId]);
189 stringstream varNameBase;
190 varNameBase <<
"line_" << probeLineId;
191 string coordName = varNameBase.str() +
"_coordinates";
192 parallelIo.writeArray(m_probeLinePositions[probeLineId], coordName);
194 varNameBase <<
"_var_";
195 for(
MInt varId = 0; varId < noVars; varId++) {
196 stringstream varName;
197 varName << varNameBase.str() << varId;
198 parallelIo.writeArray(&(vars[varId]), varName.str(), noVars);
206 for(
MInt probeLineId = 0; probeLineId < m_noProbeLines; probeLineId++) {
207 if(m_probeLineAverageDirection[probeLineId] < 0 || m_probeLineAverageDirection[probeLineId] >= nDim) {
213 if(m_probeLineDirection[probeLineId] == 1 || m_probeLineDirection[probeLineId] == 0) {
215 if(solver().m_rans) {
216 noVars = m_noVariables + 1;
218 noVars = postData().noVariables();
221 MInt noIds = m_globalNoProbeLineIds[probeLineId];
230 globalAvgVars.
fill(F0);
232 if(solver().m_rans) {
234 for(
MInt p = 0; p < m_globalNoProbeLineIds[probeLineId]; p++) {
236 for(
MInt i = 0; i < m_noProbeLineAverageIds[probeLineId][p]; i++) {
237 probeId = m_probeLineAverageIds[probeLineId][p][i];
238 const MFloat* cellVars = 0;
242 for(
MInt varId = 0; varId < m_noVariables; varId++) {
243 avgVars[p * noVars + varId] += cellVars[varId];
248 const MFloat* cellVarsDeriv1;
249 getSampleVarsDerivatives(probeId, cellVarsDeriv1);
252 for(
MInt d1 = 0; d1 < nDim; d1++) {
253 for(
MInt d2 = 0; d2 < nDim; d2++) {
254 MFloat sij = 0.5 * (deriv1(d1, d2) + deriv1(d2, d1));
259 k = sqrt(2.0 * SijSij / 0.09) * cellVars[5] / solver().sysEqn().m_Re0;
261 avgVars[p * noVars + m_noVariables] += k;
266 for(
MInt p = 0; p < m_globalNoProbeLineIds[probeLineId]; p++) {
268 for(
MInt i = 0; i < m_noProbeLineAverageIds[probeLineId][p]; i++) {
270 probeId = m_probeLineAverageIds[probeLineId][p][i];
274 for(
MInt varId = 0; varId < noVars; varId++) {
275 avgVars[p * noVars + varId] += postData().m_averagedVars[dataId][varId];
280 std::vector<std::vector<MFloat>> du(nDim, std::vector<MFloat>(nDim, F0));
281 const MInt recData = solver().a_reconstructionData(probeId);
282 std::vector<MFloat> u{postData().m_averagedVars[dataId][0], postData().m_averagedVars[dataId][1],
283 postData().m_averagedVars[dataId][2]};
285 for(
MInt nghbr = 0; nghbr < solver().a_noReconstructionNeighbors(probeId); nghbr++) {
286 const MInt recNghbrId = solver().a_reconstructionNeighborId(probeId, nghbr);
287 if(recNghbrId > -1 && recNghbrId < solver().noInternalCells()) {
289 if(dataNgbhrId > -1) {
292 const MFloat recConst_x = solver().m_reconstructionConstants[nDim * (recData + nghbr) + 0];
293 const MFloat recConst_y = solver().m_reconstructionConstants[nDim * (recData + nghbr) + 1];
294 const MFloat recConst_z = solver().m_reconstructionConstants[nDim * (recData + nghbr) + 2];
295 for(
MInt dim = 0; dim < nDim; ++dim) {
296 MFloat delta_u = postData().m_averagedVars[dataNgbhrId][dim] - u[dim];
297 du[dim][0] += recConst_x * delta_u;
298 du[dim][1] += recConst_y * delta_u;
299 du[dim][2] += recConst_z * delta_u;
304 std::vector<std::vector<MFloat>> sij(nDim, std::vector<MFloat>(nDim, F0));
306 for(
MInt d1 = 0; d1 < nDim; d1++) {
307 for(
MInt d2 = 0; d2 < nDim; d2++) {
308 sij[d1][d2] = 0.5 * (du[d1][d2] + du[d2][d1]);
309 SijSij += sij[d1][d2] * sij[d1][d2];
312 avgVars[p * noVars + (noVars - 1)] += SijSij;
318 MPI_Allreduce(&avgVars[0], &globalAvgVars[0], noVars * noIds, MPI_DOUBLE, MPI_SUM, solver().mpiComm(), AT_,
319 "avgVars",
"globalAvgVars");
322 if(solver().domainId() == 0) {
326 for(
MInt p = 0; p < m_globalNoProbeLineIds[probeLineId]; p++) {
327 for(
MInt varId = 0; varId < noVars; varId++) {
328 m_globalProbeLineAverageVars[probeLineId][p][varId] =
329 globalAvgVars[tempId] / m_globalNoProbeLineAverageIds[probeLineId][p];
347 vector<int> sortingIndex(m_globalNoProbeLineIds[probeLineId]);
348 for(
MInt p = 0; p < m_globalNoProbeLineIds[probeLineId]; p++) {
349 sorting[p] = m_probeLineAverageCoordinates[probeLineId][p];
352 iota(sortingIndex.begin(), sortingIndex.end(), x++);
353 sort(sortingIndex.begin(), sortingIndex.end(), [&](
int i,
int j) { return sorting[i] < sorting[j]; });
357 if(solver().m_rans) {
358 dir =
"#y um vm wm rhom pm num ym k";
360 if(solver().m_solverId == 1) {
361 dir =
"#y um vm wm rhom pm num ym u'u' u'v' u'w' v'v' v'w' w'w' p'";
363 dir =
"#y um vm wm rhom pm u'u' u'v' u'w' v'v' v'w' w'w' p' SijSij";
367 lineprob.precision(8);
368 MString fname =
"probeLine" + to_string(solver().m_solverId) +
"_" + to_string(probeLineId) +
"_"
370 cerr <<
"Writing " << fname << endl;
371 lineprob.open(fname);
372 for(
MInt p = 0; p < m_globalNoProbeLineIds[probeLineId]; p++) {
373 MInt index = sortingIndex[p];
375 line.append(to_string(m_probeLineAverageCoordinates[probeLineId][index]));
376 if(p == 0) lineprob << dir << endl;
377 for(
MInt k = 0; k < noVars; k++) {
379 line.append(
" " + to_string(m_globalProbeLineAverageVars[probeLineId][index][varId]));
381 lineprob << line << endl;
386 }
else if(m_probeLineDirection[probeLineId] == 2) {
393template <MInt nDim,
class SysEqn>
399 if(solver().domainId() == 0) {
400 cerr <<
"Allocating Post-processing Fv data!" << endl;
403 const MInt vapourPenSize = nDim == 3 ? 16 : 12;
404 mAlloc(m_vapourPen, m_sprayDataSize, vapourPenSize,
"m_vapourPen", F0, AT_);
405 mAlloc(m_vapourCV, m_sprayDataSize, 5 + 2 * nDim,
"m_vapourCV", F0, AT_);
408template <MInt nDim,
class SysEqn>
413 const MBool hasSpecies = solver().m_noSpecies > 0 ? true :
false;
416 for(
MInt i = 0; i < 5 + 2 * nDim; i++) {
417 m_vapourCV[m_sprayDataStep][i] = 0;
420 if(solver().isActive()) {
421 for(
MInt cellId = 0; cellId < solver().noInternalCells(); cellId++) {
422 if(!solver().c_isLeafCell(cellId))
continue;
423 if(solver().a_isInactive(cellId))
continue;
424 const MFloat cellV = 1 / solver().a_FcellVolume(cellId);
425 const MFloat rho = solver().a_variable(cellId, solver().m_sysEqn.CV->RHO);
426 const MFloat rhoY = hasSpecies ? solver().a_variable(cellId, solver().m_sysEqn.CV->RHO_Y[speciesId]) : 0;
428 m_vapourCV[m_sprayDataStep][0] += cellV * rhoY;
429 m_vapourCV[m_sprayDataStep][1] += cellV * (rho - rhoY);
430 m_vapourCV[m_sprayDataStep][2] += cellV * solver().a_variable(cellId, solver().m_sysEqn.CV->RHO_E);
431 m_vapourCV[m_sprayDataStep][3] += cellV * solver().a_variable(cellId, solver().m_sysEqn.CV->RHO_U);
432 m_vapourCV[m_sprayDataStep][4] += cellV * solver().a_variable(cellId, solver().m_sysEqn.CV->RHO_V);
433 IF_CONSTEXPR(nDim == 3) {
434 m_vapourCV[m_sprayDataStep][5] += cellV * solver().a_variable(cellId, solver().m_sysEqn.CV->RHO_W);
437 if(solver().m_hasExternalSource) {
438 MInt numVars = 2 + nDim;
439 for(
MInt i = 0; i < numVars; i++) {
441 m_vapourCV[m_sprayDataStep][3 + nDim + i] = source;
447template <MInt nDim,
class SysEqn>
451 const MInt noYLimits = 3;
452 const MInt refLvl = 10;
453 const MFloat yLimitRefLvl = 0.001;
456 array<MFloat, noYLimits> yLimits{};
462 array<array<MFloat, noYLimits>, nDim + 1> maxVapPen{};
463 array<MFloat, nDim> maxVapPenRefLvl{};
464 for(
MInt n = 0; n < noYLimits; n++) {
465 for(
MInt i = 0; i < nDim + 1; i++) {
466 maxVapPen[i][n] = 0.0;
469 for(
MInt i = 0; i < nDim; i++) {
470 maxVapPenRefLvl[i] = 0.0;
479 const MBool hasSpecies = solver().m_noSpecies > 0 ? true :
false;
481 if(solver().isActive() && hasSpecies) {
482 for(
MInt cellId = 0; cellId < solver().noInternalCells(); cellId++) {
483 if(solver().a_isInactive(cellId))
continue;
484 if(solver().c_isLeafCell(cellId)) {
485 const MFloat rho = solver().a_variable(cellId, nDim + 1);
486 const MFloat Y = hasSpecies ? solver().a_variable(cellId, nDim + 2) / rho : 0;
487 array<MFloat, nDim> centerCoords{};
489 for(
MInt n = 0; n < noYLimits; n++) {
491 for(
MInt i = 0; i < nDim; i++) {
492 centerCoords[i] = solver().a_coordinate(cellId, i);
494 array<MFloat, nDim + 1> distance{};
495 for(
int i = 0; i < nDim; i++) {
496 distance[i] = abs(centerCoords[i] - spawnCoord[i]);
500 for(
int i = 0; i < nDim + 1; i++) {
501 assignLarger(maxVapPen[i][n], distance[i]);
508 if(solver().a_level(cellId) == refLvl) {
509 solver().reduceData(cellId, &solver().a_variable(0, 0), solver().CV->noVariables);
510 const MFloat rho = solver().a_variable(cellId, nDim + 1);
511 const MFloat Y = hasSpecies ? solver().a_variable(cellId, nDim + 2) / rho : 0;
512 if(Y > yLimitRefLvl) {
513 for(
MInt i = 0; i < nDim; i++) {
514 assignLarger(maxVapPenRefLvl[i], solver().a_coordinate(cellId, i));
524 for(
MInt n = 0; n < noYLimits; n++) {
526 m_vapourPen[m_sprayDataStep][it++] = maxVapPen[nDim][n];
528 for(
MInt i = 0; i < nDim; i++) {
529 m_vapourPen[m_sprayDataStep][it++] = maxVapPen[i][n];
532 for(
MInt i = 0; i < nDim; i++) {
533 m_vapourPen[m_sprayDataStep][it++] = maxVapPenRefLvl[i];
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
This class is responsible for the point data feature. It records the state of all sampling variables ...
virtual ~PostProcessingFv()
void initSurfaceSamplingData() override
void probeLinePeriodic() override
void savePointSamplingData() override
void vapourPenetration(MFloat spawnCoord[nDim])
void initVolumeSamplingData() override
void initAveragingProperties() override
Initialize properties relevant for temporal averaging.
void probeLinePeriodicPost() override
void saveVolumeSamplingData() override
void initPointSamplingData() override
void saveSurfaceSamplingData() override
void initPostProcessing() override
void vapourMass(const MInt)
PostProcessingFv(MInt postprocessingId_, PostData< nDim > *data, SolverType *ppSolver_)
void initSprayData() override
void initMovingAverage() override
Initializes properties and allocates memory for moving averaging.
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
Surface data sampling class. Records all sampling variables on all surface elements and outputs addit...
Class to handle sampling of volume data.
MInt convertIdParent(SolverA &solverA, SolverB &solverB, const MInt solverAId)
Conversion from solverA id to the solverB id If no cell on the same level is found,...
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
MFloat distance(const MFloat *a, const MFloat *b)
PARALLELIO_DEFAULT_BACKEND ParallelIo