25template <MInt nDim,
class SolverType>
39template <MInt nDim,
class SolverType>
43 if(m_postprocessing) {
44 if(m_noPostprocessingOps > 0)
45 for(
MInt op = 0; op < m_noPostprocessingOps; op++) {
74 }
else if(m_skewness) {
83 }
else if(m_skewness) {
102 mTerm(1, AT_,
"Unknown postprocessing operation");
106 delete[] m_postprocessingOps;
110template <MInt nDim,
class SolverType>
115 m_movingGrid =
false;
116 m_movingGrid = Context::getSolverProperty<MBool>(
"movingGrid", ppsolver()->solverId(), AT_, &m_movingGrid);
131 m_postprocessing =
false;
133 Context::getSolverProperty<MBool>(
"postprocessing", ppsolver()->solverId(), AT_, &m_postprocessing);
148 m_averageVorticity = 0;
150 Context::getSolverProperty<MBool>(
"pp_averageVorticity", ppsolver()->solverId(), AT_, &m_averageVorticity);
153 m_skewness = Context::getSolverProperty<MBool>(
"pp_skewness", ppsolver()->solverId(), AT_, &m_skewness);
168 m_kurtosis = Context::getSolverProperty<MBool>(
"pp_kurtosis", ppsolver()->solverId(), AT_, &m_kurtosis);
169 if(m_kurtosis) m_skewness = 1;
183 m_computeProductionTerms =
false;
184 m_computeProductionTerms = Context::getSolverProperty<MBool>(
185 "pp_turbulentProduction", ppsolver()->solverId(), AT_, &m_computeProductionTerms);
204 m_twoPass = Context::getSolverProperty<MBool>(
"pp_twoPass", ppsolver()->solverId(), AT_, &m_twoPass);
220 m_useKahan = Context::getSolverProperty<MBool>(
"pp_useKahan", ppsolver()->solverId(), AT_, &m_useKahan);
235 m_postprocessFileName =
"";
236 m_postprocessFileName =
237 Context::getSolverProperty<MString>(
"pp_fileName", ppsolver()->solverId(), AT_, &m_postprocessFileName);
240 m_averageInterval = 0;
241 m_averageRestart = 0;
242 m_averageRestartInterval = 0;
243 m_averageStartTimestep = 0;
244 m_averageStopTimestep = 0;
245 m_noPostprocessingOps = 0;
248 m_noVariables = ppsolver()->noVariables();
250 if(m_postprocessing) {
251 for(
MInt i = 0; i < 3; i++) {
254 m_postprocessingMethods.push_back(tmp);
255 m_postprocessingMethodsDesc.push_back(st);
275 m_postprocessingOps =
nullptr;
276 if(m_noPostprocessingOps > 0) {
278 m_postprocessingOps =
new MString[m_noPostprocessingOps];
279 for(
MInt op = 0; op < m_noPostprocessingOps; op++) {
280 m_postprocessingOps[op] = Context::getSolverProperty<MString>(
281 "postprocessingOps", ppsolver()->solverId(), AT_, &m_postprocessingOps[op], op);
285 m_postprocessingMethodsDesc[1].push_back(m_postprocessingOps[op]);
288 initAverageVariables();
292 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
294 initTimeStepProperties();
295 initAverageVariables();
299 m_postprocessingMethodsDesc[2].push_back(m_postprocessingOps[op]);
301 initTimeStepProperties();
302 initAverageVariables();
306 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
308 initTimeStepProperties();
309 initAverageVariables();
313 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
315 initProductionVariables();
319 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
321 initDissipationVariables();
325 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
327 initTimeStepProperties();
328 initAverageVariables();
332 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
335 mAlloc(m_spanAvg, m_noVariables, ppsolver()->getNoCells(),
"m_spanAvg", F0, FUN_);
336 initTimeStepProperties();
337 initAverageVariables();
341 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
343 initTimeStepProperties();
344 initAverageVariables();
348 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
351 mAlloc(m_gradients, 3 * 9, ppsolver()->getNoCells(),
"m_gradients", F0, FUN_);
352 initTimeStepProperties();
353 initAverageVariables();
357 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
359 initTimeStepProperties();
360 initAverageVariables();
364 m_postprocessingMethodsDesc[1].push_back(m_postprocessingOps[op]);
366 initTimeStepProperties();
371 m_postprocessingMethodsDesc[0].push_back(m_postprocessingOps[op]);
373 initTimeStepProperties();
378 m_postprocessingMethodsDesc[2].push_back(m_postprocessingOps[op]);
380 initTimeStepProperties();
385 mTerm(1, AT_,
"Unknown postprocessing operation");
398template <MInt nDim,
class SolverType>
402 if(m_averageRestart) {
403 m_restartTimeStep = ppsolver()->m_restartTimeStep;
406 if(m_noPostprocessingOps != 0 && m_postprocessing == 1) {
407 for(
MInt op = 0; op < m_noPostprocessingOps; op++) {
413 if(m_restartTimeStep > m_averageStartTimestep && m_restartTimeStep <= m_averageStopTimestep) {
414 MString name = ppsolver()->outputDir() +
"PostprocessingRestart_";
417 sprintf(buf1,
"%d", m_averageStartTimestep);
418 sprintf(buf2,
"%d", m_restartTimeStep);
422 name.append(ppsolver()->m_outputFormat);
425 <<
" ^^^^^^^^^^^^^^^ Entering postprocessing mode PreInit ^^^^^^^^^^^^^^^^ \n"
426 <<
" ^ - Loading restart for mean flow calculation: " << name <<
"\n"
427 <<
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n\n";
429 ppsolver()->loadAverageRestartFile(name.c_str(), m_summedVars, m_square, m_cube, m_fourth);
434 if(ppsolver()->domainId() == 0) {
435 cout <<
"Subtracting mean from restart file" << endl;
448template <MInt nDim,
class SolverType>
452 if(m_noPostprocessingOps != 0 && m_postprocessing == 1) {
454 <<
" ^^^^^^^^^^^^^^^ Entering postprocessing mode PreSolve ^^^^^^^^^^^^^^^ \n"
455 <<
" ^ - Activated operations are:\n";
456 for(
MInt op = 0; op < m_noPostprocessingOps; op++)
457 m_log <<
" ^ + " << m_postprocessingOps[op] <<
"\n";
458 m_log <<
" ^ - Running:\n";
460 for(
MInt op = 0; op < (signed)m_postprocessingMethods[0].size(); op++) {
461 m_log <<
" ^ + " << m_postprocessingMethodsDesc[0][op] <<
"\n";
462 (this->*(m_postprocessingMethods[0][op]))();
464 m_log <<
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n" << endl;
468template <MInt nDim,
class SolverType>
472 if(m_noPostprocessingOps != 0 && m_postprocessing == 1) {
473 for(
MInt op = 0; op < (signed)m_postprocessingMethods[1].size(); op++) {
474 (this->*(m_postprocessingMethods[1][op]))();
479template <MInt nDim,
class SolverType>
483 if(m_noPostprocessingOps != 0 && m_postprocessing == 1) {
485 <<
" ^^^^^^^^^^^^^^^ Entering postprocessing mode PostSolve ^^^^^^^^^^^^^^^ \n"
486 <<
" ^ - Activated operations are:\n\n";
487 for(
MInt op = 0; op < m_noPostprocessingOps; op++)
488 m_log <<
" ^ + " << m_postprocessingOps[op] <<
"\n";
489 m_log <<
" ^ - Running:\n";
491 for(
MInt op = 0; op < (signed)m_postprocessingMethods[2].size(); op++) {
492 m_log <<
" ^ + " << m_postprocessingMethodsDesc[2][op] <<
"\n";
493 (this->*(m_postprocessingMethods[2][op]))();
495 m_log <<
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n" << endl;
506template <MInt nDim,
class SolverType>
510 if((
globalTimeStep - m_averageStartTimestep) % m_averageInterval == 0) {
511 if(!ppsolver()->isTravelingWave()) {
512 addAveragingSample();
514 ppsolver()->spanwiseWaveReorder();
516 if(ppsolver()->domainId() == 0) {
517 cout <<
">>>>> wave sample with interval " << m_averageInterval
518 <<
" time steps at time step: " <<
globalTimeStep <<
" has been added <<<<<" << endl;
542template <MInt nDim,
class SolverType>
545 const MInt noCells = ppsolver()->getNoCells();
546 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
548 for(
MInt cellId = 0; cellId < noCells; cellId++) {
550 MInt offsetSquare = 0;
552 for(
MInt varId = 0; varId < m_noVariables; varId++) {
553 m_summedVars[varId + offset][cellId] += m_tempWaveSample[varId][cellId];
555 offset += m_noVariables;
558 if(m_averagingFavre) {
559 const MFloat rho = m_tempWaveSample[nDim][cellId];
560 for(
MInt varId = 0; varId < m_noVariables; varId++) {
561 m_favre[varId][cellId] += m_tempWaveSample[varId][cellId] * rho;
566 if(m_averageVorticity) {
567 for(
MInt varId = 0; varId < noAveragedVorticities; varId++) {
568 m_summedVars[varId + offset][cellId] += m_tempWaveSample[varId + offset][cellId];
570 offset += noAveragedVorticities;
574 for(
MInt varId = 0; varId < nDim; varId++) {
575 m_square[varId + offsetSquare][cellId] += m_tempWaveSample[varId][cellId] * m_tempWaveSample[varId][cellId];
577 offsetSquare += nDim;
580 for(
MInt varId = 0; varId < 2 * nDim - 3; varId++) {
581 m_square[varId + offsetSquare][cellId] +=
582 m_tempWaveSample[varId % nDim][cellId] * m_tempWaveSample[(varId + 1) % nDim][cellId];
584 offsetSquare += 2 * nDim - 3;
587 m_square[offsetSquare][cellId] += m_tempWaveSample[nDim + 1][cellId] * m_tempWaveSample[nDim + 1][cellId];
591 if(m_averageVorticity) {
592 for(
MInt varId = 0; varId < noAveragedVorticities; varId++) {
593 m_square[offsetSquare + varId][cellId] +=
594 m_tempWaveSample[varId + m_noVariables][cellId] * m_tempWaveSample[varId + m_noVariables][cellId];
596 offsetSquare += noAveragedVorticities;
601 for(
MInt varId = 0; varId < nDim; varId++) {
602 m_cube[varId][cellId] += pow(m_tempWaveSample[varId][cellId], 3);
603 m_fourth[varId][cellId] += pow(m_tempWaveSample[varId][cellId], 4);
608 for(
MInt varId = 0; varId < nDim; varId++) {
609 m_cube[varId][cellId] += pow(m_tempWaveSample[varId][cellId], 3);
622template <MInt nDim,
class SolverType>
631 m_log <<
" ^ * Averaging solutions ";
635 MFloat avgStart = m_restartTimeStep;
637 for(
MInt avgTimestep = avgStart; avgTimestep <= m_averageStopTimestep; avgTimestep += m_averageInterval) {
639 stringstream filename;
640 filename << ppsolver()->outputDir() << avgTimestep << ppsolver()->m_outputFormat;
641 ppsolver()->loadSampleFile(filename.str());
642 ppsolver()->exchange();
643 ppsolver()->applyBoundaryCondition();
644 addAveragingSample();
647 if(m_averageRestartInterval != 0
648 && (avgTimestep >= m_averageStartTimestep && avgTimestep % m_averageRestartInterval == 0
649 && avgTimestep <= m_averageStopTimestep)) {
650 saveAverageRestart();
654 saveAveragedSolution(m_averageStopTimestep);
657template <MInt nDim,
class SolverType>
661 computeAveragedSolution();
664 MString name = ppsolver()->outputDir() +
"Mean_";
667 sprintf(buf1,
"%d", m_averageStartTimestep);
668 sprintf(buf2,
"%d", endTimeStep);
673 m_log <<
" ^ saving averaged variables " << name << endl;
675 ppsolver()->saveAveragedVariables(name, getNoPPVars(), m_summedVars);
691template <MInt nDim,
class SolverType>
695 const MInt noCells = ppsolver()->getNoCells();
696 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
698 const MFloat weight = F1 / m_noSamples;
700 MInt offsetSquare = 0;
703 for(
MInt cellId = 0; cellId < noCells; cellId++) {
704 for(
MInt varId = 0; varId < m_noVariables; varId++) {
705 m_summedVars[varId + offset][cellId] *= weight;
708 offset += m_noVariables;
711 if(m_averagingFavre) {
712 for(
MInt cellId = 0; cellId < noCells; cellId++) {
713 const MFloat frhom = F1 / m_summedVars[nDim][cellId];
714 for(
MInt varId = 0; varId < m_noVariables; varId++) {
715 m_favre[varId][cellId] = m_favre[varId][cellId] * weight * frhom;
721 if(m_averageVorticity) {
722 for(
MInt cellId = 0; cellId < noCells; cellId++) {
723 for(
MInt varId = 0; varId < noAveragedVorticities; varId++) {
724 m_summedVars[varId + offset][cellId] *= weight;
728 offset += noAveragedVorticities;
732 for(
MInt cellId = 0; cellId < noCells; cellId++) {
733 for(
MInt varId = 0; varId < nDim; varId++) {
734 m_summedVars[varId + offset][cellId] =
735 weight * m_square[varId][cellId] - m_summedVars[varId][cellId] * m_summedVars[varId][cellId];
739 offsetSquare += nDim;
743 for(
MInt cellId = 0; cellId < noCells; cellId++) {
744 for(
MInt varId = 0; varId < 2 * nDim - 3; varId++) {
745 m_summedVars[varId + offset][cellId] =
746 weight * m_square[varId + offsetSquare][cellId]
747 - m_summedVars[varId % nDim][cellId] * m_summedVars[(varId + 1) % nDim][cellId];
750 offset += 2 * nDim - 3;
751 offsetSquare += 2 * nDim - 3;
757 for(
MInt cellId = 0; cellId < noCells; cellId++) {
758 for(
MInt varId = 0; varId < nDim; varId++) {
759 m_summedVars[varId + offset][cellId] = weight * m_cube[varId][cellId]
760 - 3 * weight * m_summedVars[varId][cellId] * m_square[varId][cellId]
761 + 2 * pow(m_summedVars[varId][cellId], 3);
763 m_summedVars[varId + offset + nDim][cellId] =
764 weight * m_fourth[varId][cellId] - 4 * weight * m_cube[varId][cellId] * m_summedVars[varId][cellId]
765 + 6 * weight * m_square[varId][cellId] * m_summedVars[varId][cellId] * m_summedVars[varId][cellId]
766 - 3 * pow(m_summedVars[varId][cellId], 4);
771 }
else if(m_skewness) {
773 for(
MInt cellId = 0; cellId < noCells; cellId++) {
774 for(
MInt varId = 0; varId < nDim; varId++) {
775 m_summedVars[varId + offset][cellId] = weight * m_cube[varId][cellId]
776 - 3 * weight * m_summedVars[varId][cellId] * m_square[varId][cellId]
777 + 2 * pow(m_summedVars[varId][cellId], 3);
784 for(
MInt cellId = 0; cellId < noCells; cellId++) {
785 m_summedVars[offset][cellId] = weight * m_square[offsetSquare][cellId]
786 - m_summedVars[nDim + 1][cellId] * m_summedVars[nDim + 1][cellId];
791 if(m_averageVorticity) {
793 for(
MInt cellId = 0; cellId < noCells; cellId++) {
794 for(
MInt varId = 0; varId < nDim; varId++) {
795 m_summedVars[varId + offset][cellId] =
796 weight * m_square[varId + offsetSquare][cellId]
797 - m_summedVars[varId + m_noVariables][cellId] * m_summedVars[varId + m_noVariables][cellId];
801 offset += noAveragedVorticities;
802 offsetSquare += noAveragedVorticities;
821template <MInt nDim,
class SolverType>
828 const MInt noCells = ppsolver()->getNoCells();
831 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
833 if(m_averageVorticity) {
834 ppsolver()->computeVorticity();
837 for(
MInt cellId = 0; cellId < noCells; cellId++) {
848 ppsolver()->getSampleVariables(cellId, cellVars.
begin());
861 MInt offsetSquare = 0;
862 for(
MInt varId = 0; varId < m_noVariables; varId++) {
863 m_ySum[varId][cellId] = cellVars[varId] - m_cSum[varId][cellId];
864 m_tSum[varId][cellId] = m_summedVars[varId][cellId] + m_ySum[varId][cellId];
865 m_cSum[varId][cellId] = (m_tSum[varId][cellId] - m_summedVars[varId][cellId]) - m_ySum[varId][cellId];
866 m_summedVars[varId][cellId] = m_tSum[varId][cellId];
868 for(
MInt varId = 0; varId < nDim; varId++) {
869 m_ySquare[varId][cellId] = (cellVars[varId] * cellVars[varId]) - m_cSquare[varId][cellId];
870 m_tSquare[varId][cellId] = m_square[varId][cellId] + m_ySquare[varId][cellId];
871 m_cSquare[varId][cellId] = (m_tSquare[varId][cellId] - m_square[varId][cellId]) - m_ySquare[varId][cellId];
872 m_square[varId][cellId] = m_tSquare[varId][cellId];
875 for(
MInt varId = 0; varId < nDim; varId++) {
876 m_ySquare[varId + offsetSquare][cellId] =
877 (cellVars[varId % 3] * cellVars[(varId + 1) % 3]) - m_cSquare[varId + offsetSquare][cellId];
878 m_tSquare[varId + offsetSquare][cellId] =
879 m_square[varId + offsetSquare][cellId] + m_ySquare[varId + offsetSquare][cellId];
880 m_cSquare[varId + offsetSquare][cellId] =
881 (m_tSquare[varId + offsetSquare][cellId] - m_square[varId + offsetSquare][cellId])
882 - m_ySquare[varId + offsetSquare][cellId];
883 m_square[varId + offsetSquare][cellId] = m_tSquare[varId + offsetSquare][cellId];
886 for(
MInt varId = 0; varId < nDim; varId++) {
887 m_yCube[varId][cellId] = pow(cellVars[varId], 3) - m_cCube[varId][cellId];
888 m_tCube[varId][cellId] = m_cube[varId][cellId] + m_yCube[varId][cellId];
889 m_cCube[varId][cellId] = (m_tCube[varId][cellId] - m_cube[varId][cellId]) - m_yCube[varId][cellId];
890 m_cube[varId][cellId] = m_tCube[varId][cellId];
892 m_yFourth[varId][cellId] = pow(cellVars[varId], 4) - m_cFourth[varId][cellId];
893 m_tFourth[varId][cellId] = m_fourth[varId][cellId] + m_yFourth[varId][cellId];
894 m_cFourth[varId][cellId] = (m_tFourth[varId][cellId] - m_fourth[varId][cellId]) - m_yFourth[varId][cellId];
895 m_fourth[varId][cellId] = m_tFourth[varId][cellId];
897 }
else if(m_skewness) {
898 for(
MInt varId = 0; varId < nDim; varId++) {
899 m_yCube[varId][cellId] = pow(cellVars[varId], 3) - m_cCube[varId][cellId];
900 m_tCube[varId][cellId] = m_cube[varId][cellId] + m_yCube[varId][cellId];
901 m_cCube[varId][cellId] = (m_tCube[varId][cellId] - m_cube[varId][cellId]) - m_yCube[varId][cellId];
902 m_cube[varId][cellId] = m_tCube[varId][cellId];
909 MInt offsetSquare = 0;
912 for(
MInt varId = 0; varId < m_noVariables; varId++) {
913 m_summedVars[varId + offset][cellId] += cellVars[varId];
915 offset += m_noVariables;
918 if(m_averagingFavre) {
919 const MFloat rho = cellVars[nDim];
920 for(
MInt varId = 0; varId < m_noVariables; varId++) {
921 m_favre[varId][cellId] += cellVars[varId] * rho;
926 if(m_averageVorticity) {
927 for(
MInt varId = 0; varId < noAveragedVorticities; varId++) {
928 m_summedVars[varId + offset][cellId] += ppsolver()->getSampleVorticity(cellId, varId);
930 offset += noAveragedVorticities;
933 for(
MInt varId = 0; varId < nDim; varId++) {
934 m_square[varId][cellId] += cellVars[varId] * cellVars[varId];
936 offsetSquare += nDim;
937 for(
MInt varId = 0; varId < 2 * nDim - 3; varId++) {
939 m_square[offsetSquare + varId][cellId] += (cellVars[varId % nDim]) * (cellVars[(varId + 1) % nDim]);
941 offsetSquare += 2 * nDim - 3;
942 m_square[offsetSquare][cellId] += cellVars[nDim + 1] * cellVars[nDim + 1];
948 if(m_averageVorticity) {
949 for(
MInt varId = 0; varId < noAveragedVorticities; varId++) {
950 m_square[offsetSquare + varId][cellId] +=
951 ppsolver()->getSampleVorticity(cellId, varId) * ppsolver()->getSampleVorticity(cellId, varId);
953 offsetSquare += noAveragedVorticities;
958 for(
MInt varId = 0; varId < nDim; varId++) {
959 m_cube[varId][cellId] += pow(cellVars[varId], 3);
960 m_fourth[varId][cellId] += pow(cellVars[varId], 4);
962 }
else if(m_skewness) {
963 for(
MInt varId = 0; varId < nDim; varId++) {
964 m_cube[varId][cellId] += pow(cellVars[varId], 3);
986template <MInt nDim,
class SolverType>
988 if(ppsolver()->domainId() == 0) {
989 cout <<
"Loading postprocessing file " << m_postprocessFileName << endl;
991 if(m_averageRestart) {
992 ppsolver()->loadAverageRestartFile(m_postprocessFileName.c_str(), m_summedVars, m_square, m_cube, m_fourth);
993 computeAveragedSolution();
995 if(ppsolver()->domainId() == 0) {
996 cout <<
"Loading file " << m_postprocessFileName << endl;
998 ppsolver()->loadAveragedVariables(m_postprocessFileName.c_str());
1001 if(ppsolver()->domainId() == 0) {
1002 cout <<
"Filling ghost-cells..." << endl;
1004 vector<MFloat*> ppVariables;
1005 for(
MInt var = 0; var < getNoPPVars(); var++) {
1006 ppVariables.push_back(m_summedVars[var]);
1008 ppsolver()->gcFillGhostCells(ppVariables);
1010 if(ppsolver()->domainId() == 0) {
1011 cout <<
"Filling ghost-cells... FINISHED!" << endl;
1014 const MInt noCells = ppsolver()->getNoCells();
1015 for(
MInt cellId = 0; cellId < noCells; cellId++) {
1016 for(
MInt var = 0; var < m_noVariables; var++) {
1017 ppsolver()->saveVarToPrimitive(cellId, var, m_summedVars[var][cellId]);
1021 ppsolver()->exchange();
1023 if(ppsolver()->isMovingGrid()) {
1024 cout <<
"Moving grid to correct position!" << endl;
1025 ppsolver()->moveGrid(
true,
true);
1028 ppsolver()->applyBoundaryCondition();
1030 cout <<
"Computing conservative variables" << endl;
1031 ppsolver()->computeConservativeVariables();
1042template <MInt nDim,
class SolverType>
1044 ppsolver()->saveAuxData();
1048template <MInt nDim,
class SolverType>
1051 if(ppsolver()->domainId() == 0) {
1052 cout <<
"Moving grid" << endl;
1054 ppsolver()->moveGrid(
true,
true);
1056 if(ppsolver()->domainId() == 0) {
1057 cout <<
"Subtracting mean" << endl;
1060 vector<MFloat*> spanAvgList;
1063 for(
MInt var = 0; var < m_noVariables; var++) {
1064 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1065 m_spanAvg[var][I] = m_summedVars[var][I];
1069 for(
MInt var = 0; var < m_noVariables; var++) {
1070 spanAvgList.push_back(m_spanAvg[var]);
1073 ppsolver()->spanwiseAvgZonal(spanAvgList);
1075 for(
MInt var = 0; var < m_noVariables; var++) {
1076 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1077 const MFloat varMean = m_summedVars[var][I];
1078 const MFloat varSpanAvg = m_spanAvg[var][I];
1079 const MFloat varPerFluc = varMean - varSpanAvg;
1080 const MFloat varMeanWOPerFluc = varMean - varPerFluc;
1081 ppsolver()->saveVarToPrimitive(I, var, varMeanWOPerFluc);
1087 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1088 ppsolver()->getSampleVariables(I, cellVars.
begin());
1089 for(
MInt var = 0; var < m_noVariables; var++) {
1090 const MFloat varMean = m_summedVars[var][I];
1091 ppsolver()->saveVarToPrimitive(I, var, varMean);
1096 ppsolver()->exchange();
1097 ppsolver()->applyBoundaryCondition();
1098 ppsolver()->computeConservativeVariables();
1102template <MInt nDim,
class SolverType>
1105 if(ppsolver()->domainId() == 0) {
1106 cout <<
"Moving grid" << endl;
1108 ppsolver()->moveGrid(
true,
true);
1109 if(ppsolver()->domainId() == 0) {
1110 cout <<
"Reordering cells" << endl;
1112 ppsolver()->spanwiseWaveReorder();
1113 if(ppsolver()->domainId() == 0) {
1114 cout <<
"Subtracting mean" << endl;
1117 for(
MInt var = 0; var < m_noVariables; var++) {
1118 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1119 const MFloat varMean = m_summedVars[var][I];
1120 const MFloat varInst = m_tempWaveSample[var][I];
1121 const MFloat varFluc = varInst - varMean;
1122 ppsolver()->saveVarToPrimitive(I, var, varFluc);
1128 if(ppsolver()->domainId() == 0) {
1129 cout <<
"Subtracting mean" << endl;
1131 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1132 ppsolver()->getSampleVariables(I, cellVars.
begin());
1133 for(
MInt var = 0; var < m_noVariables; var++) {
1134 const MFloat varMean = m_summedVars[var][I];
1135 const MFloat varInst = cellVars[var];
1136 const MFloat varFluc = varInst - varMean;
1137 ppsolver()->saveVarToPrimitive(I, var, varFluc);
1142 ppsolver()->exchange();
1143 ppsolver()->applyBoundaryCondition();
1144 ppsolver()->computeConservativeVariables();
1146 ppsolver()->computeLambda2Criterion();
1147 ppsolver()->saveBoxes();
1159template <MInt nDim,
class SolverType>
1163 if(ppsolver()->isMovingGrid()) {
1164 cout <<
"Moving grid to correct position!" << endl;
1165 ppsolver()->moveGrid(
true,
true);
1168 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
1169 const MInt offset = m_noVariables + noAveragedVorticities;
1171 MFloat* ubar = &m_summedVars[0][0];
1172 MFloat* vbar = &m_summedVars[1][0];
1173 MFloat* wbar = &m_summedVars[2][0];
1175 MFloat* uu = &m_summedVars[offset + 0][0];
1176 MFloat* vv = &m_summedVars[offset + 1][0];
1177 MFloat* ww = &m_summedVars[offset + 2][0];
1178 MFloat* uv = &m_summedVars[offset + 3][0];
1179 MFloat* vw = &m_summedVars[offset + 4][0];
1180 MFloat* uw = &m_summedVars[offset + 5][0];
1182 for(
MInt cellId = 0; cellId < ppsolver()->getNoCells(); cellId++) {
1183 m_production[0][cellId] = -uu[cellId] * ppsolver()->dvardxyz(cellId, 0, ubar)
1184 - uv[cellId] * ppsolver()->dvardxyz(cellId, 1, ubar)
1185 - uw[cellId] * ppsolver()->dvardxyz(cellId, 2, ubar);
1186 m_production[1][cellId] = -uv[cellId] * ppsolver()->dvardxyz(cellId, 0, vbar)
1187 - vv[cellId] * ppsolver()->dvardxyz(cellId, 1, vbar)
1188 - vw[cellId] * ppsolver()->dvardxyz(cellId, 2, vbar);
1189 m_production[2][cellId] = -uw[cellId] * ppsolver()->dvardxyz(cellId, 0, wbar)
1190 - vw[cellId] * ppsolver()->dvardxyz(cellId, 1, wbar)
1191 - ww[cellId] * ppsolver()->dvardxyz(cellId, 2, wbar);
1194 ppsolver()->saveProductionTerms(m_postprocessFileName.c_str(), m_production);
1205template <MInt nDim,
class SolverType>
1209 if(ppsolver()->isMovingGrid()) {
1210 cout <<
"Moving grid to correct position!" << endl;
1211 ppsolver()->moveGrid(
true,
true);
1214 MInt noFiles = (m_dissFileEnd - m_dissFileStart) / m_dissFileStep;
1217 if(ppsolver()->domainId() == 0) {
1218 cout <<
"Computing dissipation..." << endl;
1224 for(
MInt n = 0; n < noFiles; n++) {
1225 MInt currentStep = m_dissFileStart + n * m_dissFileStep;
1226 MBool result = ppsolver()->loadBoxFile(m_dissFileDir, m_dissFilePrefix, currentStep, m_dissFileBoxNr);
1228 if(result ==
false) {
1233 if(ppsolver()->isMovingGrid()) {
1234 ppsolver()->spanwiseWaveReorder();
1235 if(ppsolver()->domainId() == 0) {
1236 cout <<
"After spanwise wave reorder" << endl;
1240 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1241 for(
MInt var = 0; var < 5; var++) {
1242 ppsolver()->setPV(var, I, m_tempWaveSample[var][I]);
1247 ppsolver()->exchange();
1248 ppsolver()->applyBoundaryCondition();
1252 if(ppsolver()->domainId() == 0) {
1253 cout <<
"Computing fluctuations..." << endl;
1256 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1257 for(
MInt var = 0; var < 5; var++) {
1258 const MFloat varMean = m_summedVars[var][I];
1259 const MFloat varInst = ppsolver()->getPV(var, I);
1260 const MFloat fluc = varInst - varMean;
1261 ppsolver()->setPV(var, I, fluc);
1265 ppsolver()->exchange();
1266 ppsolver()->applyBoundaryCondition();
1268 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1269 for(
MInt var = 0; var < 3; var++) {
1270 velFluc(var, I) = ppsolver()->getPV(var, I);
1274 if(ppsolver()->domainId() == 0) {
1275 cout <<
"Computing strain tensor..." << endl;
1278 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1279 for(
MInt ii = 0; ii < 3; ii++) {
1280 for(
MInt jj = 0; jj < 3; jj++) {
1281 const MFloat sij = ppsolver()->dvardxyz(I, jj, &velFluc(ii, 0));
1282 const MFloat sji = ppsolver()->dvardxyz(I, ii, &velFluc(jj, 0));
1284 diss1[I] += sij * sij;
1285 diss2[I] += sij * sji;
1291 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1292 diss1[I] /= noSamples;
1293 diss2[I] /= noSamples;
1295 m_dissipation[I] = diss1[I] + diss2[I];
1298 if(ppsolver()->domainId() == 0) {
1299 cout <<
"Computing dissipation..." << endl;
1302 ppsolver()->saveDissipation(m_postprocessFileName.c_str(), m_dissipation);
1305template <MInt nDim,
class SolverType>
1310template <MInt nDim,
class SolverType>
1316template <MInt nDim,
class SolverType>
1320 if(ppsolver()->domainId() == 0) {
1321 cout <<
"Moving grid" << endl;
1323 ppsolver()->moveGrid(
true,
true);
1326 const MInt noVars = 9;
1327 const MInt noCells = ppsolver()->getNoCells();
1328 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
1329 const MInt offset = m_noVariables + noAveragedVorticities;
1334 vector<MFloat*> spanAvgList;
1335 for(
MInt var = 0; var < getNoPPVars(); var++) {
1336 spanAvgList.push_back(m_summedVars[var]);
1339 ppsolver()->spanwiseAvgZonal(spanAvgList);
1340 vector<MFloat*> ppVariables;
1341 for(
MInt var = 0; var < getNoPPVars(); var++) {
1342 ppVariables.push_back(m_summedVars[var]);
1344 ppsolver()->gcFillGhostCells(ppVariables);
1349 for(
MInt dim = 0; dim < nDim; dim++) {
1350 for(
MInt var = 0; var < 3; var++) {
1351 for(
MInt cellId = 0; cellId < noCells; cellId++) {
1352 m_gradients[var + dim * noVars][cellId] = ppsolver()->dvardxyz(cellId, dim, m_summedVars[var]);
1357 for(
MInt var = 0; var < 6; var++) {
1358 for(
MInt cellId = 0; cellId < noCells; cellId++) {
1359 m_gradients[3 + var + dim * noVars][cellId] = ppsolver()->dvardxyz(cellId, dim, m_summedVars[var + offset]);
1366 gradientNames[0] =
"dudx";
1367 gradientNames[1] =
"dvdx";
1368 gradientNames[2] =
"dwdx";
1369 gradientNames[3] =
"duudx";
1370 gradientNames[4] =
"dvvdx";
1371 gradientNames[5] =
"dwwdx";
1372 gradientNames[6] =
"duvdx";
1373 gradientNames[7] =
"duwdx";
1374 gradientNames[8] =
"dvwdx";
1376 gradientNames[9] =
"dudy";
1377 gradientNames[10] =
"dvdy";
1378 gradientNames[11] =
"dwdy";
1379 gradientNames[12] =
"duudy";
1380 gradientNames[13] =
"dvvdy";
1381 gradientNames[14] =
"dwwdy";
1382 gradientNames[15] =
"duvdy";
1383 gradientNames[16] =
"duwdy";
1384 gradientNames[17] =
"dvwdy";
1386 gradientNames[18] =
"dudz";
1387 gradientNames[19] =
"dvdz";
1388 gradientNames[20] =
"dwdz";
1389 gradientNames[21] =
"duudz";
1390 gradientNames[22] =
"dvvdz";
1391 gradientNames[23] =
"dwwdz";
1392 gradientNames[24] =
"duvdz";
1393 gradientNames[25] =
"duwdz";
1394 gradientNames[26] =
"dvwdz";
1396 MString gradientFileName =
"meanGradients.hdf5";
1397 ppsolver()->saveGradients(gradientFileName.c_str(), m_gradients, &gradientNames[0]);
1400template <MInt nDim,
class SolverType>
1404 if(ppsolver()->domainId() == 0) {
1405 cout <<
"Moving grid" << endl;
1407 ppsolver()->moveGrid(
true,
true);
1410 const MInt noCells = ppsolver()->getNoCells();
1411 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
1412 const MInt offset = m_noVariables + noAveragedVorticities;
1425 MFloat*
const u = &m_summedVars[0][0];
1426 MFloat*
const v = &m_summedVars[1][0];
1427 MFloat*
const w = &m_summedVars[2][0];
1428 MFloat*
const rho = &m_summedVars[3][0];
1429 MFloat*
const p = &m_summedVars[4][0];
1430 MFloat*
const uu = &m_summedVars[offset][0];
1431 MFloat*
const uv = &m_summedVars[offset + 3][0];
1432 MFloat*
const uw = &m_summedVars[offset + 4][0];
1434 m_sutherlandConstant = ppsolver()->getSutherlandConstant();
1435 m_sutherlandPlusOne = m_sutherlandConstant + F1;
1437 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1438 const MFloat T = ppsolver()->getGamma() * p[I] / rho[I];
1439 mue[I] = SUTHERLANDLAW(T);
1446 if(ppsolver()->domainId() == 0) {
1447 cout <<
"Computing spanwise average/periodic fluctuations" << endl;
1454 for(
MInt var = 0; var < m_noVariables; var++) {
1455 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1456 spanAvg(var, I) = m_summedVars[var][I];
1460 vector<MFloat*> spanVariables;
1461 for(
MInt var = 0; var < m_noVariables; var++) {
1462 spanVariables.push_back(&spanAvg(var, 0));
1464 ppsolver()->spanwiseAvgZonal(spanVariables);
1465 ppsolver()->gcFillGhostCells(spanVariables);
1467 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1468 uTilde[I] = u[I] - spanAvg(0, I);
1469 vTilde[I] = v[I] - spanAvg(1, I);
1470 wTilde[I] = w[I] - spanAvg(2, I);
1471 rhoTilde[I] = rho[I] - spanAvg(3, I);
1472 pTilde[I] = p[I] - spanAvg(4, I);
1474 uuTilde[I] = uTilde[I] * uTilde[I];
1475 uvTilde[I] = uTilde[I] * vTilde[I];
1476 uwTilde[I] = uTilde[I] * wTilde[I];
1478 u[I] = spanAvg(0, I);
1479 v[I] = spanAvg(1, I);
1480 w[I] = spanAvg(2, I);
1481 rho[I] = spanAvg(3, I);
1482 p[I] = spanAvg(4, I);
1486 vector<MFloat*> ppVariables;
1487 for(
MInt var = 0; var < getNoPPVars(); var++) {
1488 ppVariables.push_back(m_summedVars[var]);
1490 ppsolver()->spanwiseAvgZonal(ppVariables);
1491 ppsolver()->gcFillGhostCells(ppVariables);
1515 duuTildedx.
fill(F0);
1516 duwTildedz.
fill(F0);
1535 nuduTildedx.
fill(F0);
1536 nuduTildedz.
fill(F0);
1537 nuduTildedxx.
fill(F0);
1538 nuduTildedzz.
fill(F0);
1540 if(ppsolver()->domainId() == 0) {
1541 cout <<
"Computing gradients" << endl;
1544 const MInt noGC = ppsolver()->getNoGhostLayers();
1546 const MInt* nCells = ppsolver()->getCellGrid();
1547 const MInt* nActiveCells = ppsolver()->getActiveCells();
1548 const MInt* nOffsetCells = ppsolver()->getOffsetCells();
1550 for(
MInt i = 1; i < nCells[2] - 1; i++) {
1551 for(
MInt k = 1; k < nCells[0] - 1; k++) {
1552 for(
MInt j = 1; j < nCells[1] - 1; j++) {
1553 const MInt I = i + (j + k * nCells[1]) * nCells[2];
1554 dudx[I] = ppsolver()->dvardxyz(I, 0, u);
1555 dudy[I] = ppsolver()->dvardxyz(I, 1, u);
1556 dudz[I] = ppsolver()->dvardxyz(I, 2, u);
1557 dpdx[I] = ppsolver()->dvardxyz(I, 0, p);
1559 duTildedx[I] = ppsolver()->dvardxyz(I, 0, &uTilde[0]);
1560 duTildedy[I] = ppsolver()->dvardxyz(I, 1, &uTilde[0]);
1561 duTildedz[I] = ppsolver()->dvardxyz(I, 2, &uTilde[0]);
1562 dpTildedx[I] = ppsolver()->dvardxyz(I, 0, &pTilde[0]);
1564 duudx[I] = ppsolver()->dvardxyz(I, 0, uu);
1565 duwdz[I] = ppsolver()->dvardxyz(I, 2, uw);
1567 duuTildedx[I] = ppsolver()->dvardxyz(I, 0, &uuTilde[0]);
1568 duwTildedz[I] = ppsolver()->dvardxyz(I, 2, &uwTilde[0]);
1570 nududx[I] = mue[I] / rho[I] * dudx[I];
1571 nududz[I] = mue[I] / rho[I] * dudz[I];
1573 nuduTildedx[I] = mue[I] / rho[I] * duTildedx[I];
1574 nuduTildedz[I] = mue[I] / rho[I] * duTildedz[I];
1579 if(ppsolver()->domainId() == 0) {
1580 cout <<
"Computing second order gradients" << endl;
1583 for(
MInt i = 1; i < nCells[2] - 1; i++) {
1584 for(
MInt k = 1; k < nCells[0] - 1; k++) {
1585 for(
MInt j = 1; j < nCells[1] - 1; j++) {
1586 const MInt I = i + (j + k * nCells[1]) * nCells[2];
1587 nududxx[I] = ppsolver()->dvardxyz(I, 0, &nududx[0]);
1588 nududzz[I] = ppsolver()->dvardxyz(I, 2, &nududz[0]);
1590 nuduTildedxx[I] = ppsolver()->dvardxyz(I, 0, &nuduTildedx[0]);
1591 nuduTildedzz[I] = ppsolver()->dvardxyz(I, 2, &nuduTildedz[0]);
1596 const MInt globalNoCellsI = ppsolver()->getGrid()->getMyBlockNoCells(2);
1597 const MInt globalNoCellsK = ppsolver()->getGrid()->getMyBlockNoCells(0);
1598 const MInt totalNoCellsIK = globalNoCellsI * globalNoCellsK;
1600 const MInt noDecompVars = 11;
1601 MFloatScratchSpace cfDecomposedLocal(noDecompVars, totalNoCellsIK, AT_,
"cfDecomposedLocal");
1602 MFloatScratchSpace cfDecomposedGlobal(noDecompVars, totalNoCellsIK, AT_,
"cfDecomposedGlobal");
1604 cfDecomposedLocal.
fill(F0);
1606 const MFloat gammaMinusOne = ppsolver()->getGamma() - 1.0;
1607 const MFloat t8 = 1.0 / (1.0 + F1B2 * gammaMinusOne *
POW2(ppsolver()->getMa()));
1608 const MFloat u8 = ppsolver()->getMa() * sqrt(t8);
1611 const MFloat fre0 = 1.0 / ppsolver()->getRe0();
1613 if(ppsolver()->domainId() == 0) {
1614 cout <<
"Computing decomposition activeCells[0]: " << nActiveCells[0] <<
" activeCells[1]: " << nActiveCells[1]
1615 <<
" activeCells[2]: " << nActiveCells[2] << endl;
1616 cout <<
"GlobalCellsI: " << globalNoCellsI << endl;
1619 for(
MInt i = 0; i < nActiveCells[2]; i++) {
1620 for(
MInt k = 0; k < nActiveCells[0]; k++) {
1621 for(
MInt j = 0; j < nActiveCells[1]; j++) {
1622 const MInt globalId = (i + nOffsetCells[2]) + (k + nOffsetCells[1]) * (globalNoCellsI);
1623 const MInt I = i + noGC + ((j + noGC) + (k + noGC) * nCells[1]) * nCells[2];
1625 const MFloat dy = ppsolver()->getCellLengthY(i + noGC, j + noGC, k + noGC);
1627 cfDecomposedLocal(0, globalId) += fac * fre0 * mue[I] / rho[I] * dudy[I] * dudy[I] * dy;
1629 cfDecomposedLocal(1, globalId) += fac * fre0 * mue[I] / rho[I] * dudy[I] * duTildedy[I] * dy;
1631 cfDecomposedLocal(2, globalId) += fac * (-uv[I] * dudy[I] * dy);
1633 cfDecomposedLocal(3, globalId) += fac * (-uvTilde[I] * dudy[I] * dy);
1635 cfDecomposedLocal(4, globalId) += fac * ((u[I] - u8) * (u[I] * dudx[I] + v[I] * dudy[I] + w[I] * dudz[I]) * dy);
1637 cfDecomposedLocal(5, globalId) +=
1638 fac * ((u[I] - u8) * (u[I] * duTildedx[I] + v[I] * duTildedy[I] + w[I] * duTildedz[I]) * dy);
1640 cfDecomposedLocal(6, globalId) +=
1641 fac * ((u[I] - u8) * (uTilde[I] * dudx[I] + vTilde[I] * dudy[I] + wTilde[I] * dudz[I]) * dy);
1643 cfDecomposedLocal(7, globalId) += fac * (u[I] - u8) * dpdx[I] * dy;
1645 cfDecomposedLocal(8, globalId) += fac * (u[I] - u8) * dpTildedx[I] * dy;
1647 cfDecomposedLocal(9, globalId) -=
1648 fac * (u[I] - u8) * (fre0 * nududxx[I] + fre0 * nuduTildedxx[I] - duuTildedx[I] - duudx[I]) * dy;
1649 cfDecomposedLocal(10, globalId) -=
1650 fac * (u[I] - u8) * (fre0 * nududzz[I] + fre0 * nuduTildedzz[I] - duwTildedz[I] - duwdz[I]) * dy;
1655 if(ppsolver()->domainId() == 0) {
1656 cout <<
"Before MPI Allreduce" << endl;
1660 &cfDecomposedGlobal(0, 0),
1661 noDecompVars * totalNoCellsIK,
1664 ppsolver()->getCommunicator(),
1666 "cfDecomposedLocal",
1667 "cfDecomposedGlobal");
1669 MFloatScratchSpace cfDecomposedLine(noDecompVars, globalNoCellsI, AT_,
"cfDecomposedLine");
1670 cfDecomposedLine.
fill(F0);
1672 if(ppsolver()->domainId() == 0) {
1673 cout <<
"Now averaging in spanwise direction, no cells spanwise: " << globalNoCellsK << endl;
1676 for(
MInt var = 0; var < noDecompVars; var++) {
1677 for(
MInt i = 0; i < globalNoCellsI; i++) {
1678 for(
MInt k = 0; k < globalNoCellsK; k++) {
1679 const MInt globalId = i + k * globalNoCellsI;
1680 cfDecomposedLine(var, i) += cfDecomposedGlobal(var, globalId);
1682 cfDecomposedLine(var, i) /= (
MFloat)globalNoCellsK;
1687 if(ppsolver()->domainId() == 0) {
1688 MString filename =
"./cf_decomposed.dat";
1690 f_forces = fopen(filename.c_str(),
"w");
1691 for(
MInt i = 0; i < globalNoCellsI; i++) {
1692 for(
MInt var = 0; var < noDecompVars; var++) {
1693 fprintf(f_forces,
"%f ", cfDecomposedLine(var, i));
1695 fprintf(f_forces,
"\n");
1700 if(ppsolver()->domainId() == 0) {
1701 cout <<
"Cf decomposition finished!" << endl;
1706template <MInt nDim,
class SolverType>
1710 if(ppsolver()->domainId() == 0) {
1711 cout <<
"Moving grid" << endl;
1713 ppsolver()->moveGrid(
true,
true);
1716 const MInt noCells = ppsolver()->getNoCells();
1717 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
1718 const MInt offset = m_noVariables + noAveragedVorticities;
1722 MFloat*
const u = &m_summedVars[0][0];
1723 MFloat*
const v = &m_summedVars[1][0];
1724 MFloat*
const w = &m_summedVars[2][0];
1725 MFloat*
const rho = &m_summedVars[3][0];
1726 MFloat*
const p = &m_summedVars[4][0];
1727 MFloat*
const uu = &m_summedVars[offset][0];
1728 MFloat*
const uv = &m_summedVars[offset + 3][0];
1729 MFloat*
const uw = &m_summedVars[offset + 4][0];
1731 m_sutherlandConstant = ppsolver()->getSutherlandConstant();
1732 m_sutherlandPlusOne = m_sutherlandConstant + F1;
1734 for(
MInt I = 0; I < ppsolver()->getNoCells(); I++) {
1735 const MFloat T = ppsolver()->getGamma() * p[I] / rho[I];
1736 mue[I] = SUTHERLANDLAW(T);
1741 vector<MFloat*> ppVariables;
1742 for(
MInt var = 0; var < getNoPPVars(); var++) {
1743 ppVariables.push_back(m_summedVars[var]);
1745 ppsolver()->spanwiseAvgZonal(ppVariables);
1746 ppsolver()->gcFillGhostCells(ppVariables);
1773 if(ppsolver()->domainId() == 0) {
1774 cout <<
"Computing gradients" << endl;
1777 const MInt noGC = ppsolver()->getNoGhostLayers();
1779 const MInt* nCells = ppsolver()->getCellGrid();
1780 const MInt* nActiveCells = ppsolver()->getActiveCells();
1781 const MInt* nOffsetCells = ppsolver()->getOffsetCells();
1783 for(
MInt i = 1; i < nCells[2] - 1; i++) {
1784 for(
MInt k = 1; k < nCells[0] - 1; k++) {
1785 for(
MInt j = 1; j < nCells[1] - 1; j++) {
1786 const MInt I = i + (j + k * nCells[1]) * nCells[2];
1787 dudx[I] = ppsolver()->dvardxyz(I, 0, u);
1788 dudy[I] = ppsolver()->dvardxyz(I, 1, u);
1789 dudz[I] = ppsolver()->dvardxyz(I, 2, u);
1790 dpdx[I] = ppsolver()->dvardxyz(I, 0, p);
1792 duudx[I] = ppsolver()->dvardxyz(I, 0, uu);
1793 duwdz[I] = ppsolver()->dvardxyz(I, 2, uw);
1795 nududx[I] = mue[I] / rho[I] * dudx[I];
1796 nududz[I] = mue[I] / rho[I] * dudz[I];
1801 if(ppsolver()->domainId() == 0) {
1802 cout <<
"Computing second order gradients" << endl;
1805 for(
MInt i = 1; i < nCells[2] - 1; i++) {
1806 for(
MInt k = 1; k < nCells[0] - 1; k++) {
1807 for(
MInt j = 1; j < nCells[1] - 1; j++) {
1808 const MInt I = i + (j + k * nCells[1]) * nCells[2];
1809 nududxx[I] = ppsolver()->dvardxyz(I, 0, &nududx[0]);
1810 nududzz[I] = ppsolver()->dvardxyz(I, 2, &nududz[0]);
1815 const MInt globalNoCellsI = ppsolver()->getGrid()->getMyBlockNoCells(2);
1816 const MInt globalNoCellsJ = ppsolver()->getGrid()->getMyBlockNoCells(1);
1817 const MInt globalNoCellsK = ppsolver()->getGrid()->getMyBlockNoCells(0);
1818 const MInt totalNoCellsIK = globalNoCellsI * globalNoCellsK;
1820 const MInt noDecompVars = 7;
1821 MFloatScratchSpace cfDecomposedLocal(noDecompVars, totalNoCellsIK, AT_,
"cfDecomposedLocal");
1822 MFloatScratchSpace cfDecomposedGlobal(noDecompVars, totalNoCellsIK, AT_,
"cfDecomposedGlobal");
1824 cfDecomposedLocal.
fill(F0);
1826 const MFloat gammaMinusOne = ppsolver()->getGamma() - 1.0;
1827 const MFloat t8 = 1.0 / (1.0 + F1B2 * gammaMinusOne *
POW2(ppsolver()->getMa()));
1828 const MFloat u8 = ppsolver()->getMa() * sqrt(t8);
1831 const MFloat fre0 = 1.0 / ppsolver()->getRe0();
1833 if(ppsolver()->domainId() == 0) {
1834 cout <<
"Computing decomposition activeCells[0]: " << nActiveCells[0] <<
" activeCells[1]: " << nActiveCells[1]
1835 <<
" activeCells[2]: " << nActiveCells[2] << endl;
1836 cout <<
"GlobalCellsI: " << globalNoCellsI << endl;
1839 for(
MInt i = 0; i < nActiveCells[2]; i++) {
1840 for(
MInt k = 0; k < nActiveCells[0]; k++) {
1841 for(
MInt j = 0; j < nActiveCells[1]; j++) {
1842 const MInt I = i + noGC + ((j + noGC) + (k + noGC) * nCells[1]) * nCells[2];
1843 const MInt globalId = (i + nOffsetCells[2]) + (k + nOffsetCells[1]) * (globalNoCellsI);
1844 const MFloat dy = ppsolver()->getCellLengthY(i + noGC, j + noGC, k + noGC);
1846 cfDecomposedLocal(0, globalId) += ppsolver()->getCellCoordinate(I, 0);
1848 cfDecomposedLocal(1, globalId) += fac * fre0 * mue[I] / rho[I] * dudy[I] * dudy[I] * dy;
1850 cfDecomposedLocal(2, globalId) += fac * (-uv[I] * dudy[I] * dy);
1852 cfDecomposedLocal(3, globalId) += fac * ((u[I] - u8) * (u[I] * dudx[I] + v[I] * dudy[I] + w[I] * dudz[I]) * dy);
1854 cfDecomposedLocal(4, globalId) += fac * (u[I] - u8) * dpdx[I] * dy;
1856 cfDecomposedLocal(5, globalId) -= fac * (u[I] - u8) * (fre0 * nududxx[I] - duudx[I]) * dy;
1857 cfDecomposedLocal(6, globalId) -= fac * (u[I] - u8) * (fre0 * nududzz[I] - duwdz[I]) * dy;
1862 if(ppsolver()->domainId() == 0) {
1863 cout <<
"Before MPI Allreduce" << endl;
1867 &cfDecomposedGlobal(0, 0),
1868 noDecompVars * totalNoCellsIK,
1871 ppsolver()->getCommunicator(),
1873 "cfDecomposedLocal",
1874 "cfDecomposedGlobal");
1876 MFloatScratchSpace cfDecomposedLine(noDecompVars, globalNoCellsI, AT_,
"cfDecomposedLine");
1877 cfDecomposedLine.
fill(F0);
1879 if(ppsolver()->domainId() == 0) {
1880 cout <<
"Now averaging in spanwise direction, no cells spanwise: " << globalNoCellsK << endl;
1883 for(
MInt var = 0; var < noDecompVars; var++) {
1884 for(
MInt i = 0; i < globalNoCellsI; i++) {
1885 for(
MInt k = 0; k < globalNoCellsK; k++) {
1886 const MInt globalId = i + k * globalNoCellsI;
1887 cfDecomposedLine(var, i) += cfDecomposedGlobal(var, globalId);
1889 cfDecomposedLine(var, i) /= (
MFloat)globalNoCellsK;
1892 cfDecomposedLine(var, i) /= (
MFloat)globalNoCellsJ;
1898 if(ppsolver()->domainId() == 0) {
1899 MString filename =
"./cf_decomposed.dat";
1901 f_forces = fopen(filename.c_str(),
"w");
1902 for(
MInt i = 0; i < globalNoCellsI; i++) {
1903 for(
MInt var = 0; var < noDecompVars; var++) {
1904 fprintf(f_forces,
"%f ", cfDecomposedLine(var, i));
1906 fprintf(f_forces,
"\n");
1911 if(ppsolver()->domainId() == 0) {
1912 cout <<
"Cf decomposition finished!" << endl;
1925template <MInt nDim,
class SolverType>
1929 initTimeStepProperties();
1944 Context::getSolverProperty<MInt>(
"pp_averageRestart", ppsolver()->solverId(), AT_, &m_averageRestart);
1956 m_averageRestartInterval = Context::getSolverProperty<MInt>(
1957 "pp_averageRestartInterval", ppsolver()->solverId(), AT_, &m_averageRestartInterval);
1971 m_averagingFavre =
false;
1973 Context::getSolverProperty<MBool>(
"pp_averagingFavre", ppsolver()->solverId(), AT_, &m_averagingFavre);
1976 if(m_averageRestartInterval % ppsolver()->restartInterval() != 0) {
1977 mTerm(1, AT_,
"The property 'averageRestartInterval' has to be a multiple of the property 'restartInterval'...");
1990template <MInt nDim,
class SolverType>
1993 const MInt noCells = ppsolver()->getNoCells();
1994 const MInt noVars = getNoPPVars();
1995 const MInt noSquareVars = getNoPPSquareVars();
1997 mAlloc(m_summedVars, noVars, noCells,
"m_summedVars", F0, FUN_);
1998 mAlloc(m_square, noSquareVars, noCells,
"m_square", F0, FUN_);
2000 if(m_averagingFavre) {
2001 mAlloc(m_favre, getNoVars(), noCells,
"m_favre", F0, FUN_);
2005 m_log <<
"Allocating cube and fourth field for kurtosis computation for " << noCells <<
" cells" << endl;
2006 mAlloc(m_cube, nDim, noCells,
"m_cube", F0, FUN_);
2007 mAlloc(m_fourth, nDim, noCells,
"m_fourth", F0, FUN_);
2008 }
else if(m_skewness ) {
2009 mAlloc(m_cube, nDim, noCells,
"m_cube", F0, FUN_);
2014 m_log <<
"m_useKahan is activated" << endl;
2015 mAlloc(m_cSum, m_noVariables + 3 * (nDim - 1), noCells,
"m_cSum", F0, FUN_);
2016 mAlloc(m_tSum, m_noVariables + 3 * (nDim - 1), noCells,
"m_tSum", F0, FUN_);
2017 mAlloc(m_ySum, m_noVariables + 3 * (nDim - 1), noCells,
"m_ySum", F0, FUN_);
2018 mAlloc(m_cSquare, 3 * (nDim - 1), noCells,
"m_cSquare", F0, FUN_);
2019 mAlloc(m_tSquare, 3 * (nDim - 1), noCells,
"m_tSquare", F0, FUN_);
2020 mAlloc(m_ySquare, 3 * (nDim - 1), noCells,
"m_ySquare", F0, FUN_);
2022 mAlloc(m_cCube, nDim, noCells,
"m_cCube", F0, FUN_);
2023 mAlloc(m_tCube, nDim, noCells,
"m_tCube", F0, FUN_);
2024 mAlloc(m_yCube, nDim, noCells,
"m_yCube", F0, FUN_);
2025 mAlloc(m_cFourth, nDim, noCells,
"m_cFourth", F0, FUN_);
2026 mAlloc(m_tFourth, nDim, noCells,
"m_tFourth", F0, FUN_);
2027 mAlloc(m_yFourth, nDim, noCells,
"m_yFourth", F0, FUN_);
2028 }
else if(m_skewness) {
2029 mAlloc(m_cCube, nDim, noCells,
"m_cCube", F0, FUN_);
2030 mAlloc(m_tCube, nDim, noCells,
"m_tCube", F0, FUN_);
2031 mAlloc(m_yCube, nDim, noCells,
"m_yCube", F0, FUN_);
2035 mAlloc(m_avgVariableNames, noVars,
"m_avgVariableNames", AT_);
2036 mAlloc(m_avgFavreNames, getNoVars(),
"m_avgFavreNames", AT_);
2040 m_avgVariableNames[0] =
"um";
2041 m_avgVariableNames[1] =
"vm";
2042 IF_CONSTEXPR(nDim == 3) { m_avgVariableNames[2] =
"wm"; }
2043 m_avgVariableNames[nDim] =
"rhom";
2044 m_avgVariableNames[nDim + 1] =
"pm";
2045 MInt offset = m_noVariables;
2048 if(m_averageVorticity) {
2049 IF_CONSTEXPR(nDim == 3) {
2050 m_avgVariableNames[offset + 0] =
"vortxm";
2051 m_avgVariableNames[offset + 1] =
"vortym";
2052 m_avgVariableNames[offset + 2] =
"vortzm";
2056 m_avgVariableNames[offset + 0] =
"vortzm";
2062 m_avgVariableNames[offset + 0] =
"uu";
2063 m_avgVariableNames[offset + 1] =
"vv";
2065 IF_CONSTEXPR(nDim == 3) {
2066 m_avgVariableNames[offset + 0] =
"ww";
2067 m_avgVariableNames[offset + 1] =
"uv";
2068 m_avgVariableNames[offset + 2] =
"vw";
2069 m_avgVariableNames[offset + 3] =
"uw";
2073 m_avgVariableNames[offset + 0] =
"uv";
2078 if(noVars > m_noVariables + 3 * (nDim - 1) + 1 && m_skewness) {
2079 IF_CONSTEXPR(nDim == 3) {
2080 m_avgVariableNames[offset + 0] =
"uuu";
2081 m_avgVariableNames[offset + 1] =
"vvv";
2082 m_avgVariableNames[offset + 2] =
"www";
2086 m_avgVariableNames[offset + 0] =
"uuu";
2087 m_avgVariableNames[offset + 1] =
"vvv";
2093 if((noVars > m_noVariables + 3 * (nDim - 1) + nDim + 1) && m_kurtosis) {
2094 IF_CONSTEXPR(nDim == 3) {
2095 m_avgVariableNames[offset + 0] =
"uuuu";
2096 m_avgVariableNames[offset + 1] =
"vvvv";
2097 m_avgVariableNames[offset + 2] =
"wwww";
2101 m_avgVariableNames[offset + 0] =
"uuuu";
2102 m_avgVariableNames[offset + 1] =
"vvvv";
2108 m_avgVariableNames[offset + 0] =
"pp";
2112 if(m_averageVorticity) {
2113 IF_CONSTEXPR(nDim == 3) {
2114 m_avgVariableNames[offset + 0] =
"vortrmsx";
2115 m_avgVariableNames[offset + 1] =
"vortrmsy";
2116 m_avgVariableNames[offset + 2] =
"vortrmsz";
2120 m_avgVariableNames[offset + 0] =
"vortrmsz";
2125 if(m_averagingFavre) {
2127 m_avgFavreNames[0] =
"um_favre";
2128 m_avgFavreNames[1] =
"vm_favre";
2129 IF_CONSTEXPR(nDim == 3) { m_avgFavreNames[2] =
"wm_favre"; }
2130 m_avgFavreNames[nDim] =
"rhom_favre";
2131 m_avgFavreNames[nDim + 1] =
"pm_favre";
2135template <MInt nDim,
class SolverType>
2137 const MInt noCells = ppsolver()->getNoCells();
2138 mAlloc(m_production, nDim, noCells,
"m_production", F0, FUN_);
2141template <MInt nDim,
class SolverType>
2143 const MInt noCells = ppsolver()->getNoCells();
2144 mAlloc(m_dissipation, noCells,
"m_dissipation", F0, FUN_);
2148 m_dissFileDir = Context::getSolverProperty<MString>(
"pp_dissFileDir", ppsolver()->solverId(), AT_, &m_dissFileDir);
2150 m_dissFilePrefix =
"";
2152 Context::getSolverProperty<MString>(
"pp_dissFilePrefix", ppsolver()->solverId(), AT_, &m_dissFilePrefix);
2154 m_dissFileBoxNr = 0;
2155 m_dissFileBoxNr = Context::getSolverProperty<MInt>(
"pp_dissFileBoxNr", ppsolver()->solverId(), AT_, &m_dissFileBoxNr);
2157 m_dissFileStart = -1;
2158 m_dissFileStart = Context::getSolverProperty<MInt>(
"pp_dissFileStart", ppsolver()->solverId(), AT_, &m_dissFileStart);
2160 m_dissFileStep = -1;
2161 m_dissFileStep = Context::getSolverProperty<MInt>(
"pp_dissFileStep", ppsolver()->solverId(), AT_, &m_dissFileStep);
2164 m_dissFileEnd = Context::getSolverProperty<MInt>(
"pp_dissFileEnd", ppsolver()->solverId(), AT_, &m_dissFileEnd);
2179template <MInt nDim,
class SolverType>
2194 m_averageInterval = 0;
2196 Context::getSolverProperty<MInt>(
"pp_averageInterval", ppsolver()->solverId(), AT_, &m_averageInterval);
2199 if(m_averageInterval == 0) {
2200 mTerm(1, AT_,
"Please specify the property 'averageInterval' ...");
2214 m_averageStartTimestep = -1;
2215 m_averageStartTimestep =
2216 Context::getSolverProperty<MInt>(
"pp_averageStartTimestep", ppsolver()->solverId(), AT_, &m_averageStartTimestep);
2218 if(m_averageStartTimestep == 0) {
2219 mTerm(1, AT_,
"Please specify the property 'averageStartTimestep' ...");
2233 m_averageStopTimestep = -1;
2234 m_averageStopTimestep =
2235 Context::getSolverProperty<MInt>(
"pp_averageStopTimestep", ppsolver()->solverId(), AT_, &m_averageStopTimestep);
2237 if(m_averageStopTimestep == 0) {
2238 mTerm(1, AT_,
"Please specify the property 'averageStopTimestep' ...");
2253 m_averageRestart = 0;
2255 Context::getSolverProperty<MInt>(
"pp_averageRestart", ppsolver()->solverId(), AT_, &m_averageRestart);
2268 m_averageRestartInterval = 1000000;
2269 m_averageRestartInterval = Context::getSolverProperty<MInt>(
2270 "pp_averageRestartInterval", ppsolver()->solverId(), AT_, &m_averageRestartInterval);
2284template <MInt nDim,
class SolverType>
2288 const MInt noCells = ppsolver()->getNoCells();
2302 m_movingAvgInterval = 1;
2303 m_movingAvgInterval =
2304 Context::getSolverProperty<MInt>(
"pp_movingAvgInterval", ppsolver()->solverId(), AT_, &m_movingAvgInterval);
2305 if(m_movingAvgInterval < 1) {
2306 TERMM(1,
"m_movingAvgInterval has to be >=1");
2308 if(m_averageInterval % m_movingAvgInterval != 0 || m_movingAvgInterval > m_averageInterval) {
2309 TERMM(1,
"m_movingAvgInterval has to be a factor of m_averageInterval");
2320 m_movingAvgDataPoints =
2321 Context::getSolverProperty<MInt>(
"pp_movingAvgDataPoints", ppsolver()->solverId(), AT_, &m_movingAvgDataPoints);
2322 if(m_movingAvgDataPoints < 2) {
2323 TERMM(1,
"m_movingAvgDataPoints has to be at least 2");
2338 m_averageVorticity = 0;
2339 m_averageVorticity =
2340 Context::getSolverProperty<MBool>(
"pp_averageVorticity", ppsolver()->solverId(), AT_, &m_averageVorticity);
2342 m_movingAvgCounter = 0;
2344 m_movAvgNoVariables = m_noVariables;
2345 if(m_averageVorticity == 1) {
2346 m_movAvgNoVariables += (2 * nDim - 3);
2348 mAlloc(m_movAvgVariables, noCells, m_movAvgNoVariables * m_movingAvgDataPoints,
"m_movAvgVariables", F0, FUN_);
2349 mAlloc(m_movAvgVarNames, 2 * m_movAvgNoVariables,
"m_movAvgVarNames",
MString(
"default"), FUN_);
2353template <MInt nDim,
class SolverType>
2358 MString name = ppsolver()->outputDir() +
"PostprocessingRestart_";
2361 sprintf(buf1,
"%d", m_averageStartTimestep);
2366 m_log <<
" ^ saving average restart " << name << endl;
2368 ppsolver()->saveAverageRestart(name, getNoPPVars(), m_summedVars, m_square, m_cube, m_fourth);
2380template <MInt nDim,
class SolverType>
2392 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
2393 const MInt noVars = m_noVariables
2394 + noAveragedVorticities
2398 + noAveragedVorticities;
2411template <MInt nDim,
class SolverType>
2416 const MInt noAveragedVorticities = (m_averageVorticity != 0) * (nDim * 2 - 3);
2417 const MInt noVars = 3 * (nDim - 1)
2419 + noAveragedVorticities;
2423template <MInt nDim,
class SolverType>
2426 const MInt noVars = nDim + 2;
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
void initAverageVariables()
allocates memory for averageSolutions() and averageSolutionsInSolve()
void postprocessPreInit()
void computeAverageSkinFriction()
Computes skin friction of an averaged field.
void subtractPeriodicFluctuations()
MInt getNoPPSquareVars()
Returns number of pp Square variables.
void loadAveragedSolution()
Loads an averaged file again.
void averageSolutionsInSolve()
void postprocessInSolve()
void postprocessPostSolve()
void computeAveragedSolution()
Computes the mean variables from summed vars.
void initTimeStepProperties()
Initializes timestep properties for postprocessing.
void initAverageIn()
Initializes properties for averaging during solver run.
MInt getNoPPVars()
Returns number of postprocessing variables.
void computeProductionTerms()
Computes the production terms from an averaged field.
void addAveragingSample()
Adds one sample to the summedVars.
void saveAverageRestart()
StructuredPostprocessing()
Constructor for the postprocessing solver.
void computeDissipationTerms()
Computes the production terms from an averaged field.
void postprocessPreSolve()
void addTempWaveSample()
Adds for the travelling wave setups.
void initDissipationVariables()
void initStructuredPostprocessing()
~StructuredPostprocessing()
Destructor for the postprocessing solver.
void saveAveragedSolution(MInt)
void initProductionVariables()
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
@ PP_COMPUTE_PRODUCTION_TERMS_PRE
@ PP_LOAD_AVERAGED_SOLUTION_PRE
@ PP_SUBTRACT_PERIODIC_FLUCTUATIONS
@ PP_COMPUTE_DISSIPATION_TERMS_PRE
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