17#if not defined(MAIA_MS_COMPILER)
38 m_eps(std::numeric_limits<
MFloat>::epsilon()) {
39 (void)propertiesGroups;
46 cout <<
"Initializing Structured Solver..." << endl;
75 m_grid->gridDecomposition(
false);
79 m_log <<
"Setting porous properties..." << endl;
81 m_log <<
"Setting porous properties... SUCCESSFUL!" << endl;
83 m_log <<
"Setting zonal properties..." << endl;
85 m_log <<
"Setting zonal properties... SUCCESSFUL!" << endl;
87 m_log <<
"Allocating variables..." << endl;
89 m_log <<
"Allocating variables... SUCCESSFUL!" << endl;
91 m_log <<
"Reading input output properties..." << endl;
93 m_log <<
"Reading input output properties... SUCCESSFUL!" << endl;
101 m_grid->prepareReadGrid();
131 IF_CONSTEXPR(nDim == 3) {
185 MFloat localDeviationSquare =
POW2(localDeviation);
186 MFloat globalMaxDeviation = F0;
187 MFloat globalMinDeviation = F0;
190 MInt globalMinNoCells = 0;
192 "globalMaxDeviation");
194 "globalMinDeviation");
196 "localDeviation",
"globalAvgDeviation");
197 globalAvgDeviation = sqrt(globalAvgDeviation /
noDomains());
205 cout <<
"///////////////////////////////////////////////////////////////////" << endl
207 <<
"Average cells per domain: " << averageCellsPerDomain << endl
208 <<
"Max no of cells per domain: " << globalMaxNoCells << endl
209 <<
"Min no of cells per domain: " << globalMinNoCells << endl
210 <<
"Average deviation from average: " << globalAvgDeviation * 100.0 <<
" percent" << endl
211 <<
"Maximum deviation from average: +" << globalMaxDeviation * 100.0 <<
" / " << globalMinDeviation * 100.0
212 <<
" percent" << endl
213 <<
"///////////////////////////////////////////////////////////////////" << endl;
219 cout <<
"Reading Grid..." << endl;
221 m_log <<
"->reading the grid file" << endl;
225 m_log <<
"------------- Grid read successfully! -------------- " << endl;
227 cout <<
"Reading Grid SUCCESSFUL!" << endl;
248 if(scratchMemory > 1024.0) {
249 scratchMemory /= 1024.0;
252 if(scratchMemory > 1024.0) {
253 scratchMemory /= 1024.0;
256 cout <<
"=== Total global scratch space memory: " << setprecision(2) << fixed << scratchMemory << memoryUnit
266 RECORD_TIMER_STOP(m_timers[Timers::Structured]);
280 MInt noFQFieldsNeeded = 0;
281 for(
MInt i = 0; i < FQ->maxNoFQVariables; i++) {
282 noFQFieldsNeeded += FQ->neededFQVariables[i];
285 FQ->noFQVariables = noFQFieldsNeeded;
287 m_log <<
"Allocating " << noFQFieldsNeeded <<
" FQ fields for " << m_noCells <<
"..." << endl;
288 mAlloc(m_cells->fq, noFQFieldsNeeded, m_noCells,
"m_cells->fq", F0, AT_);
289 mAlloc(FQ->loadedFromRestartFile, noFQFieldsNeeded,
"FQ->loadedFromRestartFile",
false, AT_);
290 m_log <<
"Allocating " << noFQFieldsNeeded <<
" FQ fields for " << m_noCells <<
"...SUCCESSFUL" << endl;
293 for(
MInt i = 0; i < FQ->maxNoFQVariables; i++) {
294 if(FQ->neededFQVariables[i] == 0) {
298 FQ->activateFQField(i, currentPos, FQ->outputFQVariables[i], FQ->boxOutputFQVariables[i]);
300 FQ->noFQBoxOutput += (
MInt)FQ->boxOutputFQVariables[i];
307 if(m_movingGrid || m_bodyForce) {
308 if(m_travelingWave) {
309 mAlloc(m_tempWaveSample, (PV->noVariables + (2 * nDim - 3)), m_noCells,
"m_tempWaveSample", F0, FUN_);
313 if(m_localTimeStep) {
314 mAlloc(m_cells->localTimeStep, m_noCells,
"m_cells->localTimeStep", -1.01010101, AT_);
317 mAlloc(m_cells->variables, m_maxNoVariables, m_noCells,
"m_cells->variables", -99999.0, AT_);
318 mAlloc(m_cells->pvariables, m_maxNoVariables, m_noCells,
"m_cells->pvariables", -99999.0, AT_);
319 mAlloc(m_cells->temperature, m_noCells,
"m_cells->temperature", -99999.0, AT_);
320 mAlloc(m_cells->oldVariables, m_maxNoVariables, m_noCells,
"m_cells->oldVariables", -99999.0, AT_);
321 mAlloc(m_cells->dss, nDim, m_noCells,
"m_cells->dss", F0, AT_);
326 mAlloc(m_cells->dxt, nDim, m_noCells,
"m_cells->dxt", F0, AT_);
329 MInt noVarsFluxes = (CV->noVariables - 1 + m_rans);
331 m_log <<
"Allocating fFlux with " << (CV->noVariables - 1 + m_rans) <<
" variables for " << m_noCells <<
" cells"
334 mAlloc(m_cells->rightHandSide, CV->noVariables, m_noCells,
"m_cells->rhs", F0, AT_);
335 mAlloc(m_cells->flux, CV->noVariables, m_noCells,
"m_cells->flux", 10000.0, AT_);
336 mAlloc(m_cells->eFlux, noVarsFluxes, m_noCells,
"m_cells->eFlux", F0, AT_);
337 mAlloc(m_cells->fFlux, noVarsFluxes, m_noCells,
"m_cells->fFlux", F0, AT_);
338 mAlloc(m_cells->gFlux, noVarsFluxes, m_noCells,
"m_cells->gFlux", F0, AT_);
340 mAlloc(m_cells->viscousFlux, (nDim + m_porous), m_noCells,
"m_cells->viscousFlux", 1000.0, AT_);
342 mAlloc(m_QLeft, m_maxNoVariables,
"m_QLeft", F0, AT_);
343 mAlloc(m_QRight, m_maxNoVariables,
"m_QRight", F0, AT_);
346 IF_CONSTEXPR(nDim == 2) {
347 if(m_viscCompact)
mAlloc(m_cells->dT, 4, m_noCells,
"m_cells->dT", F0, AT_);
359 m_outputIterationNumber = 0;
360 m_outputFormat =
".hdf5";
361 m_lastOutputTimeStep = -1;
376 m_forceOutputInterval = 0;
378 m_forceOutputInterval =
379 Context::getSolverProperty<MInt>(
"forceOutputInterval", m_solverId, AT_, &m_forceOutputInterval);
381 m_forceOutputInterval =
382 Context::getSolverProperty<MInt>(
"dragOutputInterval", m_solverId, AT_, &m_forceOutputInterval);
385 if(m_forceOutputInterval > 0) {
394 m_auxOutputDir = m_solutionOutput;
396 m_auxOutputDir = Context::getSolverProperty<MString>(
"auxOutputDir", m_solverId, AT_);
399 if(strcmp((m_auxOutputDir.substr(m_auxOutputDir.length() - 1, 1)).c_str(), comparator.c_str()) != 0) {
400 m_auxOutputDir = m_auxOutputDir +
"/";
418 m_forceAsciiOutputInterval = 0;
420 m_forceAsciiOutputInterval =
421 Context::getSolverProperty<MInt>(
"forceAsciiOutputInterval", m_solverId, AT_, &m_forceAsciiOutputInterval);
423 m_forceAsciiOutputInterval =
424 Context::getSolverProperty<MInt>(
"dragAsciiOutputInterval", m_solverId, AT_, &m_forceAsciiOutputInterval);
441 m_forceAsciiComputeInterval = 0;
443 m_forceAsciiComputeInterval =
444 Context::getSolverProperty<MInt>(
"forceAsciiComputeInterval", m_solverId, AT_, &m_forceAsciiComputeInterval);
446 m_forceAsciiComputeInterval =
447 Context::getSolverProperty<MInt>(
"dragAsciiComputeInterval", m_solverId, AT_, &m_forceAsciiComputeInterval);
450 if(m_forceAsciiComputeInterval > m_forceAsciiOutputInterval) {
451 m_forceAsciiComputeInterval = m_forceAsciiOutputInterval;
454 if(m_forceAsciiOutputInterval > 0 && m_forceAsciiComputeInterval == 0) {
455 m_forceAsciiComputeInterval = 1;
470 m_forceSecondOrder =
true;
472 m_forceSecondOrder = Context::getSolverProperty<MBool>(
"forceSecondOrder", m_solverId, AT_, &m_forceSecondOrder);
474 m_forceSecondOrder = Context::getSolverProperty<MBool>(
"dragSecondOrder", m_solverId, AT_, &m_forceSecondOrder);
477 if(m_forceSecondOrder) {
478 m_log <<
"Second order force computation is activated" << endl;
494 m_outputOffset = Context::getSolverProperty<MInt>(
"outputOffset", m_solverId, AT_, &m_outputOffset);
512 m_ignoreUID = Context::getSolverProperty<MBool>(
"ignoreUID", m_solverId, AT_, &m_ignoreUID);
513 m_log <<
"WARNING!!!!!!!!!!!!!!: UID was not checked. Solution and grid might not fit together" << endl;
529 m_restart = Context::getSolverProperty<MBool>(
"restartFile", m_solverId, AT_, &m_restart);
531 m_restartTimeStep = 0;
540 m_useNonSpecifiedRestartFile =
false;
541 m_useNonSpecifiedRestartFile =
542 Context::getSolverProperty<MBool>(
"useNonSpecifiedRestartFile", m_solverId, AT_, &m_useNonSpecifiedRestartFile);
560 m_changeMa = Context::getSolverProperty<MBool>(
"changeMa", m_solverId, AT_, &m_changeMa);
576 m_debugOutput =
false;
577 m_debugOutput = Context::getSolverProperty<MBool>(
"debugOutput", m_solverId, AT_, &m_debugOutput);
580 FQ->neededFQVariables[FQ->BLOCKID] = 1;
581 FQ->neededFQVariables[FQ->CELLID] = 1;
584 FQ->neededFQVariables[FQ->MU_L] = 1;
585 FQ->outputFQVariables[FQ->MU_L] =
false;
586 FQ->neededFQVariables[FQ->MU_T] = 1;
587 FQ->outputFQVariables[FQ->MU_T] =
false;
602 m_savePartitionOutput =
false;
603 m_savePartitionOutput =
604 Context::getSolverProperty<MBool>(
"savePartitionOutput", m_solverId, AT_, &m_savePartitionOutput);
621 m_bForce = Context::getSolverProperty<MBool>(
"computeForce", m_solverId, AT_, &m_bForce);
623 m_bForce = Context::getSolverProperty<MBool>(
"computeCfCp", m_solverId, AT_, &m_bForce);
627 m_log <<
"<<<<< Skin-friction and Pressure Coefficient Computation: ENABLED" << endl;
644 m_bPower = Context::getSolverProperty<MBool>(
"computePower", m_solverId, AT_, &m_bPower);
646 m_log <<
"<<<<< Power Computation: ENABLED" << endl;
662 m_detailAuxData =
false;
663 m_detailAuxData = Context::getSolverProperty<MBool>(
"detailAuxData", m_solverId, AT_, &m_detailAuxData);
678 m_bForceLineAverage =
false;
680 m_bForceLineAverage =
681 Context::getSolverProperty<MBool>(
"computeForceLineAverage", m_solverId, AT_, &m_bForceLineAverage);
683 m_bForceLineAverage =
684 Context::getSolverProperty<MBool>(
"computeCpLineAverage", m_solverId, AT_, &m_bForceLineAverage);
701 m_forceAveragingDir = 0;
703 m_forceAveragingDir = Context::getSolverProperty<MInt>(
"forceAveragingDir", m_solverId, AT_, &m_forceAveragingDir);
705 m_forceAveragingDir = Context::getSolverProperty<MInt>(
"cpAveragingDir", m_solverId, AT_, &m_forceAveragingDir);
721 m_auxDataCoordinateLimits =
false;
722 m_auxDataCoordinateLimits =
723 Context::getSolverProperty<MBool>(
"auxDataCoordinateLimits", m_solverId, AT_, &m_auxDataCoordinateLimits);
727 if(m_forceOutputInterval || m_forceAsciiOutputInterval) {
733 if(m_auxDataCoordinateLimits) {
734 m_auxDataLimits =
nullptr;
735 MInt noAuxDataLimits = 4;
736 mAlloc(m_auxDataLimits, noAuxDataLimits,
"m_auxDataLimits", F0, AT_);
738 for(
MInt i = 0; i < noAuxDataLimits; ++i) {
752 m_auxDataLimits[i] = -99999.9;
753 m_auxDataLimits[i] = Context::getSolverProperty<MFloat>(
"auxDataLimits", m_solverId, AT_, &m_auxDataLimits[i], i);
756 m_log <<
"AuxData limited area"
757 <<
", lower x-limit: " << m_auxDataLimits[0] <<
", upper x-limit: " << m_auxDataLimits[1]
758 <<
", lower z-limit: " << m_auxDataLimits[2] <<
", upper z-limit: " << m_auxDataLimits[3] << endl;
774 m_computeLambda2 =
false;
775 m_computeLambda2 = Context::getSolverProperty<MBool>(
"computeLambda2", m_solverId, AT_, &m_computeLambda2);
776 if(m_computeLambda2) {
777 FQ->neededFQVariables[FQ->LAMBDA2] = 1;
778 FQ->boxOutputFQVariables[FQ->LAMBDA2] = 1;
794 m_vorticityOutput =
false;
795 m_vorticityOutput = Context::getSolverProperty<MBool>(
"vorticityOutput", m_solverId, AT_, &m_vorticityOutput);
810 m_averageVorticity =
false;
811 m_averageVorticity = Context::getSolverProperty<MBool>(
"pp_averageVorticity", m_solverId, AT_, &m_averageVorticity);
813 if(m_vorticityOutput || m_averageVorticity) {
814 for(
MInt v = 0; v < nDim; v++) {
815 FQ->neededFQVariables[FQ->VORTX + v] = 1;
820 if(!m_vorticityOutput) {
821 for(
MInt v = 0; v < nDim; v++) {
822 FQ->outputFQVariables[FQ->VORTX + v] =
false;
830 mAlloc(m_variableNames, m_maxNoVariables,
"m_variableNames", AT_);
833 m_variableNames[CV->RHO_U] =
"rhoU";
834 m_variableNames[CV->RHO_E] =
"rhoE";
835 m_variableNames[CV->RHO] =
"rho";
839 m_variableNames[CV->RHO_U] =
"rhoU";
840 m_variableNames[CV->RHO_V] =
"rhoV";
841 m_variableNames[CV->RHO_E] =
"rhoE";
842 m_variableNames[CV->RHO] =
"rho";
846 m_variableNames[CV->RHO_U] =
"rhoU";
847 m_variableNames[CV->RHO_V] =
"rhoV";
848 m_variableNames[CV->RHO_W] =
"rhoW";
849 m_variableNames[CV->RHO_E] =
"rhoE";
850 m_variableNames[CV->RHO] =
"rho";
854 mTerm(1, AT_,
"spatial dimension not implemented for m_variableNames");
860 if(nDim + 2 < CV->noVariables) {
861 m_variableNames[nDim + 2] =
"rhoZ";
862 for(
MInt i = nDim + 2; i < CV->noVariables; ++i) {
864 number << i - (nDim + 2);
865 MString varName =
"rho" + number.str();
866 m_variableNames[i] = varName;
870 mAlloc(m_pvariableNames, m_maxNoVariables,
"m_pvariableNames", AT_);
873 m_pvariableNames[PV->U] =
"u";
874 m_pvariableNames[PV->P] =
"p";
875 m_pvariableNames[PV->RHO] =
"rho";
879 m_pvariableNames[PV->U] =
"u";
880 m_pvariableNames[PV->V] =
"v";
881 m_pvariableNames[PV->P] =
"p";
882 m_pvariableNames[PV->RHO] =
"rho";
886 m_pvariableNames[PV->U] =
"u";
887 m_pvariableNames[PV->V] =
"v";
888 m_pvariableNames[PV->W] =
"w";
889 m_pvariableNames[PV->P] =
"p";
890 m_pvariableNames[PV->RHO] =
"rho";
894 mTerm(1, AT_,
"spatial dimension not implemented for m_variableNames");
900 if(nDim + 2 < m_maxNoVariables) {
901 for(
MInt i = nDim + 2; i < m_maxNoVariables; ++i) {
903 number << i - (nDim + 2);
904 MString varName =
"rans" + number.str();
905 m_pvariableNames[i] = varName;
921 m_residualOutputInterval = 1;
922 m_residualOutputInterval =
923 Context::getSolverProperty<MInt>(
"residualOutputInterval", m_solverId, AT_, &m_residualOutputInterval);
925 m_residualFileExist =
false;
931 m_intpPointsStart =
nullptr;
932 m_intpPointsDelta =
nullptr;
933 m_intpPointsDelta2D =
nullptr;
934 m_intpPointsNoPoints =
nullptr;
935 m_intpPointsNoPoints2D =
nullptr;
936 m_intpPointsCoordinates =
nullptr;
937 m_intpPointsHasPartnerGlobal =
nullptr;
938 m_intpPointsHasPartnerLocal =
nullptr;
939 m_intpPointsVarsGlobal =
nullptr;
940 m_intpPointsVarsLocal =
nullptr;
941 m_intpPointsNoPointsTotal = 0;
942 m_intpPointsNoLines = 0;
943 m_intpPointsNoLines2D = 0;
957 m_intpPointsOutputInterval = 0;
958 m_intpPointsOutputInterval =
959 Context::getSolverProperty<MInt>(
"intpPointsOutputInterval", m_solverId, AT_, &m_intpPointsOutputInterval);
961 if(m_intpPointsOutputInterval > 0) {
974 m_intpPointsOutputDir = m_solutionOutput;
976 m_intpPointsOutputDir = Context::getSolverProperty<MString>(
"intpPointsOutputDir", m_solverId, AT_);
979 if(strcmp((m_intpPointsOutputDir.substr(m_intpPointsOutputDir.length() - 1, 1)).c_str(), comparator.c_str())
981 m_intpPointsOutputDir = m_intpPointsOutputDir +
"/";
1083 m_intpPointsNoLines = noLineStartX;
1085 if(m_intpPointsNoLines != noLineStartX || m_intpPointsNoLines != noLineStartY || m_intpPointsNoLines != noLineStartZ
1086 || m_intpPointsNoLines != noLineDeltaX || m_intpPointsNoLines != noLineDeltaY
1087 || m_intpPointsNoLines != noLineDeltaZ || m_intpPointsNoLines != noLineNoPoints) {
1089 "The number of Entries for 'intpPointsStartX', 'intpPointsStartY',"
1090 "'intpPointsStartZ', 'intpPointsDeltaX', 'intpPointsDeltaY' and "
1091 "'intpPointsDeltaZ' do not coincide!! Please check");
1159 m_intpPointsNoLines2D = noLineNoPoints2D;
1161 if(m_intpPointsNoLines2D != noLineDeltaX2d || m_intpPointsNoLines2D != noLineDeltaY2d
1162 || m_intpPointsNoLines2D != noLineDeltaZ2d || m_intpPointsNoLines2D != noLineNoPoints2D) {
1163 cout <<
"no2dLines: " << m_intpPointsNoLines2D <<
" lineDeltaY2D: " << noLineDeltaY2d
1164 <<
" lineDeltaX2D: " << noLineDeltaX2d <<
" lineDeltaZ2D: " << noLineDeltaZ2d << endl;
1166 "The number of Entries for 'lineDeltaX2D', 'lineDeltaY2D' and 'lineDeltaZ2D' do not coincide!! "
1171 m_intpPointsNoLines2D = m_intpPointsNoLines;
1174 mAlloc(m_intpPointsStart, nDim, m_intpPointsNoLines,
"m_intpPointsStart", F0, AT_);
1175 mAlloc(m_intpPointsDelta, nDim, m_intpPointsNoLines,
"m_intpPointsDelta", F0, AT_);
1176 mAlloc(m_intpPointsNoPoints, m_intpPointsNoLines,
"m_intpPointsNoPoints", 0, AT_);
1177 mAlloc(m_intpPointsNoPoints2D, m_intpPointsNoLines2D,
"m_intpPointsNoPoints2D", 0, AT_);
1178 mAlloc(m_intpPointsDelta2D, nDim, m_intpPointsNoLines2D,
"m_intpPointsDelta2D", F0, AT_);
1179 mAlloc(m_intpPointsOffsets, m_intpPointsNoLines,
"m_intpPointsOffsets", 0, AT_);
1188 for(
MInt i = 0; i < m_intpPointsNoLines; ++i) {
1190 for(
MInt dim = 0; dim < nDim; dim++) {
1191 m_intpPointsStart[dim][i] = -99999.9;
1192 m_intpPointsDelta[dim][i] = -99999.9;
1194 m_intpPointsNoPoints[i] = -1;
1196 m_intpPointsStart[0][i] =
1197 Context::getSolverProperty<MFloat>(
"intpPointsStartX", m_solverId, AT_, &m_intpPointsStart[0][i], i);
1198 m_intpPointsStart[1][i] =
1199 Context::getSolverProperty<MFloat>(
"intpPointsStartY", m_solverId, AT_, &m_intpPointsStart[1][i], i);
1200 m_intpPointsStart[2][i] =
1201 Context::getSolverProperty<MFloat>(
"intpPointsStartZ", m_solverId, AT_, &m_intpPointsStart[2][i], i);
1202 m_intpPointsDelta[0][i] =
1203 Context::getSolverProperty<MFloat>(
"intpPointsDeltaX", m_solverId, AT_, &m_intpPointsDelta[0][i], i);
1204 m_intpPointsDelta[1][i] =
1205 Context::getSolverProperty<MFloat>(
"intpPointsDeltaY", m_solverId, AT_, &m_intpPointsDelta[1][i], i);
1206 m_intpPointsDelta[2][i] =
1207 Context::getSolverProperty<MFloat>(
"intpPointsDeltaZ", m_solverId, AT_, &m_intpPointsDelta[2][i], i);
1208 m_intpPointsNoPoints[i] =
1209 Context::getSolverProperty<MInt>(
"intpPointsNoPoints", m_solverId, AT_, &m_intpPointsNoPoints[i], i);
1212 m_intpPoints =
false;
1218 m_intpPoints =
true;
1220 for(
MInt i = 0; i < m_intpPointsNoLines2D; ++i) {
1222 for(
MInt dim = 0; dim < nDim; dim++) {
1223 m_intpPointsDelta2D[dim][i] = -99999.9;
1225 m_intpPointsNoPoints2D[i] = -1;
1227 m_intpPointsDelta2D[0][i] =
1228 Context::getSolverProperty<MFloat>(
"intpPointsDeltaX2D", m_solverId, AT_, &m_intpPointsDelta2D[0][i], i);
1229 m_intpPointsDelta2D[1][i] =
1230 Context::getSolverProperty<MFloat>(
"intpPointsDeltaY2D", m_solverId, AT_, &m_intpPointsDelta2D[1][i], i);
1231 m_intpPointsDelta2D[2][i] =
1232 Context::getSolverProperty<MFloat>(
"intpPointsDeltaZ2D", m_solverId, AT_, &m_intpPointsDelta2D[2][i], i);
1233 m_intpPointsNoPoints2D[i] =
1234 Context::getSolverProperty<MInt>(
"intpPointsNoPoints2D", m_solverId, AT_, &m_intpPointsNoPoints2D[i], i);
1238 for(
MInt i = 0; i < m_intpPointsNoLines2D; i++) {
1239 m_intpPointsNoPoints2D[i] = 1;
1241 for(
MInt fieldId = 0; fieldId < m_intpPointsNoLines; fieldId++) {
1242 for(
MInt dim = 0; dim < nDim; dim++) {
1243 m_intpPointsDelta2D[dim][fieldId] = 0;
1248 for(
MInt i = 0; i < m_intpPointsNoLines; i++) {
1249 m_intpPointsNoPointsTotal += m_intpPointsNoPoints[i] * m_intpPointsNoPoints2D[i];
1252 mAlloc(m_intpPointsCoordinates, nDim, m_intpPointsNoPointsTotal,
"m_intpPointsCoordinates", F0, AT_);
1253 mAlloc(m_intpPointsHasPartnerGlobal, m_intpPointsNoPointsTotal,
"m_intpPointsHasPartnerGlobal", 0, AT_);
1254 mAlloc(m_intpPointsHasPartnerLocal, m_intpPointsNoPointsTotal,
"m_intpPointsHasPartnerLocal", 0, AT_);
1255 mAlloc(m_intpPointsVarsLocal, CV->noVariables, m_intpPointsNoPointsTotal,
"m_intpPointsVarsLocal", F0, AT_);
1256 mAlloc(m_intpPointsVarsGlobal, CV->noVariables, m_intpPointsNoPointsTotal,
"m_intpPointsVarsGlobal", F0, AT_);
1262 for(
MInt fieldId = 0; fieldId < m_intpPointsNoLines; fieldId++) {
1263 m_intpPointsOffsets[fieldId] = offset;
1265 for(
MInt pointId2d = 0; pointId2d < m_intpPointsNoPoints2D[fieldId]; pointId2d++) {
1266 for(
MInt pointId = 0; pointId < m_intpPointsNoPoints[fieldId]; pointId++) {
1267 for(
MInt dim = 0; dim < nDim; dim++) {
1268 m_intpPointsCoordinates[dim][offset] = m_intpPointsStart[dim][fieldId]
1269 + pointId * m_intpPointsDelta[dim][fieldId]
1270 + pointId2d * m_intpPointsDelta2D[dim][fieldId];
1305 m_boxOutputInterval = 0;
1306 m_boxOutputInterval = Context::getSolverProperty<MInt>(
"boxOutputInterval", m_solverId, AT_, &m_boxOutputInterval);
1308 if(m_boxOutputInterval > 0) {
1335 m_boxWriteCoordinates =
false;
1336 m_boxWriteCoordinates =
1337 Context::getSolverProperty<MBool>(
"boxWriteCoordinates", m_solverId, AT_, &m_boxWriteCoordinates);
1351 m_boxOutputDir = m_solutionOutput;
1353 m_boxOutputDir = Context::getSolverProperty<MString>(
"boxOutputDir", m_solverId, AT_);
1356 if(strcmp((m_boxOutputDir.substr(m_boxOutputDir.length() - 1, 1)).c_str(), comparator.c_str()) != 0) {
1357 m_boxOutputDir = m_boxOutputDir +
"/";
1361 mAlloc(m_boxBlock, m_boxNoBoxes,
"m_boxBlock", 0, AT_);
1362 mAlloc(m_boxOffset, m_boxNoBoxes, nDim,
"m_boxOffset", 0, AT_);
1363 mAlloc(m_boxSize, m_boxNoBoxes, nDim,
"m_boxSize", 0, AT_);
1365 for(
MInt i = 0; i < m_boxNoBoxes; ++i) {
1368 for(
MInt dim = 0; dim < nDim; dim++) {
1369 m_boxOffset[i][dim] = -1;
1370 m_boxSize[i][dim] = -1;
1373 m_boxBlock[i] = Context::getSolverProperty<MInt>(
"boxBlock", m_solverId, AT_, &m_boxBlock[i], i);
1387 IF_CONSTEXPR(nDim == 3) {
1388 m_boxOffset[i][0] = Context::getSolverProperty<MInt>(
"boxOffsetK", m_solverId, AT_, &m_boxOffset[i][0], i);
1404 m_boxOffset[i][nDim - 2] = Context::getSolverProperty<MInt>(
"boxOffsetJ", m_solverId, AT_, &m_boxOffset[i][1], i);
1418 m_boxOffset[i][nDim - 1] = Context::getSolverProperty<MInt>(
"boxOffsetI", m_solverId, AT_, &m_boxOffset[i][2], i);
1432 IF_CONSTEXPR(nDim == 3) {
1433 m_boxSize[i][0] = Context::getSolverProperty<MInt>(
"boxSizeK", m_solverId, AT_, &m_boxSize[i][0], i);
1448 m_boxSize[i][nDim - 2] = Context::getSolverProperty<MInt>(
"boxSizeJ", m_solverId, AT_, &m_boxSize[i][1], i);
1462 m_boxSize[i][nDim - 1] = Context::getSolverProperty<MInt>(
"boxSizeI", m_solverId, AT_, &m_boxSize[i][2], i);
1490 m_nodalBoxOutputInterval = 0;
1491 m_nodalBoxOutputInterval =
1492 Context::getSolverProperty<MInt>(
"nodalBoxOutputInterval", m_solverId, AT_, &m_nodalBoxOutputInterval);
1494 if(m_nodalBoxOutputInterval > 0) {
1495 m_nodalBoxInitialized =
false;
1496 m_nodalBoxTotalLocalSize = -1;
1524 m_nodalBoxWriteCoordinates =
false;
1525 m_nodalBoxWriteCoordinates =
1526 Context::getSolverProperty<MBool>(
"nodalBoxWriteCoordinates", m_solverId, AT_, &m_nodalBoxWriteCoordinates);
1540 m_nodalBoxOutputDir = m_solutionOutput;
1542 m_nodalBoxOutputDir = Context::getSolverProperty<MString>(
"nodalBoxOutputDir", m_solverId, AT_);
1545 if(strcmp((m_nodalBoxOutputDir.substr(m_nodalBoxOutputDir.length() - 1, 1)).c_str(), comparator.c_str()) != 0) {
1546 m_nodalBoxOutputDir = m_nodalBoxOutputDir +
"/";
1550 mAlloc(m_nodalBoxBlock, m_nodalBoxNoBoxes,
"m_nodalBoxBlock", 0, AT_);
1551 mAlloc(m_nodalBoxOffset, m_nodalBoxNoBoxes, nDim,
"m_nodalBoxOffset", 0, AT_);
1552 mAlloc(m_nodalBoxPoints, m_nodalBoxNoBoxes, nDim,
"m_nodalBoxPoints", 0, AT_);
1554 for(
MInt i = 0; i < m_nodalBoxNoBoxes; ++i) {
1555 m_nodalBoxBlock[i] = -1;
1557 for(
MInt dim = 0; dim < nDim; dim++) {
1558 m_nodalBoxOffset[i][dim] = -1;
1559 m_nodalBoxPoints[i][dim] = -1;
1562 m_nodalBoxBlock[i] = Context::getSolverProperty<MInt>(
"nodalBoxBlock", m_solverId, AT_, &m_nodalBoxBlock[i], i);
1576 m_nodalBoxOffset[i][0] =
1577 Context::getSolverProperty<MInt>(
"nodalBoxOffsetK", m_solverId, AT_, &m_nodalBoxOffset[i][0], i);
1591 m_nodalBoxOffset[i][1] =
1592 Context::getSolverProperty<MInt>(
"nodalBoxOffsetJ", m_solverId, AT_, &m_nodalBoxOffset[i][1], i);
1606 m_nodalBoxOffset[i][2] =
1607 Context::getSolverProperty<MInt>(
"nodalBoxOffsetI", m_solverId, AT_, &m_nodalBoxOffset[i][2], i);
1621 m_nodalBoxPoints[i][0] =
1622 Context::getSolverProperty<MInt>(
"nodalBoxPointsK", m_solverId, AT_, &m_nodalBoxPoints[i][0], i);
1636 m_nodalBoxPoints[i][1] =
1637 Context::getSolverProperty<MInt>(
"nodalBoxPointsJ", m_solverId, AT_, &m_nodalBoxPoints[i][1], i);
1651 m_nodalBoxPoints[i][2] =
1652 Context::getSolverProperty<MInt>(
"nodalBoxPointsI", m_solverId, AT_, &m_nodalBoxPoints[i][2], i);
1680 m_pointsToAsciiOutputInterval = 0;
1681 m_pointsToAsciiOutputInterval =
1682 Context::getSolverProperty<MInt>(
"pointsToAsciiOutputInterval", m_solverId, AT_, &m_pointsToAsciiOutputInterval);
1698 m_pointsToAsciiComputeInterval = 0;
1699 m_pointsToAsciiComputeInterval = Context::getSolverProperty<MInt>(
"pointsToAsciiComputeInterval", m_solverId, AT_,
1700 &m_pointsToAsciiComputeInterval);
1702 if(m_pointsToAsciiComputeInterval > m_pointsToAsciiOutputInterval) {
1703 m_pointsToAsciiComputeInterval = m_pointsToAsciiOutputInterval;
1706 if(m_pointsToAsciiOutputInterval > 0 && m_pointsToAsciiComputeInterval == 0) {
1707 m_pointsToAsciiComputeInterval = 1;
1710 if(m_pointsToAsciiOutputInterval > 0) {
1711 m_pointsToAsciiVarId = 0;
1712 m_pointsToAsciiVarId =
1713 Context::getSolverProperty<MInt>(
"pointsToAsciiVarId", m_solverId, AT_, &m_pointsToAsciiVarId);
1715 m_pointsToAsciiLastOutputStep = 0;
1716 m_pointsToAsciiLastComputationStep = 0;
1720 mAlloc(m_pointsToAsciiCoordinates, nDim, m_pointsToAsciiNoPoints,
"m_pointsToAsciiCoordinates", 0.0, AT_);
1721 mAlloc(m_pointsToAsciiHasPartnerLocal, m_pointsToAsciiNoPoints,
"m_pointsToAsciiHasPartnerLocal", 0, AT_);
1722 mAlloc(m_pointsToAsciiHasPartnerGlobal, m_pointsToAsciiNoPoints,
"m_pointsToAsciiHasPartnerGlobal", 0, AT_);
1723 mAlloc(m_pointsToAsciiVars, m_pointsToAsciiOutputInterval, m_pointsToAsciiNoPoints + 3,
"m_pointsToAsciiVars", 0.0,
1726 if(domainId() == 0) {
1727 cout <<
"noAsciiCells: " << m_pointsToAsciiNoPoints << endl;
1730 for(
MInt i = 0; i < m_pointsToAsciiNoPoints; ++i) {
1731 for(
MInt dim = 0; dim < nDim; dim++) {
1732 m_pointsToAsciiCoordinates[dim][i] = -1.0;
1747 m_pointsToAsciiCoordinates[0][i] =
1748 Context::getSolverProperty<MFloat>(
"pointsToAsciiX", m_solverId, AT_, &m_pointsToAsciiCoordinates[0][i], i);
1762 m_pointsToAsciiCoordinates[1][i] =
1763 Context::getSolverProperty<MFloat>(
"pointsToAsciiY", m_solverId, AT_, &m_pointsToAsciiCoordinates[1][i], i);
1777 m_pointsToAsciiCoordinates[2][i] =
1778 Context::getSolverProperty<MFloat>(
"pointsToAsciiZ", m_solverId, AT_, &m_pointsToAsciiCoordinates[2][i], i);
1801 m_useConvectiveUnitWrite =
false;
1802 m_useConvectiveUnitWrite =
1803 Context::getSolverProperty<MBool>(
"useConvectiveUnitWrite", m_solverId, AT_, &m_useConvectiveUnitWrite);
1805 if(m_useConvectiveUnitWrite) {
1819 m_convectiveUnitInterval = 1.0;
1820 m_convectiveUnitInterval =
1821 Context::getSolverProperty<MFloat>(
"convectiveUnitInterval", m_solverId, AT_, &m_convectiveUnitInterval);
1823 m_noConvectiveOutputs = 0;
1839 m_sampleSolutionFiles =
false;
1840 m_sampleSolutionFiles =
1841 Context::getSolverProperty<MBool>(
"sampleSolutionFiles", m_solverId, AT_, &m_sampleSolutionFiles);
1861 m_restartInterpolation =
false;
1862 m_restartInterpolation =
1863 Context::getSolverProperty<MBool>(
"restartInterpolation", m_solverId, AT_, &m_restartInterpolation);
1874 (void)propertiesGroups;
1890 m_noSpecies = Context::getSolverProperty<MInt>(
"noSpecies", m_solverId, AT_, &m_noSpecies);
1892 FQ = make_unique<StructuredFQVariables>();
1895 mAlloc(FQ->neededFQVariables, FQ->maxNoFQVariables,
"FQ->neededFQVariables", 0, AT_);
1896 mAlloc(FQ->outputFQVariables, FQ->maxNoFQVariables,
"FQ->outputFQVariables",
true, AT_);
1897 mAlloc(FQ->boxOutputFQVariables, FQ->maxNoFQVariables,
"FQ->boxOutputFQVariables",
false, AT_);
1900 m_periodicConnection = 0;
1923 m_referenceLength = F1;
1924 m_referenceLength = Context::getSolverProperty<MFloat>(
"referenceLength", m_solverId, AT_, &m_referenceLength);
1926 if(fabs(m_referenceLength - F1) > m_eps) {
1927 m_log <<
"WARNING: referenceLength != 1.0. The correct implementation of this is not checked. Don't use it "
1928 "unless you REALLY know what you are doing."
1944 m_physicalReferenceLength = F1;
1945 m_physicalReferenceLength =
1946 Context::getSolverProperty<MFloat>(
"physicalReferenceLength", m_solverId, AT_, &m_physicalReferenceLength);
1966 m_Re = Context::getSolverProperty<MFloat>(
"Re", m_solverId, AT_) / m_referenceLength;
1982 m_Pr = Context::getSolverProperty<MFloat>(
"Pr", m_solverId, AT_, &m_Pr);
1998 m_ReTau = Context::getSolverProperty<MFloat>(
"ReTau", m_solverId, AT_) / m_referenceLength;
2012 m_Ma = Context::getSolverProperty<MFloat>(
"Ma", m_solverId, AT_);
2026 mAlloc(m_angle, nDim,
"m_angle", F0, AT_);
2028 for(
MInt i = 0; i < (nDim - 1); i++) {
2029 m_angle[i] = Context::getSolverProperty<MFloat>(
"angle", m_solverId, AT_, i);
2030 m_angle[i] *= PI / 180.0;
2047 mAlloc(m_volumeForce, nDim,
"m_volumeAcceleration", F0, AT_);
2048 m_considerVolumeForces =
false;
2049 m_considerVolumeForces =
2050 Context::getSolverProperty<MBool>(
"considerVolumeForces", m_solverId, AT_, &m_considerVolumeForces);
2052 if(m_considerVolumeForces) {
2053 for(
MInt i = 0; i < nDim; i++) {
2067 m_volumeForce[i] = Context::getSolverProperty<MFloat>(
"volumeForce", m_solverId, AT_, i);
2084 m_gamma = Context::getSolverProperty<MFloat>(
"gamma", m_solverId, AT_, &m_gamma);
2086 m_gammaMinusOne = m_gamma - F1;
2087 m_fgammaMinusOne = F1 / (m_gammaMinusOne);
2101 m_initialCondition = Context::getSolverProperty<MInt>(
"initialCondition", m_solverId, AT_);
2103 m_channelFullyPeriodic =
false;
2104 m_channelFullyPeriodic =
2105 Context::getSolverProperty<MBool>(
"channelFullyPeriodic", m_solverId, AT_, &m_channelFullyPeriodic);
2106 if(m_channelFullyPeriodic && (m_initialCondition == 1233 || m_initialCondition == 1234))
2107 mTerm(1,
"Fully periodic channel computation works with volume forces and not a pressure gradient!");
2108 m_channelHeight = -F1;
2109 m_channelWidth = -F1;
2110 m_channelLength = -F1;
2111 m_channelInflowPlaneCoordinate = -111111.1111111;
2113 m_channelC2 = -3.05;
2116 if(m_channelFullyPeriodic) {
2117 m_considerVolumeForces =
true;
2118 m_volumeForceMethod = Context::getSolverProperty<MInt>(
"volumeForceMethod", m_solverId, AT_);
2119 m_volumeForceUpdateInterval = Context::getSolverProperty<MInt>(
"volumeForceUpdateInterval", m_solverId, AT_);
2121 switch(m_initialCondition) {
2138 m_channelHeight = Context::getSolverProperty<MFloat>(
"channelHeight", m_solverId, AT_);
2153 m_channelWidth = Context::getSolverProperty<MFloat>(
"channelWidth", m_solverId, AT_);
2168 m_channelLength = Context::getSolverProperty<MFloat>(
"channelLength", m_solverId, AT_);
2182 m_channelInflowPlaneCoordinate = Context::getSolverProperty<MFloat>(
"channelInflowCoordinate", m_solverId, AT_);
2196 m_channelC1 = Context::getSolverProperty<MFloat>(
"loglawC1", m_solverId, AT_, &m_channelC1);
2210 m_channelC2 = Context::getSolverProperty<MFloat>(
"loglawC2", m_solverId, AT_, &m_channelC1);
2224 m_channelC3 = Context::getSolverProperty<MFloat>(
"loglawC3", m_solverId, AT_, &m_channelC1);
2238 m_channelC4 = Context::getSolverProperty<MFloat>(
"loglawC4", m_solverId, AT_, &m_channelC1);
2239 m_log <<
"============= Channel flow activated =============" << endl;
2240 m_log <<
"-> channelHeight: " << m_channelHeight << endl;
2241 m_log <<
"-> channelWidth: " << m_channelWidth << endl;
2242 m_log <<
"-> channelLength: " << m_channelLength << endl;
2243 m_log <<
"-> channelInflowPlaneCoordinate: " << m_channelInflowPlaneCoordinate << endl;
2244 m_log <<
"-> Log law properties: " << endl;
2245 m_log <<
"--> C1: " << m_channelC1 << endl;
2246 m_log <<
"--> C2: " << m_channelC2 << endl;
2247 m_log <<
"--> C3: " << m_channelC3 << endl;
2248 m_log <<
"--> C4: " << m_channelC4 << endl;
2249 m_log <<
"============= Channel flow summary finished =============" << endl;
2269 m_channelHeight = Context::getSolverProperty<MFloat>(
"pipeDiameter", m_solverId, AT_);
2270 m_channelWidth = m_channelHeight;
2284 m_channelLength = Context::getSolverProperty<MFloat>(
"pipeLength", m_solverId, AT_);
2298 m_channelInflowPlaneCoordinate = Context::getSolverProperty<MFloat>(
"pipeInflowCoordinate", m_solverId, AT_);
2299 m_channelC1 = Context::getSolverProperty<MFloat>(
"loglawC1", m_solverId, AT_, &m_channelC1);
2300 m_channelC2 = Context::getSolverProperty<MFloat>(
"loglawC2", m_solverId, AT_, &m_channelC1);
2301 m_channelC3 = Context::getSolverProperty<MFloat>(
"loglawC3", m_solverId, AT_, &m_channelC1);
2302 m_channelC4 = Context::getSolverProperty<MFloat>(
"loglawC4", m_solverId, AT_, &m_channelC1);
2303 m_log <<
"============= Pipe flow activated =============" << endl;
2304 m_log <<
"-> pipeRadius: " << m_channelHeight << endl;
2305 m_log <<
"-> pipeLength: " << m_channelLength << endl;
2306 m_log <<
"-> pipeInflowPlaneCoordinate: " << m_channelInflowPlaneCoordinate << endl;
2307 m_log <<
"-> Log law properties: " << endl;
2308 m_log <<
"--> C1: " << m_channelC1 << endl;
2309 m_log <<
"--> C2: " << m_channelC2 << endl;
2310 m_log <<
"--> C3: " << m_channelC3 << endl;
2311 m_log <<
"--> C4: " << m_channelC4 << endl;
2312 m_log <<
"============= Pipe flow summary finished =============" << endl;
2334 m_referenceTemperature = 273.15;
2335 m_referenceTemperature =
2336 Context::getSolverProperty<MFloat>(
"referenceTemperature", m_solverId, AT_, &m_referenceTemperature);
2350 m_sutherlandConstant = 110.4;
2351 m_sutherlandConstant =
2352 Context::getSolverProperty<MFloat>(
"sutherlandConstant", m_solverId, AT_, &m_sutherlandConstant);
2353 m_sutherlandConstant /= m_referenceTemperature;
2354 m_sutherlandPlusOne = m_sutherlandConstant + F1;
2368 m_useSandpaperTrip =
false;
2370 m_useSandpaperTrip = Context::getSolverProperty<MBool>(
"tripSandpaper", m_solverId, AT_, &m_useSandpaperTrip);
2373 MString govEqs =
"NAVIER_STOKES";
2374 govEqs = Context::getSolverProperty<MString>(
"govEqs", m_solverId, AT_, &govEqs);
2395 m_fsc = Context::getSolverProperty<MInt>(
"fsc", m_solverId, AT_, &m_fsc);
2396 m_fsc = m_fsc ? 1 : 0;
2398 if(!
approx(m_angle[0], F0, MFloatEps))
2399 mTerm(1,
"angle[0] is not zero. Refer to the description of the fsc property");
2400 m_Re /=
cos(m_angle[1]);
2404 m_useBlasius =
false;
2405 m_useBlasius = Context::getSolverProperty<MBool>(
"useBlasius", m_solverId, AT_, &m_useBlasius);
2418 m_movingGridTimeOffset = F0;
2419 m_movingGridStepOffset = 0;
2420 m_movingGridInitialStart =
true;
2421 m_gridMovingMethod = 0;
2422 m_movingGrid =
false;
2425 m_travelingWave =
false;
2426 m_streamwiseTravelingWave =
false;
2427 m_waveTimeStepComputed =
false;
2429 m_waveBeginTransition = 0.0;
2430 m_waveEndTransition = 0.0;
2431 m_waveRestartFadeIn =
false;
2433 m_waveAmplitude = 0.0;
2435 m_waveCellsPerWaveLength = -1;
2436 m_waveNoStepsPerCell = -1;
2453 m_movingGrid = Context::getSolverProperty<MBool>(
"movingGrid", m_solverId, AT_, &m_movingGrid);
2458 m_mgExchangeCoordinates =
true;
2460 m_mgExchangeCoordinates =
2461 Context::getSolverProperty<MBool>(
"mgExchangeCoordinates", m_solverId, AT_, &m_mgExchangeCoordinates);
2477 m_gridMovingMethod = Context::getSolverProperty<MInt>(
"gridMovingMethod", m_solverId, AT_);
2493 m_wallVel = Context::getSolverProperty<MFloat>(
"wallVel", m_solverId, AT_);
2510 m_movingGridTimeOffset =
2511 Context::getSolverProperty<MFloat>(
"movingGridTimeOffset", m_solverId, AT_, &m_movingGridTimeOffset);
2528 m_movingGridSaveGrid = 0;
2530 m_movingGridSaveGrid =
2531 Context::getSolverProperty<MBool>(
"movingGridSaveGrid", m_solverId, AT_, &m_movingGridSaveGrid);
2549 m_synchronizedMGOutput =
false;
2550 m_synchronizedMGOutput =
2551 Context::getSolverProperty<MBool>(
"synchronizedMGOutput", m_solverId, AT_, &m_synchronizedMGOutput);
2553 m_log <<
"synchronizedMGOutput is activated? " << m_synchronizedMGOutput << endl;
2555 if(m_gridMovingMethod == 9 || m_gridMovingMethod == 10 || m_gridMovingMethod == 11 || m_gridMovingMethod == 13) {
2556 m_travelingWave =
true;
2557 m_constantTimeStep =
true;
2560 if(m_gridMovingMethod == 12 || m_gridMovingMethod == 15) {
2561 m_streamwiseTravelingWave =
true;
2562 m_constantTimeStep =
true;
2587 m_bodyForce =
false;
2589 m_bodyForce = Context::getSolverProperty<MBool>(
"bodyForce", m_solverId, AT_, &m_bodyForce);
2593 m_movingGridTimeOffset = F0;
2594 m_movingGridStepOffset = 0;
2595 m_movingGridInitialStart =
true;
2596 m_bodyForceMethod = 0;
2597 m_movingGridTimeOffset = F0;
2599 m_travelingWave =
false;
2600 m_waveTimeStepComputed =
false;
2602 m_waveBeginTransition = 0.0;
2603 m_waveEndTransition = 0.0;
2604 m_waveRestartFadeIn =
false;
2606 m_waveAmplitude = 0.0;
2608 m_waveCellsPerWaveLength = -1;
2609 m_waveNoStepsPerCell = -1;
2610 m_synchronizedMGOutput = 0;
2612 m_mgExchangeCoordinates =
true;
2614 m_mgExchangeCoordinates =
2615 Context::getSolverProperty<MBool>(
"mgExchangeCoordinates", m_solverId, AT_, &m_mgExchangeCoordinates);
2631 m_bodyForceMethod = Context::getSolverProperty<MInt>(
"bodyForceMethod", m_solverId, AT_);
2647 m_wavePenetrationHeight = Context::getSolverProperty<MFloat>(
"wavePenetrationHeight", m_solverId, AT_);
2664 m_movingGridTimeOffset =
2665 Context::getSolverProperty<MFloat>(
"movingGridTimeOffset", m_solverId, AT_, &m_movingGridTimeOffset);
2682 m_synchronizedMGOutput =
false;
2683 m_synchronizedMGOutput =
2684 Context::getSolverProperty<MBool>(
"synchronizedMGOutput", m_solverId, AT_, &m_synchronizedMGOutput);
2686 m_log <<
"synchronizedMGOutput is activated? " << m_synchronizedMGOutput << endl;
2689 if(m_bodyForceMethod == 10 || m_bodyForceMethod == 11) {
2690 m_travelingWave =
true;
2691 m_constantTimeStep =
true;
2718 m_constantTimeStep =
true;
2719 m_constantTimeStep = Context::getSolverProperty<MBool>(
"constantTimeStep", m_solverId, AT_, &m_constantTimeStep);
2734 m_localTimeStep =
false;
2735 m_localTimeStep = Context::getSolverProperty<MBool>(
"localTimeStep", m_solverId, AT_, &m_localTimeStep);
2750 m_timeStepComputationInterval = 1;
2751 if(!m_constantTimeStep) {
2752 m_timeStepComputationInterval = Context::getSolverProperty<MInt>(
"timeStepComputationInterval", m_solverId, AT_,
2753 &m_timeStepComputationInterval);
2769 m_noGhostLayers = Context::getSolverProperty<MInt>(
"noGhostLayers", m_solverId, AT_);
2786 m_cfl = Context::getSolverProperty<MFloat>(
"cfl", m_solverId, AT_);
2801 m_limiter = Context::getSolverProperty<MBool>(
"limiter", m_solverId, AT_, &m_limiter);
2816 m_limiterMethod =
"ALBADA";
2817 m_limiterMethod = Context::getSolverProperty<MString>(
"limiterMethod", m_solverId, AT_);
2833 m_limiterVisc =
false;
2834 m_limiterVisc = Context::getSolverProperty<MBool>(
"limiterVisc", m_solverId, AT_, &m_limiterVisc);
2837 ASSERT(nDim == 2,
"Only available in 2D by now!");
2838 m_CFLVISC = Context::getSolverProperty<MFloat>(
"cfl_visc", m_solverId, AT_);
2839 FQ->neededFQVariables[FQ->LIMITERVISC] = 1;
2840 FQ->outputFQVariables[FQ->LIMITERVISC] =
false;
2867 m_musclScheme =
"Standard";
2868 m_musclScheme = Context::getSolverProperty<MString>(
"musclScheme", m_solverId, AT_, &m_musclScheme);
2894 m_ausmScheme =
"Standard";
2895 m_ausmScheme = Context::getSolverProperty<MString>(
"ausmScheme", m_solverId, AT_, &m_ausmScheme);
2909 m_convergenceCriterion = 1e-12;
2910 m_convergenceCriterion =
2911 Context::getSolverProperty<MFloat>(
"convergenceCriterion", m_solverId, AT_, &m_convergenceCriterion);
2926 m_chi = Context::getSolverProperty<MFloat>(
"upwindCoefficient", m_solverId, AT_);
2940 m_viscCompact =
false;
2941 m_viscCompact = Context::getSolverProperty<MBool>(
"viscCompact", m_solverId, AT_, &m_viscCompact);
2967 m_porous = Context::getSolverProperty<MBool>(
"porous", m_solverId, AT_);
2970 if(!m_porous)
return;
2972 m_blockType =
"fluid";
2985 m_porousBlockIds.resize( m_grid->getNoBlocks(), -1);
2987 const MInt inputBoxID = m_grid->getMyBlockId();
2988 for(
MInt i = 0; i < noPorousSolvers; ++i) {
2989 const MInt porousSolver = Context::getSolverProperty<MInt>(
"porousSolvers", m_solverId, AT_, i);
2990 m_porousBlockIds[porousSolver] = i;
2991 if(inputBoxID == porousSolver) m_blockType =
"porous";
3002 FQ->neededFQVariables[FQ->POROSITY] = 1;
3003 FQ->outputFQVariables[FQ->POROSITY] =
false;
3005 if(m_blockType ==
"porous") {
3006 m_log <<
"Domain " << domainId()
3007 <<
" belongs to a " + m_blockType +
" solver. PorousId=" << m_porousBlockIds[inputBoxID]
3015 FQ->neededFQVariables[FQ->DARCY] = 1;
3016 FQ->outputFQVariables[FQ->DARCY] =
false;
3017 FQ->neededFQVariables[FQ->FORCH] = 1;
3018 FQ->outputFQVariables[FQ->FORCH] =
false;
3019 for(
MInt d = 0; d < nDim; ++d) {
3020 FQ->neededFQVariables[FQ->NORMAL[d]] = 1;
3021 FQ->outputFQVariables[FQ->NORMAL[d]] =
false;
3038 m_c_Dp = Context::getSolverProperty<MFloat>(
"c_Dp", m_solverId, AT_, &m_c_Dp);
3039 m_c_Dp_eps = Context::getSolverProperty<MFloat>(
"c_Dp_eps", m_solverId, AT_, &m_c_Dp_eps);
3040 m_c_wd = Context::getSolverProperty<MFloat>(
"c_wd", m_solverId, AT_, &m_c_wd);
3041 m_c_t = Context::getSolverProperty<MFloat>(
"c_t", m_solverId, AT_, &m_c_t);
3042 m_c_eps = Context::getSolverProperty<MFloat>(
"c_eps", m_solverId, AT_, &m_c_eps);
3045 if(m_blockType ==
"porous") {
3046 const MInt inputBoxID = m_grid->getMyBlockId();
3047 const MFloat por = Context::getSolverProperty<MFloat>(
"porosity", m_solverId, AT_,
3048 m_porousBlockIds[inputBoxID]);
3050 Context::getSolverProperty<MFloat>(
"Da", m_solverId, AT_, m_porousBlockIds[inputBoxID]);
3052 Context::getSolverProperty<MFloat>(
"cf", m_solverId, AT_, m_porousBlockIds[inputBoxID]);
3053 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
3054 m_cells->fq[FQ->POROSITY][cellId] = por;
3055 m_cells->fq[FQ->DARCY][cellId] = Da;
3056 m_cells->fq[FQ->FORCH][cellId] = cf;
3060 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
3061 m_cells->fq[FQ->POROSITY][cellId] = 1.0;
3062 m_cells->fq[FQ->DARCY][cellId] = std::numeric_limits<MFloat>::max();
3075 if(!m_isInitTimers) {
3076 TERMM(1,
"Timers were not initialized.");
3079 return m_timers[timerId];
3087 NEW_TIMER_GROUP_NOCREATE(m_timerGroup,
"Structured Solver");
3088 NEW_TIMER_NOCREATE(m_timers[Timers::Structured],
"total object lifetime", m_timerGroup);
3089 RECORD_TIMER_START(m_timers[Timers::Structured]);
3092 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Constructor],
"Constructor", m_timers[Timers::Structured]);
3093 RECORD_TIMER_START(m_timers[Timers::Constructor]);
3095 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::GridDecomposition],
"Grid Decomposition", m_timers[Timers::Constructor]);
3096 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::GridReading],
"Grid reading", m_timers[Timers::Constructor]);
3097 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::BuildUpSponge],
"Build up sponge", m_timers[Timers::Constructor]);
3098 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ComputeMetrics],
"Compute Metrics", m_timers[Timers::Constructor]);
3099 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ComputeJacobian],
"Compute Jacobian", m_timers[Timers::Constructor]);
3102 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::RunInit],
"Init", m_timers[Timers::Structured]);
3103 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::LoadRestart],
"Load restart", m_timers[Timers::RunInit]);
3104 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::LoadVariables],
"load restart variables", m_timers[Timers::LoadRestart]);
3105 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::LoadSponge],
"load sponge", m_timers[Timers::LoadRestart]);
3106 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::LoadSTG],
"load STG", m_timers[Timers::LoadRestart]);
3109 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Run],
"Run function", m_timers[Timers::Structured]);
3110 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MainLoop],
"Main loop", m_timers[Timers::Run]);
3111 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ConvectiveFlux],
"Convective Flux", m_timers[Timers::MainLoop]);
3112 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ViscousFlux],
"Viscous Flux", m_timers[Timers::MainLoop]);
3113 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGVolumeFlux],
"Volume Flux", m_timers[Timers::MainLoop]);
3114 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SandpaperTrip],
"Sandpaper tripping", m_timers[Timers::MainLoop]);
3116 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MovingGrid],
"Moving Grid", m_timers[Timers::MainLoop]);
3117 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGVolumeFlux],
"MG Volume Flux", m_timers[Timers::MovingGrid]);
3118 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGMoveGrid],
"MG Move Grid", m_timers[Timers::MovingGrid]);
3119 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGExchange],
"MG Exchange", m_timers[Timers::MGMoveGrid]);
3120 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGCellCenterCoordinates],
"MG Cell Center Coordinates",
3121 m_timers[Timers::MGMoveGrid]);
3122 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGMetrics],
"MG Metrics", m_timers[Timers::MGMoveGrid]);
3123 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGSurfaceMetrics],
"MG Surface Metrics", m_timers[Timers::MGMetrics]);
3124 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGCellMetrics],
"MG Cell Metrics", m_timers[Timers::MGMetrics]);
3125 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGCornerMetrics],
"MG Corner Metrics", m_timers[Timers::MGMetrics]);
3126 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGJacobian],
"MG Jacobian", m_timers[Timers::MGMoveGrid]);
3128 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MGSaveGrid],
"MG Save Grid", m_timers[Timers::MovingGrid]);
3130 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Exchange],
"Exchange", m_timers[Timers::MainLoop]);
3131 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Gather],
"Gather", m_timers[Timers::Exchange]);
3132 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Send],
"Send", m_timers[Timers::Exchange]);
3133 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SendWait],
"SendWait", m_timers[Timers::Exchange]);
3134 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Receive],
"Receive", m_timers[Timers::Exchange]);
3135 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ReceiveWait],
"ReceiveWait", m_timers[Timers::Exchange]);
3136 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Scatter],
"Scatter", m_timers[Timers::Exchange]);
3137 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Receive],
"Receive", m_timers[Timers::Exchange]);
3139 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::BoundaryCondition],
"Boundary Conditions", m_timers[Timers::MainLoop]);
3141 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::RungeKutta],
"RungeKutta", m_timers[Timers::MainLoop]);
3143 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SaveOutput],
"Save output", m_timers[Timers::Run]);
3144 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SaveSolution],
"Save solution", m_timers[Timers::SaveOutput]);
3145 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SaveForces],
"Save forces", m_timers[Timers::SaveOutput]);
3146 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SaveAuxdata],
"Save auxdata", m_timers[Timers::SaveOutput]);
3147 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SaveBoxes],
"Save boxes", m_timers[Timers::SaveOutput]);
3148 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SaveIntpPoints],
"Save lines", m_timers[Timers::SaveOutput]);
3151 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SetTimeStep],
"Set Time Step", m_timers[Timers::MainLoop]);
3152 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::UpdateSponge],
"Update sponge", m_timers[Timers::MainLoop]);
3155 m_isInitTimers =
true;
3161 mAlloc(m_channelRoots, 4,
"m_channelRoots", -1, AT_);
3164 mAlloc(m_commPerRotRoots, 4,
"m_commPerRotRoots", -1, AT_);
3170 mAlloc(m_commZonal, m_noBlocks,
"m_commZonal", AT_);
3171 mAlloc(m_commZonalRoot, m_noBlocks,
"m_commZonalRoot", -1, AT_);
3172 mAlloc(m_commZonalRootGlobal, m_noBlocks,
"m_commZonalRoot", -1, AT_);
3174 m_commZonalMyRank = -1;
3175 m_zonalRootRank =
false;
3179 for(
MInt i = 0; i < m_noBlocks; i++) {
3180 MPI_Group groupZonal, newGroupZonal;
3181 vector<MInt> tmpPartitions;
3182 MInt blockDomainId = 0;
3183 MInt hasBlockDomain = 0;
3184 MInt hasBlockDomainGlobal = 0;
3186 MIntScratchSpace nblockDomainOffset(noDomains(), AT_,
"nblockDomainOffset");
3187 if(m_blockId == i) {
3188 blockDomainId = domainId();
3191 MPI_Allreduce(&hasBlockDomain, &hasBlockDomainGlobal, 1, MPI_INT, MPI_SUM, m_StructuredComm, AT_,
3192 "hasBlockDomain",
"hasBlockDomainGlobal");
3193 MPI_Allgather(&hasBlockDomain, 1, MPI_INT, &nblockDomainArray[0], 1, MPI_INT, m_StructuredComm, AT_,
3194 "hasBlockDomain",
"nblockDomainArray[0]");
3195 nblockDomainOffset[0] = 0;
3196 for(
MInt j = 1; j < noDomains(); j++) {
3197 nblockDomainOffset[j] = nblockDomainOffset[j - 1] + nblockDomainArray[j - 1];
3200 MPI_Allgatherv(&blockDomainId, nblockDomainArray[domainId()], MPI_INT, &zonalRanks[0], &nblockDomainArray[0],
3201 &nblockDomainOffset[0], MPI_INT, m_StructuredComm, AT_,
"blockDomainId",
"zonalRanks[0]");
3204 MInt zonalcommsize = hasBlockDomainGlobal;
3206 MPI_Comm_group(m_StructuredComm, &groupZonal, AT_,
"groupZonal");
3207 MPI_Group_incl(groupZonal, zonalcommsize, &zonalRanks[0], &newGroupZonal, AT_);
3208 MPI_Comm_create(m_StructuredComm, newGroupZonal, &m_commZonal[i], AT_,
"m_commZonal[i]");
3210 if(domainId() == zonalRanks[0]) {
3211 MPI_Comm_rank(m_commZonal[i], &m_commZonalRoot[i]);
3212 MPI_Comm_rank(m_StructuredComm, &m_commZonalRootGlobal[i]);
3213 m_zonalRootRank =
true;
3216 MPI_Bcast(&m_commZonalRoot[0], m_noBlocks, MPI_INT, zonalRanks[0], m_StructuredComm, AT_,
"m_commZonalRoot[0]");
3217 MPI_Bcast(&m_commZonalRootGlobal[0], m_noBlocks, MPI_INT, zonalRanks[0], m_StructuredComm, AT_,
3218 "m_commZonalRootGlobal[0]");
3251 MInt auxDataType = 0;
3252 auxDataType = Context::getSolverProperty<MInt>(
"auxDataType", m_solverId, AT_, &auxDataType);
3254 std::vector<MInt> auxDataWindowIds;
3255 if(auxDataType == 3) {
3257 mTerm(1,
"auxDataType==3 requires the property 'auxDataWindowIds'!");
3259 auxDataWindowIds.resize(noAuxDataWindowIds);
3260 for(
MInt i = 0; i < noAuxDataWindowIds; ++i) {
3261 auxDataWindowIds[i] =
3262 Context::getSolverProperty<MInt>(
"auxDataWindowIds", m_solverId, AT_, &auxDataWindowIds[i], i);
3270 MBool force =
false;
3273 m_windowInfo->createAuxDataMap(auxDataType, m_blockType, m_porousBlockIds, auxDataWindowIds, force);
3282 m_spongeLayerThickness =
nullptr;
3283 m_betaSponge =
nullptr;
3284 m_sigmaSponge =
nullptr;
3285 m_noSpongeDomainInfos = 0;
3286 m_spongeLayerType = 1;
3287 m_targetDensityFactor = F0;
3288 m_computeSpongeFactor =
true;
3289 MBool readSpongeFromBc =
true;
3303 m_useSponge =
false;
3304 m_useSponge = Context::getSolverProperty<MBool>(
"useSponge", m_solverId, AT_, &m_useSponge);
3307 FQ->neededFQVariables[FQ->SPONGE_FACTOR] = 1;
3323 readSpongeFromBc = Context::getSolverProperty<MBool>(
"readSpongeFromBC", m_solverId, AT_, &readSpongeFromBc);
3326 if(readSpongeFromBc) {
3356 m_noSpongeDomainInfos = noSpongeIds;
3371 m_spongeLayerType = Context::getSolverProperty<MInt>(
"spongeLayerType", m_solverId, AT_, &m_spongeLayerType);
3378 if(m_noSpongeDomainInfos != noSpongeBeta || m_noSpongeDomainInfos != noSpongeSigma) {
3379 mTerm(1, AT_,
"The number of sponge properties does not match");
3383 mAlloc(m_spongeLayerThickness, m_noSpongeDomainInfos,
"m_spongeLayerThicknesses", F0, AT_);
3384 mAlloc(m_sigmaSponge, m_noSpongeDomainInfos,
"m_sigmaSponge", AT_);
3385 mAlloc(m_betaSponge, m_noSpongeDomainInfos,
"m_betaSponge", AT_);
3386 mAlloc(m_spongeBcWindowInfo, m_noSpongeDomainInfos,
"m_spongeBcWindowInfo", AT_);
3389 for(
MInt i = 0; i < m_noSpongeDomainInfos; ++i) {
3404 m_spongeLayerThickness[i] = -1.0;
3405 m_spongeLayerThickness[i] =
3406 Context::getSolverProperty<MFloat>(
"spongeLayerThickness", m_solverId, AT_, &m_spongeLayerThickness[i], i);
3420 m_betaSponge[i] = F0;
3422 Context::getSolverProperty<MFloat>(
"betaSponge", m_solverId, AT_, &m_spongeLayerThickness[i], i);
3436 m_sigmaSponge[i] = F0;
3438 Context::getSolverProperty<MFloat>(
"sigmaSponge", m_solverId, AT_, &m_spongeLayerThickness[i], i);
3442 if(readSpongeFromBc) {
3443 for(
MInt i = 0; i < m_noSpongeDomainInfos; ++i) {
3444 m_spongeBcWindowInfo[i] = -1;
3445 m_spongeBcWindowInfo[i] =
3446 Context::getSolverProperty<MInt>(
"spongeBndryCndIds", m_solverId, AT_, &m_spongeBcWindowInfo[i], i);
3449 for(
MInt i = 0; i < m_noSpongeDomainInfos; ++i) {
3450 m_spongeBcWindowInfo[i] = -1;
3451 m_spongeBcWindowInfo[i] =
3452 Context::getSolverProperty<MInt>(
"spongeWindowIds", m_solverId, AT_, &m_spongeBcWindowInfo[i], i);
3474 m_targetDensityFactor = F1;
3475 m_targetDensityFactor =
3476 Context::getSolverProperty<MFloat>(
"targetDensityFactor", m_solverId, AT_, &m_targetDensityFactor);
3478 m_windowInfo->setSpongeInformation(m_noSpongeDomainInfos, m_betaSponge, m_sigmaSponge, m_spongeLayerThickness,
3479 m_spongeBcWindowInfo, readSpongeFromBc);
3495 m_computeSpongeFactor =
true;
3497 m_computeSpongeFactor =
3498 Context::getSolverProperty<MBool>(
"computeSpongeFactor", m_solverId, AT_, &m_computeSpongeFactor);
3504 if(m_spongeLayerType == 2) {
3506 FQ->neededFQVariables[FQ->SPONGE_RHO] = 1;
3507 FQ->neededFQVariables[FQ->SPONGE_RHO_E] = 1;
3510 if(m_spongeLayerType == 4) {
3512 FQ->neededFQVariables[FQ->SPONGE_RHO] = 1;
3541 m_noRKSteps = Context::getSolverProperty<MInt>(
"noRKSteps", m_solverId, AT_, &m_noRKSteps);
3544 mAlloc(m_RKalpha, m_noRKSteps,
"m_RKalpha", -F1, AT_);
3558 if(m_noRKSteps == 5) {
3559 MFloat RK5DefaultCoeffs[5] = {0.25, 0.16666666666, 0.375, 0.5, 1.};
3560 for(
MInt i = 0; i < m_noRKSteps; i++) {
3562 Context::getSolverProperty<MFloat>(
"rkalpha-step", m_solverId, AT_, (
MFloat*)&RK5DefaultCoeffs[i], i);
3566 if(m_noRKSteps == 1) m_RKalpha[0] = 1.0;
3573 MFloat RK5DefaultCoeffs[5] = {0.059, 0.14, 0.273, 0.5, 1.0};
3574 for(
MInt i = 0; i < m_noRKSteps; i++) {
3576 Context::getSolverProperty<MFloat>(
"rkalpha-step-rans", m_solverId, AT_, &RK5DefaultCoeffs[i], i);
3594 m_rungeKuttaOrder = 2;
3595 m_rungeKuttaOrder = Context::getSolverProperty<MInt>(
"rungeKuttaOrder", m_solverId, AT_, &m_rungeKuttaOrder);
3602 setRungeKuttaProperties();
3606 m_physicalTime = F0;
3610 m_physicalTime = -1.0;
3617 if(
approx(m_time, F0, m_eps)) {
3619 m_workloadIncrement = 1;
3620 m_firstMaxResidual = F0;
3621 m_firstAvrgResidual = F0;
3629 m_stgIsActive =
false;
3630 m_stgInitialStartup =
false;
3633 IF_CONSTEXPR(nDim < 3) {
return; }
3647 m_stgIsActive =
false;
3649 m_stgIsActive = Context::getSolverProperty<MBool>(
"useSTG", m_solverId, AT_, &m_stgIsActive);
3654 m_stgIsActive =
true;
3659 m_stgRootRank =
false;
3661 for(
MInt i = 0; i < abs((
MInt)m_windowInfo->physicalBCMap.size()); ++i) {
3662 if(m_windowInfo->physicalBCMap[i]->BC == 7909) {
3664 m_stgFace = m_windowInfo->physicalBCMap[i]->face;
3670 MPI_Comm_rank(m_commStg, &m_commStgMyRank);
3672 m_commStgMyRank = -1;
3688 m_stgSubSup =
false;
3690 m_stgSubSup = Context::getSolverProperty<MBool>(
"stgSubSup", m_solverId, AT_, &m_stgSubSup);
3705 m_stgSupersonic =
false;
3707 m_stgSupersonic = Context::getSolverProperty<MBool>(
"stgSupersonic", m_solverId, AT_, &m_stgSupersonic);
3709 if(m_stgSupersonic && m_stgSubSup) {
3710 m_stgSubSup =
false;
3711 if(domainId() == 0) {
3712 cout <<
"WARNING: You activated conflicting properties stgSubSup "
3713 <<
"and stgSupersonic, thus only the pure supersonic formulation will be used. "
3714 <<
"Switch off stgSupersonic to get the mixed formulation" << endl;
3734 m_stgBLT1 = Context::getSolverProperty<MFloat>(
"BLT1", m_solverId, AT_, &m_stgBLT1);
3751 m_stgBLT2 = Context::getSolverProperty<MFloat>(
"BLT2", m_solverId, AT_, &m_stgBLT2);
3768 m_stgBLT3 = Context::getSolverProperty<MFloat>(
"BLT3", m_solverId, AT_, &m_stgBLT3);
3782 m_stgDelta99Inflow = -1.0;
3783 m_stgDelta99Inflow = Context::getSolverProperty<MFloat>(
"deltaIn", m_solverId, AT_, &m_stgDelta99Inflow);
3785 m_stgBLT1 = m_stgBLT1 * m_stgDelta99Inflow;
3786 m_stgBLT2 = m_stgBLT2 * m_stgDelta99Inflow;
3788 mAlloc(m_stgLengthFactors, 3,
"m_solver->m_stgLengthFactors", F0, AT_);
3789 m_stgLengthFactors[0] = 1.0;
3790 m_stgLengthFactors[1] = 0.6;
3791 m_stgLengthFactors[2] = 1.5;
3809 for(
MInt i = 0; i < 3; i++) {
3810 m_stgLengthFactors[i] =
3811 Context::getSolverProperty<MFloat>(
"stgLengthFactors", m_solverId, AT_, &m_stgLengthFactors[i], i);
3815 mAlloc(m_stgRSTFactors, 3,
"m_solver->m_stgRSTFactors", F0, AT_);
3816 m_stgRSTFactors[0] = 0.7;
3817 m_stgRSTFactors[1] = 0.4;
3818 m_stgRSTFactors[2] = 0.5;
3836 for(
MInt i = 0; i < 3; i++) {
3837 m_stgRSTFactors[i] =
3838 Context::getSolverProperty<MFloat>(
"stgRSTFactors", m_solverId, AT_, &m_stgRSTFactors[i], i);
3855 m_stgMaxNoEddies = 200;
3856 m_stgMaxNoEddies = Context::getSolverProperty<MInt>(
"stgMaxNoEddies", m_solverId, AT_, &m_stgMaxNoEddies);
3871 m_stgExple = Context::getSolverProperty<MFloat>(
"stgExple", m_solverId, AT_, &m_stgExple);
3886 m_stgEddieDistribution = 1.0;
3888 m_stgEddieDistribution =
3889 Context::getSolverProperty<MFloat>(
"stgEddieDistribution", m_solverId, AT_, &m_stgEddieDistribution);
3905 m_stgCreateNewEddies =
false;
3907 m_stgCreateNewEddies =
3908 Context::getSolverProperty<MBool>(
"stgCreateNewEddies", m_solverId, AT_, &m_stgCreateNewEddies);
3923 m_stgInitialStartup =
false;
3924 m_stgInitialStartup = Context::getSolverProperty<MBool>(
"stgInitialStartup", m_solverId, AT_, &m_stgInitialStartup);
3938 m_stgEddieLengthScales =
false;
3940 m_stgEddieLengthScales =
3941 Context::getSolverProperty<MBool>(
"stgEddieLengthScales", m_solverId, AT_, &m_stgEddieLengthScales);
3956 m_stgShapeFunction = 4;
3958 m_stgShapeFunction = Context::getSolverProperty<MInt>(
"stgShapeFunction", m_solverId, AT_, &m_stgShapeFunction);
3961 if(m_stgInitialStartup) {
3963 FQ->neededFQVariables[FQ->NU_T] = 1;
3966 m_stgNoEddieProperties = 6;
3967 if(m_stgEddieLengthScales) {
3968 m_stgNoEddieProperties = 9;
3970 mAlloc(m_stgEddies, m_stgMaxNoEddies, m_stgNoEddieProperties,
"m_solver->m_stgEddies", -F1, AT_);
3972 m_stgNoVariables = 20;
3973 MInt noSTGCells = m_nCells[0] * m_nCells[1] * 3;
3974 mAlloc(m_cells->stg_fq, m_stgNoVariables, noSTGCells,
"m_cells->stg_fq", F0, AT_);
3976 m_stgBoxSize[0] = 0;
3977 m_stgBoxSize[1] = 0;
3978 m_stgBoxSize[2] = 0;
3980 m_log <<
"===========================================================" << endl
3981 <<
" STG PROPERTIES " << endl
3982 <<
"===========================================================" << endl
3983 <<
"Initial Start: " << m_stgInitialStartup << endl
3984 <<
"SubSup (Mixed subsonic/supersonic bc): " << m_stgSubSup << endl
3985 <<
"Supersonic BC: " << m_stgSupersonic << endl
3986 <<
"BLT 1,2,3: " << m_stgBLT1 <<
", " << m_stgBLT2 <<
", " << m_stgBLT3 << endl
3987 <<
"Delta0 inflow: " << m_stgDelta99Inflow << endl
3988 <<
"Length factors: " << m_stgLengthFactors[0] <<
", " << m_stgLengthFactors[1] <<
", "
3989 << m_stgLengthFactors[2] << endl
3990 <<
"Number of eddies: " << m_stgMaxNoEddies << endl
3991 <<
"Length scale exponent: " << m_stgExple << endl
3992 <<
"Eddie distribution: " << m_stgEddieDistribution << endl
3993 <<
"Create new eddies: " << m_stgCreateNewEddies << endl
3994 <<
"Eddie lengthscales: " << m_stgEddieLengthScales << endl
3995 <<
"Shape function: " << m_stgShapeFunction << endl
3996 <<
"Number of eddie properties: " << m_stgNoEddieProperties << endl
3997 <<
"Number of stg variables: " << m_stgNoVariables << endl
3998 <<
"===========================================================" << endl;
4003 m_stgBoxSize[0] = m_nCells[0];
4004 m_stgBoxSize[1] = m_nCells[1];
4005 m_stgBoxSize[2] = 3;
4008 mTerm(1, AT_,
"STG Method is not prepared for faces different than 0 or 1!");
4021 m_bc2600IsActive =
false;
4023 m_bc2600RootRank = -1;
4024 for(
MInt i = 0; i < abs((
MInt)m_windowInfo->globalStructuredBndryCndMaps.size()); ++i) {
4025 if(m_windowInfo->globalStructuredBndryCndMaps[i]->BC == 2600) {
4026 m_bc2600IsActive =
true;
4031 if(m_bc2600IsActive) {
4033 MInt localRank = 9999999;
4034 for(
MInt i = 0; i < abs((
MInt)m_windowInfo->physicalBCMap.size()); ++i) {
4035 if(m_windowInfo->physicalBCMap[i]->BC == 2600) {
4037 m_bc2600Face = m_windowInfo->physicalBCMap[i]->face;
4038 localRank = domainId();
4043 MPI_Allreduce(&localRank, &m_bc2600RootRank, 1, MPI_INT, MPI_MIN, m_StructuredComm, AT_,
"localRank",
4044 "m_bc2600RootRank");
4047 MPI_Comm_rank(m_commBC2600, &m_commBC2600MyRank);
4049 m_commBC2600MyRank = -1;
4065 m_bc2600InitialStartup =
false;
4066 m_bc2600InitialStartup =
4067 Context::getSolverProperty<MBool>(
"initialStartup2600", m_solverId, AT_, &m_bc2600InitialStartup);
4069 mAlloc(m_bc2600noCells, nDim,
"m_bc2600noCells", 0, AT_);
4070 mAlloc(m_bc2600noActiveCells, nDim,
"m_bc2600noCells", 0, AT_);
4071 mAlloc(m_bc2600noOffsetCells, nDim,
"m_bc2600noCells", 0, AT_);
4073 for(
MInt dim = 0; dim < nDim; dim++) {
4074 m_bc2600noOffsetCells[dim] = m_nOffsetCells[dim];
4075 m_bc2600noCells[dim] = m_nCells[dim];
4076 m_bc2600noActiveCells[dim] = m_bc2600noCells[dim] - 2 * m_noGhostLayers;
4078 m_bc2600noOffsetCells[nDim - 1] = 0;
4079 m_bc2600noCells[nDim - 1] = m_noGhostLayers;
4080 m_bc2600noActiveCells[nDim - 1] = m_noGhostLayers;
4082 for(
MInt dim = 0; dim < nDim; dim++) {
4083 noCellsBC *= m_bc2600noCells[dim];
4085 mAlloc(m_bc2600Variables, m_maxNoVariables, noCellsBC,
"m_bc2600Variables", -123.456, AT_);
4092 m_bc2601IsActive =
false;
4094 for(
MInt i = 0; i < abs((
MInt)m_windowInfo->globalStructuredBndryCndMaps.size()); ++i) {
4095 if(m_windowInfo->globalStructuredBndryCndMaps[i]->BC == 2601) {
4096 m_bc2601IsActive =
true;
4100 if(m_bc2601IsActive) {
4114 m_bc2601InitialStartup =
false;
4115 m_bc2601InitialStartup =
4116 Context::getSolverProperty<MBool>(
"initialStartup2601", m_solverId, AT_, &m_bc2601InitialStartup);
4126 m_bc2601GammaEpsilon = 0.12;
4127 m_bc2601GammaEpsilon =
4128 Context::getSolverProperty<MFloat>(
"gammaEpsilon2601", m_solverId, AT_, &m_bc2601GammaEpsilon);
4130 mAlloc(m_bc2601noCells, nDim,
"m_bc2601noCells", 0, AT_);
4131 mAlloc(m_bc2601noActiveCells, nDim,
"m_bc2601noCells", 0, AT_);
4132 mAlloc(m_bc2601noOffsetCells, nDim,
"m_bc2601noCells", 0, AT_);
4134 for(
MInt dim = 0; dim < nDim; dim++) {
4135 m_bc2601noOffsetCells[dim] = m_nOffsetCells[dim];
4136 m_bc2601noCells[dim] = m_nCells[dim];
4137 m_bc2601noActiveCells[dim] = m_bc2601noCells[dim] - 2 * m_noGhostLayers;
4139 m_bc2601noOffsetCells[nDim - 2] = 0;
4140 m_bc2601noCells[nDim - 2] = m_noGhostLayers;
4141 m_bc2601noActiveCells[nDim - 2] = m_noGhostLayers;
4143 for(
MInt dim = 0; dim < nDim; dim++) {
4144 noCellsBC *= m_bc2601noCells[dim];
4146 mAlloc(m_bc2601Variables, CV->noVariables, noCellsBC,
"m_bc2601Variables", -123.456, AT_);
4159 MBool fullRANS =
false;
4177 m_zonal = Context::getSolverProperty<MBool>(
"zonal", m_solverId, AT_);
4193 fullRANS = Context::getSolverProperty<MBool>(
"fullRANS", m_solverId, AT_, &fullRANS);
4198 FQ->neededFQVariables[FQ->AVG_RHO] = 1;
4199 FQ->neededFQVariables[FQ->AVG_U] = 1;
4200 FQ->neededFQVariables[FQ->AVG_V] = 1;
4201 FQ->neededFQVariables[FQ->AVG_W] = 1;
4202 FQ->neededFQVariables[FQ->AVG_P] = 1;
4204 m_zonalExchangeInterval = 5;
4205 m_zonalExchangeInterval =
4206 Context::getSolverProperty<MInt>(
"zonalExchangeInterval", m_solverId, AT_, &m_zonalExchangeInterval);
4208 m_zonalAveragingFactor = 128.0;
4209 m_zonalAveragingFactor =
4210 Context::getSolverProperty<MFloat>(
"zonalAvgFactor", m_solverId, AT_, &m_zonalAveragingFactor);
4225 MInt noRansZones = 0;
4226 noRansZones = Context::getSolverProperty<MInt>(
"noRansZones", m_solverId, AT_, &noRansZones);
4242 for(
MInt RANS = 0; RANS < noRansZones; RANS++) {
4243 ransZones[RANS] = Context::getSolverProperty<MInt>(
"ransZone", m_solverId, AT_, &ransZones[RANS], RANS);
4247 for(
MInt RANS = 0; RANS < noRansZones; RANS++) {
4248 MInt blockID = m_grid->getMyBlockId();
4249 if(blockID == ransZones[RANS]) {
4250 m_zoneType =
"RANS";
4256 MInt NOZONES[2] = {0, 0};
4257 MInt NOZONESH[2] = {0, 0};
4259 if(m_zoneType ==
"RANS") {
4267 MPI_Allreduce(NOZONES, NOZONESH, 2, MPI_INT, MPI_SUM, m_StructuredComm, AT_,
"NOZONES",
"NOZONESH");
4270 if(domainId() == 0) {
4271 cout <<
"////////////////////////////////////////////////////////////////////////" << endl;
4272 cout <<
"No of RANS partitions: " << NOZONESH[0] <<
" , No of LES partitions: " << NOZONESH[1] << endl;
4273 cout <<
"////////////////////////////////////////////////////////////////////////" << endl;
4275 m_log <<
"No of RANS partitions: " << NOZONESH[0] <<
" , No of LES partitions: " << NOZONESH[1] << endl;
4279 m_log <<
"Starting a full RANS computation" << endl;
4280 m_zoneType =
"RANS";
4284 if(m_zonal || m_rans) {
4286 static_cast<RansMethod>(
string2enum(Context::getSolverProperty<MString>(
"ransMethod", m_solverId, AT_)));
4290 mTerm(1,
"Usage of 2-eq. RANS model requires specification of rans2eq_mode: {init|production}");
4291 m_rans2eq_mode = Context::getSolverProperty<MString>(
"rans2eq_mode", m_solverId, AT_, &m_rans2eq_mode);
4292 if(m_rans2eq_mode !=
"init" && m_rans2eq_mode !=
"production")
mTerm(1,
"OMG! OMG!");
4296 mTerm(1,
"Porous RANS computation is only supported by k-epsilon model!");
4300 m_keps_nonDimType =
true;
4301 m_keps_nonDimType = Context::getSolverProperty<MBool>(
"keps_nonDimType", m_solverId, AT_, &m_keps_nonDimType);
4305 mTerm(1,
"Usage of k-epsilon model requires specification of inflow turbulenceIntensity");
4306 m_I = Context::getSolverProperty<MFloat>(
"turbulenceIntensity", m_solverId, AT_, &m_I);
4312 if(turbLengthScaleExists + turbViscRatioExists + turbEpsInfty != 1)
4313 mTerm(1,
"Usage of k-epsilon model requires the specification of either a turbulentLengthScale or a "
4314 "turbulentViscosityRatio");
4316 if(turbLengthScaleExists) {
4318 m_epsScale = Context::getSolverProperty<MFloat>(
"turbulentLengthScale", m_solverId, AT_);
4319 }
else if(turbViscRatioExists) {
4322 m_epsScale = Context::getSolverProperty<MFloat>(
"turbulentViscosityRatio", m_solverId, AT_);
4325 m_epsScale = Context::getSolverProperty<MFloat>(
"turbEpsInfty", m_solverId, AT_);
4329 FQ->neededFQVariables[FQ->POROUS_INDICATOR] = 1;
4330 FQ->outputFQVariables[FQ->POROUS_INDICATOR] =
false;
4334 FQ->neededFQVariables[FQ->NU_T] = 1;
4335 FQ->outputFQVariables[FQ->NU_T] =
true;
4338 FQ->neededFQVariables[FQ->UTAU] = 1;
4339 FQ->outputFQVariables[FQ->UTAU] =
false;
4341 FQ->neededFQVariables[FQ->UTAU2] = 1;
4342 FQ->outputFQVariables[FQ->UTAU2] =
false;
4347 FQ->neededFQVariables[FQ->WALLDISTANCE] = 1;
4348 FQ->outputFQVariables[FQ->WALLDISTANCE] =
false;
4353 m_ransTransPos = -1000000.0;
4355 m_ransTransPos = Context::getSolverProperty<MFloat>(
"ransTransPos", m_solverId, AT_, &m_ransTransPos);
4364 if(m_zoneType ==
"RANS") {
4368 CV = make_unique<MConservativeVariables<nDim>>(m_noSpecies, m_noRansEquations);
4369 PV = make_unique<MPrimitiveVariables<nDim>>(m_noSpecies, m_noRansEquations);
4372 m_noRansEquations = 0;
4373 CV = make_unique<MConservativeVariables<nDim>>(m_noSpecies);
4374 PV = make_unique<MPrimitiveVariables<nDim>>(m_noSpecies);
4380 m_maxNoVariables = -1;
4381 MPI_Allreduce(&PV->noVariables, &m_maxNoVariables, 1, MPI_INT, MPI_MAX, m_StructuredComm, AT_,
"PV->noVariables",
4382 "m_maxNoVariables");
4383 m_log <<
"Max number of variables: " << m_maxNoVariables << endl;
4395 const MInt noVars = CV->noVariables;
4396 for(
MInt cellId = 0; cellId < m_noCells; cellId++) {
4397 for(
MInt varId = 0; varId < noVars; varId++) {
4398 m_cells->rightHandSide[varId][cellId] = F0;
4414template <MFloat (FvStructuredSolver<nDim>::*totalEnergy_func)(MInt) const>
4416 m_log <<
"we got into the general formulation but should be in the other one" << endl;
4417 const MFloat FgammaMinusOne = F1 / (m_gamma - 1.0);
4418 MFloat**
const RESTRICT cvars = m_cells->variables;
4419 MFloat**
const RESTRICT pvars = m_cells->pvariables;
4420 MFloat rhoVelocity[3] = {0.0, 0.0, 0.0};
4422 for(
MInt cellId = 0; cellId < m_noCells; cellId++) {
4425 const MFloat rho = pvars[PV->RHO][cellId];
4427 for(
MInt i = 0; i < nDim; i++) {
4428 rhoVelocity[i] = pvars[PV->VV[i]][cellId] * rho;
4429 velPOW2 +=
POW2(pvars[PV->VV[i]][cellId]);
4433 cvars[CV->RHO][cellId] = rho;
4434 for(
MInt i = 0; i < nDim; i++) {
4435 cvars[CV->RHO_VV[i]][cellId] = rhoVelocity[i];
4438 cvars[CV->RHO_E][cellId] =
4439 pvars[PV->P][cellId] * FgammaMinusOne + F1B2 * rho * velPOW2 + (this->*totalEnergy_func)(cellId);
4442 for(
MInt ransVar = 0; ransVar < m_noRansEquations; ransVar++) {
4445 cvars[CV->RANS_VAR[ransVar]][cellId] = pvars[PV->RANS_VAR[ransVar]][cellId] * rho;
4449 for(
MInt s = 0; s < m_noSpecies; s++) {
4450 cvars[CV->RHO_Y[s]][cellId] = pvars[PV->Y[s]][cellId] * rho;
4458 if(m_rans2eq_mode ==
"production")
4459 computeConservativeVariables_<&FvStructuredSolver::totalEnergy_twoEqRans>();
4461 computeConservativeVariables_();
4463 computeConservativeVariables_();
4469 m_cells->pvariables[varId][cellId] = var;
4477 switch(m_volumeForceMethod) {
4483 if(
globalTimeStep % m_volumeForceUpdateInterval == 0 && m_RKStep == 0) {
4484 const MFloat relaxationFactor = 0.02;
4485 MPI_Allreduce(MPI_IN_PLACE, &m_inflowVelAvg, 1, MPI_DOUBLE, MPI_MAX, m_StructuredComm, AT_,
"MPI_IN_PLACE",
4488 <<
": inflowVelAvg(targetVelAvg)=" << m_inflowVelAvg <<
"(" << PV->UInfinity
4489 <<
"), volumeForce=" << m_volumeForce[0] <<
" -> ";
4490 const MFloat deltaVelAvg = PV->UInfinity - m_inflowVelAvg;
4491 m_volumeForce[0] += deltaVelAvg / (m_volumeForceUpdateInterval * m_timeStep) * relaxationFactor;
4492 m_volumeForce[0] = std::max(m_volumeForce[0], 0.0);
4493 m_log << setprecision(6) << m_volumeForce[0] << endl;
4494 m_inflowVelAvg = -1.0;
4498 mTerm(1,
"Unknown volume force method!");
4507 for(
MInt dim = 0; dim < nDim; dim++) {
4508 for(
MInt cellId = 0; cellId < m_noCells; cellId++) {
4509 m_cells->rightHandSide[CV->RHO_VV[dim]][cellId] +=
4510 m_cells->variables[CV->RHO][cellId] * m_volumeForce[dim] * m_cells->cellJac[cellId];
4511 m_cells->rightHandSide[CV->RHO_E][cellId] +=
4512 m_cells->variables[CV->RHO_VV[dim]][cellId] * m_volumeForce[dim] * m_cells->cellJac[cellId];
4528 constexpr MInt nDim = 3;
4532 stringstream filename;
4533 filename << m_boxOutputDir <<
"boxOutput" << m_outputIterationNumber << m_outputFormat;
4537 writeHeaderAttributes(&pio,
"boxes");
4538 writePropertiesAsAttributes(&pio,
"");
4539 pio.setAttribute(m_boxNoBoxes,
"noBoxes",
"");
4542 ParallelIo::size_type localBoxSize[nDim]{0};
4543 ParallelIo::size_type localBoxOffset[nDim]{0};
4544 ParallelIo::size_type globalBoxSize[nDim]{0};
4545 ParallelIo::size_type localDomainBoxOffset[nDim]{0};
4547 for(
MInt i = 0; i < m_noBlocks; ++i) {
4548 for(
MInt b = 0;
b < m_boxNoBoxes; ++
b) {
4549 if(m_boxBlock[
b] == i) {
4552 for(
MInt dim = 0; dim < nDim; ++dim) {
4553 globalBoxSize[dim] = m_boxSize[
b][dim];
4556 stringstream pathName;
4557 pathName <<
"/box" <<
b;
4559 pio.setAttribute(m_boxOffset[
b][2],
"offseti", pathName.str());
4560 pio.setAttribute(m_boxOffset[
b][1],
"offsetj", pathName.str());
4561 pio.setAttribute(m_boxOffset[
b][0],
"offsetk", pathName.str());
4563 pio.setAttribute(m_boxSize[
b][2],
"sizei", pathName.str());
4564 pio.setAttribute(m_boxSize[
b][1],
"sizej", pathName.str());
4565 pio.setAttribute(m_boxSize[
b][0],
"sizek", pathName.str());
4567 pio.setAttribute(i,
"blockId", pathName.str());
4569 MInt hasCoordinates = 0;
4571 for(
MInt v = 0; v < m_maxNoVariables; v++) {
4575 for(
MInt v = 0; v < FQ->noFQVariables; v++) {
4576 if(FQ->fqWriteOutputBoxes[v]) {
4581 if(m_boxWriteCoordinates) {
4588 pio.setAttribute(hasCoordinates,
"hasCoordinates", pathName.str());
4593 for(
MInt b = 0;
b < m_boxNoBoxes; ++
b) {
4595 if(m_boxBlock[
b] == m_blockId
4596 && ((m_nOffsetCells[2] <= m_boxOffset[
b][2] && m_boxOffset[
b][2] < m_nOffsetCells[2] + m_nActiveCells[2])
4597 || (m_boxOffset[
b][2] <= m_nOffsetCells[2] && m_nOffsetCells[2] < m_boxOffset[
b][2] + m_boxSize[
b][2]))
4598 && ((m_nOffsetCells[1] <= m_boxOffset[
b][1] && m_boxOffset[
b][1] < m_nOffsetCells[1] + m_nActiveCells[1])
4599 || (m_boxOffset[
b][1] <= m_nOffsetCells[1] && m_nOffsetCells[1] < m_boxOffset[
b][1] + m_boxSize[
b][1]))
4600 && ((m_nOffsetCells[0] <= m_boxOffset[
b][0] && m_boxOffset[
b][0] < m_nOffsetCells[0] + m_nActiveCells[0])
4601 || (m_boxOffset[
b][0] <= m_nOffsetCells[0]
4602 && m_nOffsetCells[0] < m_boxOffset[
b][0] + m_boxSize[
b][0]))) {
4605 for(
MInt dim = 0; dim < nDim; ++dim) {
4606 if(m_nOffsetCells[dim] <= m_boxOffset[
b][dim]
4607 && m_boxOffset[
b][dim] + m_boxSize[
b][dim] < m_nOffsetCells[dim] + m_nActiveCells[dim]) {
4608 localBoxSize[dim] = m_boxSize[
b][dim];
4609 localBoxOffset[dim] = 0;
4610 localDomainBoxOffset[dim] = m_boxOffset[
b][dim] - m_nOffsetCells[dim];
4611 }
else if(m_nOffsetCells[dim] <= m_boxOffset[
b][dim]) {
4612 localBoxSize[dim] = (m_nOffsetCells[dim] + m_nActiveCells[dim]) - m_boxOffset[
b][dim];
4613 localBoxOffset[dim] = 0;
4614 localDomainBoxOffset[dim] = m_boxOffset[
b][dim] - m_nOffsetCells[dim];
4615 }
else if(m_boxOffset[
b][dim] <= m_nOffsetCells[dim]
4616 && m_nOffsetCells[dim] + m_nActiveCells[dim] < m_boxOffset[
b][dim] + m_boxSize[
b][dim]) {
4617 localBoxSize[dim] = m_nActiveCells[dim];
4618 localBoxOffset[dim] = m_nOffsetCells[dim] - m_boxOffset[
b][dim];
4619 localDomainBoxOffset[dim] = 0;
4621 localBoxSize[dim] = (m_boxOffset[
b][dim] + m_boxSize[
b][dim]) - m_nOffsetCells[dim];
4622 localBoxOffset[dim] = m_nOffsetCells[dim] - m_boxOffset[
b][dim];
4623 localDomainBoxOffset[dim] = 0;
4627 stringstream pathName;
4628 pathName <<
"/box" <<
b;
4629 MInt totalLocalSize = 1;
4630 for(
MInt dim = 0; dim < nDim; ++dim) {
4631 totalLocalSize *= localBoxSize[dim];
4633 MInt noFields = m_maxNoVariables;
4634 if(FQ->noFQBoxOutput > 0) noFields += FQ->noFQBoxOutput;
4635 if(m_boxWriteCoordinates) noFields += nDim;
4638 MFloatScratchSpace localBoxVar(noFields * totalLocalSize, AT_,
"local Box Variables");
4644 MFloat noVars = m_maxNoVariables;
4645 for(
MInt var = 0; var < noVars; ++var) {
4646 for(
MInt k = m_noGhostLayers + localDomainBoxOffset[0];
4647 k < m_noGhostLayers + localDomainBoxOffset[0] + localBoxSize[0];
4649 for(
MInt j = m_noGhostLayers + localDomainBoxOffset[1];
4650 j < m_noGhostLayers + localDomainBoxOffset[1] + localBoxSize[1];
4652 for(
MInt i = m_noGhostLayers + localDomainBoxOffset[2];
4653 i < m_noGhostLayers + localDomainBoxOffset[2] + localBoxSize[2];
4655 cellId = i + (j + k * m_nCells[1]) * m_nCells[2];
4656 MInt boxI = i - m_noGhostLayers - localDomainBoxOffset[2];
4657 MInt boxJ = j - m_noGhostLayers - localDomainBoxOffset[1];
4658 MInt boxK = k - m_noGhostLayers - localDomainBoxOffset[0];
4659 localId = var * totalLocalSize + (boxI + (boxJ + boxK * localBoxSize[1]) * localBoxSize[2]);
4660 localBoxVar[localId] = m_cells->pvariables[var][
cellId];
4665 offset += m_maxNoVariables;
4667 if(FQ->noFQBoxOutput > 0) {
4668 for(
MInt v = 0; v < FQ->noFQVariables; ++v) {
4669 if(FQ->fqWriteOutputBoxes[v]) {
4670 for(
MInt k = m_noGhostLayers + localDomainBoxOffset[0];
4671 k < m_noGhostLayers + localDomainBoxOffset[0] + localBoxSize[0];
4673 for(
MInt j = m_noGhostLayers + localDomainBoxOffset[1];
4674 j < m_noGhostLayers + localDomainBoxOffset[1] + localBoxSize[1];
4676 for(
MInt i = m_noGhostLayers + localDomainBoxOffset[2];
4677 i < m_noGhostLayers + localDomainBoxOffset[2] + localBoxSize[2];
4679 cellId = i + (j + k * m_nCells[1]) * m_nCells[2];
4680 MInt boxI = i - m_noGhostLayers - localDomainBoxOffset[2];
4681 MInt boxJ = j - m_noGhostLayers - localDomainBoxOffset[1];
4682 MInt boxK = k - m_noGhostLayers - localDomainBoxOffset[0];
4683 localId = (offset)*totalLocalSize + (boxI + (boxJ + boxK * localBoxSize[1]) * localBoxSize[2]);
4684 localBoxVar[localId] = m_cells->fq[v][
cellId];
4693 if(m_boxWriteCoordinates) {
4694 for(
MInt dim = 0; dim < nDim; dim++) {
4695 for(
MInt k = m_noGhostLayers + localDomainBoxOffset[0];
4696 k < m_noGhostLayers + localDomainBoxOffset[0] + localBoxSize[0];
4698 for(
MInt j = m_noGhostLayers + localDomainBoxOffset[1];
4699 j < m_noGhostLayers + localDomainBoxOffset[1] + localBoxSize[1];
4701 for(
MInt i = m_noGhostLayers + localDomainBoxOffset[2];
4702 i < m_noGhostLayers + localDomainBoxOffset[2] + localBoxSize[2];
4704 cellId = i + (j + k * m_nCells[1]) * m_nCells[2];
4705 MInt boxI = i - m_noGhostLayers - localDomainBoxOffset[2];
4706 MInt boxJ = j - m_noGhostLayers - localDomainBoxOffset[1];
4707 MInt boxK = k - m_noGhostLayers - localDomainBoxOffset[0];
4708 localId = (offset + dim) * totalLocalSize + (boxI + (boxJ + boxK * localBoxSize[1]) * localBoxSize[2]);
4709 localBoxVar[localId] = m_cells->coordinates[dim][
cellId];
4720 for(
MInt v = 0; v < m_maxNoVariables; v++) {
4721 pio.writeArray(&localBoxVar[v * totalLocalSize], pathName.str(), m_pvariableNames[v], nDim, localBoxOffset,
4724 offset = m_maxNoVariables;
4726 for(
MInt v = 0; v < FQ->noFQVariables; ++v) {
4727 if(FQ->fqWriteOutputBoxes[v]) {
4728 pio.writeArray(&localBoxVar[(offset)*totalLocalSize], pathName.str(), FQ->fqNames[v], nDim, localBoxOffset,
4734 if(m_boxWriteCoordinates) {
4735 pio.writeArray(&localBoxVar[(offset + 0) * totalLocalSize], pathName.str(),
"x", nDim, localBoxOffset,
4737 pio.writeArray(&localBoxVar[(offset + 1) * totalLocalSize], pathName.str(),
"y", nDim, localBoxOffset,
4739 pio.writeArray(&localBoxVar[(offset + 2) * totalLocalSize], pathName.str(),
"z", nDim, localBoxOffset,
4745 stringstream pathName;
4746 pathName <<
"/box" <<
b;
4747 for(
MInt dim = 0; dim < nDim; ++dim) {
4748 localBoxSize[dim] = 0;
4749 localBoxOffset[dim] = 0;
4752 for(
MInt v = 0; v < m_maxNoVariables; ++v) {
4753 pio.writeArray(&empty, pathName.str(), m_pvariableNames[v], nDim, localBoxOffset, localBoxSize);
4755 for(
MInt v = 0; v < FQ->noFQVariables; ++v) {
4756 if(FQ->fqWriteOutputBoxes[v]) {
4757 pio.writeArray(&empty, pathName.str(), FQ->fqNames[v], nDim, localBoxOffset, localBoxSize);
4761 if(m_boxWriteCoordinates) {
4762 pio.writeArray(&empty, pathName.str(),
"x", nDim, localBoxOffset, localBoxSize);
4763 pio.writeArray(&empty, pathName.str(),
"y", nDim, localBoxOffset, localBoxSize);
4764 pio.writeArray(&empty, pathName.str(),
"z", nDim, localBoxOffset, localBoxSize);
4780 constexpr MInt nDim = 2;
4784 stringstream filename;
4785 filename << m_boxOutputDir <<
"boxOutput" << m_outputIterationNumber << m_outputFormat;
4789 writeHeaderAttributes(&pio,
"boxes");
4790 writePropertiesAsAttributes(&pio,
"");
4791 pio.setAttribute(m_boxNoBoxes,
"noBoxes",
"");
4794 ParallelIo::size_type localBoxSize[nDim]{0};
4795 ParallelIo::size_type localBoxOffset[nDim]{0};
4796 ParallelIo::size_type globalBoxSize[nDim]{0};
4797 ParallelIo::size_type localDomainBoxOffset[nDim]{0};
4800 for(
MInt i = 0; i < m_noBlocks; ++i) {
4801 for(
MInt b = 0;
b < m_boxNoBoxes; ++
b) {
4802 if(m_boxBlock[
b] == i) {
4805 for(
MInt dim = 0; dim < nDim; ++dim) {
4806 globalBoxSize[dim] = m_boxSize[
b][dim];
4809 stringstream pathName;
4810 pathName <<
"/box" <<
b;
4812 pio.setAttribute(m_boxOffset[
b][2],
"offseti", pathName.str());
4813 pio.setAttribute(m_boxOffset[
b][1],
"offsetj", pathName.str());
4815 pio.setAttribute(m_boxSize[
b][2],
"sizei", pathName.str());
4816 pio.setAttribute(m_boxSize[
b][1],
"sizej", pathName.str());
4818 pio.setAttribute(i,
"blockId", pathName.str());
4820 MInt hasCoordinates = 0;
4822 for(
MInt v = 0; v < m_maxNoVariables; v++) {
4826 for(
MInt v = 0; v < FQ->noFQVariables; v++) {
4827 if(FQ->fqWriteOutputBoxes[v]) {
4832 if(m_boxWriteCoordinates) {
4838 pio.setAttribute(hasCoordinates,
"hasCoordinates", pathName.str());
4843 for(
MInt b = 0;
b < m_boxNoBoxes; ++
b) {
4845 if(m_boxBlock[
b] == m_blockId
4846 && ((m_nOffsetCells[1] <= m_boxOffset[
b][1] && m_boxOffset[
b][1] < m_nOffsetCells[1] + m_nActiveCells[1])
4847 || (m_boxOffset[
b][1] <= m_nOffsetCells[1] && m_nOffsetCells[1] < m_boxOffset[
b][1] + m_boxSize[
b][1]))
4848 && ((m_nOffsetCells[0] <= m_boxOffset[
b][0] && m_boxOffset[
b][0] < m_nOffsetCells[0] + m_nActiveCells[0])
4849 || (m_boxOffset[
b][0] <= m_nOffsetCells[0]
4850 && m_nOffsetCells[0] < m_boxOffset[
b][0] + m_boxSize[
b][0]))) {
4853 for(
MInt dim = 0; dim < nDim; ++dim) {
4854 if(m_nOffsetCells[dim] <= m_boxOffset[
b][dim]
4855 && m_boxOffset[
b][dim] + m_boxSize[
b][dim] < m_nOffsetCells[dim] + m_nActiveCells[dim]) {
4856 localBoxSize[dim] = m_boxSize[
b][dim];
4857 localBoxOffset[dim] = 0;
4858 localDomainBoxOffset[dim] = m_boxOffset[
b][dim] - m_nOffsetCells[dim];
4859 }
else if(m_nOffsetCells[dim] <= m_boxOffset[
b][dim]) {
4860 localBoxSize[dim] = (m_nOffsetCells[dim] + m_nActiveCells[dim]) - m_boxOffset[
b][dim];
4861 localBoxOffset[dim] = 0;
4862 localDomainBoxOffset[dim] = m_boxOffset[
b][dim] - m_nOffsetCells[dim];
4863 }
else if(m_boxOffset[
b][dim] <= m_nOffsetCells[dim]
4864 && m_nOffsetCells[dim] + m_nActiveCells[dim] < m_boxOffset[
b][dim] + m_boxSize[
b][dim]) {
4865 localBoxSize[dim] = m_nActiveCells[dim];
4866 localBoxOffset[dim] = m_nOffsetCells[dim] - m_boxOffset[
b][dim];
4867 localDomainBoxOffset[dim] = 0;
4869 localBoxSize[dim] = (m_boxOffset[
b][dim] + m_boxSize[
b][dim]) - m_nOffsetCells[dim];
4870 localBoxOffset[dim] = m_nOffsetCells[dim] - m_boxOffset[
b][dim];
4871 localDomainBoxOffset[dim] = 0;
4875 stringstream pathName;
4876 pathName <<
"/box" <<
b;
4877 MInt totalLocalSize = 1;
4878 for(
MInt dim = 0; dim < nDim; ++dim) {
4879 totalLocalSize *= localBoxSize[dim];
4881 MInt noFields = m_maxNoVariables;
4882 if(FQ->noFQBoxOutput > 0) noFields += FQ->noFQBoxOutput;
4883 if(m_boxWriteCoordinates) noFields += nDim;
4886 MFloatScratchSpace localBoxVar(noFields * totalLocalSize, AT_,
"local Box Variables");
4892 MFloat noVars = m_maxNoVariables;
4893 for(
MInt var = 0; var < noVars; ++var) {
4894 for(
MInt j = m_noGhostLayers + localDomainBoxOffset[0];
4895 j < m_noGhostLayers + localDomainBoxOffset[0] + localBoxSize[0];
4897 for(
MInt i = m_noGhostLayers + localDomainBoxOffset[1];
4898 i < m_noGhostLayers + localDomainBoxOffset[1] + localBoxSize[1];
4900 cellId = i + j * m_nCells[1];
4901 MInt boxI = i - m_noGhostLayers - localDomainBoxOffset[1];
4902 MInt boxJ = j - m_noGhostLayers - localDomainBoxOffset[0];
4903 localId = var * totalLocalSize + (boxI + boxJ * localBoxSize[1]);
4904 localBoxVar[localId] = m_cells->pvariables[var][
cellId];
4908 offset += m_maxNoVariables;
4910 if(FQ->noFQBoxOutput > 0) {
4911 for(
MInt v = 0; v < FQ->noFQVariables; ++v) {
4912 if(FQ->fqWriteOutputBoxes[v]) {
4913 for(
MInt j = m_noGhostLayers + localDomainBoxOffset[0];
4914 j < m_noGhostLayers + localDomainBoxOffset[0] + localBoxSize[0];
4916 for(
MInt i = m_noGhostLayers + localDomainBoxOffset[1];
4917 i < m_noGhostLayers + localDomainBoxOffset[1] + localBoxSize[1];
4919 cellId = i + j * m_nCells[1];
4920 MInt boxI = i - m_noGhostLayers - localDomainBoxOffset[1];
4921 MInt boxJ = j - m_noGhostLayers - localDomainBoxOffset[0];
4922 localId = (offset)*totalLocalSize + (boxI + boxJ * localBoxSize[1]);
4923 localBoxVar[localId] = m_cells->fq[v][
cellId];
4931 if(m_boxWriteCoordinates) {
4932 for(
MInt dim = 0; dim < nDim; dim++) {
4933 for(
MInt j = m_noGhostLayers + localDomainBoxOffset[0];
4934 j < m_noGhostLayers + localDomainBoxOffset[0] + localBoxSize[0];
4936 for(
MInt i = m_noGhostLayers + localDomainBoxOffset[1];
4937 i < m_noGhostLayers + localDomainBoxOffset[1] + localBoxSize[1];
4939 cellId = i + j * m_nCells[1];
4940 MInt boxI = i - m_noGhostLayers - localDomainBoxOffset[1];
4941 MInt boxJ = j - m_noGhostLayers - localDomainBoxOffset[0];
4942 localId = (offset + dim) * totalLocalSize + (boxI + boxJ * localBoxSize[1]);
4943 localBoxVar[localId] = m_cells->coordinates[dim][
cellId];
4953 for(
MInt v = 0; v < m_maxNoVariables; v++) {
4954 pio.writeArray(&localBoxVar[v * totalLocalSize], pathName.str(), m_pvariableNames[v], nDim, localBoxOffset,
4957 offset = m_maxNoVariables;
4959 for(
MInt v = 0; v < FQ->noFQVariables; ++v) {
4960 if(FQ->fqWriteOutputBoxes[v]) {
4961 pio.writeArray(&localBoxVar[(offset)*totalLocalSize], pathName.str(), FQ->fqNames[v], nDim, localBoxOffset,
4967 if(m_boxWriteCoordinates) {
4968 pio.writeArray(&localBoxVar[(offset + 0) * totalLocalSize], pathName.str(),
"x", nDim, localBoxOffset,
4970 pio.writeArray(&localBoxVar[(offset + 1) * totalLocalSize], pathName.str(),
"y", nDim, localBoxOffset,
4976 stringstream pathName;
4977 pathName <<
"/box" <<
b;
4978 for(
MInt dim = 0; dim < nDim; ++dim) {
4979 localBoxSize[dim] = 0;
4980 localBoxOffset[dim] = 0;
4983 for(
MInt v = 0; v < m_maxNoVariables; ++v) {
4984 pio.writeArray(&empty, pathName.str(), m_pvariableNames[v], nDim, localBoxOffset, localBoxSize);
4986 for(
MInt v = 0; v < FQ->noFQVariables; ++v) {
4987 if(FQ->fqWriteOutputBoxes[v]) {
4988 pio.writeArray(&empty, pathName.str(), FQ->fqNames[v], nDim, localBoxOffset, localBoxSize);
4992 if(m_boxWriteCoordinates) {
4993 pio.writeArray(&empty, pathName.str(),
"x", nDim, localBoxOffset, localBoxSize);
4994 pio.writeArray(&empty, pathName.str(),
"y", nDim, localBoxOffset, localBoxSize);
5008 stringstream gridFileName;
5010 if(m_movingGrid && m_movingGridSaveGrid) {
5012 gridNameStr = gridFileName.str();
5014 gridNameStr =
"../" + m_grid->m_gridInputFileName;
5039 pio->
setAttribute(m_physicalTimeStep,
"physicalTimeStep", path);
5040 pio->
setAttribute(m_physicalTime,
"physicalTime", path);
5042 pio->
setAttribute(m_firstMaxResidual,
"firstMaxResidual", path);
5043 pio->
setAttribute(m_firstAvrgResidual,
"firstAvrgResidual", path);
5048 pio->
setAttribute(m_movingGridStepOffset,
"movingGridStepOffset", path);
5049 pio->
setAttribute(m_movingGridTimeOffset,
"movingGridTimeOffset", path);
5051 if(m_travelingWave || m_streamwiseTravelingWave) {
5052 pio->
setAttribute(m_waveTimeStepComputed,
"waveTimeStepComputed", path);
5053 pio->
setAttribute(m_waveNoStepsPerCell,
"waveNoStepsPerCell", path);
5061 if(m_volumeForceMethod != 0) {
5062 pio->
setAttribute(m_volumeForce[0],
"volumeForce", path);
5074 RECORD_TIMER_START(m_timers[Timers::Run]);
5075 RECORD_TIMER_START(m_timers[Timers::SaveOutput]);
5078 this->postprocessInSolve();
5081 MBool writeSolution =
false;
5082 MBool writeBox =
false;
5083 MBool writeNodalBox =
false;
5084 MBool writeIntpPoints =
false;
5085 MBool writeAux =
false;
5086 MBool computeForces =
false;
5087 MBool writeForces =
false;
5088 MBool computeAsciiCells =
false;
5089 MBool writeAsciiCells =
false;
5093 if(m_useConvectiveUnitWrite) {
5098 if(m_physicalTime - (
MFloat)(m_noConvectiveOutputs)*m_convectiveUnitInterval >= m_convectiveUnitInterval) {
5100 writeSolution = isInInterval(m_solutionInterval);
5101 forceOutput = writeSolution;
5104 writeSolution = m_sampleSolutionFiles;
5105 writeBox = (m_boxOutputInterval > 0);
5106 writeNodalBox = (m_nodalBoxOutputInterval > 0);
5107 writeIntpPoints = (m_intpPointsOutputInterval > 0);
5108 writeAux = (m_forceOutputInterval > 0);
5109 computeForces = (m_forceAsciiComputeInterval > 0);
5111 m_noConvectiveOutputs++;
5112 m_outputIterationNumber = m_noConvectiveOutputs;
5117 writeSolution = isInInterval(m_solutionInterval);
5118 writeBox = isInInterval(m_boxOutputInterval);
5119 writeNodalBox = isInInterval(m_nodalBoxOutputInterval);
5120 writeIntpPoints = isInInterval(m_intpPointsOutputInterval);
5121 writeAux = isInInterval(m_forceOutputInterval);
5122 computeForces = isInInterval(m_forceAsciiComputeInterval);
5123 computeAsciiCells = isInInterval(m_pointsToAsciiComputeInterval);
5124 if(writeSolution || finalTimeStep) {
5126 writeAsciiCells =
true;
5134 if(m_vorticityOutput && (writeSolution || writeBox || forceOutput)) {
5139 if(m_computeLambda2 && (writeSolution || writeBox || forceOutput)) {
5140 computeLambda2Criterion();
5146 RECORD_TIMER_START(m_timers[Timers::SaveBoxes]);
5153 RECORD_TIMER_STOP(m_timers[Timers::SaveBoxes]);
5155 RECORD_TIMER_START(m_timers[Timers::SaveAuxdata]);
5159 RECORD_TIMER_STOP(m_timers[Timers::SaveAuxdata]);
5160 RECORD_TIMER_START(m_timers[Timers::SaveForces]);
5162 saveForcesToAsciiFile(writeForces);
5165 if(computeAsciiCells) {
5166 savePointsToAsciiFile(writeAsciiCells);
5169 RECORD_TIMER_STOP(m_timers[Timers::SaveForces]);
5170 IF_CONSTEXPR(nDim > 2) {
5171 RECORD_TIMER_START(m_timers[Timers::SaveIntpPoints]);
5172 if(writeIntpPoints) {
5173 saveInterpolatedPoints();
5175 RECORD_TIMER_STOP(m_timers[Timers::SaveIntpPoints]);
5178 if(writeSolution || forceOutput || finalTimeStep) {
5179 RECORD_TIMER_START(m_timers[Timers::SaveSolution]);
5181 if(m_savePartitionOutput) {
5185 saveAverageRestart();
5187 saveSolution(forceOutput);
5189 RECORD_TIMER_STOP(m_timers[Timers::SaveSolution]);
5191 RECORD_TIMER_STOP(m_timers[Timers::SaveOutput]);
5192 RECORD_TIMER_STOP(m_timers[Timers::Run]);
5212 stringstream fileName;
5213 fileName << m_solutionOutput << m_outputIterationNumber << m_outputFormat;
5216 if(m_movingGridSaveGrid) {
5217 m_grid->writeGrid(m_solutionOutput, m_outputFormat);
5221 m_log <<
"writing Solution file " << fileName.str() <<
" ... forceOutput: " << forceOutput << endl;
5234 writeHeaderAttributes(&pio,
"solution");
5235 writePropertiesAsAttributes(&pio,
"");
5237 ParallelIo::size_type allCells[3] = {0, 0, 0};
5238 ParallelIo::size_type stgNoEddieFields = 1200;
5239 MString stgGlobalPathStr =
"stgGlobal";
5241 for(
MInt i = 0; i < m_noBlocks; i++) {
5242 for(
MInt j = 0; j < nDim; j++) {
5243 allCells[j] = m_grid->getBlockNoCells(i, j);
5248 MString blockPathStr =
"block";
5249 blockPathStr += path.str();
5250 const char* blockPath = blockPathStr.c_str();
5255 m_log <<
"writing primitive Output" << endl;
5256 for(
MInt v = 0; v < m_maxNoVariables; v++) {
5263 if(FQ->noFQVariables > 0) {
5264 for(
MInt v = 0; v < FQ->noFQVariables; ++v) {
5265 if(FQ->fqWriteOutput[v]) {
5274 if(m_bc2600IsActive) {
5275 ParallelIo::size_type allCells2600[3] = {allCells[0], allCells[1], allCells[2]};
5276 allCells2600[nDim - 1] = m_noGhostLayers;
5277 stringstream path2600Str;
5278 path2600Str << blockPath <<
"/bc2600";
5279 std::string path2600 = path2600Str.str();
5281 for(
MInt var = 0; var < m_maxNoVariables; var++) {
5289 if(m_bc2601IsActive) {
5290 ParallelIo::size_type allCells2601[3] = {allCells[0], allCells[1], allCells[2]};
5291 allCells2601[nDim - 2] = m_noGhostLayers;
5292 stringstream path2601Str;
5293 path2601Str << blockPath <<
"/bc2601";
5294 std::string path2601 = path2601Str.str();
5296 for(
MInt var = 0; var < m_maxNoVariables; var++) {
5305 ParallelIo::size_type allCells7909[3];
5306 allCells7909[0] = allCells[0];
5307 allCells7909[1] = allCells[1];
5308 allCells7909[2] = 3;
5309 for(
MInt var = 0; var < m_stgNoVariables; var++) {
5310 stringstream stgPath;
5311 stgPath << blockPathStr <<
"/stg";
5312 stringstream fieldName;
5313 fieldName <<
"stgFQ" << var;
5322 if(m_useSandpaperTrip) {
5323 stringstream tripPath;
5324 tripPath <<
"/trip";
5325 ParallelIo::size_type dataSize = m_tripNoTrips * 2 * m_tripNoModes;
5333 stgNoEddieFields =
MInt(m_stgNoEddieProperties * m_stgMaxNoEddies);
5342 MString blockPathStr =
"block";
5343 blockPathStr += path.str();
5345 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
5346 ParallelIo::size_type ioSize[3] = {0, 0, 0};
5347 ParallelIo::size_type ioGhost[3] = {m_noGhostLayers, m_noGhostLayers, m_noGhostLayers};
5348 for(
MInt dim = 0; dim < nDim; ++dim) {
5349 ioOffset[dim] = m_nOffsetCells[dim];
5350 ioSize[dim] = m_nActiveCells[dim];
5353 for(
MInt v = 0; v < m_maxNoVariables; ++v) {
5354 pio.
writeArray(&(m_cells->pvariables[v][0]), blockPathStr, m_pvariableNames[v], nDim, ioOffset, ioSize, ioGhost);
5360 if(FQ->noFQVariables > 0) {
5361 for(
MInt v = 0; v < FQ->noFQVariables; ++v) {
5362 if(FQ->fqWriteOutput[v]) {
5363 pio.
writeArray(&m_cells->fq[v][0], blockPathStr, FQ->fqNames[v], nDim, ioOffset, ioSize, ioGhost);
5372 if(m_bc2600IsActive) {
5373 stringstream path2600Str;
5374 path2600Str << blockPathStr <<
"/bc2600";
5375 std::string path2600 = path2600Str.str();
5377 ParallelIo::size_type ioSize2600[3] = {0, 0, 0};
5378 ParallelIo::size_type ioOffset2600[3] = {0, 0, 0};
5379 ParallelIo::size_type ioGhost2600[3] = {m_noGhostLayers, m_noGhostLayers, m_noGhostLayers};
5380 for(
MInt dim = 0; dim < nDim; ++dim) {
5381 ioSize2600[dim] = m_bc2600noActiveCells[dim];
5382 ioOffset2600[dim] = m_bc2600noOffsetCells[dim];
5385 ioGhost2600[nDim - 1] = 0;
5387 for(
MInt var = 0; var < m_maxNoVariables; var++) {
5388 pio.
writeArray(&m_bc2600Variables[var][0], path2600, m_pvariableNames[var], nDim, ioOffset2600, ioSize2600,
5393 for(
MInt var = 0; var < m_maxNoVariables; var++) {
5394 pio.
writeArray(&empty, path2600, m_pvariableNames[var], nDim, ioOffset2600, ioSize2600, ioGhost2600);
5402 if(m_bc2601IsActive) {
5403 stringstream path2601Str;
5404 path2601Str << blockPathStr <<
"/bc2601";
5405 std::string path2601 = path2601Str.str();
5407 ParallelIo::size_type ioSize2601[3] = {0, 0, 0};
5408 ParallelIo::size_type ioOffset2601[3] = {0, 0, 0};
5409 ParallelIo::size_type ioGhost2601[3] = {m_noGhostLayers, m_noGhostLayers, m_noGhostLayers};
5410 for(
MInt dim = 0; dim < nDim; ++dim) {
5411 ioSize2601[dim] = m_bc2601noActiveCells[dim];
5412 ioOffset2601[dim] = m_bc2601noOffsetCells[dim];
5415 ioGhost2601[nDim - 2] = 0;
5417 for(
MInt var = 0; var < m_maxNoVariables; var++) {
5418 pio.
writeArray(&m_bc2601Variables[var][0], path2601, m_pvariableNames[var], nDim, ioOffset2601, ioSize2601,
5423 for(
MInt var = 0; var < m_maxNoVariables; var++) {
5424 pio.
writeArray(&empty, path2601, m_pvariableNames[var], nDim, ioOffset2601, ioSize2601, ioGhost2601);
5433 ParallelIo::size_type VBOffset = 0;
5435 pio.
writeArray(&m_stgEddies[0][0], stgGlobalPathStr,
"FQeddies", 1, &VBOffset, &stgNoEddieFields);
5437 stgNoEddieFields = 0;
5439 pio.
writeArray(&empty, stgGlobalPathStr,
"FQeddies", 1, &VBOffset, &stgNoEddieFields);
5444 MInt noActiveStgCells = (m_stgBoxSize[0] - 2 * m_noGhostLayers) * (m_stgBoxSize[1] - 2 * m_noGhostLayers) * 3;
5445 MFloatScratchSpace stgFqDummy(m_stgNoVariables, noActiveStgCells, AT_,
"stgFqDummy");
5447 for(
MInt var = 0; var < m_stgNoVariables; var++) {
5448 for(
MInt k = m_noGhostLayers; k < m_stgBoxSize[0] - m_noGhostLayers; k++) {
5449 for(
MInt j = m_noGhostLayers; j < m_stgBoxSize[1] - m_noGhostLayers; j++) {
5450 for(
MInt i = 0; i < m_stgBoxSize[2]; i++) {
5451 MInt cellIdBC = i + (j + k * m_stgBoxSize[1]) * 3;
5453 i + ((j - m_noGhostLayers) + (k - m_noGhostLayers) * (m_stgBoxSize[1] - 2 * m_noGhostLayers)) * 3;
5454 stgFqDummy(var, cellIdDummy) = m_cells->stg_fq[var][cellIdBC];
5460 ParallelIo::size_type bcOffset[3] = {m_nOffsetCells[0], m_nOffsetCells[1], 0};
5461 ParallelIo::size_type bcCells[3] = {m_stgBoxSize[0] - 2 * m_noGhostLayers, m_stgBoxSize[1] - 2 * m_noGhostLayers,
5464 for(
MInt var = 0; var < m_stgNoVariables; var++) {
5465 stringstream fieldName;
5466 stringstream stgPath;
5467 stgPath << blockPathStr <<
"/stg";
5468 fieldName <<
"stgFQ" << var;
5469 pio.
writeArray(&stgFqDummy(var, 0), stgPath.str(), fieldName.str(), nDim, bcOffset, bcCells);
5472 ParallelIo::size_type bcOffset[3] = {0, 0, 0};
5473 ParallelIo::size_type bcCells[3] = {0, 0, 0};
5476 for(
MInt var = 0; var < m_stgNoVariables; var++) {
5477 stringstream fieldName;
5478 stringstream stgPath;
5479 stgPath << blockPathStr <<
"/stg";
5480 fieldName <<
"stgFQ" << var;
5481 pio.
writeArray(&empty, stgPath.str(), fieldName.str(), nDim, bcOffset, bcCells);
5489 if(m_useSandpaperTrip) {
5490 stringstream tripPath;
5493 if(domainId() == 0) {
5494 ParallelIo::size_type offset = 0;
5495 ParallelIo::size_type dataSize = m_tripNoTrips * m_tripNoModes * 2;
5497 pio.
writeArray(m_tripModesG, tripPath.str(),
"tripModesG", 1, &offset, &dataSize);
5498 pio.
writeArray(m_tripModesH1, tripPath.str(),
"tripModesH1", 1, &offset, &dataSize);
5499 pio.
writeArray(m_tripModesH2, tripPath.str(),
"tripModesH2", 1, &offset, &dataSize);
5501 ParallelIo::size_type offset = 0;
5502 ParallelIo::size_type dataSize = 0;
5504 pio.
writeArray(&empty, tripPath.str(),
"tripModesG", 1, &offset, &dataSize);
5505 pio.
writeArray(&empty, tripPath.str(),
"tripModesH1", 1, &offset, &dataSize);
5506 pio.
writeArray(&empty, tripPath.str(),
"tripModesH2", 1, &offset, &dataSize);
5510 m_log <<
"...-> OK " << endl;
5523 stringstream fileName;
5524 ParallelIo::size_type noCells[3] = {0, 0, 0};
5526 fileName << m_solutionOutput <<
"partitioned" <<
globalTimeStep << m_outputFormat;
5528 writeHeaderAttributes(&pio,
"solution");
5529 writePropertiesAsAttributes(&pio,
"");
5532 for(
MInt i = 0; i < noDomains(); i++) {
5534 for(
MInt j = 0; j < nDim; j++) {
5535 noCells[j] = m_grid->getActivePoints(i, j) - 1 + 2 * m_noGhostLayers;
5539 MString partitionPathStr =
"block";
5540 partitionPathStr += path.str();
5541 const char* partitionPath = partitionPathStr.c_str();
5543 for(
MInt v = 0; v < m_maxNoVariables; v++) {
5547 for(
MInt v = 0; v < FQ->noFQVariables; v++) {
5552 ParallelIo::size_type allCells7909[3];
5553 allCells7909[0] = m_grid->getActivePoints(i, 0) - 1 + 2 * m_noGhostLayers;
5554 allCells7909[1] = m_grid->getActivePoints(i, 1) - 1 + 2 * m_noGhostLayers;
5555 allCells7909[2] = 3;
5557 for(
MInt var = 0; var < m_stgNoVariables; var++) {
5558 stringstream fieldName;
5559 stringstream stgPath;
5560 stgPath << partitionPathStr <<
"/stg";
5561 fieldName <<
"stgFQ" << var;
5568 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
5569 ParallelIo::size_type ioSize[3] = {m_nCells[0], m_nCells[1], m_nCells[2]};
5572 MString partitionPathStr =
"block";
5573 partitionPathStr += path.str();
5576 for(
MInt v = 0; v < m_maxNoVariables; ++v) {
5577 pio.
writeArray(&m_cells->pvariables[v][0], partitionPathStr, m_pvariableNames[v], nDim, ioOffset, ioSize);
5580 for(
MInt v = 0; v < FQ->noFQVariables; v++) {
5581 pio.
writeArray(&m_cells->fq[v][0], partitionPathStr, FQ->fqNames[v], nDim, ioOffset, ioSize);
5588 ParallelIo::size_type bcOffset[3] = {0, 0, 0};
5589 ParallelIo::size_type bcCells[3] = {m_nCells[0], m_nCells[1], 3};
5591 for(
MInt var = 0; var < m_stgNoVariables; var++) {
5592 stringstream fieldName;
5593 stringstream stgPath;
5594 stgPath << partitionPathStr <<
"/stg";
5595 fieldName <<
"stgFQ" << var;
5596 pio.
writeArray(&m_cells->stg_fq[var][0], stgPath.str(), fieldName.str(), nDim, bcOffset, bcCells);
5609 if(!m_useNonSpecifiedRestartFile) {
5610 TERMM(1,
"determineRestartTimeStep should only be used with useNonSpecifiedRestartFile enabled!");
5613 MString restartFile = Context::getSolverProperty<MString>(
"restartVariablesFileName", m_solverId, AT_);
5614 std::stringstream restartFileName;
5615 restartFileName << outputDir() << restartFile;
5632 RECORD_TIMER_START(m_timers[Timers::LoadRestart]);
5633 m_log <<
"loading Restart file ... " << endl;
5634 stringstream restartFileName;
5636 if(m_useNonSpecifiedRestartFile) {
5637 MString restartFile =
"restart.hdf5";
5651 Context::getSolverProperty<MString>(
"restartVariablesFileName", m_solverId, AT_);
5652 restartFileName << outputDir() << restartFile;
5654 MString restartFile =
"restart";
5668 MInt restartTimeStep = Context::getSolverProperty<MInt>(
"restartTimeStep", m_solverId, AT_);
5670 restartFileName << outputDir() << restartFile << restartTimeStep <<
".hdf5";
5673 MBool restartFromSA =
false;
5674 restartFromSA = Context::getSolverProperty<MBool>(
"restartFromSA", m_solverId, AT_, &restartFromSA);
5682 pio.getAttribute(&aUID,
"UID",
"");
5684 if(aUID.compare(m_grid->m_uID) != 0) {
5685 mTerm(1, AT_,
"FATAL: the files do not match each other according to the attribute UID");
5689 pio.getAttribute(&m_time,
"time",
"");
5690 pio.getAttribute(&m_physicalTime,
"physicalTime",
"");
5691 pio.getAttribute(&m_physicalTimeStep,
"physicalTimeStep",
"");
5692 pio.getAttribute(&m_firstMaxResidual,
"firstMaxResidual",
"");
5693 pio.getAttribute(&m_firstAvrgResidual,
"firstAvrgResidual",
"");
5694 pio.getAttribute(&m_timeStep,
"timeStep",
"");
5696 MInt isPrimitiveOutput = 1;
5697 if(pio.hasAttribute(
"primitiveOutput",
"")) {
5698 pio.getAttribute(&isPrimitiveOutput,
"primitiveOutput",
"");
5703 if(m_movingGrid || m_bodyForce) {
5704 if(pio.hasAttribute(
"movingGridStepOffset",
"")) {
5705 pio.getAttribute(&m_movingGridTimeOffset,
"movingGridTimeOffset",
"");
5706 pio.getAttribute(&m_movingGridStepOffset,
"movingGridStepOffset",
"");
5707 m_movingGridInitialStart =
false;
5709 m_movingGridTimeOffset = m_time;
5711 m_movingGridInitialStart =
true;
5714 if(pio.hasAttribute(
"waveTimeStepComputed",
"")) {
5715 pio.getAttribute(&m_waveTimeStepComputed,
"waveTimeStepComputed",
"");
5717 m_waveTimeStepComputed =
false;
5720 if(pio.hasAttribute(
"waveNoStepsPerCell",
"")) {
5721 pio.getAttribute(&m_waveNoStepsPerCell,
"waveNoStepsPerCell",
"");
5723 m_waveNoStepsPerCell = 1;
5728 if(m_useConvectiveUnitWrite) {
5729 m_noConvectiveOutputs = (
MInt)(m_physicalTime / m_convectiveUnitInterval);
5730 m_log <<
"Convective unit output iteration counter: " << m_noConvectiveOutputs << endl;
5733 if(m_movingGridInitialStart) {
5734 m_movingGridTimeOffset = m_time;
5736 if(domainId() == 0) {
5737 cout <<
"Restarting at GlobalTimeStep " <<
globalTimeStep << endl;
5741 m_log <<
"-> reading in the data ... " << endl;
5742 m_log <<
"Loading restart variables..." << endl;
5743 if(domainId() == 0) {
5744 cout <<
"Loading restart variables..." << endl;
5746 stringstream blockNumber;
5747 blockNumber << m_blockId;
5748 MString blockPathStr =
"/block";
5749 blockPathStr += blockNumber.str();
5750 const char* blockPath = blockPathStr.c_str();
5754 vector<MString> variableNames = pio.getDatasetNames(blockPath);
5756 MBool rans0 =
false;
5757 for(
MUint i = 0; i < variableNames.size(); ++i) {
5758 if(variableNames[i].find(
"rans1") != std::string::npos) {
5759 cout << variableNames[i] << endl;
5760 mTerm(1,
"Restart file contains the variable rans1, but restartFromSA was set!!!");
5762 if(variableNames[i].find(
"rans0") != std::string::npos) rans0 =
true;
5764 if(!rans0)
mTerm(1,
"Restart file does not contain variable 'rans0'!");
5768 RECORD_TIMER_START(m_timers[Timers::LoadVariables]);
5770 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
5771 ParallelIo::size_type ioSize[3] = {0, 0, 0};
5772 for(
MInt dim = 0; dim < nDim; ++dim) {
5773 ioOffset[dim] = m_nOffsetCells[dim];
5774 ioSize[dim] = m_nActiveCells[dim];
5777 if(isPrimitiveOutput) {
5778 for(
MInt var = 0; var < m_maxNoVariables - restartFromSA; var++) {
5779 m_cells->pvariables[var][0] = -1.0;
5780 pio.readArray(m_cells->pvariables[var], blockPath, m_pvariableNames[var], nDim, ioOffset, ioSize);
5781 m_log <<
"Reading " << m_pvariableNames[var] << endl;
5784 for(
MInt var = 0; var < CV->noVariables - restartFromSA; var++) {
5785 pio.readArray(m_cells->variables[var], blockPath, m_variableNames[var], nDim, ioOffset, ioSize);
5789 pio.readArray(m_cells->fq[FQ->AVG_U], blockPath, FQ->fqNames[FQ->AVG_U], nDim, ioOffset, ioSize);
5790 pio.readArray(m_cells->fq[FQ->AVG_V], blockPath, FQ->fqNames[FQ->AVG_V], nDim, ioOffset, ioSize);
5791 pio.readArray(m_cells->fq[FQ->AVG_W], blockPath, FQ->fqNames[FQ->AVG_W], nDim, ioOffset, ioSize);
5792 pio.readArray(m_cells->fq[FQ->AVG_RHO], blockPath, FQ->fqNames[FQ->AVG_RHO], nDim, ioOffset, ioSize);
5793 pio.readArray(m_cells->fq[FQ->AVG_P], blockPath, FQ->fqNames[FQ->AVG_P], nDim, ioOffset, ioSize);
5794 pio.readArray(m_cells->fq[FQ->NU_T], blockPath, FQ->fqNames[FQ->NU_T], nDim, ioOffset, ioSize);
5796 FQ->loadedFromRestartFile[FQ->AVG_U] =
true;
5797 FQ->loadedFromRestartFile[FQ->AVG_V] =
true;
5798 FQ->loadedFromRestartFile[FQ->AVG_W] =
true;
5799 FQ->loadedFromRestartFile[FQ->AVG_RHO] =
true;
5800 FQ->loadedFromRestartFile[FQ->AVG_P] =
true;
5801 FQ->loadedFromRestartFile[FQ->NU_T] =
true;
5804 RECORD_TIMER_STOP(m_timers[Timers::LoadVariables]);
5805 m_log <<
"Loading restart variables... SUCCESSFUL!" << endl;
5806 if(domainId() == 0) {
5807 cout <<
"Loading restart variables... SUCCESSFUL!" << endl;
5809 m_log <<
"-> reading in auxilliary data for restart ..." << endl;
5810 m_log <<
"--> ... sponge ..." << endl;
5815 RECORD_TIMER_START(m_timers[Timers::LoadSponge]);
5817 m_log <<
"--> ... sponge ..." << endl;
5818 if(domainId() == 0) {
5819 cout <<
"Loading sponge data..." << endl;
5821 if(m_computeSpongeFactor ==
false) {
5822 pio.readArray(m_cells->fq[FQ->SPONGE_FACTOR], blockPath, FQ->fqNames[FQ->SPONGE_FACTOR], nDim, ioOffset, ioSize);
5823 FQ->loadedFromRestartFile[FQ->SPONGE_FACTOR] =
true;
5825 if(m_spongeLayerType == 2) {
5826 pio.readArray(m_cells->fq[FQ->SPONGE_RHO], blockPath, FQ->fqNames[FQ->SPONGE_RHO], nDim, ioOffset, ioSize);
5827 FQ->loadedFromRestartFile[FQ->SPONGE_RHO] =
true;
5828 pio.readArray(m_cells->fq[FQ->SPONGE_RHO_E], blockPath, FQ->fqNames[FQ->SPONGE_RHO_E], nDim, ioOffset, ioSize);
5829 FQ->loadedFromRestartFile[FQ->SPONGE_RHO_E] =
true;
5831 if(m_spongeLayerType == 4) {
5832 pio.readArray(m_cells->fq[FQ->SPONGE_RHO], blockPath, FQ->fqNames[FQ->SPONGE_RHO], nDim, ioOffset, ioSize);
5833 FQ->loadedFromRestartFile[FQ->SPONGE_RHO] =
true;
5835 if(domainId() == 0) {
5836 cout <<
"Loading sponge data... SUCCESSFUL!" << endl;
5838 m_log <<
"--> ... sponge ... SUCCESSFUL" << endl;
5840 RECORD_TIMER_STOP(m_timers[Timers::LoadSponge]);
5845 if(isPrimitiveOutput) {
5846 this->shiftCellValuesRestart(
true);
5847 computeConservativeVariables();
5849 this->shiftCellValuesRestart(
false);
5850 computePrimitiveVariables();
5857 vector<MFloat*> zonalVars;
5858 zonalVars.push_back(m_cells->fq[FQ->AVG_U]);
5859 zonalVars.push_back(m_cells->fq[FQ->AVG_V]);
5860 zonalVars.push_back(m_cells->fq[FQ->AVG_W]);
5861 zonalVars.push_back(m_cells->fq[FQ->AVG_P]);
5862 zonalVars.push_back(m_cells->fq[FQ->AVG_RHO]);
5863 zonalVars.push_back(m_cells->fq[FQ->NU_T]);
5864 gcFillGhostCells(zonalVars);
5869 IF_CONSTEXPR(nDim == 3) {
5870 loadRestartBC2601();
5872 RECORD_TIMER_START(m_timers[Timers::LoadSTG]);
5873 loadRestartSTG(isPrimitiveOutput);
5874 RECORD_TIMER_STOP(m_timers[Timers::LoadSTG]);
5883 pio.getAttribute(&oldMa,
"Ma",
"");
5884 convertRestartVariables(oldMa);
5887 convertRestartVariablesSTG(oldMa);
5894 if(m_volumeForceMethod != 0) {
5896 pio.getAttribute(&m_volumeForce[0],
"volumeForce",
"");
5900 m_log <<
"-> reading in auxilliary data for restart ...SUCCESSFUL" << endl;
5901 m_log <<
"loading Restart file ... SUCCESSFUL " << endl;
5903 loadRestartBC2600();
5905 RECORD_TIMER_STOP(m_timers[Timers::LoadRestart]);
5917 for(
MInt j = (m_nActiveCells[0] - 1); j >= 0; j--) {
5918 for(
MInt i = (m_nActiveCells[1] - 1); i >= 0; i--) {
5919 const MInt cellId_org = i + j * m_nActiveCells[1];
5920 const MInt i_new = i + m_noGhostLayers;
5921 const MInt j_new = j + m_noGhostLayers;
5922 const MInt cellId = i_new + j_new * m_nCells[1];
5924 for(
MInt var = 0; var < CV->noVariables; var++) {
5925 m_cells->variables[var][
cellId] = m_cells->variables[var][cellId_org];
5926 m_cells->variables[var][cellId_org] = F0;
5929 for(
MInt var = 0; var < m_maxNoVariables; var++) {
5930 m_cells->pvariables[var][
cellId] = m_cells->pvariables[var][cellId_org];
5931 m_cells->pvariables[var][cellId_org] = F0;
5935 if(FQ->noFQVariables > 0) {
5936 for(
MInt var = 0; var < FQ->noFQVariables; var++) {
5937 if(FQ->loadedFromRestartFile[var]) {
5938 m_cells->fq[var][
cellId] = m_cells->fq[var][cellId_org];
5939 m_cells->fq[var][cellId_org] = F0;
5951 for(
MInt k = (m_nActiveCells[0] - 1); k >= 0; k--) {
5952 for(
MInt j = (m_nActiveCells[1] - 1); j >= 0; j--) {
5953 for(
MInt i = (m_nActiveCells[2] - 1); i >= 0; i--) {
5954 const MInt cellId_org = i + (j + k * m_nActiveCells[1]) * m_nActiveCells[2];
5955 const MInt i_new = i + m_noGhostLayers;
5956 const MInt j_new = j + m_noGhostLayers;
5957 const MInt k_new = k + m_noGhostLayers;
5958 const MInt cellId = i_new + (j_new + k_new * m_nCells[1]) * m_nCells[2];
5960 for(
MInt var = 0; var < CV->noVariables; var++) {
5961 m_cells->variables[var][
cellId] = m_cells->variables[var][cellId_org];
5962 m_cells->variables[var][cellId_org] = F0;
5965 for(
MInt var = 0; var < m_maxNoVariables; var++) {
5966 m_cells->pvariables[var][
cellId] = m_cells->pvariables[var][cellId_org];
5967 m_cells->pvariables[var][cellId_org] = F0;
5971 if(FQ->noFQVariables > 0) {
5972 for(
MInt var = 0; var < FQ->noFQVariables; var++) {
5973 if(FQ->loadedFromRestartFile[var]) {
5974 m_cells->fq[var][
cellId] = m_cells->fq[var][cellId_org];
5975 m_cells->fq[var][cellId_org] = F0;
5995 stringstream fileName;
5996 fileName << fileDir <<
"/" << filePrefix << currentStep <<
".hdf5";
5997 if(FILE* file = fopen((fileName.str()).c_str(),
"r")) {
5999 if(domainId() == 0) {
6000 cout <<
"Loading box file " << fileName.str() << endl;
6003 if(domainId() == 0) {
6004 cout <<
"Box file " << fileName.str() <<
" does not exist" << endl;
6011 stringstream boxPath;
6012 boxPath <<
"t" << currentStep <<
"/box" << boxNr;
6014 MInt boxOffset[3] = {0, 0, 0};
6015 pio.
getAttribute(&boxOffset[0],
"offsetk", boxPath.str());
6016 pio.
getAttribute(&boxOffset[1],
"offsetj", boxPath.str());
6017 pio.
getAttribute(&boxOffset[2],
"offseti", boxPath.str());
6018 MInt boxSize[3] = {0, 0, 0};
6023 ParallelIo::size_type localBoxSize[3] = {0, 0, 0};
6024 ParallelIo::size_type localBoxOffset[3] = {0, 0, 0};
6025 ParallelIo::size_type localDomainBoxOffset[3] = {0, 0, 0};
6027 if(((m_nOffsetCells[2] <= boxOffset[2] && boxOffset[2] < m_nOffsetCells[2] + m_nActiveCells[2])
6028 || (boxOffset[2] <= m_nOffsetCells[2] && m_nOffsetCells[2] < boxOffset[2] + boxSize[2]))
6029 && ((m_nOffsetCells[1] <= boxOffset[1] && boxOffset[1] < m_nOffsetCells[1] + m_nActiveCells[1])
6030 || (boxOffset[1] <= m_nOffsetCells[1] && m_nOffsetCells[1] < boxOffset[1] + boxSize[1]))
6031 && ((m_nOffsetCells[0] <= boxOffset[0] && boxOffset[0] < m_nOffsetCells[0] + m_nActiveCells[0])
6032 || (boxOffset[0] <= m_nOffsetCells[0]
6033 && m_nOffsetCells[0] < boxOffset[0] + boxSize[0]))) {
6036 for(
MInt dim = 0; dim < nDim; ++dim) {
6037 if(m_nOffsetCells[dim] <= boxOffset[dim]
6038 && boxOffset[dim] + boxSize[dim] < m_nOffsetCells[dim] + m_nActiveCells[dim]) {
6039 localBoxSize[dim] = boxSize[dim];
6040 localBoxOffset[dim] = 0;
6041 localDomainBoxOffset[dim] = boxOffset[dim] - m_nOffsetCells[dim];
6042 }
else if(m_nOffsetCells[dim] <= boxOffset[dim]) {
6043 localBoxSize[dim] = (m_nOffsetCells[dim] + m_nActiveCells[dim]) - boxOffset[dim];
6044 localBoxOffset[dim] = 0;
6045 localDomainBoxOffset[dim] = boxOffset[dim] - m_nOffsetCells[dim];
6046 }
else if(boxOffset[dim] <= m_nOffsetCells[dim]
6047 && m_nOffsetCells[dim] + m_nActiveCells[dim] < boxOffset[dim] + boxSize[dim]) {
6048 localBoxSize[dim] = m_nActiveCells[dim];
6049 localBoxOffset[dim] = m_nOffsetCells[dim] - boxOffset[dim];
6050 localDomainBoxOffset[dim] = 0;
6052 localBoxSize[dim] = (boxOffset[dim] + boxSize[dim]) - m_nOffsetCells[dim];
6053 localBoxOffset[dim] = m_nOffsetCells[dim] - boxOffset[dim];
6054 localDomainBoxOffset[dim] = 0;
6058 MInt totalLocalSize = 1;
6059 for(
MInt dim = 0; dim < nDim; ++dim) {
6060 totalLocalSize *= localBoxSize[dim];
6064 for(
MInt var = 0; var < PV->noVariables; var++) {
6065 pio.
readArray(&localBoxVar[0], boxPath.str(), m_pvariableNames[var], nDim, localBoxOffset, localBoxSize);
6067 for(
MInt k = m_noGhostLayers + localDomainBoxOffset[0];
6068 k < m_noGhostLayers + localDomainBoxOffset[0] + localBoxSize[0];
6070 for(
MInt j = m_noGhostLayers + localDomainBoxOffset[1];
6071 j < m_noGhostLayers + localDomainBoxOffset[1] + localBoxSize[1];
6073 for(
MInt i = m_noGhostLayers + localDomainBoxOffset[2];
6074 i < m_noGhostLayers + localDomainBoxOffset[2] + localBoxSize[2];
6076 const MInt cellId = i + (j + k * m_nCells[1]) * m_nCells[2];
6077 const MInt boxI = i - m_noGhostLayers - localDomainBoxOffset[2];
6078 const MInt boxJ = j - m_noGhostLayers - localDomainBoxOffset[1];
6079 const MInt boxK = k - m_noGhostLayers - localDomainBoxOffset[0];
6080 const MInt localId = boxI + (boxJ + boxK * localBoxSize[1]) * localBoxSize[2];
6081 m_cells->pvariables[var][cellId] = localBoxVar[localId];
6087 for(
MInt var = 0; var < PV->noVariables; var++) {
6088 ParallelIo::size_type offset[3] = {0, 0, 0};
6089 ParallelIo::size_type size[3] = {0, 0, 0};
6091 pio.
readArray(&empty, boxPath.str(), m_pvariableNames[var], nDim, offset, size);
6096 if(domainId() == 0) {
6097 cout <<
"Done loading box file " << currentStep << endl;
6107 stringstream fileName;
6111 fileName << m_auxOutputDir <<
"auxData" << m_outputIterationNumber << m_outputFormat;
6113 strcpy(gridFile, tempG.c_str());
6115 writeHeaderAttributes(&pio,
"auxdata");
6116 writePropertiesAsAttributes(&pio,
"");
6117 const MString powerNamesVisc[3] = {
"Pxv",
"Pyv",
"Pzv"};
6118 const MString powerNamesPres[3] = {
"Pxp",
"Pyp",
"Pzp"};
6120 const MString dataNames3D[] = {
"cfx",
"cfy",
"cfz",
"ax",
"ay",
"az",
"x",
"y",
"z"};
6123 for(
MInt i = 0; i < 3; ++i) {
6124 for(
MInt dim = 0; dim < nDim; ++dim)
6125 dataNames[cnt++] = dataNames3D[i * 3 + dim];
6127 MInt noFields = nDim;
6128 if(m_detailAuxData) {
6129 noFields = 3 * nDim;
6132 for(
auto it = m_windowInfo->m_auxDataWindowIds.cbegin(); it != m_windowInfo->m_auxDataWindowIds.cend(); ++it) {
6133 const MInt i = it->first;
6134 ParallelIo::size_type datasetSize[nDim - 1];
6135 MInt dim1 = nDim - 2;
6136 for(
MInt dim = 0; dim < nDim; ++dim) {
6137 if(m_windowInfo->globalStructuredBndryCndMaps[i]->end2[dim]
6138 == m_windowInfo->globalStructuredBndryCndMaps[i]->start2[dim]) {
6141 datasetSize[dim1--] = m_windowInfo->globalStructuredBndryCndMaps[i]->end2[dim]
6142 - m_windowInfo->globalStructuredBndryCndMaps[i]->start2[dim];
6146 stringstream datasetId;
6147 datasetId << it->second;
6149 pathName += datasetId.str();
6151 for(
MInt j = 0; j < noFields; j++) {
6158 stringstream datasetId;
6159 datasetId << it->second;
6161 pathName += datasetId.str();
6162 for(
MInt j = 0; j < nDim; j++) {
6169 for(
auto it = m_windowInfo->m_auxDataWindowIds.cbegin(); it != m_windowInfo->m_auxDataWindowIds.cend(); ++it) {
6170 stringstream datasetname;
6171 datasetname << it->second;
6173 MBool isLocalAuxMap =
false;
6174 MInt localAuxMapId = 0;
6175 const MUint noAuxDataMaps = m_windowInfo->physicalAuxDataMap.size();
6180 for(
MUint j = 0; j < noAuxDataMaps; ++j) {
6181 stringstream datasetId;
6182 datasetId << m_windowInfo->physicalAuxDataMap[j]->Id2;
6183 if(datasetId.str() == datasetname.str()) {
6184 isLocalAuxMap =
true;
6191 stringstream datasetId;
6192 datasetId << m_windowInfo->physicalAuxDataMap[localAuxMapId]->Id2;
6194 ParallelIo::size_type offset[nDim - 1] = {};
6195 ParallelIo::size_type dataSize[nDim - 1] = {};
6196 MInt dataSetSize = 1;
6197 MInt dim1 = nDim - 2;
6198 for(
MInt j = 0; j < nDim; ++j) {
6199 if(m_windowInfo->physicalAuxDataMap[localAuxMapId]->start2[j]
6200 == m_windowInfo->physicalAuxDataMap[localAuxMapId]->end2[j])
6202 dataSize[dim1] = m_windowInfo->physicalAuxDataMap[localAuxMapId]->end2[j]
6203 - m_windowInfo->physicalAuxDataMap[localAuxMapId]->start2[j];
6204 offset[dim1] = m_windowInfo->physicalAuxDataMap[localAuxMapId]->start2[j];
6205 dataSetSize *= dataSize[dim1];
6210 const MInt mapOffset = m_cells->cfOffsets[localAuxMapId];
6211 MString pathName =
"window" + datasetId.str();
6212 for(
MInt j = 0; j < noFields; j++) {
6213 pio.
writeArray(&m_cells->cf[mapOffset + dataSetSize * j], pathName, dataNames[j], nDim - 1, offset, dataSize);
6215 const MInt mapOffsetCp = m_cells->cpOffsets[localAuxMapId];
6217 pio.
writeArray(&m_cells->cp[mapOffsetCp], pathName, dataname, nDim - 1, offset, dataSize);
6221 const MInt mapOffset = m_cells->powerOffsets[localAuxMapId];
6222 MString pathName =
"window" + datasetId.str();
6223 for(
MInt j = 0; j < nDim; j++) {
6224 pio.
writeArray(&m_cells->powerVisc[mapOffset + dataSetSize * j], pathName, powerNamesVisc[j], nDim - 1,
6226 pio.
writeArray(&m_cells->powerPres[mapOffset + dataSetSize * j], pathName, powerNamesPres[j], nDim - 1,
6231 ParallelIo::size_type offset[nDim] = {};
6232 ParallelIo::size_type dataSize[nDim] = {};
6233 for(
MInt j = 0; j < nDim - 1; ++j) {
6239 MString pathName =
"window" + datasetname.str();
6241 for(
MInt j = 0; j < noFields; j++) {
6242 pio.
writeArray(&empty, pathName, dataNames[j], nDim - 1, offset, dataSize);
6245 pio.
writeArray(&empty, pathName, dataname, nDim - 1, offset, dataSize);
6249 MString pathName =
"window" + datasetname.str();
6251 for(
MInt j = 0; j < nDim; j++) {
6252 pio.
writeArray(&empty, pathName, powerNamesVisc[j], nDim - 1, offset, dataSize);
6253 pio.
writeArray(&empty, pathName, powerNamesPres[j], nDim - 1, offset, dataSize);
6260 saveForceCoefficient(&pio);
6276 MInt noWalls = m_windowInfo->m_auxDataWindowIds.size();
6286 for(
MInt i = 0; i < noWalls; ++i) {
6287 for(
MInt dim = 0; dim < nDim; dim++) {
6288 forceV(i, dim) = m_forceCoef[i * m_noForceDataFields + dim];
6289 forceC(i, dim) = m_forceCoef[i * m_noForceDataFields + nDim + dim];
6290 forceP(i, dim) = m_forceCoef[i * m_noForceDataFields + 2 * nDim + dim];
6291 force(i, dim) = forceV(i, dim) + forceC(i, dim) + forceP(i, dim);
6292 powerV(i, dim) = m_forceCoef[i * m_noForceDataFields + 3 * nDim + 1 + dim];
6293 powerP(i, dim) = m_forceCoef[i * m_noForceDataFields + 4 * nDim + 1 + dim];
6294 power(i, dim) = powerV(i, dim) + powerP(i, dim);
6296 area[i] = m_forceCoef[i * m_noForceDataFields + 3 * nDim];
6300 for(
auto it = m_windowInfo->m_auxDataWindowIds.cbegin(); it != m_windowInfo->m_auxDataWindowIds.cend(); ++it) {
6301 stringstream datasetname;
6302 datasetname << it->second;
6303 MString pathName =
"window" + datasetname.str();
6305 pio->
setAttribute(force(count, 0),
"forceX", pathName);
6306 pio->
setAttribute(forceV(count, 0),
"forceVX", pathName);
6307 pio->
setAttribute(forceP(count, 0),
"forcePX", pathName);
6308 pio->
setAttribute(forceC(count, 0),
"forceCX", pathName);
6310 pio->
setAttribute(force(count, 1),
"forceY", pathName);
6311 pio->
setAttribute(forceV(count, 1),
"forceVY", pathName);
6312 pio->
setAttribute(forceP(count, 1),
"forcePY", pathName);
6313 pio->
setAttribute(forceC(count, 1),
"forceCY", pathName);
6315 IF_CONSTEXPR(nDim == 3) {
6316 pio->
setAttribute(force(count, 2),
"forceZ", pathName);
6317 pio->
setAttribute(forceV(count, 2),
"forceVZ", pathName);
6318 pio->
setAttribute(forceP(count, 2),
"forcePZ", pathName);
6319 pio->
setAttribute(forceC(count, 2),
"forceCZ", pathName);
6325 pio->
setAttribute(power(count, 0),
"powerX", pathName);
6326 pio->
setAttribute(power(count, 1),
"powerY", pathName);
6327 pio->
setAttribute(power(count, 2),
"powerZ", pathName);
6329 pio->
setAttribute(powerP(count, 0),
"powerPX", pathName);
6330 pio->
setAttribute(powerP(count, 1),
"powerPY", pathName);
6331 pio->
setAttribute(powerP(count, 2),
"powerPZ", pathName);
6333 pio->
setAttribute(powerV(count, 0),
"powerVX", pathName);
6334 pio->
setAttribute(powerV(count, 1),
"powerVY", pathName);
6335 pio->
setAttribute(powerV(count, 2),
"powerVZ", pathName);
6354 computeAuxDataRoot();
6357 if(domainId() == 0) {
6358 MInt noWalls = m_windowInfo->m_auxDataWindowIds.size();
6370 for(
MInt i = 0; i < noWalls; ++i) {
6371 for(
MInt dim = 0; dim < nDim; dim++) {
6372 cForceV(i, dim) = m_forceCoef[i * m_noForceDataFields + dim];
6373 cForceC(i, dim) = m_forceCoef[i * m_noForceDataFields + nDim + dim];
6374 cForceP(i, dim) = m_forceCoef[i * m_noForceDataFields + 2 * nDim + dim];
6375 cForce(i, dim) = cForceV(i, dim) + cForceP(i, dim) + cForceC(i, dim);
6376 cPowerV(i, dim) = m_forceCoef[i * m_noForceDataFields + 3 * nDim + 1 + dim];
6377 cPowerP(i, dim) = m_forceCoef[i * m_noForceDataFields + 4 * nDim + 1 + dim];
6378 cPower(i, dim) = cPowerV(i, dim) + cPowerP(i, dim);
6380 area[i] = m_forceCoef[i * m_noForceDataFields + 3 * nDim];
6384 for(
MInt i = 0; i < noWalls; ++i) {
6386 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] =
globalTimeStep;
6387 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = m_time;
6388 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = m_physicalTime;
6389 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForce(i, 0);
6390 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceV(i, 0);
6391 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceP(i, 0);
6392 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceC(i, 0);
6393 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForce(i, 1);
6394 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceV(i, 1);
6395 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceP(i, 1);
6396 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceC(i, 1);
6397 IF_CONSTEXPR(nDim == 3) {
6398 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForce(i, 2);
6399 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceV(i, 2);
6400 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceP(i, 2);
6401 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cForceC(i, 2);
6403 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = area[i];
6406 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPower(i, 0);
6407 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPowerV(i, 0);
6408 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPowerP(i, 0);
6409 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPower(i, 1);
6410 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPowerV(i, 1);
6411 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPowerP(i, 1);
6412 IF_CONSTEXPR(nDim == 3) {
6413 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPower(i, 2);
6414 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPowerV(i, 2);
6415 m_forceData[m_forceCounter][i * m_noForceDataFields + cnt++] = cPowerP(i, 2);
6423 if((m_forceCounter >= m_forceAsciiOutputInterval || forceWrite) && m_lastForceOutputTimeStep !=
globalTimeStep) {
6424 cout <<
"globalTimeStep: " <<
globalTimeStep <<
" writing out to ascii file" << endl;
6427 for(
MInt i = 0; i < noWalls; ++i) {
6430 MString filename =
"./forces." + iWall.str() +
".dat";
6433 f_forces = fopen(filename.c_str(),
"a+");
6435 for(
MInt j = 0; j < m_forceCounter; j++) {
6436 fprintf(f_forces,
"%d ", (
MInt)m_forceData[j][i * m_noForceDataFields + 0]);
6437 for(
MInt k = 1; k < m_noForceDataFields; k++) {
6438 fprintf(f_forces,
" %.8f ", m_forceData[j][i * m_noForceDataFields + k]);
6440 fprintf(f_forces,
"\n");
6462 stringstream fileName;
6464 m_log <<
"writing Averaged Variables to file " << name << m_outputFormat <<
" ... " << endl;
6465 fileName << name << m_outputFormat;
6469 writeHeaderAttributes(&pio,
"solution");
6470 writePropertiesAsAttributes(&pio,
"");
6472 pio.
setAttribute(m_averageStartTimestep,
"averageStartTimeStep",
"");
6473 pio.
setAttribute(m_averageInterval,
"averageSampleInterval",
"");
6476 for(
MInt i = 0; i < m_noBlocks; i++) {
6477 ParallelIo::size_type noCells[nDim] = {};
6478 for(
MInt j = 0; j < nDim; j++) {
6479 noCells[j] = m_grid->getBlockNoCells(i, j);
6484 MString blockPathStr =
"block";
6485 blockPathStr += path.str();
6488 for(
MInt var = 0; var < noVars; var++) {
6492 if(m_averagingFavre) {
6493 for(
MInt var = 0; var < PV->noVariables; var++) {
6499 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
6500 ParallelIo::size_type ioSize[3] = {0, 0, 0};
6501 ParallelIo::size_type ioGhost[3] = {m_noGhostLayers, m_noGhostLayers, m_noGhostLayers};
6502 for(
MInt dim = 0; dim < nDim; ++dim) {
6503 ioOffset[dim] = m_nOffsetCells[dim];
6504 ioSize[dim] = m_nActiveCells[dim];
6509 MString blockPathStr =
"block";
6510 blockPathStr += path.str();
6511 for(
MInt var = 0; var < noVars; var++) {
6512 pio.
writeArray(&summedVars[var][0], blockPathStr, m_avgVariableNames[var], nDim, ioOffset, ioSize, ioGhost);
6515 if(m_averagingFavre) {
6516 for(
MInt var = 0; var < PV->noVariables; var++) {
6517 pio.
writeArray(&m_favre[var][0], blockPathStr, m_avgFavreNames[var], nDim, ioOffset, ioSize, ioGhost);
6533 stringstream fileName;
6535 m_log <<
"writing Averaged Restart Variables to file " << name << m_outputFormat <<
" ... " << endl;
6536 fileName << name << m_outputFormat;
6540 writeHeaderAttributes(&pio,
"solution");
6541 writePropertiesAsAttributes(&pio,
"");
6543 pio.
setAttribute(m_averageStartTimestep,
"averageStartTimeStep",
"");
6544 pio.
setAttribute(m_averageInterval,
"averageSampleInterval",
"");
6547 ParallelIo::size_type allCells[3];
6548 for(
MInt i = 0; i < m_noBlocks; i++) {
6549 for(
MInt j = 0; j < nDim; j++) {
6550 allCells[j] = m_grid->getBlockNoCells(i, j);
6555 MString blockPathStr =
"block";
6556 blockPathStr += path.str();
6564 if(m_averagingFavre) {
6572 if(m_averageVorticity) {
6586 if(m_averageVorticity) {
6592 if(m_kurtosis || m_skewness) {
6608 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
6609 ParallelIo::size_type ioSize[3] = {0, 0, 0};
6610 ParallelIo::size_type ioGhost[3] = {m_noGhostLayers, m_noGhostLayers, m_noGhostLayers};
6611 for(
MInt dim = 0; dim < nDim; ++dim) {
6612 ioOffset[dim] = m_nOffsetCells[dim];
6613 ioSize[dim] = m_nActiveCells[dim];
6618 MString blockPathStr =
"block";
6619 blockPathStr += path.str();
6621 pio.
writeArray(&summedVars[0][0], blockPathStr,
"u", nDim, ioOffset, ioSize, ioGhost);
6622 pio.
writeArray(&summedVars[1][0], blockPathStr,
"v", nDim, ioOffset, ioSize, ioGhost);
6623 pio.
writeArray(&summedVars[2][0], blockPathStr,
"w", nDim, ioOffset, ioSize, ioGhost);
6624 pio.
writeArray(&summedVars[3][0], blockPathStr,
"rho", nDim, ioOffset, ioSize, ioGhost);
6625 pio.
writeArray(&summedVars[4][0], blockPathStr,
"p", nDim, ioOffset, ioSize, ioGhost);
6626 offset = noVariables();
6628 if(m_averagingFavre) {
6629 pio.
writeArray(&m_favre[0][0], blockPathStr,
"um_favre", nDim, ioOffset, ioSize, ioGhost);
6630 pio.
writeArray(&m_favre[1][0], blockPathStr,
"vm_favre", nDim, ioOffset, ioSize, ioGhost);
6631 pio.
writeArray(&m_favre[2][0], blockPathStr,
"wm_favre", nDim, ioOffset, ioSize, ioGhost);
6632 pio.
writeArray(&m_favre[3][0], blockPathStr,
"rhom_favre", nDim, ioOffset, ioSize, ioGhost);
6633 pio.
writeArray(&m_favre[4][0], blockPathStr,
"pm_favre", nDim, ioOffset, ioSize, ioGhost);
6636 if(m_averageVorticity) {
6637 pio.
writeArray(&summedVars[offset + 0][0], blockPathStr,
"vortx", nDim, ioOffset, ioSize, ioGhost);
6638 pio.
writeArray(&summedVars[offset + 1][0], blockPathStr,
"vorty", nDim, ioOffset, ioSize, ioGhost);
6639 pio.
writeArray(&summedVars[offset + 2][0], blockPathStr,
"vortz", nDim, ioOffset, ioSize, ioGhost);
6642 pio.
writeArray(&square[0][0], blockPathStr,
"uu", nDim, ioOffset, ioSize, ioGhost);
6643 pio.
writeArray(&square[1][0], blockPathStr,
"vv", nDim, ioOffset, ioSize, ioGhost);
6644 pio.
writeArray(&square[2][0], blockPathStr,
"ww", nDim, ioOffset, ioSize, ioGhost);
6645 pio.
writeArray(&square[3][0], blockPathStr,
"uv", nDim, ioOffset, ioSize, ioGhost);
6646 pio.
writeArray(&square[4][0], blockPathStr,
"vw", nDim, ioOffset, ioSize, ioGhost);
6647 pio.
writeArray(&square[5][0], blockPathStr,
"uw", nDim, ioOffset, ioSize, ioGhost);
6648 pio.
writeArray(&square[6][0], blockPathStr,
"pp", nDim, ioOffset, ioSize, ioGhost);
6650 if(m_averageVorticity) {
6651 pio.
writeArray(&square[7][0], blockPathStr,
"vortxvortx", nDim, ioOffset, ioSize, ioGhost);
6652 pio.
writeArray(&square[8][0], blockPathStr,
"vortyvorty", nDim, ioOffset, ioSize, ioGhost);
6653 pio.
writeArray(&square[9][0], blockPathStr,
"vortzvortz", nDim, ioOffset, ioSize, ioGhost);
6656 if(m_kurtosis || m_skewness) {
6657 pio.
writeArray(&cube[0][0], blockPathStr,
"uuu", nDim, ioOffset, ioSize, ioGhost);
6658 pio.
writeArray(&cube[1][0], blockPathStr,
"vvv", nDim, ioOffset, ioSize, ioGhost);
6659 pio.
writeArray(&cube[2][0], blockPathStr,
"www", nDim, ioOffset, ioSize, ioGhost);
6663 pio.
writeArray(&fourth[0][0], blockPathStr,
"uuuu", nDim, ioOffset, ioSize, ioGhost);
6664 pio.
writeArray(&fourth[1][0], blockPathStr,
"vvvv", nDim, ioOffset, ioSize, ioGhost);
6665 pio.
writeArray(&fourth[2][0], blockPathStr,
"wwww", nDim, ioOffset, ioSize, ioGhost);
6678 m_log <<
"writing production terms to file " << name <<
" ... " << endl;
6682 writeHeaderAttributes(&pio,
"solution");
6683 writePropertiesAsAttributes(&pio,
"");
6685 ParallelIo::size_type allCells[3];
6686 for(
MInt i = 0; i < m_noBlocks; i++) {
6687 for(
MInt j = 0; j < nDim; j++) {
6688 allCells[j] = m_grid->getBlockNoCells(i, j);
6693 MString blockPathStr =
"block";
6694 blockPathStr += path.str();
6700 cout <<
"Dataset p1j exists, not creating new" << endl;
6712 MString blockPathStr =
"block";
6713 blockPathStr += path.str();
6715 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
6716 ParallelIo::size_type ioSize[3] = {0, 0, 0};
6717 ParallelIo::size_type ioGhost[3] = {m_noGhostLayers, m_noGhostLayers, m_noGhostLayers};
6718 for(
MInt dim = 0; dim < nDim; ++dim) {
6719 ioOffset[dim] = m_nOffsetCells[dim];
6720 ioSize[dim] = m_nActiveCells[dim];
6723 pio.
writeArray(&production[0][0], blockPathStr,
"p1j", nDim, ioOffset, ioSize, ioGhost);
6724 pio.
writeArray(&production[1][0], blockPathStr,
"p2j", nDim, ioOffset, ioSize, ioGhost);
6725 pio.
writeArray(&production[2][0], blockPathStr,
"p3j", nDim, ioOffset, ioSize, ioGhost);
6736 m_log <<
"writing dissipation terms to file " << name <<
" ... " << endl;
6740 writeHeaderAttributes(&pio,
"solution");
6741 writePropertiesAsAttributes(&pio,
"");
6743 ParallelIo::size_type allCells[3];
6744 for(
MInt i = 0; i < m_noBlocks; i++) {
6745 for(
MInt j = 0; j < nDim; j++) {
6746 allCells[j] = m_grid->getBlockNoCells(i, j);
6751 MString blockPathStr =
"block";
6752 blockPathStr += path.str();
6758 cout <<
"Dataset diss exists, not creating new" << endl;
6764 MString blockPathStr =
"block";
6765 blockPathStr += path.str();
6767 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
6768 ParallelIo::size_type ioSize[3] = {0, 0, 0};
6769 ParallelIo::size_type ioGhost[3] = {m_noGhostLayers, m_noGhostLayers, m_noGhostLayers};
6770 for(
MInt dim = 0; dim < nDim; ++dim) {
6771 ioOffset[dim] = m_nOffsetCells[dim];
6772 ioSize[dim] = m_nActiveCells[dim];
6775 pio.
writeArray(&dissipation[0], blockPathStr,
"diss", nDim, ioOffset, ioSize, ioGhost);
6787 m_log <<
"writing gradients to file " << name <<
" ... " << endl;
6791 writeHeaderAttributes(&pio,
"solution");
6792 writePropertiesAsAttributes(&pio,
"");
6794 ParallelIo::size_type allCells[3];
6795 MInt noVars = 3 * 9;
6796 for(
MInt i = 0; i < m_noBlocks; i++) {
6797 for(
MInt j = 0; j < nDim; j++) {
6798 allCells[j] = m_grid->getBlockNoCells(i, j);
6803 MString blockPathStr =
"block";
6804 blockPathStr += path.str();
6807 for(
MInt var = 0; var < noVars; var++) {
6808 if(!pio.
hasDataset(gradientNames[var], blockPathStr)) {
6811 cout <<
"Dataset " << gradientNames[var] <<
" exists, not creating new" << endl;
6819 MString blockPathStr =
"block";
6820 blockPathStr += path.str();
6822 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
6823 ParallelIo::size_type ioSize[3] = {0, 0, 0};
6824 ParallelIo::size_type ioGhost[3] = {m_noGhostLayers, m_noGhostLayers, m_noGhostLayers};
6825 for(
MInt dim = 0; dim < nDim; ++dim) {
6826 ioOffset[dim] = m_nOffsetCells[dim];
6827 ioSize[dim] = m_nActiveCells[dim];
6830 for(
MInt var = 0; var < noVars; var++) {
6831 pio.
writeArray(&gradients[var][0], blockPathStr, gradientNames[var].c_str(), nDim, ioOffset, ioSize, ioGhost);
6840 MFloat globalTimeStepMin = F0;
6842 MPI_Allreduce(&m_timeStep, &globalTimeStepMin, 1, MPI_DOUBLE, MPI_MIN, m_StructuredComm, AT_,
"m_timeStep",
6843 "globalTimeStepMin");
6845 m_timeStep = globalTimeStepMin;
6862 MInt l = 0, k = 0, j = 0, i = 0;
6863 MFloat scale = F0, hh = F0, h = F0, g = F0, f = F0;
6865 for(i = dim - 1; i > 0; i--) {
6870 for(k = 0; k < i; ++k) {
6871 scale += abs(A(i, k));
6873 if(
approx(scale, F0, m_eps)) {
6874 offdiag[i] = A(i, l);
6876 for(k = 0; k < i; ++k) {
6878 h += A(i, k) * A(i, k);
6881 g = (f >= F0 ? -sqrt(h) : sqrt(h));
6882 offdiag[i] = scale * g;
6886 for(j = 0; j < i; ++j) {
6888 for(k = 0; k < j + 1; ++k) {
6889 g += A(j, k) * A(i, k);
6891 for(k = j + 1; k < i; ++k) {
6892 g += A(k, j) * A(i, k);
6895 f += offdiag[j] * A(i, j);
6898 for(j = 0; j < i; j++) {
6900 g = offdiag[j] - hh * f;
6902 for(k = 0; k < j + 1; k++) {
6903 A(j, k) -= f * offdiag[k] + g * A(i, k);
6908 offdiag[i] = A(i, l);
6914 for(i = 0; i < n; ++i) {
6936 const MFloat eps = numeric_limits<MFloat>::epsilon();
6937 MInt m, l, iter, i, k;
6938 MFloat s, r, p, g, f, dd, c,
b;
6940 for(i = 1; i < n; ++i)
6941 offdiag[i - 1] = offdiag[i];
6942 offdiag[n - 1] = 0.0;
6943 for(l = 0; l < n; ++l) {
6946 for(m = l; m < n - 1; m++) {
6947 dd = fabs(diag[m]) + fabs(diag[m + 1]);
6948 if(fabs(offdiag[m]) <= eps * dd)
break;
6952 for(k = 0; k < dim; ++k) {
6957 g = (diag[l + 1] - diag[l]) / (2.0 * offdiag[l]);
6960 if(g < F0) r *= -F1;
6961 g = diag[m] - diag[l] + offdiag[l] / (g + r);
6964 for(i = m - 1; i >= l; i--) {
6967 offdiag[i + 1] = (r = pythag(f, g));
6975 g = diag[i + 1] - p;
6976 r = (diag[i] - g) * s + 2.0 * c *
b;
6977 diag[i + 1] = g + (p = s * r);
6980 if(
approx(r, F0, eps) && i >= l)
continue;
7001 for(
MInt i = 1; i < dim; i++) {
7004 while(j >= 0 && temp < list[j]) {
7005 list[j + 1] = list[j];
7014 MFloat absa = F0, absb = F0;
7018 return absa * sqrt(1.0 +
POW2(absb / absa));
7020 return (
approx(absb, F0, m_eps) ? F0 : absb * sqrt(1.0 +
POW2(absa / absb)));
7031 MInt noNansLocal = 0;
7032 for(
MInt cellid = 0; cellid < m_noCells; cellid++) {
7034 for(
MInt i = 0; i < CV->noVariables; i++) {
7035 if(std::isnan(m_cells->variables[i][cellid])) {
7041 MInt noNansGlobal = 0;
7042 MPI_Allreduce(&noNansLocal, &noNansGlobal, 1, MPI_INT, MPI_SUM, m_StructuredComm, AT_,
"noNansLocal",
"noNansGlobal");
7044 if(domainId() == 0) {
7045 cout <<
"GlobalTimeStep: " <<
globalTimeStep <<
" , noNansGlobal: " << noNansGlobal << endl;
7053 if(m_travelingWave || m_streamwiseTravelingWave)
return;
7057 if(noDomains() > 1) {
7061 m_physicalTimeStep = m_timeStep * m_timeRef;
7074 ASSERT(nDim == 2,
"Not implemented for 3D yet!");
7077 for(
MInt cellId = 0; cellId < m_noCells; cellId++) {
7078 const MFloat metricScale =
7079 POW2(m_cells->cellMetrics[0 * 2 + 0][cellId]) +
POW2(m_cells->cellMetrics[0 * 2 + 1][cellId])
7080 +
POW2(m_cells->cellMetrics[1 * 2 + 0][cellId]) +
POW2(m_cells->cellMetrics[1 * 2 + 1][cellId])
7082 * (m_cells->cellMetrics[0 * 2 + 0][cellId] * m_cells->cellMetrics[1 * 2 + 0][cellId]
7083 + m_cells->cellMetrics[0 * 2 + 1][cellId] * m_cells->cellMetrics[1 * 2 + 1][cellId]);
7088 m_cells->fq[FQ->LIMITERVISC][cellId] =
7089 m_CFLVISC *
POW2(m_cells->cellJac[cellId]) / (m_physicalTimeStep * metricScale);
7097 const MFloat waveTransSpeed = fabs(m_waveSpeed);
7100 if(m_travelingWave) {
7102 travelDist = abs(m_grid->m_coordinates[2][0] - m_grid->m_coordinates[2][m_nPoints[2] * m_nPoints[1]]);
7104 travelDist = abs(m_grid->m_coordinates[0][0] - m_grid->m_coordinates[0][1]);
7106 }
else if(m_streamwiseTravelingWave) {
7107 travelDist = m_waveLength;
7109 m_log <<
"WARNING!!!!!!!!!!!!!!!!!!!!: dz was fixed and hardcoded !!!!!!!!!! " << endl;
7110 travelDist = 0.33200866159432146;
7113 if(!m_waveTimeStepComputed) {
7116 if(noDomains() > 1) {
7121 m_waveNoStepsPerCell = ceil((travelDist / waveTransSpeed) / (m_timeStep));
7122 if(m_waveNoStepsPerCell < 2) {
7123 m_waveNoStepsPerCell = 2;
7127 if(domainId() == 0) {
7128 cout <<
"Old time step = " << m_timeStep << endl;
7130 m_log <<
"/////////////////// TRAVELING WAVE /////////////////////////////" << endl;
7131 m_log <<
"Old time step = " << m_timeStep << endl;
7133 m_timeStep = (travelDist / waveTransSpeed) / (m_waveNoStepsPerCell);
7134 m_physicalTimeStep = m_timeStep * m_timeRef;
7136 MBool syncSolutionInterval =
false;
7137 MBool syncForceInterval =
false;
7138 MBool syncBoxInterval =
false;
7139 MBool syncIntpPointsInterval =
false;
7143 if(m_synchronizedMGOutput) {
7151 if(domainId() == 0) {
7152 cout <<
"m_movingGridStepOffset: " << m_movingGridStepOffset
7153 <<
" m_movingGridInitialStart: " << m_movingGridInitialStart << endl;
7157 if(m_outputOffset > m_movingGridStepOffset) {
7158 const MInt offsetCounter =
7159 ceil(((
MFloat)m_outputOffset - (
MFloat)m_movingGridStepOffset) / (
MFloat)m_waveNoStepsPerCell);
7160 m_outputOffset = m_movingGridStepOffset + offsetCounter * m_waveNoStepsPerCell;
7162 m_outputOffset = m_movingGridStepOffset;
7165 if(m_useConvectiveUnitWrite) {
7166 m_log <<
"ERROR: m_useConvectiveUnitWrite and synchronized output cannot be combined (not implemented yet)"
7169 "ERROR: m_useConvetiveUnitWrite and synchronized output cannot be combined (not implemented yet)");
7171 if(m_solutionInterval) {
7172 m_solutionInterval =
7173 mMax(m_waveNoStepsPerCell,
7174 m_waveNoStepsPerCell * (
MInt)floor((
MFloat)m_solutionInterval / (
MFloat)m_waveNoStepsPerCell));
7175 syncSolutionInterval =
true;
7177 if(m_forceOutputInterval) {
7178 m_forceOutputInterval =
7179 mMax(m_waveNoStepsPerCell,
7180 m_waveNoStepsPerCell * (
MInt)floor((
MFloat)m_forceOutputInterval / (
MFloat)m_waveNoStepsPerCell));
7181 syncForceInterval =
true;
7183 if(m_boxOutputInterval) {
7184 m_boxOutputInterval =
7185 mMax(m_waveNoStepsPerCell,
7186 m_waveNoStepsPerCell * (
MInt)floor((
MFloat)m_boxOutputInterval / (
MFloat)m_waveNoStepsPerCell));
7188 syncBoxInterval =
true;
7190 if(m_intpPointsOutputInterval) {
7191 m_intpPointsOutputInterval =
7192 mMax(m_waveNoStepsPerCell,
7193 m_waveNoStepsPerCell * (
MInt)floor((
MFloat)m_boxOutputInterval / (
MFloat)m_waveNoStepsPerCell));
7194 syncIntpPointsInterval =
true;
7198 if(domainId() == 0) {
7199 cout <<
"New time step: " << m_timeStep <<
" new physical time step: " << m_physicalTimeStep << endl;
7200 cout <<
"Number of steps to move one cell width: " << travelDist / (m_waveSpeed * m_timeStep) <<
" time steps"
7202 cout <<
"Number of steps to move one physical time step: " << F1 / m_physicalTimeStep << endl;
7203 cout <<
"Number of steps to move one wave length: " << m_waveLength / (m_waveSpeed * m_timeStep) << endl;
7204 cout <<
"Cells per wavelength: " << m_waveLength / travelDist <<
" travelDist: " << travelDist << endl;
7205 cout <<
"Time for wave to travel one wave length: " << m_waveLength / m_waveSpeed << endl;
7206 cout <<
"Physical time for wave to travel one wave length: " << m_waveLength / m_waveSpeed * m_timeRef << endl;
7207 cout <<
"solution output interval was reset: " << syncSolutionInterval <<
" and changed to " << m_solutionInterval
7209 cout <<
"box output interval was reset: " << syncBoxInterval <<
" and changed to " << m_boxOutputInterval << endl;
7210 cout <<
"force output interval was reset: " << syncForceInterval <<
" and changed to " << m_forceOutputInterval
7212 cout <<
"intpPoints output interval was reset: " << syncIntpPointsInterval <<
" and changed to "
7213 << m_intpPointsOutputInterval << endl;
7216 m_log <<
"New time step: " << m_timeStep <<
" new physical time step: " << m_physicalTimeStep << endl;
7217 m_log <<
"Number of steps to move one cell width: " << travelDist / (m_waveSpeed * m_timeStep) <<
" time steps"
7219 m_log <<
"Number of steps to move one physical time step: " << F1 / m_physicalTimeStep << endl;
7220 m_log <<
"Number of steps to move one wave length: " << m_waveLength / (m_waveSpeed * m_timeStep) << endl;
7221 m_log <<
"Cells per wavelength: " << m_waveLength / travelDist <<
" travelDist: " << travelDist << endl;
7222 m_log <<
"Time for wave to travel one wave length: " << m_waveLength / m_waveSpeed << endl;
7223 m_log <<
"Physical time for wave to travel one wave length: " << m_waveLength / m_waveSpeed * m_timeRef << endl;
7224 m_log <<
"solution output interval was reset: " << syncSolutionInterval <<
" and changed to " << m_solutionInterval
7226 m_log <<
"box output interval was reset: " << syncBoxInterval <<
" and changed to " << m_boxOutputInterval << endl;
7227 m_log <<
"force output interval was reset: " << syncForceInterval <<
" and changed to " << m_forceOutputInterval
7229 m_log <<
"intpPoints output interval was reset: " << syncIntpPointsInterval <<
" and changed to "
7230 << m_intpPointsOutputInterval << endl;
7231 m_log <<
"solution writing out will start at" << m_outputOffset << endl;
7232 m_log <<
"////////////////////////////////////////////////////////////////" << endl;
7234 m_waveTimeStepComputed =
true;
7238 MBool syncSolutionInterval =
false;
7239 MBool syncForceInterval =
false;
7240 MBool syncBoxInterval =
false;
7241 MBool syncIntpPointsInterval =
false;
7244 if(m_synchronizedMGOutput) {
7253 if(m_outputOffset > m_movingGridStepOffset) {
7254 const MInt offsetCounter =
7255 ceil(((
MFloat)m_outputOffset - (
MFloat)m_movingGridStepOffset) / (
MFloat)m_waveNoStepsPerCell);
7256 m_outputOffset = m_movingGridStepOffset + offsetCounter * m_waveNoStepsPerCell;
7258 m_outputOffset = m_movingGridStepOffset;
7262 if(m_useConvectiveUnitWrite) {
7263 m_log <<
"ERROR: m_useConvectiveUnitWrite and synchronized output cannot be combined (not implemented yet)"
7266 "ERROR: m_useConvetiveUnitWrite and synchronized output cannot be combined (not implemented yet)");
7268 if(m_solutionInterval) {
7269 m_solutionInterval =
7270 mMax(m_waveNoStepsPerCell,
7271 m_waveNoStepsPerCell * (
MInt)floor((
MFloat)m_solutionInterval / (
MFloat)m_waveNoStepsPerCell));
7272 syncSolutionInterval =
true;
7274 if(m_forceOutputInterval) {
7275 m_forceOutputInterval =
7276 mMax(m_waveNoStepsPerCell,
7277 m_waveNoStepsPerCell * (
MInt)floor((
MFloat)m_forceOutputInterval / (
MFloat)m_waveNoStepsPerCell));
7278 syncForceInterval =
true;
7280 if(m_boxOutputInterval) {
7281 m_boxOutputInterval =
7282 mMax(m_waveNoStepsPerCell,
7283 m_waveNoStepsPerCell * (
MInt)floor((
MFloat)m_boxOutputInterval / (
MFloat)m_waveNoStepsPerCell));
7284 syncBoxInterval =
true;
7286 if(m_intpPointsOutputInterval) {
7287 m_intpPointsOutputInterval =
7288 mMax(m_waveNoStepsPerCell,
7289 m_waveNoStepsPerCell * (
MInt)floor((
MFloat)m_boxOutputInterval / (
MFloat)m_waveNoStepsPerCell));
7290 syncIntpPointsInterval =
true;
7294 m_log <<
"/////////////////// TRAVELING WAVE /////////////////////////////" << endl;
7295 m_log <<
"New time step: " << m_timeStep <<
" new physical time step: " << m_physicalTimeStep << endl;
7296 m_log <<
"Number of steps to move one cell width: " << travelDist / (m_waveSpeed * m_timeStep) <<
" time steps"
7298 m_log <<
"Number of steps to move one physical time step: " << F1 / m_physicalTimeStep << endl;
7299 m_log <<
"Number of steps to move one wave length: " << m_waveLength / (m_waveSpeed * m_timeStep) << endl;
7300 m_log <<
"Time for wave to travel one wave length: " << m_waveLength / m_waveSpeed << endl;
7301 m_log <<
"Cells per wavelength: " << m_waveLength / travelDist <<
" travelDist: " << travelDist << endl;
7302 m_log <<
"solution output interval was reset: " << syncSolutionInterval <<
" and changed to " << m_solutionInterval
7304 m_log <<
"box output interval was reset: " << syncBoxInterval <<
" and changed to " << m_boxOutputInterval << endl;
7305 m_log <<
"force output interval was reset: " << syncForceInterval <<
" and changed to " << m_forceOutputInterval
7307 m_log <<
"intpPoints output interval was reset: " << syncIntpPointsInterval <<
" and changed to "
7308 << m_intpPointsOutputInterval << endl;
7309 m_log <<
"solution writing out will start at" << m_outputOffset << endl;
7310 m_log <<
"////////////////////////////////////////////////////////////////" << endl;
7312 if(m_postprocessing) {
7313 const MInt waveNoStepsPerCell = m_waveNoStepsPerCell;
7314 if(m_averageInterval % waveNoStepsPerCell != 0) {
7315 m_log <<
"Changed averageInterval from " << m_averageInterval;
7316 const MInt minAverageInterval = waveNoStepsPerCell;
7318 mMax(minAverageInterval,
7319 (
MInt)(waveNoStepsPerCell * floor((
MFloat)m_averageInterval / (
MFloat)waveNoStepsPerCell)));
7320 m_log <<
" to " << m_averageInterval <<
", every " << m_averageInterval * m_physicalTimeStep
7321 <<
" convective units" << endl;
7324 const MInt waveStepOffset = m_movingGridStepOffset;
7325 if((m_averageStartTimestep - waveStepOffset) % m_averageInterval != 0) {
7326 m_log <<
"Changed averageStartTimeStep from " << m_averageStartTimestep;
7327 MInt offsetCounter =
7328 ceil(((
MFloat)m_averageStartTimestep - (
MFloat)waveStepOffset) / (
MFloat)m_averageInterval);
7329 m_averageStartTimestep = waveStepOffset + offsetCounter * m_averageInterval;
7330 m_log <<
" to " << m_averageStartTimestep <<
". Averaging every " << m_averageInterval <<
" time steps" << endl;
7333 if((m_averageStopTimestep - waveStepOffset) % m_averageInterval != 0) {
7334 m_log <<
"Changed averageStopTimeStep from " << m_averageStopTimestep;
7335 MInt offsetCounter = ceil(((
MFloat)m_averageStopTimestep - (
MFloat)waveStepOffset) / (
MFloat)m_averageInterval);
7336 m_averageStopTimestep = waveStepOffset + offsetCounter * m_averageInterval;
7337 m_log <<
" to " << m_averageStopTimestep <<
". Averaging every " << m_averageInterval <<
" time steps" << endl;
7346 const MFloat eps = pow(10.0, -5.0);
7347 if(
ABS(oldMa - m_Ma) > eps) {
7348 m_log <<
"converting restart variables from old Ma: " << oldMa <<
" to new Ma: " << m_Ma <<
" ..." << endl;
7349 const MFloat gammaMinusOne = m_gamma - 1.0;
7351 MFloat T8old = 1.0 / (1.0 + 0.5 * gammaMinusOne *
POW2(oldMa));
7352 MFloat p8old = pow(T8old, (m_gamma / gammaMinusOne)) / m_gamma;
7353 MFloat u8old = oldMa * sqrt(T8old);
7354 MFloat rho8old = pow(T8old, (1.0 / gammaMinusOne));
7356 MFloat rhoE8old = p8old / gammaMinusOne + rho8old * (F1B2 *
POW2(u8old));
7358 MFloat T8new = 1.0 / (1.0 + 0.5 * gammaMinusOne *
POW2(m_Ma));
7359 MFloat p8new = pow(T8new, (m_gamma / gammaMinusOne)) / m_gamma;
7360 MFloat u8new = m_Ma * sqrt(T8new);
7361 MFloat rho8new = pow(T8new, (1.0 / gammaMinusOne));
7363 MFloat rhoE8new = p8new / gammaMinusOne + rho8new * (F1B2 *
POW2(u8new));
7365 MFloat velRatio = u8new / u8old;
7366 MFloat rhoRatio = rho8new / rho8old;
7367 MFloat pRatio = p8new / p8old;
7368 MFloat rhoERatio = rhoE8new / rhoE8old;
7371 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
7373 m_cells->pvariables[PV->RHO][cellId] *= rhoRatio;
7375 for(
MInt i = 0; i < nDim; ++i) {
7376 m_cells->pvariables[PV->VV[i]][cellId] *= velRatio;
7379 m_cells->pvariables[PV->P][cellId] *= pRatio;
7383 if(m_spongeLayerType == 2) {
7384 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
7385 m_cells->fq[FQ->SPONGE_RHO][cellId] *= rhoRatio;
7386 m_cells->fq[FQ->SPONGE_RHO_E][cellId] *= rhoERatio;
7390 if(m_spongeLayerType == 4) {
7391 for(
MInt cellId = 0; cellId < m_noCells; ++cellId) {
7392 m_cells->fq[FQ->SPONGE_RHO][cellId] *= rhoRatio;
7397 computeConservativeVariables();
7399 m_log <<
"converting restart variables from old Ma: " << oldMa <<
" to new Ma: " << m_Ma <<
" ... SUCCESSFUL!"
7414 const MString namePrefix =
"b" + std::to_string(solverId()) +
"_";
7417 const MInt noCells = m_noCells;
7419 domainInfo.emplace_back(namePrefix +
"noStructuredCells", noCells);
7426 const MBool NotUsed(allTimings)) {
7428 const MString namePrefix =
"b" + std::to_string(solverId()) +
"_";
7431 solverTimings.emplace_back(namePrefix +
"Viscous Flux", RETURN_TIMER_TIME(m_timers[Timers::ViscousFlux]));
7432 solverTimings.emplace_back(namePrefix +
"ConvectiveFlux", RETURN_TIMER_TIME(m_timers[Timers::ConvectiveFlux]));
7433 solverTimings.emplace_back(namePrefix +
"Exchange", RETURN_TIMER_TIME(m_timers[Timers::Exchange]));
7434 solverTimings.emplace_back(namePrefix +
"BoundaryCondition", RETURN_TIMER_TIME(m_timers[Timers::BoundaryCondition]));
7435 solverTimings.emplace_back(namePrefix +
"RungeKutta Step", RETURN_TIMER_TIME(m_timers[Timers::RungeKutta]));
7436 solverTimings.emplace_back(namePrefix +
"Save output", RETURN_TIMER_TIME(m_timers[Timers::SaveOutput]));
7437 solverTimings.emplace_back(namePrefix +
"Save forces", RETURN_TIMER_TIME(m_timers[Timers::SaveForces]));
7438 solverTimings.emplace_back(namePrefix +
"Save auxdata", RETURN_TIMER_TIME(m_timers[Timers::SaveAuxdata]));
7439 solverTimings.emplace_back(namePrefix +
"Save boxes", RETURN_TIMER_TIME(m_timers[Timers::SaveBoxes]));
7440 solverTimings.emplace_back(namePrefix +
"Save intp points", RETURN_TIMER_TIME(m_timers[Timers::SaveIntpPoints]));
7441 solverTimings.emplace_back(namePrefix +
"Save solution", RETURN_TIMER_TIME(m_timers[Timers::SaveSolution]));
7442 solverTimings.emplace_back(namePrefix +
"Sandpaper tripping", RETURN_TIMER_TIME(m_timers[Timers::SandpaperTrip]));
7443 solverTimings.emplace_back(namePrefix +
"Moving Grid", RETURN_TIMER_TIME(m_timers[Timers::MovingGrid]));
7444 solverTimings.emplace_back(namePrefix +
"Moving grid volume flux", RETURN_TIMER_TIME(m_timers[Timers::MGVolumeFlux]));
7445 solverTimings.emplace_back(namePrefix +
"MG Move Grid", RETURN_TIMER_TIME(m_timers[Timers::MGMoveGrid]));
7459 m_log <<
"initialization of falkner scan cooke " << endl;
7465 vector<ParallelIo::size_type> dims = parallelIo.getArrayDims(
"eta");
7466 m_fsc_noPoints = (
MInt)(dims[0]);
7467 parallelIo.setOffset(m_fsc_noPoints, 0);
7470 mAlloc(m_fsc_eta, m_fsc_noPoints,
"m_fsc_eta", AT_);
7471 mAlloc(m_fsc_fs, m_fsc_noPoints,
"m_fsc_fs", AT_);
7472 mAlloc(m_fsc_f, m_fsc_noPoints,
"m_fsc_f", AT_);
7473 mAlloc(m_fsc_g, m_fsc_noPoints,
"m_fsc_g", AT_);
7476 parallelIo.readArray(m_fsc_eta,
"eta");
7477 parallelIo.readArray(m_fsc_fs,
"fprim");
7478 parallelIo.readArray(m_fsc_g,
"g");
7479 parallelIo.readScalar(&m_fsc_m,
"m");
7482 m_fsc_Re = cos(m_angle[1]) * m_Re;
7496 m_fsc_x0 = Context::getSolverProperty<MFloat>(
"fscX0", m_solverId, AT_, &m_fsc_x0);
7512 m_fsc_dx0 = Context::getSolverProperty<MFloat>(
"fscDX0", m_solverId, AT_, &m_fsc_dx0);
7527 m_fsc_y0 = Context::getSolverProperty<MFloat>(
"fscY0", m_solverId, AT_, &m_fsc_y0);
7530 m_log <<
"fsc Reynolds number " << m_fsc_Re << endl;
7531 m_log <<
"acceleration parameter " << m_fsc_m << endl;
7532 m_log <<
"reference location x " << m_fsc_x0 << endl;
7533 m_log <<
"reference location in maia coords " << m_fsc_dx0 << endl;
7534 m_log <<
"y position of no-slip " << m_fsc_y0 << endl;
7537 const MFloat detaB2 = m_fsc_eta[1] / F2;
7539 for(
MInt i = 1; i < m_fsc_noPoints; i++)
7540 m_fsc_f[i] = m_fsc_f[i - 1] + detaB2 * (m_fsc_fs[i - 1] + m_fsc_fs[i]);
7543 if(
true && !domainId()) {
7546 fscf.
open(
"fsc_raw.dat", ios::trunc);
7548 fscf <<
"#eta fs f g" << endl;
7549 for(
MInt i = 0; i < m_fsc_noPoints; i++) {
7550 fscf << m_fsc_eta[i] <<
" " << m_fsc_fs[i] <<
" " << m_fsc_f[i] <<
" " << m_fsc_g[i] << endl;
7555 m_log <<
" done " << endl;
7561 return getFscPressure(m_cells->coordinates[0][cellId]);
7566 const MFloat dx = coordX - m_fsc_dx0;
7567 const MFloat x = m_fsc_x0 + dx;
7569 const MFloat fac = CV->rhoInfinity *
POW2(PV->UInfinity) * F1B2;
7570 return PV->PInfinity + fac * (F1 - pow(x / m_fsc_x0, F2 * m_fsc_m));
7582 getFscVelocity(m_cells->coordinates[0][cellId], m_cells->coordinates[1][cellId], vel);
7587 const MFloat dx = coordX - m_fsc_dx0;
7588 const MFloat x = m_fsc_x0 + dx;
7589 const MFloat y = coordY - m_fsc_y0;
7590 return y * sqrt((m_fsc_m + F1) * m_fsc_Re * pow(x / m_fsc_x0, m_fsc_m) / (F2 * x));
7597 const MFloat eta = getFscEta(coordX, coordY);
7598 const MFloat dx = coordX - m_fsc_dx0;
7599 const MFloat x = m_fsc_x0 + dx;
7603 if(eta >= m_fsc_eta[m_fsc_noPoints - 1]) {
7604 fs = m_fsc_fs[m_fsc_noPoints - 1];
7605 f = m_fsc_f[m_fsc_noPoints - 1] + m_fsc_fs[m_fsc_noPoints - 1] * (eta - m_fsc_eta[m_fsc_noPoints - 1]);
7606 }
else if(eta <= F0) {
7611 const MFloat Deta = m_fsc_eta[1];
7612 const MInt etai = eta / Deta;
7613 ASSERT((etai + 1) <= (m_fsc_noPoints - 1),
"error computing the index for fsc distributions");
7614 const MFloat deta = eta - m_fsc_eta[etai];
7615 const MFloat phi = deta / Deta;
7616 fs = m_fsc_fs[etai] * (F1 - phi) + m_fsc_fs[etai + 1] * phi;
7617 f = m_fsc_f[etai] * (F1 - phi) + m_fsc_f[etai + 1] * phi;
7621 vel[0] = PV->UInfinity * pow(x / m_fsc_x0, m_fsc_m) * fs;
7623 const MFloat fac = sqrt(F2 * pow(x / m_fsc_x0, m_fsc_m) / ((m_fsc_m + F1) * m_fsc_x0 * m_fsc_Re)) / F2;
7625 vel[1] = PV->UInfinity * fac * ((F1 - m_fsc_m) * fs * eta - (F1 + m_fsc_m) * f);
7628 IF_CONSTEXPR(nDim > 2) {
7630 if(eta >= m_fsc_eta[m_fsc_noPoints - 1]) {
7631 g = m_fsc_g[m_fsc_noPoints - 1];
7632 }
else if(eta <= F0) {
7636 const MFloat Deta = m_fsc_eta[1];
7637 const MInt etai = eta / Deta;
7638 ASSERT((etai + 1) <= (m_fsc_noPoints - 1),
"error computing the index for fsc distributions");
7639 const MFloat deta = eta - m_fsc_eta[etai];
7640 const MFloat phi = deta / Deta;
7641 g = m_fsc_g[etai] * (F1 - phi) + m_fsc_g[etai + 1] * phi;
7643 vel[2] = PV->WInfinity * g;
7660 const MFloat fppwall = 0.332051914927913096446;
7663 const MFloat etamax = 20.0;
7664 const MFloat deta = 0.001;
7665 const MInt steps = etamax / deta;
7669 blasius(0, 3) = fppwall;
7672 for(
MInt i = 0; i < steps; i++) {
7673 blasius(i + 1, 0) = blasius(i, 0) + deta;
7674 blasius(i + 1, 1) = blasius(i, 1) + blasius(i, 2) * deta;
7675 blasius(i + 1, 2) = blasius(i, 2) + blasius(i, 3) * deta;
7676 blasius(i + 1, 3) = blasius(i, 3) + (-0.5 * blasius(i, 1) * blasius(i, 3)) * deta;
7679 m_blasius_noPoints = steps;
7682 mAlloc(m_blasius_eta, m_blasius_noPoints,
"m_blasius_eta", AT_);
7683 mAlloc(m_blasius_fp, m_blasius_noPoints,
"m_blasius_fp", AT_);
7684 mAlloc(m_blasius_f, m_blasius_noPoints,
"m_blasius_f", AT_);
7686 const MFloat finalfp = blasius(steps - 1, 2);
7688 for(
MInt i = 0; i < steps; i++) {
7689 m_blasius_eta[i] = blasius(i, 0);
7690 m_blasius_f[i] = blasius(i, 1) / finalfp;
7691 m_blasius_fp[i] = blasius(i, 2) / finalfp;
7695 if(domainId() == 0) {
7698 blasiusf.open(
"blasius_raw.dat", ios::trunc);
7700 blasiusf <<
"#eta f fp" << endl;
7701 for(
MInt i = 0; i < m_blasius_noPoints; i++) {
7702 blasiusf << m_blasius_eta[i] <<
" " << m_blasius_f[i] <<
" " << m_blasius_fp[i] << endl;
7708 m_blasius_dx0 = 0.0;
7722 getBlasiusVelocity(m_cells->coordinates[0][cellId], m_cells->coordinates[1][cellId], vel);
7727 const MFloat nu8 = SUTHERLANDLAW(PV->TInfinity) / CV->rhoInfinity;
7728 m_blasius_x0 = F1 /
POW2(1.7208) * PV->UInfinity / nu8 * m_Re0;
7730 const MFloat dx = coordX - m_blasius_dx0;
7731 const MFloat x = m_blasius_x0 + dx;
7732 const MFloat y = coordY - m_blasius_y0;
7734 return y * sqrt(PV->UInfinity * m_Re0 / (nu8 * x));
7741 const MFloat nu8 = SUTHERLANDLAW(PV->TInfinity) / CV->rhoInfinity;
7742 m_blasius_x0 = F1 /
POW2(1.7208) * PV->UInfinity / nu8 * m_Re0;
7743 const MFloat eta = getBlasiusEta(coordX, coordY);
7744 const MFloat dx = coordX - m_blasius_dx0;
7745 const MFloat x = m_blasius_x0 + dx;
7749 if(eta >= m_blasius_eta[m_blasius_noPoints - 1]) {
7750 fp = m_blasius_fp[m_blasius_noPoints - 1];
7751 f = m_blasius_f[m_blasius_noPoints - 1]
7752 + m_blasius_fp[m_blasius_noPoints - 1] * (eta - m_blasius_eta[m_blasius_noPoints - 1]);
7753 }
else if(eta <= F0) {
7758 const MFloat Deta = m_blasius_eta[1];
7759 const MInt etai = eta / Deta;
7760 ASSERT((etai + 1) <= (m_blasius_noPoints - 1),
"error computing the index for Blasius distributions");
7761 const MFloat deta = eta - m_blasius_eta[etai];
7762 const MFloat phi = deta / Deta;
7763 fp = m_blasius_fp[etai] * (F1 - phi) + m_blasius_fp[etai + 1] * phi;
7764 f = m_blasius_f[etai] * (F1 - phi) + m_blasius_f[etai + 1] * phi;
7767 vel[0] = PV->UInfinity * fp;
7768 vel[1] = F1B2 * sqrt(PV->UInfinity * nu8 / (x * m_Re0)) * (eta * fp - f);
7769 IF_CONSTEXPR(nDim == 3) { vel[2] = 0.0; }
7780 RECORD_TIMER_START(m_timers[Timers::RunInit]);
7781 initializeRungeKutta();
7784 RECORD_TIMER_START(m_timers[Timers::Run]);
7785 RECORD_TIMER_START(m_timers[Timers::MainLoop]);
7786 initSolutionStep(-1);
7787 RECORD_TIMER_STOP(m_timers[Timers::MainLoop]);
7788 RECORD_TIMER_STOP(m_timers[Timers::Run]);
7791 RECORD_TIMER_STOP(m_timers[Timers::RunInit]);
7796 this->postprocessPreInit();
7797 this->postprocessPreSolve();
7809 m_detailAuxData =
true;
7813 const MInt noFields = nDim + m_detailAuxData * 2 * nDim;
7815 MInt noAuxDataMaps = m_windowInfo->physicalAuxDataMap.size();
7816 if(noAuxDataMaps > 0) {
7817 mAlloc(m_cells->cfOffsets, noAuxDataMaps,
"m_cells->cfOffsets", 0, AT_);
7818 mAlloc(m_cells->cpOffsets, noAuxDataMaps,
"m_cells->cpOffsets", 0, AT_);
7819 mAlloc(m_cells->powerOffsets, noAuxDataMaps,
"m_cells->powerOffsets", 0, AT_);
7821 MInt totalSizeCf = 0, totalSizeCp = 0, totalSizePower = 0;
7822 for(
MInt i = 0; i < noAuxDataMaps; ++i) {
7824 for(
MInt j = 0; j < nDim; ++j) {
7825 if(m_windowInfo->physicalAuxDataMap[i]->end1[j] == m_windowInfo->physicalAuxDataMap[i]->start1[j]) {
7828 dataSize *= m_windowInfo->physicalAuxDataMap[i]->end1[j] - m_windowInfo->physicalAuxDataMap[i]->start1[j];
7830 m_cells->cfOffsets[i] = totalSizeCf;
7831 m_cells->cpOffsets[i] = totalSizeCp;
7832 m_cells->powerOffsets[i] = totalSizePower;
7833 totalSizeCf += dataSize * noFields;
7834 totalSizeCp += dataSize;
7835 totalSizePower += dataSize * nDim;
7838 if(totalSizeCf > 0) {
7839 mAlloc(m_cells->cf, totalSizeCf,
"m_cells->cf", -1.23456123456, AT_);
7841 if(totalSizeCp > 0) {
7842 mAlloc(m_cells->cp, totalSizeCp,
"m_cells->cp", -1.23456123456, AT_);
7846 if(totalSizePower > 0) {
7847 mAlloc(m_cells->powerVisc, totalSizePower,
"m_cells->power", -1.23456123456, AT_);
7848 mAlloc(m_cells->powerPres, totalSizePower,
"m_cells->power", -1.23456123456, AT_);
7852 m_forceHeaderNames.clear();
7853 m_forceHeaderNames.push_back(
"n");
7854 m_forceHeaderNames.push_back(
"t_ac");
7855 m_forceHeaderNames.push_back(
"t_conv");
7856 m_forceHeaderNames.push_back(
"f_x");
7857 m_forceHeaderNames.push_back(
"f_x,v");
7858 m_forceHeaderNames.push_back(
"f_x,p");
7859 m_forceHeaderNames.push_back(
"f_x,c");
7860 m_forceHeaderNames.push_back(
"f_y");
7861 m_forceHeaderNames.push_back(
"f_y,v");
7862 m_forceHeaderNames.push_back(
"f_y,p");
7863 m_forceHeaderNames.push_back(
"f_y,c");
7864 IF_CONSTEXPR(nDim == 3) {
7865 m_forceHeaderNames.push_back(
"f_z");
7866 m_forceHeaderNames.push_back(
"f_z,v");
7867 m_forceHeaderNames.push_back(
"f_z,p");
7868 m_forceHeaderNames.push_back(
"f_z,c");
7870 m_forceHeaderNames.push_back(
"area");
7872 m_forceHeaderNames.push_back(
"P_x");
7873 m_forceHeaderNames.push_back(
"P_x,v");
7874 m_forceHeaderNames.push_back(
"P_x,p");
7875 m_forceHeaderNames.push_back(
"P_y");
7876 m_forceHeaderNames.push_back(
"P_y,v");
7877 m_forceHeaderNames.push_back(
"P_y,p");
7878 IF_CONSTEXPR(nDim == 3) {
7879 m_forceHeaderNames.push_back(
"P_z");
7880 m_forceHeaderNames.push_back(
"P_z,v");
7881 m_forceHeaderNames.push_back(
"P_z,p");
7885 m_noForceDataFields = (
MInt)m_forceHeaderNames.size();
7888 const MInt noWalls = m_windowInfo->m_auxDataWindowIds.size();
7889 if(m_forceAsciiOutputInterval > 0 && noWalls * m_noForceDataFields > 0) {
7890 mAlloc(m_forceData, m_forceAsciiOutputInterval, noWalls * m_noForceDataFields,
"m_forceData", F0, AT_);
7894 if(noWalls * m_noForceDataFields > 0) {
7895 mAlloc(m_forceCoef, noWalls * m_noForceDataFields,
"m_forceCoef", F0, AT_);
7900 IF_CONSTEXPR(nDim == 3) {
7901 if(m_bForceLineAverage) {
7903 computeDomainWidth();
7907 if(domainId() == 0 && m_forceAsciiOutputInterval != 0) {
7909 const MInt noWalls = m_windowInfo->m_auxDataWindowIds.size();
7911 m_lastForceOutputTimeStep = -1;
7912 m_lastForceComputationTimeStep = -1;
7915 for(
MInt i = 0; i < noWalls; ++i) {
7918 MString filename =
"./forces." + iWall.str() +
".dat";
7921 if(FILE* file = fopen(filename.c_str(),
"r")) {
7925 f_forces = fopen(filename.c_str(),
"a+");
7928 "# Force coefficient file, the force coefficents in the 2 or 3 space directions\n"
7929 "# are listed in columns, the subscript v denotes a viscous force, p a pressure force,\n"
7930 "# and c the compressible contribution of the stress tensor\n");
7931 fprintf(f_forces,
"# 1:%s ", m_forceHeaderNames[0].c_str());
7932 for(
MInt j = 1; j < (
MInt)m_forceHeaderNames.size(); j++) {
7933 fprintf(f_forces,
" %d:%s ", (j + 1), m_forceHeaderNames[j].c_str());
7935 fprintf(f_forces,
"\n");
7949 const MInt noWalls = m_windowInfo->m_auxDataWindowIds.size();
7950 MPI_Allreduce(MPI_IN_PLACE, m_forceCoef, noWalls * m_noForceDataFields, MPI_DOUBLE, MPI_SUM, m_StructuredComm, AT_,
7951 "MPI_IN_PLACE",
"m_forceCoef");
7953 if(m_bForceLineAverage) {
7954 for(
MInt i = 0; i < noWalls * m_noForceDataFields; ++i) {
7955 m_forceCoef[i] /= m_globalDomainWidth;
7970 const MInt noWalls = m_windowInfo->m_auxDataWindowIds.size();
7973 for(
MInt i = 0; i < noWalls * m_noForceDataFields; ++i) {
7974 force(i) = m_forceCoef[i];
7978 MPI_Reduce(force.
begin(), m_forceCoef, noWalls * m_noForceDataFields, MPI_DOUBLE, MPI_SUM, 0, m_StructuredComm, AT_,
7979 "force",
"forceCoef");
7980 if(m_bForceLineAverage) {
7981 for(
MInt i = 0; i < noWalls * m_noForceDataFields; ++i) {
7982 m_forceCoef[i] /= m_globalDomainWidth;
7990 if(m_bForce && m_bPower) {
7991 computeFrictionPressureCoef(
true);
7993 computeFrictionPressureCoef(
false);
7996 if(m_bForce) computeForceCoef();
8002 if(m_bForce && m_bPower) {
8003 computeFrictionPressureCoef(
true);
8005 computeFrictionPressureCoef(
false);
8008 if(m_bForce) computeForceCoefRoot();
8023 if(noNghbrIds == 0)
return F0;
8025 const MFloat normalizationFactor = 1 / 0.01;
8027 for(
MInt n = 0; n < noNghbrIds; n++) {
8028 MInt nghbrId = nghbr[n];
8030 for(
MInt i = 0; i < nDim; i++) {
8031 dx[i] = (m_cells->coordinates[i][nghbrId] - m_grid->m_coordinates[i][ijk]) * normalizationFactor;
8034 tmpA(n, 0) = F1 * normalizationFactor;
8035 for(
MInt i = 0; i < nDim; i++) {
8036 tmpA(n, i + 1) = dx[i];
8046 for(
MInt n = 0; n < noNghbrIds; n++) {
8047 for(
MInt i = 0; i < nDim + 1; i++) {
8048 m_singularity[sID].ReconstructionConstants[i][ID + n] = tmpC(i, n) * normalizationFactor;
8062 exchange(m_sndComm, m_rcvComm);
8072 RECORD_TIMER_START(m_timers[Timers::Exchange]);
8078 if(noDomains() > 1) {
8079 std::vector<MPI_Request> sndRequests;
8080 std::vector<MPI_Request> rcvRequests;
8081 std::vector<MPI_Status> sndStatus;
8082 std::vector<MPI_Status> rcvStatus;
8083 sndRequests.reserve(sndComm.size());
8084 rcvRequests.reserve(rcvComm.size());
8086 RECORD_TIMER_START(m_timers[Timers::Gather]);
8087 gather(
false, sndComm);
8088 RECORD_TIMER_STOP(m_timers[Timers::Gather]);
8090 RECORD_TIMER_START(m_timers[Timers::Send]);
8091 send(
false, sndComm, sndRequests);
8092 RECORD_TIMER_STOP(m_timers[Timers::Send]);
8094 RECORD_TIMER_START(m_timers[Timers::Receive]);
8095 receive(
false, rcvComm, rcvRequests);
8096 RECORD_TIMER_STOP(m_timers[Timers::Receive]);
8098 RECORD_TIMER_START(m_timers[Timers::SendWait]);
8099 sndStatus.resize(sndRequests.size());
8100 MPI_Waitall(sndRequests.size(), &sndRequests[0], &sndStatus[0], AT_);
8101 RECORD_TIMER_STOP(m_timers[Timers::SendWait]);
8103 RECORD_TIMER_START(m_timers[Timers::ReceiveWait]);
8104 rcvStatus.resize(rcvRequests.size());
8105 MPI_Waitall(rcvRequests.size(), &rcvRequests[0], &rcvStatus[0], AT_);
8106 RECORD_TIMER_STOP(m_timers[Timers::ReceiveWait]);
8108 RECORD_TIMER_START(m_timers[Timers::Scatter]);
8109 scatter(
false, rcvComm);
8110 RECORD_TIMER_STOP(m_timers[Timers::Scatter]);
8117 for(
MInt periodicDir = 0; periodicDir < nDim; periodicDir++) {
8118 std::vector<MPI_Request> sndRequests;
8119 std::vector<MPI_Request> rcvRequests;
8120 std::vector<MPI_Status> sndStatus;
8121 std::vector<MPI_Status> rcvStatus;
8122 sndRequests.reserve(sndComm.size());
8123 rcvRequests.reserve(rcvComm.size());
8125 m_currentPeriodicDirection = periodicDir;
8126 RECORD_TIMER_START(m_timers[Timers::Gather]);
8127 gather(
true, sndComm);
8128 RECORD_TIMER_STOP(m_timers[Timers::Gather]);
8130 RECORD_TIMER_START(m_timers[Timers::Send]);
8131 send(
true, sndComm, sndRequests);
8132 RECORD_TIMER_STOP(m_timers[Timers::Send]);
8134 RECORD_TIMER_START(m_timers[Timers::Receive]);
8135 receive(
true, rcvComm, rcvRequests);
8136 RECORD_TIMER_STOP(m_timers[Timers::Receive]);
8138 RECORD_TIMER_START(m_timers[Timers::SendWait]);
8139 sndStatus.resize(sndRequests.size());
8140 MPI_Waitall(sndRequests.size(), &sndRequests[0], &sndStatus[0], AT_);
8141 RECORD_TIMER_STOP(m_timers[Timers::SendWait]);
8143 RECORD_TIMER_START(m_timers[Timers::ReceiveWait]);
8144 rcvStatus.resize(rcvRequests.size());
8145 MPI_Waitall(rcvRequests.size(), &rcvRequests[0], &rcvStatus[0], AT_);
8146 RECORD_TIMER_STOP(m_timers[Timers::ReceiveWait]);
8148 RECORD_TIMER_START(m_timers[Timers::Scatter]);
8149 scatter(
true, rcvComm);
8150 RECORD_TIMER_STOP(m_timers[Timers::Scatter]);
8153 RECORD_TIMER_STOP(m_timers[Timers::Exchange]);
8160 std::vector<MPI_Request>& sndRequests) {
8161 for(
auto& snd : sndComm) {
8162 if(periodicExchange && skipPeriodicDirection(snd))
continue;
8164 MPI_Request request{};
8165 const MInt tag = domainId() + (snd->tagHelper) * noDomains();
8166 const MInt err =
MPI_Isend((
void*)&snd->cellBuffer[0], snd->cellBufferSize, MPI_DOUBLE, snd->nghbrId, tag,
8167 m_StructuredComm, &request, AT_,
"snd->cellBuffer");
8168 sndRequests.push_back(request);
8169 if(err) cout <<
"rank " << domainId() <<
" sending throws error " << endl;
8176 std::vector<MPI_Request>& rcvRequests) {
8177 for(
auto& rcv : rcvComm) {
8178 if(periodicExchange && skipPeriodicDirection(rcv))
continue;
8180 MPI_Request request{};
8181 const MInt tag = rcv->nghbrId + (rcv->tagHelper) * noDomains();
8182 const MInt err =
MPI_Irecv((
void*)&rcv->cellBuffer[0], rcv->cellBufferSize, MPI_DOUBLE, rcv->nghbrId, tag,
8183 m_StructuredComm, &request, AT_,
"rcv->cellBuffer");
8184 rcvRequests.push_back(request);
8185 if(err) cout <<
"rank " << domainId() <<
" sending throws error " << endl;
8192 const MInt currentDirection = (comm->bcId - 4401) / 2;
8193 return ((
MBool)(m_currentPeriodicDirection - currentDirection));
8219 RECORD_TIMER_START(m_timers[Timers::ViscousFlux]);
8221 RECORD_TIMER_STOP(m_timers[Timers::ViscousFlux]);
8224 if(m_considerVolumeForces) {
8226 computeVolumeForces();
8229 if(m_blockType ==
"porous") {
8231 computePorousRHS(
true);
8233 computePorousRHS(
false);
8243 RECORD_TIMER_START(m_timers[Timers::UpdateSponge]);
8244 updateSpongeLayer();
8245 RECORD_TIMER_STOP(m_timers[Timers::UpdateSponge]);
8250 computePrimitiveVariables();
8255 computeCumulativeAverage(
false);
8256 if(
globalTimeStep % m_zonalExchangeInterval == 0 && m_RKStep == 0) {
8257 spanwiseAvgZonal(m_zonalSpanwiseAvgVars);
8262 RECORD_TIMER_START(m_timers[Timers::BoundaryCondition]);
8263 applyBoundaryCondition();
8264 RECORD_TIMER_STOP(m_timers[Timers::BoundaryCondition]);
8269 RECORD_TIMER_START(m_timers[Timers::Run]);
8270 RECORD_TIMER_START(m_timers[Timers::MainLoop]);
8275 RECORD_TIMER_START(m_timers[Timers::RungeKutta]);
8276 const MBool step = rungeKuttaStep();
8277 RECORD_TIMER_STOP(m_timers[Timers::RungeKutta]);
8279 RECORD_TIMER_START(m_timers[Timers::SetTimeStep]);
8280 if(step) setTimeStep();
8281 RECORD_TIMER_STOP(m_timers[Timers::SetTimeStep]);
8285 RECORD_TIMER_STOP(m_timers[Timers::MainLoop]);
8286 RECORD_TIMER_STOP(m_timers[Timers::Run]);
8298 RECORD_TIMER_START(m_timers[Timers::Run]);
8299 RECORD_TIMER_START(m_timers[Timers::MainLoop]);
8300 m_timeStepConverged = maxResidual();
8301 RECORD_TIMER_STOP(m_timers[Timers::MainLoop]);
8302 RECORD_TIMER_STOP(m_timers[Timers::Run]);
8308 RECORD_TIMER_START(m_timers[Timers::Run]);
8312 if(m_forceAsciiOutputInterval != 0) {
8313 saveForcesToAsciiFile(
true);
8315 if(m_pointsToAsciiOutputInterval != 0) {
8316 savePointsToAsciiFile(
true);
8319 saveAverageRestart();
8322 this->postprocessPostSolve();
8323 RECORD_TIMER_STOP(m_timers[Timers::Run]);
MLong allocatedBytes()
Return the number of allocated bytes.
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.
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
Base class of the structured solver.
void saveSolution(MBool)
Saves the soution to hdf5 file.
virtual MFloat getBlasiusEta(MFloat coordX, MFloat coordY)
MBool isPeriodicComm(std::unique_ptr< StructuredComm< nDim > > &)
void saveDissipation(MString, MFloat *)
Writes the dissipation into a given file.
void setInputOutputProperties()
Reads properties and initializes variables associated with input/output.
std::unique_ptr< FvStructuredSolverWindowInfo< nDim > > m_windowInfo
MInt timer(const MInt timerId) const
MInt m_rescalingCommGrRootGlobal
void initializeFvStructuredSolver(MBool *propertiesGroups)
Structured Solver Constructor reads and allocate properties/variables.
void checkNans()
Checks whole domain for NaNs and adds the number of NaNs globally.
void readAndSetAuxDataMap()
MPI_Comm m_rescalingCommGrComm
MInt m_periodicConnection
virtual void initStructuredPostprocessing()
PostProcessingSolver interface:
void receive(const MBool, std::vector< std::unique_ptr< StructuredComm< nDim > > > &, std::vector< MPI_Request > &)
FvStructuredSolver(MInt solverId, StructuredGrid< nDim > *, MBool *propertiesGroups, const MPI_Comm comm)
Constructor of the structured solver.
void postTimeStep() override
: Performs the post time step
void saveSolverSolution(MBool=false, const MBool=false) override
MFloat pythag(MFloat a, MFloat b)
void send(const MBool, std::vector< std::unique_ptr< StructuredComm< nDim > > > &, std::vector< MPI_Request > &)
void loadRestartFile()
Load Restart File (primitive and conservative output) general formulation.
void saveGradients(MString, MFloat **, MString *)
Writes the gradients into a given file.
virtual void initBlasius()
Init for Blasius boundary layer.
void getDomainDecompositionInformation(std::vector< std::pair< MString, MInt > > &domainInfo) override
Return decomposition information, i.e. number of local elements,...
void saveForcesToAsciiFile(MBool)
Function to save the force coefficients and power to an ASCII file.
MFloat computeRecConstSVD(const MInt ijk, const MInt noNghbrIds, MInt *nghbr, MInt ID, MInt sID, MFloatScratchSpace &tmpA, MFloatScratchSpace &tmpC, MFloatScratchSpace &weights, const MInt recDim)
AUX DATA ENDS /////////////////////////////////////////////////////////////.
MBool skipPeriodicDirection(std::unique_ptr< StructuredComm< nDim > > &)
void tred2(MFloatScratchSpace &A, MInt dim, MFloat *diag, MFloat *offdiag)
Householder Reduction according to Numercial Recipies in C: The Art of Scientific Computing.
void getSolverTimings(std::vector< std::pair< MString, MFloat > > &solverTimings, const MBool allTimings) override
Get solver timings.
void setBodyForceProperties()
Reads and initializes properties associated with the Moving Grid Methods.
MInt m_commBC2600RootGlobal
virtual ~FvStructuredSolver()
std::array< MInt, Timers::_count > m_timers
void finalizeInitSolver() override
MInt m_rescalingCommGrRoot
virtual void saveAverageRestart()
void setMovingGridProperties()
Reads and initializes properties associated with the Moving Grid Methods.
std::vector< std::unique_ptr< StructuredComm< nDim > > > m_sndComm
StructuredGrid< nDim > * m_grid
MInt determineRestartTimeStep() const override
Load the restart time step from the restart file (useNonSpecifiedRestartFile enabled)
MPI_Comm m_commPerRotWorld
virtual void computeConservativeVariables()
MBool m_setLocalWallDistance
void fixTimeStepTravelingWave()
void shiftCellValuesRestart(MBool)
MBool loadBoxFile(MString, MString, MInt, MInt)
Load Box file general formulation.
SingularInformation * m_singularity
void convertRestartVariables(MFloat oldMa)
void saveAveragedVariables(MString, MInt, MFloat **)
Saves the averaged (mean) variables from postprocessing to an HDF5 file.
void initializeRungeKutta()
void savePartitions()
Saves the partitioned grid into an HDF5 file. Not used in production use but useful for debugging.
virtual void getBlasiusVelocity(MInt cellId, MFloat *const vel)
Load variables for the specified timeStep.
void saveProductionTerms(MString, MFloat **)
Writes the production terms into a given file.
virtual MFloat getFscEta(MFloat coordX, MFloat coordY)
std::unique_ptr< MPrimitiveVariables< nDim > > PV
void setRungeKuttaProperties()
This function reads the properties required for Runge Kutta time stepping.
void saveForceCoefficient(ParallelIoHdf5 *parallelIoHdf5)
Saves force coefficients to an HDF5 file.
void setZonalProperties()
Set which zones are RANS and which are LES or if full LES or full RANS.
virtual void initFsc()
Init for Falkner-Skan-Cooke flow.
void setTestcaseProperties()
Reads and initializes properties associated with the Testcase.
void setNumericalProperties()
Reads and initializes properties associated with the numerical method.
MPI_Comm m_StructuredComm
virtual MFloat getFscPressure(MInt cellId)
void tqli2(MFloat *diag, MFloat *offdiag, MInt dim)
Compute Eigenvalues with implicit shift according to Numercial Recipies in C: The Art of Scientific C...
void computeForceCoef()
Function to compute the force coefficient cl, split split into the viscous part cLv and the pressure ...
MPI_Comm m_commChannelWorld
virtual void writePropertiesAsAttributes(ParallelIoHdf5 *pio, MString path)
Overloaded version of writePropertiesAsAttributes that receives ParallelIoHdf5 object pointer instead...
void computeAuxDataRoot()
void allocateAndInitBlockMemory()
void initializeFQField()
Counts the number of necessary FQ fields, allocates them and corrects the indexes of the FQ variable ...
void initSolver() override
void exchange()
SVD STUFF ENDS /////////////////////////////////////////////////////////////.
MPI_Comm m_commChannelOut
void readAndSetSpongeLayerProperties()
void setPorousProperties()
Set properties for porous blocks.
std::vector< std::unique_ptr< StructuredComm< nDim > > > m_rcvComm
MBool solutionStep() override
void computeConservativeVariables_()
void setProfileBCProperties()
virtual void getFscVelocity(MInt cellId, MFloat *const vel)
Load variables for the specified timeStep.
void resetRHS()
Reset the right hand side to zero.
void computeForceCoefRoot()
Function to compute the coefficient, split split into the viscous part cLv and the pressure part cLp ...
void allocateAuxDataMaps()
AUX DATA //////////////////////////////////////////////////////////////////.
void insertSort(MInt dim, MFloat *list)
Sorting function to sort list in ascending order.
void computeVolumeForces()
virtual void writeHeaderAttributes(ParallelIoHdf5 *pio, MString fileType)
Overloaded version of writeHeaderAttributes that receives ParallelIoHdf5 object pointer instead of 'f...
void saveVarToPrimitive(MInt, MInt, MFloat)
void open(const MString &filename, const MString &projectName, MInt fileType=0, MPI_Comm mpiComm=MPI_COMM_WORLD, MBool rootOnlyHardwired=false)
Opens a file by passing the parameters to InfoOut_<xyz>FileBuffer::open(...).
void defineArray(maiabd_type type, const MString &name, size_type totalCount)
Create a new array in the file.
void writeArray(const T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Write array data to file. [MPI]
MBool hasDataset(const MString &name, MInt dimension)
Check if the file contains an dataset with the given name and dimension.
void getAttribute(T *value, const MString &name, const MString &datasetName="")
Retrieve a file or dataset attribute.
void setAttribute(const T &value, const MString &name, const MString &datasetName="")
Set a file or dataset attribute. [MPI]
void readArray(T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Read array data from file. [MPI]
static size_t getTotalMemory()
Returns the amount of total available memory in scratch.
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
Parent class of all solvers This class is the base for all solvers. I.e. all solver class (e....
virtual MInt domainId() const
Return the domainId (rank)
const MInt m_solverId
a unique solver identifier
virtual MInt noDomains() const
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW2(const Real x)
MBool approx(const T &, const U &, const T)
constexpr T mMax(const T &x, const T &y)
MInt noRansEquations(RansMethod ransMethod)
void printAllocatedMemory(const MLong oldAllocatedBytes, const MString &solverName, const MPI_Comm comm)
Prints currently allocated memory.
std::basic_string< char > MString
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Isend
int MPI_Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgatherv
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Irecv
int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm, const MString &name, const MString &varname)
same as MPI_Comm_create, but updates the number of MPI communicators
int MPI_Group_incl(MPI_Group group, int n, const int ranks[], MPI_Group *newgroup, const MString &name)
same as MPI_Group_incl
int MPI_Comm_group(MPI_Comm comm, MPI_Group *group, const MString &name, const MString &varname)
same as MPI_Comm_group
int MPI_Waitall(int count, MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Waitall
int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Reduce
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
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast
int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgather
T cos(const T a, const T b, const T x)
Cosine slope filter.
void invert(MFloat *A, const MInt m, const MInt n)
PARALLELIO_DEFAULT_BACKEND ParallelIo