49#define RAND_MAX 9999999
52template <MInt nDim_,
class SysEqn>
54template <MInt nDim_,
class SysEqn>
56template <MInt nDim_,
class SysEqn>
58template <MInt nDim_,
class SysEqn>
60template <MInt nDim_,
class SysEqn>
62template <MInt nDim_,
class SysEqn>
64template <MInt nDim_,
class SysEqn>
66template <MInt nDim_,
class SysEqn>
68template <MInt nDim_,
class SysEqn>
70template <MInt nDim_,
class SysEqn>
72template <MInt nDim_,
class SysEqn>
83template <MInt nDim_,
class SysEqn>
88 m_geometry(&geometry_),
89 m_eps(std::numeric_limits<
MFloat>::epsilon()),
90 m_noSpecies(noSpecies),
91 m_sysEqn(solverId_, noSpecies),
118 m_multilevel =
false;
119 m_multilevel = Context::getBasicProperty<MBool>(
"multilevel", AT_, &m_multilevel);
121 m_pressureRatioChannel = F1;
123 m_pressureRatioChannel = Context::getSolverProperty<MFloat>(
"pressureRatioChannel", m_solverId, AT_);
124 m_pressureRatioStartTimeStep = -1;
126 m_pressureRatioStartTimeStep = Context::getSolverProperty<MFloat>(
"pressureRatioStartTimeStep", m_solverId, AT_);
127 m_pressureRatioEndTimeStep = -1;
129 m_pressureRatioEndTimeStep = Context::getSolverProperty<MFloat>(
"pressureRatioEndTimeStep", m_solverId, AT_);
132 m_levelSet = propertiesGroups[
LEVELSET];
135 m_LSSolver = propertiesGroups[
LS_SOLVER];
136 m_levelSetRans = propertiesGroups[
LS_RANS];
139 m_wallNormalOutput =
false;
141 m_log << endl << endl <<
"Reading Wall Normal Output properties ... " << endl;
142 m_wallNormalOutput = Context::getSolverProperty<MBool>(
"wallNormalOutput", m_solverId, AT_);
143 if(m_wallNormalOutput ==
true) {
145 m_useWallNormalInterpolation = Context::getSolverProperty<MBool>(
"useWallNormalInterpolation", m_solverId, AT_);
148 m_normalBcId = Context::getSolverProperty<MInt>(
"normalBcId", m_solverId, AT_);
152 m_normalOutputInterval = Context::getSolverProperty<MInt>(
"normalOutputInterval", m_solverId, AT_);
153 m_log <<
"normalOutputInterval = " << m_normalOutputInterval << endl;
155 mTerm(1,
"normalOutputInterval not given in property file!");
160 m_normalLength = Context::getSolverProperty<MFloat>(
"normalLength", m_solverId, AT_);
162 mTerm(1,
"normalLength not given in property file!");
167 m_normalNoPoints = Context::getSolverProperty<MInt>(
"normalNoPoints", m_solverId, AT_);
168 if(m_normalNoPoints < 2) {
169 mTerm(1,
"normalNoPoints should be at least 2");
172 mTerm(1,
"normalNoPoints not given in property file");
176 for(
MInt c = 0; c < noCoords; c++) {
177 m_normalSamplingCoords.push_back(
178 Context::getSolverProperty<MFloat>(
"normalSamplingCoords", m_solverId, AT_, c));
181 for(
MInt c = 0; c < (noCoords / 2); c++) {
182 m_normalSamplingSide.push_back(Context::getSolverProperty<MInt>(
"normalSamplingSide", m_solverId, AT_, c));
184 m_log <<
"done." << endl;
191 m_saSrfcProbeInterval = 0;
193 m_saSrfcProbeInterval =
194 Context::getSolverProperty<MInt>(
"saSrfcProbeInterval", m_solverId, AT_, &m_saSrfcProbeInterval);
195 if(m_saSrfcProbeInterval > 0) {
196 Context::getSolverProperty<MInt>(
"saSrfcProbeStart", m_solverId, AT_, &m_saSrfcProbeStart);
198 m_saSrfcProbeDir =
"";
200 m_saSrfcProbeDir = Context::getSolverProperty<MString>(
"saSrfcProbeDir", m_solverId, AT_, &m_saSrfcProbeDir);
205 m_useSandpaperTrip =
false;
207 m_useSandpaperTrip = Context::getSolverProperty<MBool>(
"useSandpaperTrip", m_solverId, AT_, &m_useSandpaperTrip);
211 m_useChannelForce =
false;
213 m_useChannelForce = Context::getSolverProperty<MBool>(
"useChannelForce", m_solverId, AT_, &m_useChannelForce);
223 m_isEEGas = Context::getSolverProperty<MBool>(
"EEGas", m_solverId, AT_, &m_isEEGas);
226 IF_CONSTEXPR(isDetChem<SysEqn>) setAndAllocateDetailedChemistryProperties();
229 MInt fvCollectorMode = 0;
230 IF_CONSTEXPR(isDetChem<SysEqn>) fvCollectorMode = 1;
238 MInt fvTimeStepMode = 0;
250 m_dualTimeStepping =
false;
251 m_dualTimeStepping = Context::getSolverProperty<MBool>(
"dualTimeStepping", m_solverId, AT_, &m_dualTimeStepping);
265 m_localTS = Context::getSolverProperty<MBool>(
"localTimeStepping", m_solverId, AT_, &m_localTS);
267 if(m_dualTimeStepping) {
275 m_cells.setFvCollectorType(fvCollectorMode);
276 m_cells.setFvTimeStepType(fvTimeStepMode);
277 m_cells.setNoCVariables(CV->noVariables, m_noSpecies);
278 m_cells.setNoPVariables(PV->noVariables);
279 m_cells.setNoFVariables(FV->noVariables);
280 m_cells.setNoAVariables(AV->noVariables);
281 m_cells.isMultilevel(m_multilevel);
283 m_cells.append(c_noCells());
284 m_totalnosplitchilds = 0;
285 m_totalnoghostcells = 0;
287 for(
MInt c = 0; c < a_noCells(); c++) {
288 a_resetPropertiesSolver(c);
292 copyGridProperties();
294 initializeFvCartesianSolver(propertiesGroups);
300 allocateCommunicationMemory();
303 setTestcaseProperties();
306 setInputOutputProperties();
309 setNumericalProperties();
312 setAndAllocateAdaptationProperties();
315 setAndAllocateSpongeLayerProperties();
318 setAndAllocateJetProperties();
321 setAndAllocateCombustionGequPvProperties();
324 setAndAllocateCombustionTFProperties();
327 setAndAllocateZonalProperties();
330 readWallModelProperties();
333 allocateAndInitSolverMemory();
338 IF_CONSTEXPR(isDetChem<SysEqn>)
if(m_heatReleaseDamp) initHeatReleaseDamp();
340 if(m_geometry->m_parallelGeometry) {
341 this->receiveWindowTriangles();
344 this->checkNoHaloLayers();
349 m_gridConvergence =
false;
351 m_storeNghbrIds =
nullptr;
352 m_identNghbrIds =
nullptr;
357 m_log <<
"* Using limited surface data reconstruction." << endl;
359 switch(
string2enum(m_surfaceValueReconstruction)) {
361 m_reconstructSurfaceData = &FvCartesianSolverXD::computeSurfaceValues;
362 m_log <<
"* Using unlimited high-order surface data reconstruction." << endl;
365 m_reconstructSurfaceData = &FvCartesianSolverXD::computeSurfaceValuesLimited;
366 m_log <<
"* Using limited high-order surface data reconstruction." << endl;
370 m_log <<
"* Using unlimited low-order (pressure)/high-order surface data reconstruction." << endl;
374 m_log <<
"* Using sensor slope-limited high-order surface data reconstruction." << endl;
378 m_log <<
"* Using manual slope-limited high-order surface data reconstruction." << endl;
379 this->setCellProperties();
380 this->initComputeSurfaceValuesLimitedSlopesMan1();
383 stringstream errorMessage;
384 errorMessage <<
"FvCartesianSolverXD::FvCartesianSolverXD(): switch variable "
385 "'m_surfaceValueReconstruction' with value "
386 << m_surfaceValueReconstruction <<
" not matching any case." << endl;
387 mTerm(1, AT_, errorMessage.str());
398 computeDomainAndSpongeDimensions();
405 if(grid().azimuthalPeriodicity()) {
406 m_rotIndVarsPV.assign(PV->noVariables, 0);
407 m_rotIndVarsPV[PV->VV[grid().azimuthalDir(0)]] = 1;
408 m_rotIndVarsPV[PV->VV[grid().azimuthalDir(1)]] = 1;
409 m_rotIndVarsCV.assign(CV->noVariables, 0);
410 m_rotIndVarsCV[CV->RHO_VV[grid().azimuthalDir(0)]] = 1;
411 m_rotIndVarsCV[CV->RHO_VV[grid().azimuthalDir(1)]] = 1;
419template <MInt nDim_,
class SysEqn>
423 for(
MInt cellId = 0; cellId < a_noCells(); ++cellId) {
426 cSquared[cellId] = F0;
429 IF_CONSTEXPR(isDetChem<SysEqn>) {
430 const MFloat dt = m_timeStep;
433 for(
MInt dim = 0; dim < nDim; dim++)
434 oldVelPow2 +=
POW2(a_oldVariable(cellId, CV->RHO_VV[dim]) / a_oldVariable(cellId, CV->RHO));
437#if defined(WITH_CANTERA)
438 sysEqn().iterateTemperature(oldT, &a_oldVariable(cellId, 0), &a_pvariable(cellId, 0), &a_avariable(cellId, 0),
442 const MFloat oldP = a_oldVariable(cellId, CV->RHO) * oldT * m_gasConstant / a_avariable(cellId, AV->W_MEAN);
443 const MFloat curP = a_pvariable(cellId, PV->P);
444 const MFloat dpdt = (curP - oldP) / dt;
447 for(
MInt dim = 0; dim < nDim; dim++) {
448 divU += a_slope(cellId, PV->VV[dim], dim);
451 MFloat DrhoDt = a_pvariable(cellId, PV->RHO) * divU;
454 for(
MInt dim = 0; dim < nDim; dim++) {
455 UgradRho = a_pvariable(cellId, PV->VV[dim]) * a_slope(cellId, PV->RHO, dim);
456 UgradP = a_pvariable(cellId, PV->VV[dim]) * a_slope(cellId, PV->P, dim);
459 const MFloat DpDt = dpdt + UgradP;
461 drhodt[cellId] = DrhoDt + UgradRho;
462 cSquared[cellId] = a_avariable(cellId, AV->GAMMA) * curP / a_variable(cellId, CV->RHO);
463 QeI[cellId] = DpDt - cSquared[cellId] * DrhoDt;
464 QeIII[cellId] = cSquared[cellId] * UgradRho - UgradP;
476template <MInt nDim_,
class SysEqn>
478 const MUint noSpecies = m_noSpecies;
480 calculateHeatRelease();
482 for(
MInt cellId = 0; cellId < a_noCells(); ++cellId) {
483 if(a_isBndryGhostCell(cellId))
continue;
484 if(a_isHalo(cellId))
continue;
486 const MFloat dampeningFactor = m_heatReleaseDamp ? m_dampFactor[cellId] : F1;
489 for(
MUint s = 0; s < noSpecies; ++s) {
490 a_rightHandSide(cellId, CV->RHO_Y[s]) -=
491 dampeningFactor * a_cellVolume(cellId) * a_speciesReactionRate(cellId, s);
494 a_rightHandSide(cellId, CV->RHO_E) -= a_cellVolume(cellId) * m_heatRelease[cellId];
498template <MInt nDim_,
class SysEqn>
502 dampDist = Context::getSolverProperty<MInt>(
"dampDist", m_solverId, AT_, &dampDist);
504 MInt noDampedWalls = 0;
506 noDampedWalls = Context::getSolverProperty<MInt>(
"noDampedWalls", m_solverId, AT_, &noDampedWalls);
508 if(noDampedWalls == 0)
509 mTerm(1,
"initHeatReleaseDamp() has been called, but noDampedWalls = 0. Check properties file.");
511 std::vector<MString> filename;
512 for(
MInt Id = 0; Id < noDampedWalls; Id++) {
514 name <<
"dampedWall." << Id;
515 filename.push_back(name.str());
518 m_dampFactor.assign(a_noCells(), F1);
520 for(
MUint Id = 0; Id < filename.size(); Id++) {
521 vector<MInt> markedCells;
523 propDist.
fill(numeric_limits<MInt>::max());
525 IF_CONSTEXPR(nDim == 2) {
527 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
528 const MFloat cellHalfLength = c_cellLengthAtLevel(a_level(cellId) + 1);
529 if(!c_noChildren(cellId) && auxGeom->
isOnGeometry(cellHalfLength, &a_coordinate(cellId, 0),
"SAT"))
530 if(grid().tree().solver2grid(cellId) > -1) markedCells.push_back(grid().tree().solver2grid(cellId));
533 IF_CONSTEXPR(nDim == 3) {
535 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
536 const MFloat cellHalfLength = c_cellLengthAtLevel(a_level(cellId) + 1);
537 if(!c_noChildren(cellId) && auxGeom->
isOnGeometry(cellHalfLength, &a_coordinate(cellId, 0),
"SAT"))
539 if(grid().tree().solver2grid(cellId) > -1) markedCells.push_back(grid().tree().solver2grid(cellId));
543 MLong tmp = markedCells.size();
544 MPI_Allreduce(MPI_IN_PLACE, &tmp, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"tmp");
545 m_log <<
" overall cells on damping region: " << tmp << endl;
548 grid().raw().propagateDistance(markedCells, propDist, dampDist);
550 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
551 if(a_isBndryGhostCell(cellId))
continue;
552 const MInt gridCellId = grid().tree().solver2grid(cellId);
553 if(gridCellId < 0)
continue;
554 if(propDist[gridCellId] != numeric_limits<MInt>::max()) {
555 m_dampFactor[cellId] = (
MFloat)propDist[gridCellId] / ((
MFloat)dampDist);
560 MPI_Allreduce(MPI_IN_PLACE, &tmp, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"tmp");
561 m_log <<
" overall damped cells: " << tmp << endl;
571template <MInt nDim_,
class SysEqn>
572template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
576 if(domainId() == 0) cout <<
"Starting a full detailed chemistry simulation." << endl;
578 m_detChemExtendedOutput =
true;
579 m_detChemExtendedOutput =
580 Context::getSolverProperty<MBool>(
"detChemExtendedOutput", m_solverId, AT_, &m_detChemExtendedOutput);
582 m_acousticAnalysis =
false;
583 m_acousticAnalysis = Context::getSolverProperty<MBool>(
"acousticAnalysis", m_solverId, AT_, &m_acousticAnalysis);
585 m_YInfinity =
nullptr;
586 m_molarMass =
nullptr;
587 m_fMolarMass =
nullptr;
588 m_standardHeatFormation =
nullptr;
590 m_detChem.infSpeciesName =
nullptr;
591 m_detChem.infSpeciesMassFraction =
nullptr;
594 m_heatReleaseDamp =
true;
595 m_heatReleaseDamp = Context::getSolverProperty<MBool>(
"heatReleaseDamp", m_solverId, AT_, &m_heatReleaseDamp);
597 m_detChem.hasChemicalReaction =
598 Context::getSolverProperty<MBool>(
"hasChemicalReaction", m_solverId, AT_, &m_detChem.hasChemicalReaction);
601 m_detChem.infTemperature =
602 Context::getSolverProperty<MFloat>(
"infTemperature", m_solverId, AT_, &m_detChem.infTemperature);
603 m_detChem.infVelocity = Context::getSolverProperty<MFloat>(
"infVelocity", m_solverId, AT_, &m_detChem.infVelocity);
604 m_detChem.infPressure = Context::getSolverProperty<MFloat>(
"infPressure", m_solverId, AT_, &m_detChem.infPressure);
606 m_detChem.laminarFlameSpeedFactor = 1.0;
607 m_detChem.laminarFlameSpeedFactor = Context::getSolverProperty<MFloat>(
"laminarFlameSpeedFactor", m_solverId, AT_,
608 &m_detChem.laminarFlameSpeedFactor);
613 ASSERT(speciesArrayLength == massFractionArrayLength,
614 "Check speciesArrayLength and massFractionArrayLength. Unequal.");
616 mAlloc(m_detChem.infSpeciesName, speciesArrayLength,
"infSpeciesName", AT_);
617 mAlloc(m_detChem.infSpeciesMassFraction, massFractionArrayLength,
"infSpeciesMassFraction", AT_);
620 mAlloc(m_YInfinity, PV->m_noSpecies,
"m_YInfinity", F0, AT_);
621 mAlloc(m_molarMass, PV->m_noSpecies,
"m_molarMass", 0.0, AT_);
622 mAlloc(m_fMolarMass, PV->m_noSpecies,
"m_fMolarMass", 0.0, AT_);
623 mAlloc(m_standardHeatFormation, PV->m_noSpecies,
"m_standardHeatFormation", 0.0, AT_);
626 for(
MInt i = 0; i < speciesArrayLength; ++i) {
627 m_detChem.infSpeciesName[i] = Context::getSolverProperty<MString>(
"infSpeciesName", m_solverId, AT_, i);
628 m_detChem.infSpeciesMassFraction[i] =
629 Context::getSolverProperty<MFloat>(
"infSpeciesMassFraction", m_solverId, AT_, i);
630 summSpecies += m_detChem.infSpeciesMassFraction[i];
633 ASSERT(summSpecies - F1 < m_eps,
634 "Initial species mass fraction composition does not equal 1. Check properties file.");
636 m_detChem.infPhi = Context::getSolverProperty<MFloat>(
"infPhi", m_solverId, AT_, &m_detChem.infPhi);
639 m_detChem.reactionMechanism =
640 Context::getSolverProperty<MString>(
"reactionMechanism", m_solverId, AT_, &m_detChem.reactionMechanism);
642 m_detChem.phaseName = Context::getSolverProperty<MString>(
"phaseName", m_solverId, AT_, &m_detChem.phaseName);
644 m_detChem.transportModel =
645 Context::getSolverProperty<MString>(
"transportModel", m_solverId, AT_, &m_detChem.transportModel);
647 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
648 m_speciesName.push_back(sysEqn().m_species->speciesName[s]);
649 m_molarMass[s] = sysEqn().m_species->molarMass[s];
650 m_fMolarMass[s] = sysEqn().m_species->fMolarMass[s];
651 m_standardHeatFormation[s] = sysEqn().m_species->standardHeatFormation[s];
655 for(
MInt i = 0; i < speciesArrayLength; ++i) {
656 const MString species = m_detChem.infSpeciesName[i];
657 const MInt speciesNameFound = sysEqn().m_species->speciesMap.count(species);
658 if(speciesNameFound ==
true) {
659 const MInt speciesIndex = sysEqn().m_species->speciesMap[species];
660 m_YInfinity[speciesIndex] = m_detChem.infSpeciesMassFraction[i];
662 mTerm(1, AT_,
"Species name given in the properties file could not be found in the reaction mechanism.");
666 if(domainId() == 0) cout <<
"Allocation of detailed chemistry primary values done." << endl;
668 initCanteraObjects();
670 m_oneDimFlame = std::make_unique<OneDFlame>(m_detChem.infTemperature, m_detChem.infPressure, m_YInfinity, domainId(),
671 m_solverId, m_speciesName);
673#if defined(WITH_CANTERA)
674 m_oneDimFlame->setCanteraObjects(m_canteraSolution, m_canteraThermo, m_canteraKinetics, m_canteraTransport);
677 m_oneDimFlame->run();
679 m_oneDimFlame->log(c_cellLengthAtLevel(maxRefinementLevel()));
687template <MInt nDim_,
class SysEqn>
688template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
690#if defined(WITH_CANTERA)
691 m_canteraSolution = Cantera::newSolution(m_detChem.reactionMechanism, m_detChem.phaseName, m_detChem.transportModel);
692 m_canteraThermo = m_canteraSolution->thermo();
693 m_canteraTransport = m_canteraSolution->transport();
694 m_canteraKinetics = m_canteraSolution->kinetics();
703#if defined(WITH_CANTERA)
704template <MInt nDim_,
class SysEqn>
705template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
707 const MInt noSurfaces = a_noSurfaces();
709 const MFloat*
const RESTRICT surfaceVars = ALIGNED_F(&a_surfaceVariable(0, 0, 0));
710 MFloat*
const RESTRICT surfaceCoefficients = hasSC ? ALIGNED_F(&a_surfaceCoefficient(0, 0)) :
nullptr;
712 const MInt noPVars = PV->noVariables;
713 const MUint noSurfaceCoefficients = hasSC ? SC->m_noSurfaceCoefficients : 0;
714 const MInt surfaceVarMemory = 2 * PV->noVariables;
716 for(
MInt srfcId = 0; srfcId < noSurfaces; ++srfcId) {
717 const MInt offset = srfcId * surfaceVarMemory;
718 const MFloat*
const RESTRICT vars0 = ALIGNED_F(surfaceVars + offset);
719 const MFloat*
const RESTRICT vars1 = ALIGNED_F(vars0 + noPVars);
721 const MInt coefficientOffset = srfcId * noSurfaceCoefficients;
722 MFloat*
const RESTRICT srfcCoeff = hasSC ? ALIGNED_F(surfaceCoefficients + coefficientOffset) :
nullptr;
725 sysEqn().computeSurfaceCoefficients(m_RKStep, vars0, vars1, srfcCoeff, m_canteraThermo, m_canteraTransport);
734#if defined(WITH_CANTERA)
735template <MInt nDim_,
class SysEqn>
736template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
738 Cantera::IdealGasReactor zeroD_reactor;
739 zeroD_reactor.insert(m_canteraSolution);
741 Cantera::ReactorNet zeroD_reactorNet;
742 zeroD_reactorNet.setVerbose(
false);
743 zeroD_reactorNet.addReactor(zeroD_reactor);
744 zeroD_reactorNet.setTolerances(1e-9, 1e-9);
746 const MUint noCells = a_noCells();
747 const MUint noPVars = PV->noVariables;
748 const MUint noAVars = hasAV ? AV->noVariables : 0;
750 MFloat*
const RESTRICT pvars = &a_pvariable(0, 0);
751 MFloat*
const RESTRICT reactionRates = &a_speciesReactionRate(0, 0);
752 MFloat*
const RESTRICT avars = hasAV ? &a_avariable(0, 0) :
nullptr;
754 for(
MUint cellId = 0; cellId < noCells; ++cellId) {
756 if(a_isHalo(cellId)) {
757 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
758 a_speciesReactionRate(cellId, s) = F0;
763 const MUint cellPVarOffset = cellId * noPVars;
764 const MUint cellAVarOffset = hasAV ? cellId * noAVars : 0;
765 const MUint reactionRateOffset = cellId * PV->m_noSpecies;
767 const MFloat*
const RESTRICT pvarsCell = pvars + cellPVarOffset;
768 const MFloat*
const RESTRICT avarsCell = hasAV ? avars + cellAVarOffset :
nullptr;
769 MFloat*
const RESTRICT reactionRatesCell = reactionRates + reactionRateOffset;
771 sysEqn().computeSpeciesReactionRates(m_timeStep, a_cellVolume(cellId), pvarsCell, avarsCell, reactionRatesCell,
772 &zeroD_reactor, &zeroD_reactorNet, m_canteraSolution, m_canteraThermo);
781template <MInt nDim_,
class SysEqn>
782template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
784#if defined(WITH_CANTERA)
785 computeSurfaceCoefficients();
794#if defined(WITH_CANTERA)
795template <MInt nDim_,
class SysEqn>
796template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
798 const MUint noCells = a_noCells();
799 const MUint noPVars = PV->noVariables;
800 const MUint noAVars = hasAV ? AV->noVariables : 0;
802 const MFloat*
const RESTRICT pvars = &a_pvariable(0, 0);
803 MFloat*
const RESTRICT avars = hasAV ? &a_avariable(0, 0) :
nullptr;
805 for(
MUint cellId = 0; cellId < noCells; ++cellId) {
806 const MUint cellPVarOffset = cellId * noPVars;
807 const MUint cellAVarOffset = hasAV ? cellId * noAVars : 0;
809 const MFloat*
const RESTRICT pvarsCell = pvars + cellPVarOffset;
810 MFloat*
const RESTRICT avarsCell = hasAV ? avars + cellAVarOffset :
nullptr;
812 sysEqn().computeGamma(pvarsCell, avarsCell, m_canteraThermo);
822template <MInt nDim_,
class SysEqn>
823template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
825 const MUint noCells = a_noCells();
826 const MUint noCVars = CV->noVariables;
827 const MUint noAVars = hasAV ? AV->noVariables : 0;
829 MFloat*
const RESTRICT cvars = &a_variable(0, 0);
830 MFloat*
const RESTRICT avars = hasAV ? &a_avariable(0, 0) :
nullptr;
832 for(
MUint cellId = 0; cellId < noCells; ++cellId) {
833 const MUint cellCVarOffset = cellId * noCVars;
834 const MUint cellAVarOffset = hasAV ? cellId * noAVars : 0;
836 const MFloat*
const RESTRICT cvarsCell = cvars + cellCVarOffset;
837 MFloat*
const RESTRICT avarsCell = hasAV ? avars + cellAVarOffset :
nullptr;
839 sysEqn().computeMeanMolarWeight_CV(cvarsCell, avarsCell);
848template <MInt nDim_,
class SysEqn>
849template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
851 const MUint noCells = a_noCells();
852 const MUint noPVars = PV->noVariables;
853 const MUint noAVars = hasAV ? AV->noVariables : 0;
855 MFloat*
const RESTRICT pvars = &a_pvariable(0, 0);
856 MFloat*
const RESTRICT avars = hasAV ? &a_avariable(0, 0) :
nullptr;
858 for(
MUint cellId = 0; cellId < noCells; ++cellId) {
859 const MUint cellPVarOffset = cellId * noPVars;
860 const MUint cellAVarOffset = hasAV ? cellId * noAVars : 0;
862 const MFloat*
const RESTRICT pvarsCell = pvars + cellPVarOffset;
863 MFloat*
const RESTRICT avarsCell = hasAV ? avars + cellAVarOffset :
nullptr;
865 sysEqn().computeMeanMolarWeight_PV(pvarsCell, avarsCell);
873template <MInt nDim_,
class SysEqn>
874template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
876 const MFloat*
const cvarsCell = &a_variable(cellId, 0);
877 MFloat*
const avarsCell = hasAV ? &a_avariable(cellId, 0) :
nullptr;
879 sysEqn().computeMeanMolarWeight_CV(cvarsCell, avarsCell);
882template <MInt nDim_,
class SysEqn>
883template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
885 const MFloat*
const pvarsCell = &a_pvariable(cellId, 0);
886 MFloat*
const avarsCell = hasAV ? &a_avariable(cellId, 0) :
nullptr;
888 sysEqn().computeMeanMolarWeight_PV(pvarsCell, avarsCell);
894template <MInt nDim_,
class SysEqn>
895template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
897 const MInt majorSpeciesIndex = sysEqn().m_species->majorSpeciesIndex;
899 for(
MInt cellId = 0; cellId < a_noCells(); ++cellId) {
900 MFloat massFractionSum = F0;
901 for(
MInt s = 0; s < m_noSpecies; ++s) {
902 if(s == majorSpeciesIndex) {
905 massFractionSum += a_variable(cellId, CV->RHO_Y[s]);
907 a_variable(cellId, CV->RHO_Y[majorSpeciesIndex]) = a_variable(cellId, CV->RHO) - massFractionSum;
913template <MInt nDim_,
class SysEqn>
931 m_nonBlockingComm =
false;
934 if(noNeighborDomains() > 0 && isActive()) {
937 MInt totalNoWindowCells = 0;
938 MInt totalNoHaloCells = 0;
939 for(
MInt d = 0; d < noNeighborDomains(); d++) {
940 haloCellsCnt[d] = noHaloCells(d);
941 totalNoHaloCells += noHaloCells(d);
942 windowCellsCnt[d] = noWindowCells(d);
943 totalNoWindowCells += noWindowCells(d);
947 "MPI_IN_PLACE",
"totalNoWindowCells");
949 "MPI_IN_PLACE",
"totalNoHaloCells");
952 message <<
"Solver #" << solverId() <<
" - maximum number of window cells among ranks: " << totalNoWindowCells
954 message <<
"Solver #" << solverId() <<
" - maximum number of halo cells among ranks: " << totalNoHaloCells
959 mAlloc(m_maxLevelHaloCells, noNeighborDomains(), &haloCellsCnt[0],
"m_maxLevelHaloCells", AT_);
960 mAlloc(m_maxLevelWindowCells, noNeighborDomains(), &windowCellsCnt[0],
"m_maxLevelWindowCells", AT_);
961 mAlloc(m_noMaxLevelHaloCells, noNeighborDomains(),
"m_noMaxLevelHaloCells", 0, AT_);
962 mAlloc(m_noMaxLevelWindowCells, noNeighborDomains(),
"m_noMaxLevelWindowCells", 0, AT_);
964 mAlloc(m_sendBuffers, noNeighborDomains(), &windowCellsCnt[0], m_dataBlockSize,
"m_sendBuffers", AT_);
965 mAlloc(m_receiveBuffers, noNeighborDomains(), &haloCellsCnt[0], m_dataBlockSize,
"m_receiveBuffers", AT_);
966 mAlloc(m_mpi_request, noNeighborDomains(),
"m_mpi_request", AT_);
968 m_nonBlockingComm = Context::getSolverProperty<MBool>(
"nonBlockingComm", m_solverId, AT_, &m_nonBlockingComm);
971 mTerm(1,
"Activate nonBlockingComm to make split MPI communication work (splitMpiComm).");
975 if(m_nonBlockingComm) {
976 mAlloc(m_sendBuffersNoBlocking, noNeighborDomains(), &windowCellsCnt[0], m_dataBlockSize,
977 "m_sendBuffersNoBlocking", AT_);
978 mAlloc(m_receiveBuffersNoBlocking, noNeighborDomains(), &haloCellsCnt[0], m_dataBlockSize,
979 "m_receiveBuffersNoBlocking", AT_);
980 mAlloc(m_mpi_receiveRequest, noNeighborDomains(),
"m_mpi_receiveRequest ", AT_);
981 mAlloc(m_mpi_sendRequest, noNeighborDomains(),
"m_mpi_sendRequest", AT_);
982 for(
MInt i = 0; i < noNeighborDomains(); i++) {
983 m_mpi_receiveRequest[i] = MPI_REQUEST_NULL;
984 m_mpi_sendRequest[i] = MPI_REQUEST_NULL;
993template <MInt nDim_,
class SysEqn>
996 for(
MInt id = 0;
id < a_noCells(); ++
id) {
997 assertValidGridCellId(
id);
998 for(
MInt dir = 0; dir < nDim; ++dir) {
999 a_coordinate(
id, dir) = c_coordinate(
id, dir);
1004 for(
MInt id = 0;
id < a_noCells(); ++
id) {
1005 a_level(
id) = c_level(
id);
1009 for(
MInt c = 0; c < a_noCells(); c++) {
1010 a_isHalo(c) =
false;
1011 a_isWindow(c) =
false;
1012 a_isPeriodic(c) =
false;
1016 for(
MInt i = 0; i < noNeighborDomains(); i++) {
1017 for(
MInt c = 0; c < noHaloCells(i); c++) {
1018 a_isHalo(haloCellId(i, c)) =
true;
1022 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
1023 for(
MInt c = 0; c < grid().noAzimuthalHaloCells(i); c++) {
1024 a_isHalo(grid().azimuthalHaloCell(i, c)) =
true;
1027 for(
MInt c = 0; c < grid().noAzimuthalUnmappedHaloCells(); c++) {
1028 a_isHalo(grid().azimuthalUnmappedHaloCell(c)) =
true;
1032 for(
MInt i = 0; i < noNeighborDomains(); i++) {
1033 for(
MInt c = 0; c < noWindowCells(i); c++) {
1034 a_isWindow(windowCellId(i, c)) =
true;
1038 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
1039 for(
MInt c = 0; c < grid().noAzimuthalWindowCells(i); c++) {
1040 a_isWindow(grid().azimuthalWindowCell(i, c)) =
true;
1046 for(
MInt c = 0; c < a_noCells(); c++) {
1051 for(
MInt id = 0;
id < a_noCells(); ++
id) {
1053 assertValidGridCellId(
id);
1054 a_isPeriodic(
id) = grid().isPeriodic(
id);
1061template <MInt nDim_,
class SysEqn>
1066 m_log << endl <<
"------------Properties Groups----------" << endl;
1067 m_log <<
"Levelset is " << (m_levelSet ?
"on" :
"off") <<
"!" << endl;
1068 m_log <<
"Mb is " << (m_levelSetMb ?
"on" :
"off") <<
"!" << endl;
1069 m_log <<
"Combustion is " << (m_combustion ?
"on" :
"off") <<
"!" << endl;
1070 m_log <<
"LS with RANS is " << (m_levelSetRans ?
"on" :
"off") <<
"!" << endl;
1071 m_log << endl <<
"-------------Other Switches-----------" << endl;
1072 m_log <<
"Thickened Flame is " << (m_thickenedFlame ?
"on" :
"off") <<
"!" << endl;
1075 m_hasExternalSource =
false;
1076 m_hasExternalSource =
1078 || Context::getSolverProperty<MBool>(
"particleMomentumCoupling", m_solverId, AT_, &m_hasExternalSource)
1079 || Context::getSolverProperty<MBool>(
"particleHeatCoupling", m_solverId, AT_, &m_hasExternalSource)
1080 || Context::getSolverProperty<MBool>(
"particleMassCoupling", m_solverId, AT_, &m_hasExternalSource);
1084 if(m_hasExternalSource) {
1085 mAlloc(m_externalSource, maxNoGridCells(), CV->noVariables,
"m_externalForces", 0.0, AT_);
1086 m_log <<
"Allocated memory for external sources." << endl;
1090 if(m_sensorParticle) {
1091 ASSERT(this->m_adaptation,
"");
1095 m_bndryGhostCellsOffset = a_noCells();
1098 m_maxNoSurfaces = Context::getSolverProperty<MInt>(
"maxNoSurfaces", m_solverId, AT_);
1100 m_dataBlockSize =
mMax(CV->noVariables, PV->noVariables);
1101 m_slopeMemory = PV->noVariables * nDim;
1102 m_surfaceVarMemory = 2 * PV->noVariables;
1105 m_oldMomentOfVorticity = F0;
1106 m_oldNegativeMomentOfVorticity = F0;
1107 m_oldPositiveMomentOfVorticity = F0;
1110 m_associatedBodyIds = (
MInt*)
nullptr;
1111 m_internalBodyId = (
MInt*)
nullptr;
1133 m_calcSlopesAfterStep =
false;
1134 m_calcSlopesAfterStep =
1135 Context::getSolverProperty<MBool>(
"calcSlopesAfterStep", m_solverId, AT_, &m_calcSlopesAfterStep);
1137 m_lsCutCellBaseLevel = maxRefinementLevel();
1148template <MInt nDim_,
class SysEqn>
1152 const MInt maxNoCells = maxNoGridCells();
1166 if(m_periodicCells == 1 || m_periodicCells == 2 || m_periodicCells == 3) {
1167 MInt m_maxNoPeriodicCells = 0;
1179 m_maxNoPeriodicCells =
1180 Context::getSolverProperty<MInt>(
"maxNoPeriodicCells", m_solverId, AT_, &m_maxNoPeriodicCells);
1182 mAlloc(m_sortedPeriodicCells, m_maxNoPeriodicCells,
"m_sortedPeriodicCells", -1, AT_);
1183 mAlloc(m_rotAxisCoord, 2,
"rotAxisCoord", F0, AT_);
1184 for(
MInt i = 0; i < 2; i++) {
1185 m_rotAxisCoord[i] = 0.0;
1186 m_rotAxisCoord[i] = Context::getSolverProperty<MFloat>(
"rotAxisCoord", m_solverId, AT_, &m_rotAxisCoord[i], i);
1191 MBool bndryRfnJump =
false;
1192 bndryRfnJump = Context::getSolverProperty<MBool>(
"bndryRfnJump", m_solverId, AT_, &bndryRfnJump);
1194 mAlloc(m_bndryRfnJumpInformation_, maxNoCells,
"m_bndryRfnJumpInformation_", -1, AT_);
1195 mAlloc(m_bndryRfnJumpInformation, maxNoCells * 4,
"m_bndryRfnJumpInformation", -1, AT_);
1198 m_surfaces.setNoSpecies(m_noSpecies);
1199 m_surfaces.setNoMaxSrfcs(m_maxNoSurfaces);
1200 m_surfaces.setNoVariables(PV->noVariables);
1201 m_surfaces.setNoFVariables(FV->noVariables);
1202 const MInt noSurfaceCoefficients = hasSC ? SC->m_noSurfaceCoefficients : 0;
1203 m_surfaces.setNoSurfaceCoefficients(noSurfaceCoefficients);
1204 m_surfaces.setSolverType(
string2enum(Context::getSolverProperty<MString>(
"solvertype", m_solverId, AT_)));
1205 m_surfaces.reset(m_maxNoSurfaces);
1207 m_noActiveCells = 0;
1208 m_reconstructionConstants.reserve(2 * nDim * a_noCells() * nDim);
1209 m_reconstructionCellIds.reserve(2 * nDim * a_noCells());
1210 m_reconstructionNghbrIds.reserve(2 * nDim * a_noCells());
1211 mAlloc(m_A, m_cells.noRecNghbrs(), m_cells.noRecNghbrs(),
"m_A", F0, AT_);
1212 mAlloc(m_ATA, m_cells.noRecNghbrs(), m_cells.noRecNghbrs(),
"m_ATA", F0, AT_);
1213 mAlloc(m_ATAi, m_cells.noRecNghbrs(), m_cells.noRecNghbrs(),
"m_ATAi", F0, AT_);
1214 mAlloc(m_cellSurfaceMapping, maxNoGridCells(), m_noDirs,
"m_cellSurfaceMapping", -1, AT_);
1218 if(m_averageVorticity) {
1219 mAlloc(m_vorticity, noInternalCells(), m_vorticitySize,
"m_vorticity", AT_);
1220 for(
MInt i = 0; i < noInternalCells(); i++) {
1221 for(
MInt j = 0; j < m_vorticitySize; j++) {
1222 m_vorticity[i][j] = 0.0;
1226 m_vorticity =
nullptr;
1230 mAlloc(m_domainBoundaries, 2 * nDim,
"m_domainBoundaries", F0, AT_);
1233 mAlloc(m_kronecker, nDim, nDim,
"m_kronecker", F0, AT_);
1235 m_kronecker[i][i] = F1;
1238 m_bodyCenter =
nullptr;
1239 m_bodyVelocity =
nullptr;
1240 m_bodyVelocityDt1 =
nullptr;
1241 m_bodyVelocityDt2 =
nullptr;
1242 m_bodyTemperature =
nullptr;
1249template <MInt nDim_,
class SysEqn>
1265 m_maxIterations = 1;
1266 m_maxIterations = Context::getSolverProperty<MInt>(
"maxIterations", m_solverId, AT_, &m_maxIterations);
1281 m_periodicCells = 0;
1282 m_periodicCells = Context::getSolverProperty<MInt>(
"periodicCells", m_solverId, AT_, &m_periodicCells);
1284 m_referenceLength = F1;
1295 m_referenceLength = Context::getSolverProperty<MFloat>(
"referenceLength", m_solverId, AT_, &m_referenceLength);
1297 if(fabs(m_referenceLength - F1) > m_eps) {
1298 m_log <<
"WARNING: referenceLength != 1.0. The correct implementation of this is not checked. Don't use it "
1299 "unless you REALLY know what you are doing."
1320 m_Re = Context::getSolverProperty<MFloat>(
"Re", m_solverId, AT_) / m_referenceLength;
1335 m_Pr = Context::getSolverProperty<MFloat>(
"Pr", m_solverId, AT_, &m_Pr);
1349 m_Ma = Context::getSolverProperty<MFloat>(
"Ma", m_solverId, AT_);
1362 mAlloc(m_angle, nDim,
"m_angle", F0, AT_);
1366 for(
MInt i = 0; i < (nDim - 1); i++) {
1367 m_angle[i] = Context::getSolverProperty<MFloat>(
"angle", m_solverId, AT_, i);
1368 m_angle[i] *= PI / 180.0;
1384 m_gamma = Context::getSolverProperty<MFloat>(
"gamma", m_solverId, AT_, &m_gamma);
1386 m_considerVolumeForces =
false;
1397 m_considerVolumeForces = Context::getSolverProperty<MBool>(
"considerVolumeForces", m_solverId, AT_, &tmpFalse);
1411 m_considerRotForces =
false;
1412 m_considerRotForces = Context::getSolverProperty<MBool>(
"considerRotForces", m_solverId, AT_, &tmpFalse);
1414 mAlloc(m_volumeAcceleration, nDim,
"m_volumeAcceleration", F0, AT_);
1416 if(m_considerVolumeForces) {
1420 for(
MInt i = 0; i < nDim; i++) {
1421 m_volumeAcceleration[i] =
1422 Context::getSolverProperty<MFloat>(
"volumeForce", m_solverId, AT_, &m_volumeAcceleration[i], i);
1437 m_initialCondition = Context::getSolverProperty<MInt>(
"initialCondition", m_solverId, AT_);
1449 MString govEqs =
"NAVIER_STOKES";
1450 govEqs = Context::getSolverProperty<MString>(
"govEqs", m_solverId, AT_, &govEqs);
1457 m_gasConstant = 8.314472;
1469 m_gasConstant = Context::getSolverProperty<MFloat>(
"gasConstant", m_solverId, AT_, &m_gasConstant);
1471 m_referenceTemperature = 273.15;
1485 m_referenceTemperature =
1486 Context::getSolverProperty<MFloat>(
"referenceTemperature", m_solverId, AT_, &m_referenceTemperature);
1488 m_sutherlandConstant = 110.4;
1500 m_sutherlandConstant =
1501 Context::getSolverProperty<MFloat>(
"sutherlandConstant", m_solverId, AT_, &m_sutherlandConstant);
1503 m_sutherlandConstantThermal = m_sutherlandConstant;
1515 m_sutherlandConstantThermal =
1516 Context::getSolverProperty<MFloat>(
"sutherlandConstantThermal", m_solverId, AT_, &m_sutherlandConstantThermal);
1518 m_sutherlandConstant /= m_referenceTemperature;
1519 m_sutherlandPlusOne = m_sutherlandConstant + F1;
1520 m_sutherlandConstantThermal /= m_referenceTemperature;
1521 m_sutherlandPlusOneThermal = m_sutherlandConstantThermal + F1;
1537 m_changeMa = Context::getSolverProperty<MBool>(
"changeMa", m_solverId, AT_, &m_changeMa);
1540 m_previousMa = m_Ma;
1553 m_previousMa = Context::getSolverProperty<MFloat>(
"previousMa", m_solverId, AT_, &m_previousMa);
1556 m_useCreateCutFaceMGC =
false;
1568 m_useCreateCutFaceMGC =
1569 Context::getSolverProperty<MBool>(
"useCreateCutFaceMGC", m_solverId, AT_, &m_useCreateCutFaceMGC);
1583 m_strouhal = F2 * PI;
1584 m_strouhal = Context::getSolverProperty<MFloat>(
"Strouhal", m_solverId, AT_, &m_strouhal);
1588 m_forcingAmplitude = F1B2;
1589 m_noForcingCycles = 5;
1591 m_forcing = Context::getSolverProperty<MBool>(
"forcing", m_solverId, AT_, &m_forcing);
1604 m_forcingAmplitude = Context::getSolverProperty<MFloat>(
"forcingAmplitude", m_solverId, AT_, &m_forcingAmplitude);
1617 m_noForcingCycles = Context::getSolverProperty<MInt>(
"noForcingCycles", m_solverId, AT_, &m_noForcingCycles);
1633 for(
MInt i = 0; i < noCutOffInterface; i++) {
1634 m_cutOffInterface.insert(Context::getSolverProperty<MInt>(
"cutOffInterface", m_solverId, AT_, i));
1647 m_testCaseName =
"NONE";
1648 m_testCaseName = Context::getSolverProperty<MString>(
"testCaseName", m_solverId, AT_, &m_testCaseName);
1658 m_weightBndryCells =
true;
1659 m_weightBndryCells = Context::getSolverProperty<MBool>(
"weightFvBndryCells", m_solverId, AT_, &m_weightBndryCells);
1668 m_weightCutOffCells =
true;
1669 m_weightCutOffCells = Context::getSolverProperty<MBool>(
"weightFvCutOffCells", m_solverId, AT_, &m_weightCutOffCells);
1678 m_weightBc1601 =
true;
1679 m_weightBc1601 = Context::getSolverProperty<MBool>(
"weightFvBc1601", m_solverId, AT_, &m_weightBc1601);
1688 m_weightInactiveCell =
false;
1689 m_weightInactiveCell =
1690 Context::getSolverProperty<MBool>(
"weightFvInactiveCell", m_solverId, AT_, &m_weightInactiveCell);
1699 m_weightLvlJumps =
false;
1700 m_weightLvlJumps = Context::getSolverProperty<MBool>(
"weightFvLvlJumps", m_solverId, AT_, &m_weightLvlJumps);
1710 m_weightNearBndryCells =
false;
1711 m_weightNearBndryCells =
1712 Context::getSolverProperty<MBool>(
"weightFvNearBndryCells", m_solverId, AT_, &m_weightNearBndryCells);
1721 m_weightSmallCells =
false;
1722 m_weightSmallCells = Context::getSolverProperty<MBool>(
"weightFvSmallCells", m_solverId, AT_, &m_weightSmallCells);
1732 m_limitWeights =
false;
1733 m_limitWeights = Context::getSolverProperty<MBool>(
"limitDLBWeights", solverId(), AT_, &m_limitWeights);
1742 m_weightBaseCell = 1.0;
1743 m_weightBaseCell = Context::getSolverProperty<MFloat>(
"weightBaseCell", solverId(), AT_, &m_weightBaseCell);
1752 m_weightLeafCell = 1.0;
1753 m_weightLeafCell = Context::getSolverProperty<MFloat>(
"weightLeafCell", solverId(), AT_, &m_weightLeafCell);
1762 m_weightActiveCell = 1.0;
1763 m_weightActiveCell = Context::getSolverProperty<MFloat>(
"weightAvticeCell", solverId(), AT_, &m_weightLeafCell);
1773 m_weightBndryCell = 0.0;
1774 m_weightBndryCell = Context::getSolverProperty<MFloat>(
"weightBndryCell", solverId(), AT_, &m_weightBndryCell);
1784 m_weightNearBndryCell = 0.0;
1785 m_weightNearBndryCell =
1786 Context::getSolverProperty<MFloat>(
"weightNearBndryCell", solverId(), AT_, &m_weightNearBndryCell);
1798 m_weightMulitSolverFactor = 1.0;
1799 m_weightMulitSolverFactor =
1800 Context::getSolverProperty<MFloat>(
"weightMulitSolverFactor", solverId(), AT_, &m_weightMulitSolverFactor);
1812 m_EEGas.RKSemiImplicitFactor = 0.5;
1813 m_EEGas.RKSemiImplicitFactor =
1814 Context::getSolverProperty<MFloat>(
"RKSemiImplicitFactor", m_solverId, AT_, &m_EEGas.RKSemiImplicitFactor);
1816 mAlloc(m_EEGas.uOtherPhase, maxNoGridCells(), nDim,
"m_EEGas.uOtherPhase", F0, AT_);
1817 mAlloc(m_EEGas.uOtherPhaseOld, maxNoGridCells(), nDim,
"m_EEGas.uOtherPhaseOld", F0, AT_);
1818 mAlloc(m_EEGas.gradUOtherPhase, maxNoGridCells(), nDim * nDim,
"m_EEGas.gradUOtherPhase", F0, AT_);
1819 mAlloc(m_EEGas.vortOtherPhase, maxNoGridCells(), nDim,
"m_EEGas.vortOtherPhase", F0, AT_);
1820 mAlloc(m_EEGas.nuTOtherPhase, maxNoGridCells(),
"m_EEGas.nuTOtherPhase", F0, AT_);
1821 mAlloc(m_EEGas.nuEffOtherPhase, maxNoGridCells(),
"m_EEGas.nuEffOtherPhase", F0, AT_);
1823 if(m_noSpecies != 1) {
1824 mTerm(1, AT_,
"noSpecies has to be 1 for gas-liquid Euler-Euler simulations");
1826 if(domainId() == 0) cerr <<
"FV Solver EEGas!" << endl;
1844 m_EEGas.dragModel = 0;
1845 m_EEGas.dragModel = Context::getSolverProperty<MInt>(
"EEGasDragModel", m_solverId, AT_, &m_EEGas.dragModel);
1847 if(m_EEGas.dragModel == 2) {
1857 m_EEGas.CD = Context::getSolverProperty<MFloat>(
"EEGasCD", m_solverId, AT_, &m_EEGas.CD);
1868 m_EEGas.Eo0 = Context::getSolverProperty<MFloat>(
"EEGasEo0", m_solverId, AT_, &m_EEGas.Eo0);
1877 m_EEGas.bubbleDiameter = 0.001;
1878 m_EEGas.bubbleDiameter =
1879 Context::getSolverProperty<MFloat>(
"bubbleDiameter", m_solverId, AT_, &m_EEGas.bubbleDiameter);
1888 m_EEGas.liquidDensity = 774;
1889 m_EEGas.liquidDensity =
1890 Context::getSolverProperty<MFloat>(
"EEGasLiquidDensity", m_solverId, AT_, &m_EEGas.liquidDensity);
1899 m_EEGas.eps = 1.0e-10;
1900 m_EEGas.eps = Context::getSolverProperty<MFloat>(
"EEGasEps", m_solverId, AT_, &m_EEGas.eps);
1910 m_EEGas.CL = Context::getSolverProperty<MFloat>(
"EEGasCL", m_solverId, AT_, &m_EEGas.CL);
1921 m_EEGas.gasSource = 0;
1922 m_EEGas.gasSource = Context::getSolverProperty<MInt>(
"EEGasGasSource", m_solverId, AT_, &m_EEGas.gasSource);
1931 m_EEGas.gasSourceMassFlow = 0.0;
1932 m_EEGas.gasSourceMassFlow =
1933 Context::getSolverProperty<MFloat>(
"EEGasGasSourceMassFlow", m_solverId, AT_, &m_EEGas.gasSourceMassFlow);
1935 if(m_EEGas.gasSource > 1 && m_EEGas.gasSourceMassFlow < 1.0e-16) {
1936 mTerm(1, AT_,
"EEGasGasSourceMassFlow needed!");
1939 if(m_EEGas.gasSource == 9) {
1941 if(l_noElements % nDim * 2 != 0) {
1942 mTerm(1, AT_,
"number of elements in EEGasGasSourceBox has to be a multiple of 2*nDim");
1944 m_EEGas.noGasSourceBoxes = l_noElements / (nDim * 2);
1945 if(domainId() == 0) cerr <<
"number of gasSourceBoxes detected: " << m_EEGas.noGasSourceBoxes << endl;
1946 for(
MInt i = 0; i < m_EEGas.noGasSourceBoxes * nDim * 2; i++) {
1953 m_EEGas.gasSourceBox.push_back(Context::getSolverProperty<MFloat>(
"EEGasGasSourceBox", m_solverId, AT_, i));
1964 m_EEGas.bubblePathDispersion =
true;
1965 m_EEGas.bubblePathDispersion =
1966 Context::getSolverProperty<MBool>(
"bubblePathDispersion", m_solverId, AT_, &m_EEGas.bubblePathDispersion);
1975 m_EEGas.initialAlpha = 0.0;
1976 m_EEGas.initialAlpha = Context::getSolverProperty<MFloat>(
"initialAlpha", m_solverId, AT_, &m_EEGas.initialAlpha);
1985 m_EEGas.alphaInf = m_EEGas.initialAlpha;
1986 m_EEGas.alphaInf = Context::getSolverProperty<MFloat>(
"alphaInf", m_solverId, AT_, &m_EEGas.alphaInf);
1995 m_EEGas.alphaIn = m_EEGas.initialAlpha;
1996 m_EEGas.alphaIn = Context::getSolverProperty<MFloat>(
"alphaIn", m_solverId, AT_, &m_EEGas.alphaIn);
2005 m_EEGas.schmidtNumber = 1.0;
2006 m_EEGas.schmidtNumber = Context::getSolverProperty<MFloat>(
"schmidtNumber", m_solverId, AT_, &m_EEGas.schmidtNumber);
2015 m_EEGas.uDLimiter =
true;
2016 m_EEGas.uDLimiter = Context::getSolverProperty<MBool>(
"uDLimiter", m_solverId, AT_, &m_EEGas.uDLimiter);
2025 m_EEGas.uDLim = 0.2;
2026 m_EEGas.uDLim = Context::getSolverProperty<MFloat>(
"uDLim", m_solverId, AT_, &m_EEGas.uDLim);
2036 m_EEGas.interpolationFactor = 0.5;
2037 m_EEGas.interpolationFactor = Context::getSolverProperty<MFloat>(
"EEMultiphaseInterpolationFactor", m_solverId, AT_,
2038 &m_EEGas.interpolationFactor);
2050 m_EEGas.depthCorrection = m_isEEGas;
2051 m_EEGas.depthCorrection =
2052 Context::getSolverProperty<MBool>(
"depthCorrection", m_solverId, AT_, &m_EEGas.depthCorrection);
2054 if(m_EEGas.depthCorrection) {
2057 mTerm(1, AT_,
"gravityRefCoords and depthCorrectionCoefficients are required for depthCorrection!");
2060 for(
MInt i = 0; i < nDim; i++) {
2067 m_EEGas.gravityRefCoords.push_back(Context::getSolverProperty<MFloat>(
"gravityRefCoords", m_solverId, AT_, i));
2077 m_EEGas.depthCorrectionCoefficients.push_back(
2078 Context::getSolverProperty<MFloat>(
"depthCorrectionCoefficients", m_solverId, AT_, i));
2083 mTerm(1, AT_,
"EEGasGravity required for EEGas!");
2084 }
else if(m_isEEGas) {
2085 for(
MInt i = 0; i < nDim; i++) {
2092 m_EEGas.gravity.push_back(Context::getSolverProperty<MFloat>(
"EEGasGravity", m_solverId, AT_, i));
2101template <MInt nDim_,
class SysEqn>
2105 m_molecularWeight =
nullptr;
2106 m_FmolecularWeight =
nullptr;
2107 m_molarFormationEnthalpy =
nullptr;
2108 m_formationEnthalpy =
nullptr;
2109 m_referenceComposition =
nullptr;
2110 m_secondaryReferenceComposition =
nullptr;
2113 if(m_combustion && m_thickenedFlame) {
2114 mAlloc(m_molecularWeight, m_noSpecies,
"m_molecularWeight", F1, AT_);
2115 mAlloc(m_FmolecularWeight, m_noSpecies,
"m_FmolecularWeight", F1, AT_);
2118 for(
MInt s = 0; s < m_noSpecies; s++) {
2130 m_molecularWeight[s] =
2131 Context::getSolverProperty<MFloat>(
"molecularWeight", m_solverId, AT_, &m_molecularWeight[s], s);
2132 m_FmolecularWeight[s] = F1 / m_molecularWeight[s];
2157 mAlloc(m_molarFormationEnthalpy, m_noSpecies,
"m_molarFormationEnthalpy", F1, AT_);
2158 mAlloc(m_formationEnthalpy, m_noSpecies,
"m_formationEnthalpy", F1, AT_);
2159 mAlloc(m_referenceComposition, m_noSpecies,
"m_referenceComposition", F1, AT_);
2160 mAlloc(m_secondaryReferenceComposition, m_noSpecies,
"m_secondaryReferenceComposition", F0, AT_);
2162 for(
MInt s = 0; s < m_noSpecies; s++) {
2163 m_molarFormationEnthalpy[s] = Context::getSolverProperty<MFloat>(
"molarFormationEnthalpy", m_solverId, AT_,
2164 &m_molarFormationEnthalpy[s], s);
2165 m_referenceComposition[s] =
2166 Context::getSolverProperty<MFloat>(
"referenceComposition", m_solverId, AT_, &m_referenceComposition[s], s);
2167 m_secondaryReferenceComposition[s] = Context::getSolverProperty<MFloat>(
2168 "secondaryReferenceComposition", m_solverId, AT_, &m_secondaryReferenceComposition[s], s);
2169 m_formationEnthalpy[s] = m_molarFormationEnthalpy[s] / m_molecularWeight[s];
2172 m_referenceDensityTF = 1.25;
2184 m_referenceDensityTF =
2185 Context::getSolverProperty<MFloat>(
"referenceDensity", m_solverId, AT_, &m_referenceDensityTF);
2198 m_heatReleaseReductionFactor = F1;
2199 m_heatReleaseReductionFactor = Context::getSolverProperty<MFloat>(
"heatReleaseReductionFactor", m_solverId, AT_,
2200 &m_heatReleaseReductionFactor);
2201 m_thickeningFactor = F1;
2214 m_thickeningFactor = Context::getSolverProperty<MFloat>(
"thickeningFactor", m_solverId, AT_, &m_thickeningFactor);
2228 m_reactionScheme = Context::getSolverProperty<MString>(
"reactionScheme", m_solverId, AT_, &m_reactionScheme);
2235template <MInt nDim_,
class SysEqn>
2239 m_spongeLayerThickness = F0;
2240 m_createSpongeBoundary =
false;
2241 m_spongeLayerLayout = 0;
2242 m_spongeLayerType = 0;
2243 m_targetDensityFactor = F1;
2244 m_noSpongeFactors = 0;
2246 m_sigmaSpongeInflow = F0;
2247 m_noSpongeBndryCndIds = 0;
2248 m_spongeTimeDep =
false;
2249 m_noMaxSpongeBndryCells = 0;
2250 m_velocitySponge = 0;
2266 m_spongeLayerThickness =
2267 Context::getSolverProperty<MFloat>(
"spongeLayerThickness", m_solverId, AT_, &m_spongeLayerThickness);
2280 MFloat cellLength = c_cellLengthAtLevel(maxUniformRefinementLevel());
2281 m_spongeLayerThickness =
2282 (
MFloat)Context::getSolverProperty<MInt>(
"spongeLayerThickness_int", m_solverId, AT_) * cellLength;
2284 cerr <<
" m_spongeLayerThickness is: " << m_spongeLayerThickness << endl;
2288 if(m_spongeLayerThickness > 0) {
2300 m_createSpongeBoundary =
2301 Context::getSolverProperty<MBool>(
"createSpongeBoundary", m_solverId, AT_, &m_createSpongeBoundary);
2303 if(m_createSpongeBoundary) {
2305 setAndAllocateSpongeBoundaryProperties();
2308 setAndAllocateSpongeDomainProperties(F0);
2314 m_noCellsInsideSpongeLayer = 0;
2315 if(!m_createSpongeBoundary) {
2316 mAlloc(m_cellsInsideSpongeLayer, maxNoGridCells(),
"m_cellsInsideSpongeLayer", -1, AT_);
2318 mAlloc(m_cellsInsideSpongeLayer, m_noMaxSpongeBndryCells,
"m_cellsInsideSpongeLayer", -1, AT_);
2325template <MInt nDim_,
class SysEqn>
2329 m_noLimitedSlopesVar = 0;
2330 m_limitedSlopesVar =
nullptr;
2345 m_cfl = Context::getSolverProperty<MFloat>(
"cfl", m_solverId, AT_);
2361 m_cflViscous = F1B4;
2362 m_cflViscous = Context::getSolverProperty<MFloat>(
"cflViscous", m_solverId, AT_, &m_cflViscous);
2375 m_orderOfReconstruction = 1;
2376 m_orderOfReconstruction =
2377 Context::getSolverProperty<MInt>(
"orderOfReconstruction", m_solverId, AT_, &m_orderOfReconstruction);
2379 m_RKalpha =
nullptr;
2394 m_limiter = Context::getSolverProperty<MInt>(
"limiter", m_solverId, AT_, &m_limiter);
2396 m_surfaceValueReconstruction =
"HOCD";
2410 m_surfaceValueReconstruction =
2411 Context::getSolverProperty<MString>(
"surfaceValueReconstruction", m_solverId, AT_, &m_surfaceValueReconstruction);
2415 m_noLimitedSlopesVar = 0;
2418 mTerm(1, AT_,
"no limited variables is wrong");
2421 mAlloc(m_limitedSlopesVar, PV->noVariables - m_noSpecies,
"m_limitedSlopesVar", -1, AT_);
2423 mAlloc(tmpRead, tmp,
"tmpRead", -1, AT_);
2425 for(
MInt i = 0; i < tmp; i++) {
2438 tmpRead[i] = Context::getSolverProperty<MInt>(
"limitedSlopesVar", m_solverId, AT_, &tmpRead[i], i);
2439 if(tmpRead[i] < 0 || tmpRead[i] > 1) {
2440 mTerm(1, AT_,
"ERROR: limitedSlopesVar should be 0 or 1");
2445 for(
MInt d = 0; d < nDim; d++) {
2446 if(tmpRead[0] > 0) {
2447 m_limitedSlopesVar[d] = PV->VV[d];
2448 m_noLimitedSlopesVar++;
2449 m_log <<
"setting variable " << d <<
" as limited variable" << endl;
2456 for(
MInt d = nDim; d < (PV->noVariables - m_noSpecies); d++) {
2457 if(tmpRead[d - nDim + 1] != 0) {
2458 m_limitedSlopesVar[m_noLimitedSlopesVar] = d;
2459 m_noLimitedSlopesVar++;
2460 m_log <<
"setting variable " << d <<
" as limited variable" << endl;
2463 m_log << m_noLimitedSlopesVar <<
" number of limited variables" << endl;
2464 for(
MInt d = 0; d < m_noLimitedSlopesVar; d++) {
2465 m_log <<
"limited variable is: " << m_limitedSlopesVar[d] << endl;
2482 m_viscousFluxScheme =
"FIVE_POINT";
2483 m_viscousFluxScheme = Context::getSolverProperty<MString>(
"viscousFluxScheme", m_solverId, AT_, &m_viscousFluxScheme);
2484 m_log << endl <<
"viscous-flux scheme: " << m_viscousFluxScheme << endl << endl;
2502 m_enhanceThreePointViscFluxFactor = Context::getSolverProperty<MFloat>(
2503 "enhanceThreePointViscFluxFactor", m_solverId, AT_, &m_enhanceThreePointViscFluxFactor);
2505 m_enhanceThreePointViscFluxFactor = 0.1;
2509 m_advectiveFluxScheme =
"AUSM";
2511 m_advectiveFluxScheme =
2512 Context::getSolverProperty<MString>(
"advectiveFluxScheme", m_solverId, AT_, &m_advectiveFluxScheme);
2529 m_gridInterfaceFilter =
false;
2530 m_gridInterfaceFilter =
2531 Context::getSolverProperty<MBool>(
"gridInterfaceFilter", m_solverId, AT_, &m_gridInterfaceFilter);
2545 m_force1DFiltering =
false;
2546 m_force1DFiltering = Context::getSolverProperty<MBool>(
"force1D", m_solverId, AT_, &m_force1DFiltering);
2558 if(m_dualTimeStepping) {
2559 m_physicalTimeStep = Context::getSolverProperty<MFloat>(
"physicalTimeStep", m_solverId, AT_);
2562 m_maxNoTimeSteps = Context::getSolverProperty<MInt>(
"timeSteps", m_solverId, AT_);
2577 m_timeStepMethod = Context::getSolverProperty<MInt>(
"timeStepMethod", m_solverId, AT_);
2590 m_timeStepNonBlocking =
false;
2591 m_timeStepNonBlocking =
2592 Context::getSolverProperty<MBool>(
"timeStepNonBlocking", m_solverId, AT_, &m_timeStepNonBlocking);
2597 m_timeStepComputationInterval = m_restart ? -1 : 0;
2613 m_timeStepComputationInterval =
2614 Context::getSolverProperty<MInt>(
"timeStepComputationInterval", m_solverId, AT_, &m_timeStepComputationInterval);
2617 m_log <<
"TimeStepComputationInterval: ";
2618 switch(m_timeStepComputationInterval) {
2620 m_log <<
"0 (default)";
2624 m_log <<
"-1 (never, using time step from restart file)";
2628 if(m_timeStepComputationInterval < 0) {
2629 mTerm(1, AT_,
"timeStepComputationInterval out-of-range [-1, infinity)");
2631 m_log << m_timeStepComputationInterval <<
" (recompute dt every " << m_timeStepComputationInterval
2639 mTerm(-1,
"ERROR: usePreviousTimeStep has been removed. Set timeStepComputationInterval instead. If you were using "
2640 "usePreviousTimeStep = 0 you have to set timeStepComputationInterval = 0. If you were using "
2641 "usePreviousTimeStep = 1 you can either set timeStepComputationInterval = -1, or remove the property "
2642 "completely because -1 is the default value of timeStepComputationInterval when restarting. Check the "
2643 "aiawiki for more information.");
2647 m_timeStepVolumeWeighted =
false;
2656 m_timeStepVolumeWeighted =
2657 Context::getSolverProperty<MBool>(
"timeStepVolumeWeighted", m_solverId, AT_, &m_timeStepVolumeWeighted);
2659 m_timeStepFixedValue = -1.0;
2660 m_timeStepFixedValue = Context::getSolverProperty<MFloat>(
"fixedTimeStep", m_solverId, AT_, &m_timeStepFixedValue);
2662 m_log <<
"Time step computation settings: volumeWeighted = " << m_timeStepVolumeWeighted
2663 <<
"; fixedTimeStepValue = " << m_timeStepFixedValue << std::endl;
2676 m_globalUpwindCoefficient = F0;
2677 m_globalUpwindCoefficient =
2678 Context::getSolverProperty<MFloat>(
"globalUpwindCoefficient", m_solverId, AT_, &m_globalUpwindCoefficient);
2679 m_chi = Context::getSolverProperty<MFloat>(
"upwindCoefficient", m_solverId, AT_);
2682 m_upwindMethod = Context::getSolverProperty<MInt>(
"upwindMethod", m_solverId, AT_, &m_upwindMethod);
2683 m_2ndOrderWeights =
false;
2684 m_2ndOrderWeights = Context::getSolverProperty<MBool>(
"weights2ndOrder", m_solverId, AT_, &m_2ndOrderWeights);
2685 m_reExcludeBndryDiagonals =
false;
2686 m_reExcludeBndryDiagonals =
2687 Context::getSolverProperty<MBool>(
"reExcludeBndryDiagonals", m_solverId, AT_, &m_reExcludeBndryDiagonals);
2705 m_reConstSVDWeightMode = 0;
2706 m_reConstSVDWeightMode =
2707 Context::getSolverProperty<MInt>(
"reConstSVDWeightMode", m_solverId, AT_, &m_reConstSVDWeightMode);
2708 m_relocateCenter =
false;
2709 m_relocateCenter = Context::getSolverProperty<MBool>(
"relocateCenter", m_solverId, AT_, &m_relocateCenter);
2711 if(m_bndryLevelJumps) {
2712 ASSERT(m_reConstSVDWeightMode != 1,
"Mode not working for bndry-level-jumps!");
2726 m_convergenceCriterion = 1e-12;
2727 m_convergenceCriterion =
2728 Context::getSolverProperty<MFloat>(
"convergenceCriterion", m_solverId, AT_, &m_convergenceCriterion);
2730 m_timeStepConvergenceCriterion = 1e-6;
2731 m_timeStepConvergenceCriterion = Context::getSolverProperty<MFloat>(
"timeStepConvergenceCriterion", m_solverId, AT_,
2732 &m_timeStepConvergenceCriterion);
2734 m_useCentralDifferencingSlopes =
false;
2735 m_useCentralDifferencingSlopes = Context::getSolverProperty<MBool>(
"useCentralDifferencingSlopes", m_solverId, AT_,
2736 &m_useCentralDifferencingSlopes);
2738 m_spongeTimeVelocity = 0;
2739 m_spongeTimeVelocity = Context::getSolverProperty<MInt>(
"spongeTimeVelocity", m_solverId, AT_, &m_spongeTimeVelocity);
2745template <MInt nDim_,
class SysEqn>
2762 m_solutionOffset = 0;
2763 m_solutionOffset = Context::getSolverProperty<MInt>(
"solutionOffset", m_solverId, AT_, &m_solutionOffset);
2772 m_outputPhysicalTime =
false;
2773 m_outputPhysicalTime =
2774 Context::getSolverProperty<MBool>(
"outputPhysicalTime", m_solverId, AT_, &m_outputPhysicalTime);
2789 for(
MInt i = 0; i < noSolutionTimeSteps; i++) {
2790 MInt sts = Context::getSolverProperty<MInt>(
"solutionTimeSteps", m_solverId, AT_, i);
2791 m_solutionTimeSteps.insert(sts);
2792 cerr <<
" inserted time step " << sts <<
" to solution time steps! " << endl;
2796 m_integratedHeatReleaseOutput =
false;
2797 m_integratedHeatReleaseOutput =
2798 Context::getSolverProperty<MBool>(
"integratedHeatReleaseOutput", m_solverId, AT_, &m_integratedHeatReleaseOutput);
2800 m_integratedHeatReleaseOutputInterval = 0;
2801 m_integratedHeatReleaseOutputInterval = Context::getSolverProperty<MInt>(
2802 "integratedHeatReleaseOutputInterval", m_solverId, AT_, &m_integratedHeatReleaseOutputInterval);
2804 m_dragOutputInterval = 0;
2805 m_dragOutputInterval = Context::getSolverProperty<MInt>(
"dragOutputInterval", m_solverId, AT_, &m_dragOutputInterval);
2816 m_surfDistParallel = Context::getSolverProperty<MBool>(
"surfaceDistributionParallel", m_solverId, AT_, &tmpFalse);
2829 m_surfDistCartesian = Context::getSolverProperty<MBool>(
"surfaceDistributionCartesian", m_solverId, AT_, &tmpFalse);
2843 m_saveVorticityToRestart =
false;
2844 m_saveVorticityToRestart =
2845 Context::getSolverProperty<MBool>(
"saveVorticityToRestart", m_solverId, AT_, &m_saveVorticityToRestart);
2847 m_vorticityOutput = Context::getSolverProperty<MBool>(
"vorticityOutput", m_solverId, AT_, &tmpTrue);
2860 m_qCriterionOutput = Context::getSolverProperty<MBool>(
"qCriterionOutput", m_solverId, AT_, &tmpTrue);
2872 m_vtuWritePointData =
false;
2873 m_vtuWritePointData = Context::getSolverProperty<MBool>(
"vtuWritePointData", m_solverId, AT_, &m_vtuWritePointData);
2874 m_log <<
"m_vtuWritePointData: " << m_vtuWritePointData << endl;
2887 m_vtuCutCellOutput = (nDim == 3);
2888 IF_CONSTEXPR(nDim == 3)
2889 m_vtuCutCellOutput =
Context::getSolverProperty<
MBool>("vtuCutCellOutput", m_solverId, AT_, &m_vtuCutCellOutput);
2890 m_vtuGeometryOutput.clear();
2891 IF_CONSTEXPR(nDim == 3) {
2893 m_log <<
"VTU geometry output for boundaryIds: ";
2903 MInt bcId = Context::getSolverProperty<MInt>(
"vtuGeometryOutput", m_solverId, AT_, i);
2904 m_vtuGeometryOutput.insert(bcId);
2905 m_log << bcId <<
" ";
2918 m_vtuGeometryOutputExtended =
false;
2919 m_vtuGeometryOutputExtended =
2920 Context::getSolverProperty<MBool>(
"vtuGeometryOutputExtended", m_solverId, AT_, &m_vtuGeometryOutputExtended);
2921 m_vtuWriteGeometryFile =
true;
2922 m_vtuWriteGeometryFile =
2923 Context::getSolverProperty<MBool>(
"vtuGeometryFile", m_solverId, AT_, &m_vtuWriteGeometryFile);
2925 m_vtuWriteParticleFile =
true;
2926 m_vtuWriteParticleFile =
2927 Context::getSolverProperty<MBool>(
"vtuParticleFile", m_solverId, AT_, &m_vtuWriteParticleFile);
2936 m_vtuGlobalIdOutput =
false;
2937 m_vtuGlobalIdOutput = Context::getSolverProperty<MBool>(
"vtuGlobalIdOutput", m_solverId, AT_, &m_vtuGlobalIdOutput);
2946 m_vtuDomainIdOutput =
false;
2947 m_vtuDomainIdOutput = Context::getSolverProperty<MBool>(
"vtuDomainIdOutput", m_solverId, AT_, &m_vtuDomainIdOutput);
2956 m_vtuDensityOutput =
true;
2957 m_vtuDensityOutput = Context::getSolverProperty<MBool>(
"vtuDensityOutput", m_solverId, AT_, &m_vtuDensityOutput);
2966 m_vtuLevelSetOutput =
false;
2967 m_vtuLevelSetOutput = Context::getSolverProperty<MBool>(
"vtuLevelSetOutput", m_solverId, AT_, &m_vtuLevelSetOutput);
2979 m_vtuQCriterionOutput =
false;
2980 m_vtuQCriterionOutput =
2981 Context::getSolverProperty<MBool>(
"vtuQCriterionOutput", m_solverId, AT_, &m_vtuQCriterionOutput);
2992 m_vtuLambda2Output =
false;
2993 m_vtuLambda2Output = Context::getSolverProperty<MBool>(
"vtuLambda2Output", m_solverId, AT_, &m_vtuLambda2Output);
3002 m_vtuVorticityOutput =
false;
3003 m_vtuVorticityOutput =
3004 Context::getSolverProperty<MBool>(
"vtuVorticityOutput", m_solverId, AT_, &m_vtuVorticityOutput);
3005 IF_CONSTEXPR(nDim == 2) { m_vtuVorticityOutput =
false; }
3014 m_vtuVelocityGradientOutput =
false;
3015 m_vtuVelocityGradientOutput =
3016 Context::getSolverProperty<MBool>(
"vtuVelocityGradientOutput", m_solverId, AT_, &m_vtuVelocityGradientOutput);
3025 m_vtuSaveHeaderTesting =
false;
3026 m_vtuSaveHeaderTesting =
3027 Context::getSolverProperty<MBool>(
"vtuSaveHeaderTesting", m_solverId, AT_, &m_vtuSaveHeaderTesting);
3040 m_vtuLevelThreshold = maxRefinementLevel();
3042 m_vtuLevelThreshold = Context::getSolverProperty<MInt>(
"vtuLevelThreshold", m_solverId, AT_, &m_vtuLevelThreshold);
3043 if(m_vtuLevelThreshold <= 0) m_vtuLevelThreshold = maxRefinementLevel();
3044 m_log <<
"m_vtuLevelThreshold: " << m_vtuLevelThreshold << endl;
3057 m_vtuCoordinatesThreshold =
nullptr;
3059 mAlloc(m_vtuCoordinatesThreshold, 6,
"m_vtuCoordinatesThreshold", F0, AT_);
3060 for(
MInt i = 0; i < 2 * nDim; i++) {
3061 m_vtuCoordinatesThreshold[i] = Context::getSolverProperty<MFloat>(
"vtuCoordinatesThreshold", m_solverId, AT_,
3062 &m_vtuCoordinatesThreshold[i], i);
3065 m_log <<
"m_vtuCoordinatesThreshold: ";
3066 if(m_vtuCoordinatesThreshold ==
nullptr)
3069 for(
MInt i = 0; i < 2 * nDim; i++) {
3070 m_log << m_vtuCoordinatesThreshold[i] <<
" ";
3075 m_variablesName =
new const MChar*[PV->noVariables];
3076 for(
MInt i = 0; i < PV->noVariables; ++i) {
3077 m_variablesName[i] =
new MChar[10];
3081 m_variablesName[count] =
"u";
3083 m_variablesName[count] =
"v";
3085 IF_CONSTEXPR(nDim == 3) {
3086 m_variablesName[count] =
"w";
3089 m_variablesName[count] =
"rho";
3091 m_variablesName[count] =
"p";
3093 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
3094 IF_CONSTEXPR(SysEqn::m_ransModel ==
RANS_SA_DV || SysEqn::m_ransModel ==
RANS_FS) {
3095 m_variablesName[count] =
"nu";
3099 m_variablesName[count] =
"k";
3101 m_variablesName[count] =
"omega";
3107 m_variablesName[count] =
"c";
3110 if(m_noSpecies == 1) {
3111 m_variablesName[count] =
"Y";
3115 IF_CONSTEXPR(isDetChem<SysEqn>) {
3116 if(m_noSpecies > 1) {
3117 for(
MInt s = 0; s < m_noSpecies; s++) {
3118 MString str = (
"Y" + m_speciesName[s]);
3120 strcpy(c, str.c_str());
3121 m_variablesName[count] = c;
3130 m_vorticitySize = 0;
3131 if(m_vorticityOutput) {
3132 IF_CONSTEXPR(nDim == 3) {
3133 m_vorticitySize = 3;
3134 m_vorticityName =
new const MChar*[m_vorticitySize];
3135 for(
MInt i = 0; i < 3; ++i)
3136 m_vorticityName[i] =
new MChar[16];
3138 m_vorticityName[0] =
"vorticity(x)";
3139 m_vorticityName[1] =
"vorticity(y)";
3140 m_vorticityName[2] =
"vorticity(z)";
3142 else IF_CONSTEXPR(nDim == 2) {
3143 m_vorticitySize = 1;
3144 m_vorticityName =
new const MChar*[m_vorticitySize];
3145 for(
MInt i = 0; i < 1; ++i)
3146 m_vorticityName[i] =
new MChar[16];
3147 m_vorticityName[0] =
"vorticity(z)";
3150 m_vorticityName = (
const MChar**)
nullptr;
3153 m_vorticityName = (
const MChar**)
nullptr;
3168 m_outputFormat = m_levelSetMb ?
"VTU" :
"NETCDF";
3169 m_outputFormat = Context::getSolverProperty<MString>(
"outputFormat", m_solverId, AT_, &m_outputFormat);
3172 m_log <<
"WARNING: Output format changed to " << m_outputFormat <<
" for massive parallel computation! " << endl;
3173 m_outputFormat =
"NETCDF";
3176 m_log <<
"WARNING: Output format changed to " << m_outputFormat <<
" for massive parallel computation! " << endl;
3177 m_outputFormat =
"VTU";
3180 m_log <<
" * Using output format " << m_outputFormat << endl;
3183 m_outputOffset = Context::getSolverProperty<MInt>(
"outputOffset", m_solverId, AT_, &m_outputOffset);
3199 m_writeOutData = Context::getSolverProperty<MInt>(
"writeOutData", m_solverId, AT_, &m_writeOutData);
3213 m_recordBodyData = Context::getSolverProperty<MBool>(
"recordBodyData", m_solverId, AT_, &tmpFalse);
3214 m_recordLandA = Context::getSolverProperty<MBool>(
"recordLandA", m_solverId, AT_, &tmpFalse);
3229 m_recordWallVorticity = Context::getSolverProperty<MBool>(
"recordWallVorticity", m_solverId, AT_, &tmpFalse);
3245 m_writeCutCellsToGridFile = Context::getSolverProperty<MBool>(
"writeCutCellsToGridFile", m_solverId, AT_, &tmpFalse);
3260 m_restartBc2800 =
false;
3261 m_restartBc2800 = Context::getSolverProperty<MBool>(
"restartBc2800", m_solverId, AT_, &m_restartBc2800);
3263 if(m_useNonSpecifiedRestartFile && isMultilevel()) {
3264 mTerm(1,
"Error: useNonSpecifiedRestartFile needs to be disables for a multilevel computation");
3278 m_restartBackupInterval = 25000;
3279 m_restartBackupInterval =
3280 Context::getSolverProperty<MInt>(
"restartBackupInterval", m_solverId, AT_, &m_restartBackupInterval);
3294 m_restartOldVariables =
false;
3295 m_restartOldVariables =
3296 Context::getSolverProperty<MBool>(
"restartOldVariables", m_solverId, AT_, &m_restartOldVariables);
3311 m_restartOldVariablesReset =
false;
3312 m_restartOldVariablesReset =
3313 Context::getSolverProperty<MBool>(
"restartOldVariablesReset", m_solverId, AT_, &m_restartOldVariablesReset);
3328 m_checkCellSurfaces = Context::getSolverProperty<MBool>(
"checkCellSurfaces", m_solverId, AT_, &tmpFalse);
3329 if(m_checkCellSurfaces)
m_log <<
" * Checking cell surfaces for consistency! " << endl;
3331 m_bodyIdOutput =
false;
3341 m_bodyIdOutput = Context::getSolverProperty<MBool>(
"bodyIdOutput", m_solverId, AT_, &m_bodyIdOutput);
3343 m_levelSetOutput =
false;
3354 m_levelSetOutput = Context::getSolverProperty<MBool>(
"levelSetOutput", m_solverId, AT_, &m_levelSetOutput);
3356 m_isActiveOutput =
false;
3367 m_isActiveOutput = Context::getSolverProperty<MBool>(
"isActiveOutput", m_solverId, AT_, &m_isActiveOutput);
3378 m_domainIdOutput =
false;
3379 m_domainIdOutput = Context::getSolverProperty<MBool>(
"domainIdOutput", m_solverId, AT_, &m_domainIdOutput);
3381 setSamplingProperties();
3388template <MInt nDim_,
class SysEqn>
3400 m_sampleRate = 0.000001;
3401 m_sampleRate = Context::getSolverProperty<MFloat>(
"sampleRate", m_solverId, AT_, &m_sampleRate);
3411 m_samplingTimeBegin = std::numeric_limits<MFloat>::max();
3412 m_samplingTimeBegin = Context::getSolverProperty<MFloat>(
"samplingTimeBegin", m_solverId, AT_, &m_samplingTimeBegin);
3421 m_samplingTimeEnd = 0;
3422 m_samplingTimeEnd = Context::getSolverProperty<MFloat>(
"samplingTimeEnd", m_solverId, AT_, &m_samplingTimeEnd);
3433 m_samplingStartCycle = -1;
3434 m_samplingStartCycle = Context::getSolverProperty<MInt>(
"samplingStartCycle", m_solverId, AT_, &m_samplingStartCycle);
3443 m_samplingEndCycle = -1;
3444 m_samplingEndCycle = Context::getSolverProperty<MInt>(
"samplingEndCycle", m_solverId, AT_, &m_samplingEndCycle);
3447 m_samplesPerCycle = 100.;
3455 m_samplesPerCycle = Context::getSolverProperty<MFloat>(
"samplesPerCycle", m_solverId, AT_, &m_samplesPerCycle);
3464 m_samplingStartIteration = -99999.0;
3465 m_samplingStartIteration =
3466 Context::getSolverProperty<MInt>(
"samplingStartIteration", m_solverId, AT_, &m_samplingStartIteration);
3475 m_noSamplingCycles = 2;
3476 m_noSamplingCycles = Context::getSolverProperty<MInt>(
"noSamplingCycles", m_solverId, AT_, &m_noSamplingCycles);
3479 m_noTimeStepsBetweenSamples = -1;
3483 m_forceNoTimeSteps = 0;
3484 m_forceNoTimeSteps = Context::getSolverProperty<MInt>(
"forceNoTimeSteps", m_solverId, AT_, &m_forceNoTimeSteps);
3494template <MInt nDim_,
class SysEqn>
3498 MBool tmpFalse =
false;
3503 m_confinedFlame =
false;
3504 m_plenumWall =
false;
3505 m_useCorrectedBurningVelocity =
false;
3506 m_totalDamp =
false;
3507 m_MaFlameTube = m_Ma;
3508 m_pressureLossFlameSpeed = 1;
3509 m_pressureLossCorrection = F0;
3510 m_recordPressure =
false;
3511 m_recordFlameFrontPosition =
false;
3512 m_structuredFlameOutput =
false;
3513 m_structuredFlameOutputLevel = 0;
3514 m_twoFlames =
false;
3515 m_acousticAnalysis =
false;
3519 m_marksteinLength = 0.1;
3538 m_marksteinLength = Context::getSolverProperty<MFloat>(
"marksteinLength", m_solverId, AT_);
3540 m_marksteinLengthPercentage = F1;
3551 m_marksteinLengthPercentage =
3552 Context::getSolverProperty<MFloat>(
"marksteinLengthPercentage", m_solverId, AT_, &m_marksteinLengthPercentage);
3554 m_log <<
"neutral markstein length is:" << m_marksteinLength << endl;
3556 m_marksteinLength *= m_marksteinLengthPercentage;
3557 m_log <<
"markstein length is changed to :" << m_marksteinLength << endl;
3558 m_log <<
"markstein length percentage is :" << m_marksteinLengthPercentage << endl;
3573 m_zeroLineCorrection = Context::getSolverProperty<MBool>(
"zeroLineCorrection", m_solverId, AT_, &tmpFalse);
3575 m_inletTubeAreaRatio = F1;
3585 m_inletTubeAreaRatio =
3586 Context::getSolverProperty<MFloat>(
"inletTubeAreaRatio", m_solverId, AT_, &m_inletTubeAreaRatio);
3588 m_inletOutletAreaRatio = F1;
3601 m_inletOutletAreaRatio =
3602 Context::getSolverProperty<MFloat>(
"inletOutletAreaRatio", m_solverId, AT_, &m_inletOutletAreaRatio);
3604 m_flameOutletAreaRatio = F1;
3615 m_flameOutletAreaRatio =
3616 Context::getSolverProperty<MFloat>(
"flameOutletAreaRatio", m_solverId, AT_, &m_flameOutletAreaRatio);
3632 m_massFlux = Context::getSolverProperty<MBool>(
"massFlux", m_solverId, AT_, &tmpFalse);
3644 m_confinedFlame = Context::getSolverProperty<MBool>(
"confinedFlame", m_solverId, AT_, &tmpFalse);
3656 m_plenum = Context::getSolverProperty<MBool>(
"plenum", m_solverId, AT_, &tmpFalse);
3668 m_plenumWall = Context::getSolverProperty<MBool>(
"plenumWall", m_solverId, AT_, &tmpFalse);
3671 m_plenum = m_plenumWall;
3685 m_useCorrectedBurningVelocity = Context::getSolverProperty<MBool>(
"useCorrectedBurningVelocity", m_solverId, AT_,
3686 &m_useCorrectedBurningVelocity);
3698 m_filterFlameTubeEdges = Context::getSolverProperty<MBool>(
"filterFlameTubeEdges", m_solverId, AT_, &tmpFalse);
3700 m_filterFlameTubeEdgesDistance = -9999.9;
3710 m_filterFlameTubeEdgesDistance = Context::getSolverProperty<MFloat>(
"filterFlameTubeEdgesDistance", m_solverId, AT_,
3711 &m_filterFlameTubeEdgesDistance);
3722 m_totalDamp = Context::getSolverProperty<MBool>(
"totalDamp", m_solverId, AT_, &tmpFalse);
3724 m_heatReleaseDamp = 1;
3737 m_heatReleaseDamp = Context::getSolverProperty<MBool>(
"heatReleaseDamp", m_solverId, AT_, &m_heatReleaseDamp);
3751 m_modelCheck = Context::getSolverProperty<MBool>(
"modelCheck", m_solverId, AT_, &tmpFalse);
3770 m_flameSpeed = Context::getSolverProperty<MFloat>(
"flameSpeed", m_solverId, AT_);
3772 m_analyticIntegralVelocity = m_Ma;
3784 m_analyticIntegralVelocity =
3785 Context::getSolverProperty<MFloat>(
"analyticIntegralVelocity", m_solverId, AT_, &m_analyticIntegralVelocity);
3787 m_meanVelocity = F1B2 * m_Ma;
3799 m_meanVelocity = Context::getSolverProperty<MFloat>(
"meanVelocity", m_solverId, AT_, &m_meanVelocity);
3802 m_pressureLossFlameSpeed = 0;
3817 m_pressureLossFlameSpeed =
3818 Context::getSolverProperty<MInt>(
"pressureLossFlameSpeed", m_solverId, AT_, &m_pressureLossFlameSpeed);
3820 m_pressureLossCorrection = F0;
3832 m_pressureLossCorrection =
3833 Context::getSolverProperty<MFloat>(
"pressureLossCorrection", m_solverId, AT_, &m_pressureLossCorrection);
3835 m_constantFlameSpeed = 0;
3850 m_constantFlameSpeed =
3851 Context::getSolverProperty<MInt>(
"constantFlameSpeed", m_solverId, AT_, &m_constantFlameSpeed);
3853 m_neutralFlameStrouhal = -F1;
3863 m_neutralFlameStrouhal =
3864 Context::getSolverProperty<MFloat>(
"neutralFlameStrouhal", m_solverId, AT_, &m_neutralFlameStrouhal);
3866 m_noReactionCells = 0.026367201;
3885 m_noReactionCells = Context::getSolverProperty<MFloat>(
"noReactionCells", m_solverId, AT_, &m_noReactionCells);
3887 m_MaFlameTube = m_Ma;
3898 m_MaFlameTube = Context::getSolverProperty<MFloat>(
"MaFlameTube", m_solverId, AT_, &m_MaFlameTube);
3922 m_recordPressure = Context::getSolverProperty<MBool>(
"recordPressure", m_solverId, AT_, &tmpFalse);
3943 m_recordFlameFrontPosition =
3944 Context::getSolverProperty<MBool>(
"recordFlameFrontPosition", m_solverId, AT_, &tmpFalse);
3958 m_structuredFlameOutput = Context::getSolverProperty<MBool>(
"structuredFlameOutput", m_solverId, AT_, &tmpFalse);
3976 m_structuredFlameOutputLevel = 0;
3977 m_structuredFlameOutputLevel =
3978 Context::getSolverProperty<MInt>(
"structuredFlameOutputLevel", m_solverId, AT_, &m_structuredFlameOutputLevel);
3989 m_twoFlames = Context::getSolverProperty<MBool>(
"twoFlames", m_solverId, AT_, &tmpFalse);
3991 m_dampingDistanceFlameBaseExtVel = 0.05;
4001 m_dampingDistanceFlameBaseExtVel = Context::getSolverProperty<MFloat>(
"dampingDistanceFlameBaseExtVel", m_solverId,
4002 AT_, &m_dampingDistanceFlameBaseExtVel);
4005 m_dampingDistanceFlameBase = 0.259;
4015 m_dampingDistanceFlameBase =
4016 Context::getSolverProperty<MFloat>(
"dampingDistanceFlameBase", m_solverId, AT_, &m_dampingDistanceFlameBase);
4018 m_initialFlameHeight = F1;
4033 m_initialFlameHeight =
4034 Context::getSolverProperty<MFloat>(
"initialFlameHeight", m_solverId, AT_, &m_initialFlameHeight);
4036 m_radiusFlameTube = 0.5;
4053 m_radiusFlameTube = Context::getSolverProperty<MFloat>(
"radiusFlameTube", m_solverId, AT_, &m_radiusFlameTube);
4066 m_radiusVelFlameTube =
4067 Context::getSolverProperty<MFloat>(
"radiusVelFlameTube", m_solverId, AT_, &m_radiusFlameTube);
4080 m_radiusOutlet = Context::getSolverProperty<MFloat>(
"radiusOutlet", m_solverId, AT_, &m_radiusFlameTube);
4082 m_realRadiusFlameTube = m_radiusFlameTube;
4093 m_realRadiusFlameTube =
4094 Context::getSolverProperty<MFloat>(
"realRadiusFlameTube", m_solverId, AT_, &m_realRadiusFlameTube);
4109 m_radiusFlameTube2 = Context::getSolverProperty<MFloat>(
"radiusFlameTube2", m_solverId, AT_, &m_radiusFlameTube);
4112 m_radiusInjector = F2;
4124 m_radiusInjector = Context::getSolverProperty<MFloat>(
"radiusInjector", m_solverId, AT_, &m_radiusInjector);
4126 m_yOffsetInjector = -12.48535161836571205000;
4138 m_yOffsetInjector = Context::getSolverProperty<MFloat>(
"yOffsetInjector", m_solverId, AT_, &m_yOffsetInjector);
4140 m_yOffsetFlameTube = 0.04;
4159 m_yOffsetFlameTube = Context::getSolverProperty<MFloat>(
"yOffsetFlameTube", m_solverId, AT_, &m_yOffsetFlameTube);
4175 m_yOffsetFlameTube2 = Context::getSolverProperty<MFloat>(
"yOffsetFlameTube2", m_solverId, AT_, &m_yOffsetFlameTube);
4177 m_xOffsetFlameTube = 0.0;
4196 m_xOffsetFlameTube = Context::getSolverProperty<MFloat>(
"xOffsetFlameTube", m_solverId, AT_, &m_xOffsetFlameTube);
4198 m_xOffsetFlameTube2 = -m_xOffsetFlameTube;
4217 m_xOffsetFlameTube2 = Context::getSolverProperty<MFloat>(
"xOffsetFlameTube2", m_solverId, AT_, &m_xOffsetFlameTube);
4238 m_tubeLength = Context::getSolverProperty<MFloat>(
"tubeLength", m_solverId, AT_, &m_tubeLength);
4259 m_outletLength = Context::getSolverProperty<MFloat>(
"outletLength", m_solverId, AT_, &m_outletLength);
4261 m_laminarFlameThickness = c_cellLengthAtLevel(maxRefinementLevel());
4278 m_laminarFlameThickness =
4279 Context::getSolverProperty<MFloat>(
"laminarFlameThickness", m_solverId, AT_, &m_laminarFlameThickness);
4281 m_subfilterVariance = F1;
4309 m_subfilterVariance =
4310 Context::getSolverProperty<MFloat>(
"subfilterVariance", m_solverId, AT_, &m_subfilterVariance);
4323 m_c0 = Context::getSolverProperty<MFloat>(
"c0", m_solverId, AT_, &m_c0);
4326 m_rhoUnburnt = -99999.0;
4337 m_rhoUnburnt = Context::getSolverProperty<MFloat>(
"rhoUnburnt", m_solverId, AT_, &m_rhoUnburnt);
4338 if(
approx(m_rhoUnburnt, -99999.0, MFloatEps)
4339 && (m_initialCondition == 1990 || m_initialCondition == 19901 || m_initialCondition == 1991
4340 || m_initialCondition == 19911)) {
4341 cerr <<
" rho unburnt should be set in your property file, as well TbTu and marksteinLength, see file "
4342 "HeatChange and MarksteinNeutral files !!!"
4344 mTerm(1, AT_,
"Error for rhoUnburnt property");
4348 m_burntUnburntTemperatureRatio = F1;
4360 m_burntUnburntTemperatureRatio = Context::getSolverProperty<MFloat>(
"burntUnburntTemperatureRatio", m_solverId, AT_,
4361 &m_burntUnburntTemperatureRatio);
4363 m_temperatureChange = 0;
4376 m_temperatureChange = Context::getSolverProperty<MInt>(
"temperatureChange", m_solverId, AT_, &m_temperatureChange);
4378 if(m_temperatureChange != 0) {
4390 m_burntUnburntTemperatureRatioStart =
4391 Context::getSolverProperty<MFloat>(
"burntUnburntTemperatureRatioStart", m_solverId, AT_);
4393 m_burntUnburntTemperatureRatioEnd = m_burntUnburntTemperatureRatio;
4405 m_burntUnburntTemperatureRatioEnd = Context::getSolverProperty<MFloat>(
4406 "burntUnburntTemperatureRatioEnd", m_solverId, AT_, &m_burntUnburntTemperatureRatioEnd);
4409 m_targetDensityFactor = F1 / m_burntUnburntTemperatureRatio;
4428 m_targetDensityFactor =
4429 Context::getSolverProperty<MFloat>(
"targetDensityFactor", m_solverId, AT_, &m_targetDensityFactor);
4430 if(!
approx(m_targetDensityFactor, (F1 / m_burntUnburntTemperatureRatio), MFloatEps)) {
4431 cerr <<
"Warning: target density factor is not equal to the inverse of the burnt unburnt temperature ratio!!!"
4433 cerr <<
"targetDensityFactor = " << m_targetDensityFactor << endl;
4434 cerr <<
"-> change the targetDensityFactor to " << F1 / m_burntUnburntTemperatureRatio << endl;
4437 m_deltaXtemperatureProfile = 0.00;
4449 m_deltaXtemperatureProfile =
4450 Context::getSolverProperty<MFloat>(
"deltaXtemperatureProfile", m_solverId, AT_, &m_deltaXtemperatureProfile);
4452 m_deltaYtemperatureProfile = 0.01;
4464 m_deltaYtemperatureProfile =
4465 Context::getSolverProperty<MFloat>(
"deltaYtemperatureProfile", m_solverId, AT_, &m_deltaYtemperatureProfile);
4467 m_thermalProfileStartFactor = F1;
4478 m_thermalProfileStartFactor =
4479 Context::getSolverProperty<MFloat>(
"thermalProfileStartFactor", m_solverId, AT_, &m_thermalProfileStartFactor);
4481 m_flameRadiusOffset = F0;
4493 m_flameRadiusOffset =
4494 Context::getSolverProperty<MFloat>(
"flameRadiusOffset", m_solverId, AT_, &m_flameRadiusOffset);
4496 m_shearLayerStrength = 50.0;
4507 m_shearLayerStrength =
4508 Context::getSolverProperty<MFloat>(
"shearLayerStrength", m_solverId, AT_, &m_shearLayerStrength);
4510 m_inflowTemperatureRatio = F1;
4522 m_inflowTemperatureRatio =
4523 Context::getSolverProperty<MFloat>(
"inflowTemperatureRatio", m_solverId, AT_, &m_inflowTemperatureRatio);
4525 m_lambdaPerturbation = F1;
4537 m_lambdaPerturbation =
4538 Context::getSolverProperty<MFloat>(
"lambdaPerturbation", m_solverId, AT_, &m_lambdaPerturbation);
4540 m_perturbationAmplitude = 0.001;
4552 m_perturbationAmplitude =
4553 Context::getSolverProperty<MFloat>(
"perturbationAmplitude", m_solverId, AT_, &m_perturbationAmplitude);
4555 m_perturbationAmplitudeCorr = m_perturbationAmplitude;
4567 m_perturbationAmplitudeCorr =
4568 Context::getSolverProperty<MFloat>(
"perturbationAmplitudeCorr", m_solverId, AT_, &m_perturbationAmplitudeCorr);
4582 m_divergenceTreatment = Context::getSolverProperty<MBool>(
"divergenceTreatment", m_solverId, AT_, &tmpFalse);
4596 m_acousticAnalysis = Context::getSolverProperty<MBool>(
"acousticAnalysis", m_solverId, AT_, &m_acousticAnalysis);
4610 m_ScT = Context::getSolverProperty<MFloat>(
"ScT", m_solverId, AT_, &m_ScT);
4624 m_NuT = Context::getSolverProperty<MFloat>(
"NuT", m_solverId, AT_, &m_NuT);
4626 m_integralAmplitude = 0.015188;
4638 m_integralAmplitude =
4639 Context::getSolverProperty<MFloat>(
"integralAmplitude", m_solverId, AT_, &m_integralAmplitude);
4641 m_integralLengthScale = 0.3;
4653 m_integralLengthScale =
4654 Context::getSolverProperty<MFloat>(
"integralLengthScale", m_solverId, AT_, &m_integralLengthScale);
4667template <MInt nDim_,
class SysEqn>
4684 m_jet = Context::getSolverProperty<MBool>(
"jet", m_solverId, AT_, &m_jet);
4694 m_chevron = Context::getSolverProperty<MBool>(
"chevron", m_solverId, AT_, &m_chevron);
4707 m_maNozzleExit = -1.0;
4708 m_maNozzleExit = Context::getSolverProperty<MFloat>(
"machNozzleExit", m_solverId, AT_);
4720 m_inletRadius = -1.0;
4721 m_inletRadius = Context::getSolverProperty<MFloat>(
"inletRadius", m_solverId, AT_);
4733 m_outletRadius = -1.0;
4734 m_outletRadius = Context::getSolverProperty<MFloat>(
"outletRadius", m_solverId, AT_);
4747 m_normJetTemperature = 1.0;
4748 m_normJetTemperature = Context::getSolverProperty<MFloat>(
"jetTemperature", m_solverId, AT_);
4751 m_momentumThickness = 0.05;
4752 m_momentumThickness =
4753 Context::getSolverProperty<MFloat>(
"momentumThickness", m_solverId, AT_, &m_momentumThickness);
4769 m_jetForcing =
false;
4770 m_jetForcing = Context::getSolverProperty<MBool>(
"jetForcing", m_solverId, AT_, &m_jetForcing);
4783 m_shearLayerThickness = F0;
4784 m_shearLayerThickness =
4785 Context::getSolverProperty<MFloat>(
"shearLayerThickness", m_solverId, AT_, &m_shearLayerThickness);
4799 m_MaCoflow = Context::getSolverProperty<MFloat>(
"MaCoflow", m_solverId, AT_, &m_MaCoflow);
4800 m_jetHalfWidth = 0.5;
4801 m_jetCoflowOffset = m_jetHalfWidth + 0.125;
4802 m_jetCoflowEndOffset = m_jetHalfWidth + 2.375;
4803 m_jetHalfLength = 4.165;
4804 m_jetHalfLength = Context::getSolverProperty<MFloat>(
"jetHalfLength", m_solverId, AT_, &m_jetHalfLength);
4805 m_primaryJetRadius = F1B4;
4806 m_secondaryJetRadius = F1B2;
4807 m_forceCoefficient = F0;
4808 m_densityRatio = F1;
4809 m_targetVelocityFactor = F1;
4811 m_momentumThickness = F0;
4828 m_jetHeight = Context::getSolverProperty<MFloat>(
"jetHeight", m_solverId, AT_, &m_jetHeight);
4841 m_primaryJetRadius = Context::getSolverProperty<MFloat>(
"primaryJetRadius", m_solverId, AT_, &m_primaryJetRadius);
4853 m_secondaryJetRadius =
4854 Context::getSolverProperty<MFloat>(
"secondaryJetRadius", m_solverId, AT_, &m_secondaryJetRadius);
4866 m_targetVelocityFactor =
4867 Context::getSolverProperty<MFloat>(
"targetVelocityFactor", m_solverId, AT_, &m_targetVelocityFactor);
4881 m_jetForcingPosition = 0.5;
4882 m_jetForcingPosition =
4883 Context::getSolverProperty<MFloat>(
"jetForcingPosition", m_solverId, AT_, &m_jetForcingPosition);
4897 m_jetRandomSeed = 1;
4898 m_jetRandomSeed = Context::getSolverProperty<MFloat>(
"jetRandomSeed", m_solverId, AT_, &m_jetRandomSeed);
4911 m_modeNumbers = Context::getSolverProperty<MInt>(
"modeNumbers", m_solverId, AT_, &m_modeNumbers);
4923 m_momentumThickness = 0.025;
4924 m_momentumThickness =
4925 Context::getSolverProperty<MFloat>(
"momentumThickness", m_solverId, AT_, &m_momentumThickness);
4939 m_jetType = Context::getSolverProperty<MInt>(
"jetType", m_solverId, AT_, &m_jetType);
4951 m_forceCoefficient = 0.007;
4952 m_forceCoefficient = Context::getSolverProperty<MFloat>(
"forceCoefficient", m_solverId, AT_, &m_forceCoefficient);
4953 m_densityRatio = Context::getSolverProperty<MFloat>(
"densityRatio", m_solverId, AT_, &m_densityRatio);
4969 mAlloc(m_jetConst, m_noJetConst,
"m_jetConst", F0, AT_);
4970 for(
MInt i = 0; i < m_noJetConst; i++) {
4971 m_jetConst[i] = Context::getSolverProperty<MFloat>(
"jetConst", m_solverId, AT_, &m_jetConst[i], i);
4972 m_log <<
"jet constants a = " << m_jetConst[i] << endl;
4986template <MInt nDim_,
class SysEqn>
4989 MBool tmpFalse =
false;
4997 cerr <<
"ERROR: sponge properties don't have the same size" << endl << endl;
4998 cerr <<
"check the number of the following properties: " << endl;
4999 cerr <<
" - spongeBndryCndIds " << endl;
5000 cerr <<
" - sigmaSponge " << endl;
5001 cerr <<
" - spongeDirections " << endl;
5002 cerr <<
" - spongeFactor " << endl;
5003 mTerm(1, AT_,
"ERROR: sponge properties don't have the same array size");
5018 mAlloc(m_spongeDirections, m_noSpongeBndryCndIds,
"m_spongeDirections", -1, AT_);
5019 mAlloc(m_spongeBndryCndIds, m_noSpongeBndryCndIds,
"m_spongeBndryCndIds", 1, AT_);
5020 mAlloc(m_spongeFactor, m_noSpongeBndryCndIds,
"m_spongeFactor", F1, AT_);
5021 mAlloc(m_sigmaSpongeBndryId, m_noSpongeBndryCndIds,
"m_sigmaSpongeBndryId", F0, AT_);
5022 mAlloc(m_sigmaEndSpongeBndryId, m_noSpongeBndryCndIds,
"m_sigmaEndSpongeBndryId", 100000.0, AT_);
5023 mAlloc(m_spongeTimeDependent, m_noSpongeBndryCndIds,
"m_spongeTimeDependent", 0, AT_);
5024 mAlloc(m_spongeStartIteration, m_noSpongeBndryCndIds,
"m_spongeStartIteration", F0, AT_);
5025 mAlloc(m_spongeEndIteration, m_noSpongeBndryCndIds,
"m_spongeEndIteration", 100000.0, AT_);
5026 mAlloc(m_spongeCoord, m_noSpongeBndryCndIds,
"m_spongeCoord", -100000.0, AT_);
5028 for(
MInt i = 0; i < m_noSpongeBndryCndIds; i++) {
5043 m_spongeFactor[i] = Context::getSolverProperty<MFloat>(
"spongeFactor", m_solverId, AT_, &m_spongeFactor[i], i);
5057 m_spongeDirections[i] =
5058 Context::getSolverProperty<MInt>(
"spongeDirections", m_solverId, AT_, &m_spongeDirections[i], i);
5070 m_spongeBndryCndIds[i] =
5071 Context::getSolverProperty<MInt>(
"spongeBndryCndIds", m_solverId, AT_, &m_spongeBndryCndIds[i], i);
5084 m_sigmaSpongeBndryId[i] =
5085 Context::getSolverProperty<MFloat>(
"sigmaSponge", m_solverId, AT_, &m_sigmaSpongeBndryId[i], i);
5098 m_sigmaEndSpongeBndryId[i] =
5099 Context::getSolverProperty<MFloat>(
"sigmaEndSponge", m_solverId, AT_, &m_sigmaEndSpongeBndryId[i], i);
5111 m_spongeStartIteration[i] =
5112 Context::getSolverProperty<MFloat>(
"spongeStartIteration", m_solverId, AT_, &m_spongeStartIteration[i], i);
5125 m_spongeEndIteration[i] =
5126 Context::getSolverProperty<MFloat>(
"spongeEndIteration", m_solverId, AT_, &m_spongeEndIteration[i], i);
5141 m_spongeTimeDependent[i] =
5142 Context::getSolverProperty<MInt>(
"spongeTimeDependent", m_solverId, AT_, &m_spongeTimeDependent[i], i);
5144 if(!m_spongeTimeDep && m_spongeTimeDependent[i] >= 1) {
5145 m_spongeTimeDep =
true;
5161 m_noMaxSpongeBndryCells =
5162 Context::getSolverProperty<MInt>(
"noMaxSpongeBndryCells", m_solverId, AT_, &m_noMaxSpongeBndryCells);
5185 m_spongeLayerLayout = Context::getSolverProperty<MInt>(
"spongeLayerLayout", m_solverId, AT_, &m_spongeLayerLayout);
5186 if(m_spongeLayerLayout != 0) {
5187 cerr <<
"WARNING: spongeLayerLayout " << m_spongeLayerLayout
5188 <<
" not yet implemented for the new create sponge at a specified boundary" << endl;
5210 m_spongeLayerType = Context::getSolverProperty<MInt>(
"spongeLayerType", m_solverId, AT_, &m_spongeLayerType);
5230 m_targetDensityFactor =
5231 Context::getSolverProperty<MFloat>(
"targetDensityFactor", m_solverId, AT_, &m_targetDensityFactor);
5234 m_spongeReductionFactor = F1;
5253 m_spongeReductionFactor =
5254 Context::getSolverProperty<MFloat>(
"spongeReductionFactor", m_solverId, AT_, &m_spongeReductionFactor);
5270 m_velocitySponge = Context::getSolverProperty<MBool>(
"velocitySponge", m_solverId, AT_, &tmpFalse);
5273 m_spongeWeight = 1.0;
5286 m_spongeWeight = Context::getSolverProperty<MFloat>(
"spongeWeight", m_solverId, AT_, &m_spongeWeight);
5301 m_spongeBeta = Context::getSolverProperty<MFloat>(
"spongeBeta", m_solverId, AT_, &m_spongeBeta);
5315 m_specialSpongeTreatment = Context::getSolverProperty<MBool>(
"specialSpongeTreatment", m_solverId, AT_, &tmpFalse);
5327template <MInt nDim_,
class SysEqn>
5332 mAlloc(m_spongeFactor, 2 * nDim,
"m_spongeFactor", F0, AT_);
5334 mAlloc(m_spongeCoord, 4 * nDim,
"m_spongeFactor", F0, AT_);
5350 m_sigmaSponge = Context::getSolverProperty<MFloat>(
"sigmaSponge", m_solverId, AT_);
5366 m_sigmaSpongeInflow = Context::getSolverProperty<MFloat>(
"sigmaSpongeInflow", m_solverId, AT_, &m_sigmaSponge);
5368 if((m_sigmaSponge > F0) || (m_sigmaSpongeInflow > F0)) {
5385 for(
MInt i = 0; i < 2 * nDim; i++) {
5386 m_spongeFactor[i] = F1;
5388 m_noSpongeFactors = 2 * nDim;
5391 if(m_noSpongeFactors != 2 * nDim) {
5392 stringstream errorMessage;
5393 errorMessage <<
" Error in FvCartesianSolver::FvCartesianSolver Constructor: number of sponge factors is "
5394 "not equal 2 * space "
5395 "dimensions -> please provide "
5396 << 2 * nDim <<
" sponge factors in property spongeFactor! Exiting!";
5397 mTerm(1, AT_, errorMessage.str());
5399 for(
MInt i = 0; i < m_noSpongeFactors; i++) {
5400 m_spongeFactor[i] = Context::getSolverProperty<MFloat>(
"spongeFactor", m_solverId, AT_, &m_spongeFactor[i], i);
5429 m_spongeLayerLayout = Context::getSolverProperty<MInt>(
"spongeLayerLayout", m_solverId, AT_, &m_spongeLayerLayout);
5450 m_spongeLayerType = Context::getSolverProperty<MInt>(
"spongeLayerType", m_solverId, AT_, &m_spongeLayerType);
5470 m_targetDensityFactor =
5471 Context::getSolverProperty<MFloat>(
"targetDensityFactor", m_solverId, AT_, &m_targetDensityFactor);
5485template <MInt nDim_,
class SysEqn>
5492 m_adaptationSinceLastRestart =
false;
5493 m_adaptationSinceLastRestartBackup =
5496 m_currentGridFileName = grid().gridInputFileName();
5498 m_forceRestartGrid =
false;
5499 m_forceRestartGrid = Context::getSolverProperty<MBool>(
"forceRestartGrid", m_solverId, AT_, &m_forceRestartGrid);
5501 m_recalcIds =
nullptr;
5515 this->m_adaptationInterval = 0;
5516 this->m_adaptationInterval =
5517 Context::getSolverProperty<MInt>(
"adaptationInterval", m_solverId, AT_, &this->m_adaptationInterval);
5519 m_allowInterfaceRefinement =
false;
5520 m_allowInterfaceRefinement =
5521 Context::getSolverProperty<MBool>(
"allowInterfaceRefinement", m_solverId, AT_, &m_allowInterfaceRefinement);
5523 mAlloc(m_recalcIds, maxNoCells,
"m_recalcIds", -1, AT_);
5530 mAlloc(m_innerBandWidth, maxRefinementLevel(),
"m_innerBandWidth", F0, AT_);
5531 mAlloc(m_outerBandWidth, maxRefinementLevel(),
"m_outerBandWidth", F0, AT_);
5532 mAlloc(m_bandWidth, maxRefinementLevel(),
"m_bandWidth", 0, AT_);
5533 if(m_sensorParticle) {
5534 mAlloc(m_particleWidth, maxRefinementLevel(),
"m_particleWidth", 0, AT_);
5535 MInt range[2] = {2, 0};
5536 for(
MInt i = 0; i < 2; i++) {
5537 range[i] = Context::getSolverProperty<MInt>(
"particleAdapRange", solverId(), AT_, &range[i], i);
5540 mTerm(1, AT_,
"Particle adaptation range in FV solver not set correctly!");
5542 m_particleWidth[maxRefinementLevel() - 1] = range[0];
5543 for(
MInt i = maxRefinementLevel() - 2; i >= 0; i--) {
5544 m_particleWidth[i] = (m_particleWidth[i + 1] / 2) + 1 + range[1];
5559 MFloat distFac[2] = {18.0, 9.0};
5560 for(
MInt i = 0; i < 2; i++) {
5561 distFac[i] = Context::getSolverProperty<MFloat>(
"mbBandWidth", m_solverId, AT_, &distFac[i], i);
5563 m_outerBandWidth[maxRefinementLevel() - 1] = distFac[0] * c_cellLengthAtLevel(maxRefinementLevel());
5564 m_bandWidth[maxRefinementLevel() - 1] = distFac[0];
5565 for(
MInt i = maxRefinementLevel() - 2; i >= 0; i--) {
5566 m_outerBandWidth[i] = m_outerBandWidth[i + 1] + (distFac[1] * c_cellLengthAtLevel(i + 1));
5567 m_bandWidth[i] = (m_bandWidth[i + 1] / 2) + 1 + distFac[1];
5569 for(
MInt i = 0; i < maxRefinementLevel(); i++) {
5570 m_innerBandWidth[i] = -m_outerBandWidth[i];
5571 m_log <<
"bandwidth level " << i <<
": " << m_innerBandWidth[i] <<
" " << m_outerBandWidth[i] << endl;
5574 m_adaptationDampingDistance = std::numeric_limits<MFloat>::max();
5577 m_refineDiagonals =
true;
5589 m_refineDiagonals = Context::getSolverProperty<MBool>(
"refineDiagonals", m_solverId, AT_, &m_refineDiagonals);
5592template <MInt nDim_,
class SysEqn>
5597 MBool fullRANS =
false;
5599 m_zonalRestartInterpolationSolverId = 0;
5601 m_noRansEquations = 0;
5602 m_turbulenceDegree = F0;
5616 fullRANS = Context::getSolverProperty<MBool>(
"fullRANS", m_solverId, AT_, &fullRANS);
5620 m_log <<
"Starting a full RANS computation" << endl;
5624 m_azimuthalAngle = F0;
5625 m_azimuthalAngle = Context::getBasicProperty<MFloat>(
"azimuthalAngle", AT_, &m_azimuthalAngle);
5634 m_multipleFvSolver = Context::getSolverProperty<MBool>(
"multipleFv", m_solverId, AT_, &m_multipleFvSolver);
5637 m_zonal = Context::getBasicProperty<MBool>(
"zonal", AT_, &m_zonal);
5641 if(Context::getBasicProperty<MInt>(
"noRANSSolvers", AT_) > 0) {
5642 MInt noRANSSolvers = Context::getBasicProperty<MInt>(
"noRANSSolvers", AT_, &noRANSSolvers);
5643 for(
MInt b = 0;
b < noRANSSolvers;
b++) {
5644 MInt RANSSolver = Context::getBasicProperty<MInt>(
"RANSSolver", AT_, &RANSSolver,
b);
5646 if(m_solverId == RANSSolver) {
5651 m_zonalTransferInterval = Context::getSolverProperty<MInt>(
"zonalTransferInterval", m_solverId, AT_);
5652 m_multipleFvSolver =
true;
5654 m_zonalAveragingTimeStep =
5655 Context::getSolverProperty<MInt>(
"zonalAveragingTimeStep", m_solverId, AT_, &m_zonalAveragingTimeStep);
5659 m_calcLESAverage = Context::getSolverProperty<MBool>(
"calcLESAverage", m_solverId, AT_, &m_calcLESAverage);
5663 m_preliminarySponge = Context::getSolverProperty<MBool>(
"preliminarySponge", m_solverId, AT_, &m_preliminarySponge);
5666 if(m_zonal || m_preliminarySponge) {
5667 m_STGSponge = Context::getSolverProperty<MBool>(
"STGSponge", m_solverId, AT_, &m_STGSponge);
5670 m_stgSpongeTimeStep =
5671 Context::getSolverProperty<MInt>(
"stgSpongeTimeStep", m_solverId, AT_, &m_stgSpongeTimeStep);
5673 mAlloc(m_stgSpongePositions, m_noStgSpongePositions,
"m_stgSpongePositions", FUN_);
5674 for(
MInt i = 0; i < m_noStgSpongePositions; i++) {
5675 m_stgSpongePositions[i] =
5676 Context::getSolverProperty<MFloat>(
"stgSpongePositions", m_solverId, AT_, &m_stgSpongePositions[i], i);
5679 m_spongeLimitFactor = Context::getBasicProperty<MFloat>(
"limitFactor", AT_, &m_spongeLimitFactor);
5691 if(m_calcLESAverage) {
5692 m_restartLESAverage = Context::getSolverProperty<MBool>(
"restartLESAverage", m_solverId, AT_, &m_restartLESAverage);
5693 m_averageStartTimeStep =
5694 Context::getSolverProperty<MInt>(
"averageStartTimeStep", m_solverId, AT_, &m_averageStartTimeStep);
5695 m_LESNoVarAverage = Context::getSolverProperty<MInt>(
"noLESAverageVar", m_solverId, AT_, &m_LESNoVarAverage);
5697 m_7901Position = Context::getBasicProperty<MFloat>(
"bc7901Position", AT_, &m_7901Position);
5698 m_7901faceNormalDir = Context::getBasicProperty<MInt>(
"bc7901faceNormalDir", AT_, &m_7901faceNormalDir);
5699 m_7901periodicDir = Context::getBasicProperty<MInt>(
"bc7901periodicDir", AT_, &m_7901periodicDir);
5700 m_7901wallDir = Context::getBasicProperty<MInt>(
"bc7901wallDir", AT_, &m_7901wallDir);
5703 if(m_STGSponge && !m_calcLESAverage)
mTerm(1,
"calcLESAverage has to be turned on while using STGSponge");
5706 m_stgStartTimeStep = Context::getSolverProperty<MInt>(
"stgStartTimeStep", m_solverId, AT_, &m_stgStartTimeStep);
5709 m_rntStartTimeStep = Context::getSolverProperty<MInt>(
"rntStartTimeStep", m_solverId, AT_, &m_rntStartTimeStep);
5712 m_resetInitialCondition =
false;
5714 m_resetInitialCondition = Context::getBasicProperty<MBool>(
"resetInitialCondition", AT_, &m_resetInitialCondition);
5716 m_resetInitialCondition = Context::getBasicProperty<MBool>(
"nonZonalRestart", AT_, &m_resetInitialCondition);
5719 if(m_resetInitialCondition) {
5720 m_zonalRestartInterpolationSolverId = Context::getSolverProperty<MInt>(
5721 "zonalRestartInterpolationSolverId", m_solverId, AT_, &m_zonalRestartInterpolationSolverId);
5724 if(m_resetInitialCondition && domainId() == 0) {
5725 cerr <<
"Resetting initial Condition and times!" << endl;
5729 m_noRansEquations = SysEqn::m_noRansEquations;
5731 if(m_noRansEquations == 0)
mTerm(1,
"RANS activated, but noRansEquations equal to 0");
5733 m_ransTransPos = -1000000.0;
5735 m_ransTransPos = Context::getSolverProperty<MFloat>(
"ransTransPos", m_solverId, AT_, &m_ransTransPos);
5737 IF_CONSTEXPR(SysEqn::m_ransModel ==
RANS_FS) {
5738 m_turbulenceDegree = Context::getSolverProperty<MFloat>(
"turbulenceDegree", m_solverId, AT_, &m_turbulenceDegree);
5754 m_stgIsActive =
false;
5756 m_stgIsActive = Context::getSolverProperty<MBool>(
"useSTG", m_solverId, AT_, &m_stgIsActive);
5768 mTerm(-1,
"Property 'bc7909RANSSolverType' required for bc7909, but not found!");
5770 m_bc7909RANSSolverType =
5771 Context::getSolverProperty<MString>(
"bc7909RANSSolverType", m_solverId, AT_, &m_bc7909RANSSolverType);
5773 mAlloc(m_stgEddieCoverage, 3, maxNoGridCells(),
"m_stgEddieCoverage", F0, AT_);
5782template <MInt nDim_,
class SysEqn>
5799 m_noRKSteps = Context::getSolverProperty<MInt>(
"noRKSteps", m_solverId, AT_, &m_noRKSteps);
5802 mAlloc(m_RKalpha, m_noRKSteps,
"m_RKalpha", -F1, AT_);
5804 MFloat RK5DefaultCoeffs[5] = {0.25, 0.16666666666, 0.375, 0.5, 1.};
5816 if(m_noRKSteps == 5) {
5817 for(
MInt i = 0; i < m_noRKSteps; i++) {
5818 m_RKalpha[i] = Context::getSolverProperty<MFloat>(
"rkalpha-step", m_solverId, AT_, &RK5DefaultCoeffs[i], i);
5821 for(
MInt i = 0; i < m_noRKSteps; i++) {
5822 m_RKalpha[i] = Context::getSolverProperty<MFloat>(
"rkalpha-step", m_solverId, AT_, i);
5826 m_rungeKuttaOrder = 2;
5839 m_rungeKuttaOrder = Context::getSolverProperty<MInt>(
"rungeKuttaOrder", m_solverId, AT_, &m_rungeKuttaOrder);
5848template <MInt nDim_,
class SysEqn>
5852 MFloat pressureLoss = F0;
5854 m_log <<
"TbTu = " << m_burntUnburntTemperatureRatio << endl;
5856 if(m_forcing || m_structuredFlameOutput) {
5857 const MFloat slOverU = m_flameSpeed / m_MaFlameTube;
5858 const MFloat Lf = m_realRadiusFlameTube * tan(acos(slOverU));
5859 m_flameStrouhal = m_strouhal / Lf;
5861 if(m_neutralFlameStrouhal > 0) {
5862 m_flameStrouhal = m_neutralFlameStrouhal;
5865 m_flameStrouhal = F0;
5868 m_flameStrouhal *= m_timeRef;
5869 m_neutralFlameStrouhal *= m_timeRef;
5872 m_marksteinLengthTh = (F1 - m_rhoInfinity * F1 / m_burntUnburntTemperatureRatio) / (F2 * m_strouhal);
5874 m_log <<
"neutral markstein length (theory) = " << m_marksteinLengthTh << endl << endl;
5878 m_temperatureFlameTube = m_TInfinity;
5881 m_pressureFlameTube = m_PInfinity;
5884 m_velocityFlameTube = m_VInfinity;
5886 m_rhoFlameTube = m_rhoInfinity;
5889 if(!(m_initialCondition == 1991 || m_initialCondition == 19911)) {
5890 m_rhoUnburnt = m_rhoInfinity;
5892 m_rhoBurnt = m_rhoInfinity / m_burntUnburntTemperatureRatio;
5895 m_pressureUnburnt = m_PInfinity + m_rhoInfinity *
POW2(m_flameSpeed) * (m_burntUnburntTemperatureRatio - F1);
5897 m_log <<
"CFL number: " << m_cfl << endl;
5898 m_log <<
"smallest Cell distance according to max refinement Level: " << c_cellLengthAtLevel(maxRefinementLevel())
5902 if(m_restart && (m_initialCondition == 1991 || m_initialCondition == 19911)) {
5904 m_log <<
"corrected m_rhoUnburnt = " << m_rhoUnburnt << endl;
5905 m_log <<
"corrected TbTu = " << m_burntUnburntTemperatureRatio << endl;
5907 m_rhoBurnt = m_rhoUnburnt / m_burntUnburntTemperatureRatio;
5908 m_log <<
"corrected m_rhoBurnt = " << m_rhoBurnt << endl;
5912 m_DthInfinity = sysEqn().m_muInfinity / (m_rhoUnburnt * m_Pr);
5913 m_log <<
"corrected DthInfinity = " << m_DthInfinity << endl;
5915 m_marksteinLengthTh = (F1 - m_rhoUnburnt * F1 / m_burntUnburntTemperatureRatio) / (F2 * m_strouhal);
5917 m_log <<
"corrected neutral markstein length (theory) = " << m_marksteinLengthTh << endl;
5918 m_log <<
"perturbation amplitude = " << m_perturbationAmplitude << endl;
5924 if(m_restart && (m_initialCondition == 1990 || m_initialCondition == 19901)) {
5926 m_log <<
"corrected m_rhoUnburnt (should be set by your properties file) = " << m_rhoUnburnt << endl;
5927 m_log <<
"corrected TbTu (should be set by your properties file) = " << m_burntUnburntTemperatureRatio << endl;
5928 m_rhoBurnt = m_rhoUnburnt / m_burntUnburntTemperatureRatio;
5929 m_log <<
"corrected m_rhoBurnt = " << m_rhoBurnt << endl;
5932 m_DthInfinity = sysEqn().m_muInfinity / (m_rhoUnburnt * m_Pr);
5933 m_log <<
"corrected DthInfinity = " << m_DthInfinity << endl;
5935 m_marksteinLengthTh = (F1 - m_rhoUnburnt * F1 / m_burntUnburntTemperatureRatio) / (F2 * m_strouhal);
5937 m_log <<
"corrected neutral markstein length (theory) = " << m_marksteinLengthTh << endl;
5938 m_log <<
"CFL number: " << m_cfl << endl;
5939 m_log <<
"smallest Cell distance according to max refinement Level: " << c_cellLengthAtLevel(maxRefinementLevel())
5943 m_log <<
"actual used markstein length (should be set by your properties file)" << m_marksteinLength << endl;
5946 if(m_confinedFlame) {
5947 m_velocityOutlet = m_rhoInfinity / (m_rhoFlameTube * m_targetDensityFactor) * m_VInfinity * m_inletOutletAreaRatio;
5949 m_meanVelocity *= sqrt(m_TInfinity);
5951 m_meanVelocityOutlet =
5952 m_rhoInfinity / (m_rhoFlameTube * m_targetDensityFactor) * m_meanVelocity * m_inletOutletAreaRatio;
5953 m_log <<
"mean velocity " << m_meanVelocity << endl;
5954 m_log <<
"mean velocity outlet" << m_meanVelocityOutlet << endl;
5956 m_deltaPL = m_rRe0 * sysEqn().m_muInfinity * m_meanVelocity * F3 * m_tubeLength /
POW2(m_radiusVelFlameTube);
5957 m_log <<
"friction deltaP tube " << m_deltaPL << endl;
5958 m_deltaPL += m_rRe0 * SUTHERLANDLAW(m_burntUnburntTemperatureRatio) * m_meanVelocityOutlet * F3 * m_outletLength
5959 /
POW2(m_radiusOutlet);
5960 m_log <<
"friction deltaP total " << m_deltaPL << endl;
5962 MFloat pressureLossFlame = m_rhoInfinity * (m_burntUnburntTemperatureRatio - F1);
5963 if(m_pressureLossFlameSpeed != 0) {
5964 pressureLossFlame *=
POW2(m_flameSpeed);
5966 pressureLossFlame *=
POW2(m_VInfinity);
5968 pressureLossFlame += m_rhoFlameTube * m_targetDensityFactor *
POW2(m_meanVelocityOutlet) * m_flameOutletAreaRatio;
5969 pressureLossFlame -= m_rhoFlameTube *
POW2(m_meanVelocity);
5970 m_log <<
"pressureLoss" << pressureLossFlame << endl;
5971 m_deltaPL += pressureLossFlame;
5972 m_log <<
"deltaP total = friction deltaP + pressureLoss " << m_deltaPL << endl;
5973 m_deltaPL += m_pressureLossCorrection;
5974 m_log <<
"deltaP total = friction deltaP + pressureLoss + pressureLossCorrection " << m_deltaPL << endl;
5975 m_log <<
" pressure forced at inlet p = pInf + totaldeltaP " << m_PInfinity + m_deltaPL << endl;
5976 m_meanPressure = m_PInfinity + m_deltaPL;
5977 m_log <<
"mean pressure is initialized according to the inlet pressure" << endl;
5978 m_log <<
" pressure forced at outlet p = pInf " << m_PInfinity << endl;
5982 if(m_plenum && !m_confinedFlame) {
5984 m_temperatureFlameTube = sysEqn().temperature_IR(m_MaFlameTube);
5986 m_velocityFlameTube = m_MaFlameTube * sqrt(m_temperatureFlameTube);
5988 m_timeRef = m_velocityFlameTube;
5990 m_rhoFlameTube = sysEqn().density_IR(m_temperatureFlameTube);
5994 if(m_combustion && m_plenumWall) {
5996 m_rhoInfinity / (m_rhoFlameTube * m_targetDensityFactor) * m_VInfinity * m_inletOutletAreaRatio;
5998 m_pressureFlameTube = sysEqn().pressure_IR(m_temperatureFlameTube);
5999 sysEqn().m_muInfinity = SUTHERLANDLAW(m_temperatureFlameTube);
6002 m_DInfinity = sysEqn().m_muInfinity;
6003 sysEqn().m_Re0 = m_Re * sysEqn().m_muInfinity / (m_rhoFlameTube * m_MaFlameTube * sqrt(m_temperatureFlameTube));
6004 m_rRe0 = 1. / sysEqn().m_Re0;
6007 m_DthInfinity = sysEqn().m_muInfinity / (m_rhoFlameTube * m_Pr);
6009 m_rhoEInfinity = sysEqn().internalEnergy(m_pressureFlameTube, m_rhoFlameTube,
POW2(m_velocityFlameTube));
6012 pressureLoss = m_rhoInfinity *
POW2(m_VInfinity) * (m_inletTubeAreaRatio - F1);
6014 m_log <<
"***************************************************************************" << endl;
6015 m_log <<
"Plenum - Computation:" << endl;
6016 m_log <<
"Initial Condition summary referred to the averaged values of the flame tube" << endl;
6017 m_log <<
"***************************************************************************" << endl;
6018 m_log <<
"Re = " << m_Re << endl;
6019 m_log <<
"Re0 (used in code) = " << sysEqn().m_Re0 << endl;
6020 m_log <<
"Ma_fl (used in code) = " << m_MaFlameTube << endl;
6021 m_log <<
"T_fl = " << m_temperatureFlameTube << endl;
6022 m_log <<
"V_fl = " << m_velocityFlameTube << endl;
6023 m_log <<
"P_fl = " << m_pressureFlameTube << endl;
6024 m_log <<
"rho_fl (used in code) = " << m_rhoFlameTube << endl;
6025 m_log <<
"rhoEInfinity (used in code) = " << m_rhoEInfinity << endl;
6026 m_log <<
"mu_Infinity (used in code) = " << sysEqn().m_muInfinity << endl;
6027 m_log <<
"D_Infinity (used in code) = " << m_DInfinity << endl;
6028 m_log <<
"Dth_Infinity (used in code) = " << m_DthInfinity << endl << endl;
6029 m_log <<
"Tb/Tu (used in code) = " << m_burntUnburntTemperatureRatio << endl << endl;
6032 m_log <<
"******************************************************************" << endl;
6033 m_log <<
"Plenum + Wall - Computation:" << endl;
6034 m_log <<
"Additional information for the use of no slip walls at the outlet:" << endl;
6035 m_log <<
"******************************************************************" << endl;
6036 m_log <<
"inletOutletAreaRatio = " << m_inletOutletAreaRatio << endl;
6037 m_log <<
"inletTubeAreaRatio = " << m_inletTubeAreaRatio << endl;
6038 m_log <<
"flameOutletAreaRatio = " << m_flameOutletAreaRatio << endl;
6039 m_log <<
"averaged velocity outlet = " << m_velocityOutlet << endl;
6040 m_log <<
"Calculating additional pressure loss ... " << pressureLoss << endl;
6042 pressureLoss += m_rhoFlameTube * m_targetDensityFactor
6043 * (
POW2(m_velocityOutlet) -
POW2(m_flameSpeed) * m_flameOutletAreaRatio);
6046 m_log <<
"pressure loss = " << pressureLoss << endl;
6049 if(m_confinedFlame) {
6050 m_log <<
"******************************************************************" << endl;
6051 m_log <<
"Confined flame - Computation:" << endl;
6052 m_log <<
"Additional information for the use of no slip walls at the outlet:" << endl;
6053 m_log <<
"******************************************************************" << endl;
6054 m_log <<
"inletOutletAreaRatio = " << m_inletOutletAreaRatio << endl;
6055 m_log <<
"flameOutletAreaRatio = " << m_flameOutletAreaRatio << endl;
6056 m_log <<
"averaged velocity outlet = " << m_velocityOutlet << endl;
6057 m_log <<
"Calculating additional pressure loss ... " << pressureLoss << endl;
6065 IF_CONSTEXPR(nDim == 3) {
6067 MFloat FDL = 1 / m_DthInfinity;
6068 MFloat DL = m_DthInfinity;
6074 MFloat Dt = m_NuT / m_ScT;
6076 MFloat flameSpeed = m_flameSpeed;
6078 MFloat delta = c_cellLengthAtLevel(maxLevel());
6079 MFloat uAmpl = pow(m_integralAmplitude, 3);
6081 uAmpl /= m_integralLengthScale;
6082 uAmpl = pow(uAmpl, F1B3);
6083 m_Da = flameSpeed * delta / (uAmpl * m_laminarFlameThickness);
6085 MFloat bFactor = pow(b3T, 2) / (F2 * b1T * m_ScT);
6087 bFactor *= m_NuT * FDL * m_flameSpeed / uAmpl;
6089 MFloat b3Factor = pow(b3T, 2) * m_NuT;
6090 b3Factor /= (m_ScT * DL);
6093 MFloat turbFlameSpeed = -bFactor;
6094 turbFlameSpeed += sqrt(pow(bFactor, 2) + b3Factor);
6095 turbFlameSpeed *= m_flameSpeed;
6097 m_turbFlameSpeed = turbFlameSpeed;
6098 m_log <<
"Da = " << m_Da << endl;
6099 MFloat Ka = sqrt(pow((uAmpl / m_flameSpeed), 3) * m_laminarFlameThickness / delta);
6100 m_log <<
"Ka = " << Ka << endl;
6102 m_log <<
"turbulent flame speed = " << m_turbFlameSpeed << endl;
6103 m_log <<
"turbulent flame speed/lam flame speed = " << m_turbFlameSpeed / m_flameSpeed << endl;
6107 FDa *= F1 / pow(m_Da, 2);
6108 m_log <<
"Pitsch model for Da > 1 " << endl;
6110 m_log <<
"Pitsch model for Da < 1 " << endl;
6112 m_log <<
"turbulent diffusivity D_tk = " << FDa << endl;
6113 m_log <<
"ratio of integral velocity to flame speed " << m_integralAmplitude / m_flameSpeed << endl;
6119template <MInt nDim_,
class SysEqn>
6123 const MInt noFVars = FV->noVariables;
6127#pragma omp parallel for collapse(2)
6129 for(
MInt id = 0;
id < a_noCells();
id++) {
6130 for(
MInt varId = 0; varId < noFVars; varId++) {
6131 a_rightHandSide(
id, varId) = F0;
6140template <MInt nDim_,
class SysEqn>
6144 copyVarsToSmallCells();
6146 if(m_gridInterfaceFilter) {
6147 filterConservativeVariablesAtFineToCoarseGridInterfaces();
6150 computePrimitiveVariables();
6160template <MInt nDim_,
class SysEqn>
6166 for(
MInt ac = 0; ac < m_noActiveCells; ac++) {
6167 cellId = m_activeCellIds[ac];
6170 for(
MInt i = 0; i < 2; i++) {
6171 radius += pow(a_coordinate(cellId, i + 1) - m_rotAxisCoord[i], 2.0);
6173 radius = sqrt(radius);
6176 MFloat phi_mid = 74.9355804414;
6177 MFloat v_t_mid = m_UInfinity * sin(phi_mid / 180.0 * PI);
6178 v_t = v_t_mid / ((150.0 + 67.5) / 2.0) * radius;
6181 a_rightHandSide(m_activeCellIds[ac], CV->RHO_VV[1]) -=
6182 a_cellVolume(m_activeCellIds[ac])
6183 * (F2 * v_t * a_pvariable(cellId, PV->RHO) * a_pvariable(cellId, PV->W) / radius
6184 + a_pvariable(cellId, PV->RHO) * pow(v_t / radius, 2.0) * (a_coordinate(cellId, 1) - m_rotAxisCoord[0]));
6186 a_rightHandSide(m_activeCellIds[ac], CV->RHO_VV[2]) -=
6187 a_cellVolume(m_activeCellIds[ac])
6188 * (-F2 * v_t * a_pvariable(cellId, PV->RHO) * a_pvariable(cellId, PV->V) / radius
6189 + a_pvariable(cellId, PV->RHO) * pow(v_t / radius, 2.0) * (a_coordinate(cellId, 2) - m_rotAxisCoord[1]));
6192 IF_CONSTEXPR(hasE<SysEqn>)
6193 a_rightHandSide(m_activeCellIds[ac], CV->RHO_E) -=
6194 a_cellVolume(m_activeCellIds[ac]) * a_pvariable(cellId, PV->RHO) * pow(v_t / radius, 2.0)
6195 * ((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) * a_pvariable(cellId, PV->V)
6196 + (a_coordinate(cellId, 2) - m_rotAxisCoord[1]) * a_pvariable(cellId, PV->W));
6204template <MInt nDim_,
class SysEqn>
6208 if(m_isEEGas)
return;
6211#pragma omp parallel for collapse(2)
6213 for(
MInt ac = 0; ac < m_noActiveCells; ac++) {
6214 for(
MInt i = 0; i < nDim; i++) {
6215 a_rightHandSide(m_activeCellIds[ac], CV->RHO_VV[i]) -=
6216 a_pvariable(m_activeCellIds[ac], PV->RHO) * m_volumeAcceleration[i] * a_cellVolume(m_activeCellIds[ac]);
6217 IF_CONSTEXPR(hasE<SysEqn>)
6218 a_rightHandSide(m_activeCellIds[ac], CV->RHO_E) -= a_pvariable(m_activeCellIds[ac], PV->VV[i])
6219 * a_pvariable(m_activeCellIds[ac], PV->RHO)
6220 * m_volumeAcceleration[i] * a_cellVolume(m_activeCellIds[ac]);
6226template <MInt nDim_,
class SysEqn>
6229 return mMax(1, (
MInt)(F1 / (timeStep() * m_timeRef * m_sampleRate)));
6237template <MInt nDim_,
class SysEqn>
6241 if(noNeighborDomains() == 0)
return;
6245 for(
MInt d = 0; d < noNeighborDomains(); d++) {
6246 haloCellsCnt[d] = noHaloCells(d);
6247 windowCellsCnt[d] = noWindowCells(d);
6251 mAlloc(m_maxLevelHaloCells, noNeighborDomains(), &haloCellsCnt[0],
"m_maxLevelHaloCells", AT_);
6253 mAlloc(m_maxLevelWindowCells, noNeighborDomains(), &windowCellsCnt[0],
"m_maxLevelWindowCells", AT_);
6256 isOnMaxLevel.
fill(0);
6258 for(
MInt i = 0; i < noNeighborDomains(); i++) {
6259 m_noMaxLevelHaloCells[i] = 0;
6260 for(
MInt j = 0; j < noHaloCells(i); j++) {
6261 if(!a_hasProperty(haloCellId(i, j), SolverCell::IsOnCurrentMGLevel)) {
6264 m_maxLevelHaloCells[i][m_noMaxLevelHaloCells[i]] = haloCellId(i, j);
6265 m_noMaxLevelHaloCells[i]++;
6266 isOnMaxLevel(haloCellId(i, j)) = 1;
6273 &isOnMaxLevel[0], &recvBuffer[0]);
6276 for(
MInt i = 0; i < noNeighborDomains(); i++) {
6277 m_noMaxLevelWindowCells[i] = 0;
6278 for(
MInt j = 0; j < noWindowCells(i); j++) {
6279 if(recvBuffer[recvSize]) {
6281 m_maxLevelWindowCells[i][m_noMaxLevelWindowCells[i]] = windowCellId(i, j);
6282 m_noMaxLevelWindowCells[i]++;
6288 prepareMpiExchange();
6290 if(grid().noAzimuthalNeighborDomains() > 0) {
6291 initAzimuthalMaxLevelExchange();
6294 initNearBoundaryExchange();
6300template <MInt nDim_,
class SysEqn>
6305 if(m_nonBlockingComm) {
6306 m_maxLvlMpiSendNeighbor.clear();
6307 m_maxLvlMpiRecvNeighbor.clear();
6308 MInt noSendNghbrs = 0;
6309 MInt noRecvNghbrs = 0;
6312 for(
MInt i = 0; i < noNeighborDomains(); i++) {
6313 if(m_mpi_receiveRequest[i] != MPI_REQUEST_NULL) {
6316 if(m_mpi_sendRequest[i] != MPI_REQUEST_NULL) {
6321 for(
MInt i = 0; i < noNeighborDomains(); i++) {
6322 MInt bufferCounter = m_noMaxLevelHaloCells[i] * m_dataBlockSize;
6323 if(bufferCounter > 0) {
6325 mpiComm(), &m_mpi_receiveRequest[noRecvNghbrs], AT_,
"m_receiveBuffersNoBlocking[i]");
6326 m_maxLvlMpiRecvNeighbor.push_back(i);
6329 bufferCounter = m_noMaxLevelWindowCells[i] * m_dataBlockSize;
6330 if(bufferCounter > 0) {
6332 mpiComm(), &m_mpi_sendRequest[noSendNghbrs], AT_,
"m_sendBuffersNoBlocking[i]");
6333 m_maxLvlMpiSendNeighbor.push_back(i);
6338 m_mpiSendRequestsOpen =
false;
6339 m_mpiRecvRequestsOpen =
false;
6343template <MInt nDim_,
class SysEqn>
6347 RECORD_TIMER_START(m_tcomm);
6348 RECORD_TIMER_START(m_texchange);
6355 if(grid().azimuthalPeriodicity()) {
6356 exchangeFloatDataAzimuthal(&a_pvariable(0, 0), PV->noVariables, m_rotIndVarsPV);
6360 RECORD_TIMER_STOP(m_texchange);
6361 RECORD_TIMER_STOP(m_tcomm);
6367template <MInt nDim_,
class SysEqn>
6371 RECORD_TIMER_START(m_tcomm);
6372 RECORD_TIMER_START(m_texchange);
6375 if(!m_nonBlockingComm) {
6382 if(grid().azimuthalPeriodicity()) {
6383 mTerm(1, AT_,
"non blocking comm is not implemented for azimuthal periodicity");
6386 finishMpiExchange();
6389 if(grid().azimuthalPeriodicity()) {
6390 exchangeFloatDataAzimuthal<false>(&a_pvariable(0, 0), PV->noVariables, m_rotIndVarsPV);
6392 RECORD_TIMER_STOP(m_texchange);
6393 RECORD_TIMER_STOP(m_tcomm);
6395 if(m_wmLES && m_RKStep == m_noRKSteps - 1) {
6396 RECORD_TIMER_START(m_timers[Timers::WMExchange]);
6398 RECORD_TIMER_STOP(m_timers[Timers::WMExchange]);
6410template <MInt nDim_,
class SysEqn>
6415 RECORD_TIMER_START(m_tgatherAndSend);
6416 RECORD_TIMER_START(m_tgatherAndSendWait);
6417 if(m_mpiSendRequestsOpen) {
6418 MPI_Waitall((
MInt)m_maxLvlMpiSendNeighbor.size(), m_mpi_sendRequest, MPI_STATUSES_IGNORE, AT_);
6420 RECORD_TIMER_STOP(m_tgatherAndSendWait);
6423 if(!m_mpiRecvRequestsOpen) {
6424 MPI_Startall((
MInt)m_maxLvlMpiRecvNeighbor.size(), m_mpi_receiveRequest, AT_);
6425 m_mpiRecvRequestsOpen =
true;
6429 for(
MInt i = 0; i < (
MInt)m_maxLvlMpiSendNeighbor.size(); i++) {
6430 const MInt completedId = m_maxLvlMpiSendNeighbor[i];
6431 MInt bufferCounter = 0;
6432 for(
MInt j = 0; j < m_noMaxLevelWindowCells[completedId]; j++) {
6433 copy_n(&a_pvariable(m_maxLevelWindowCells[completedId][j], 0),
6435 &m_sendBuffersNoBlocking[completedId][bufferCounter]);
6436 bufferCounter += m_dataBlockSize;
6440 MPI_Startall((
MInt)m_maxLvlMpiSendNeighbor.size(), m_mpi_sendRequest, AT_);
6442 m_mpiSendRequestsOpen =
true;
6444 RECORD_TIMER_STOP(m_tgatherAndSend);
6454template <MInt nDim_,
class SysEqn>
6458 if(!m_mpiRecvRequestsOpen) {
6459 mTerm(1,
"MPI receive requests are not open.");
6462 MBool useWaitsome =
false;
6463 RECORD_TIMER_START(m_tscatter);
6466 const MBool loadWasRunning = this->isLoadTimerRunning();
6467 if(loadWasRunning) {
6468 this->stopLoadTimer(AT_);
6469 this->startIdleTimer(AT_);
6470 this->disableDlbTimers();
6477 MInt noCompleted = 0;
6478 RECORD_TIMER_START(m_tscatterWaitSome);
6479 MPI_Waitsome((
MInt)m_maxLvlMpiRecvNeighbor.size(), m_mpi_receiveRequest, &noCompleted, &completedIds[0],
6480 MPI_STATUSES_IGNORE, AT_);
6481 RECORD_TIMER_STOP(m_tscatterWaitSome);
6484 if(noCompleted == MPI_UNDEFINED) {
6489 for(
MInt i = 0; i < noCompleted; i++) {
6490 const MInt completedId = completedIds[i];
6491 MInt bufferCounter = 0;
6492 for(
MInt j = 0; j < m_noMaxLevelHaloCells[completedId]; j++) {
6493 copy_n(&m_receiveBuffersNoBlocking[completedId][bufferCounter],
6495 &a_pvariable(m_maxLevelHaloCells[completedId][j], 0));
6496 bufferCounter += m_dataBlockSize;
6501 if(loadWasRunning) {
6502 this->reEnableDlbTimers();
6503 this->stopIdleTimer(AT_);
6504 this->startLoadTimer(AT_);
6507 RECORD_TIMER_START(m_tscatterWaitSome);
6508 MPI_Waitall((
MInt)m_maxLvlMpiRecvNeighbor.size(), m_mpi_receiveRequest, MPI_STATUSES_IGNORE, AT_);
6509 RECORD_TIMER_STOP(m_tscatterWaitSome);
6513 for(
MInt n = 0; n < (
MInt)m_maxLvlMpiRecvNeighbor.size(); n++) {
6514 const MInt i = m_maxLvlMpiRecvNeighbor[n];
6515 MInt bufferCounter = 0;
6516 for(
MInt j = 0; j < m_noMaxLevelHaloCells[i]; j++) {
6517 std::copy_n(&m_receiveBuffersNoBlocking[i][bufferCounter], m_dataBlockSize,
6518 &a_pvariable(m_maxLevelHaloCells[i][j], 0));
6519 bufferCounter += m_dataBlockSize;
6524 RECORD_TIMER_STOP(m_tscatter);
6528 RECORD_TIMER_START(m_treceive);
6529 MPI_Startall((
MInt)m_maxLvlMpiRecvNeighbor.size(), m_mpi_receiveRequest, AT_);
6530 m_mpiRecvRequestsOpen =
true;
6531 RECORD_TIMER_STOP(m_treceive);
6539template <MInt nDim_,
class SysEqn>
6544 if(m_mpiSendRequestsOpen) {
6545 MPI_Waitall((
MInt)m_maxLvlMpiSendNeighbor.size(), m_mpi_sendRequest, MPI_STATUSES_IGNORE, AT_);
6546 m_mpiSendRequestsOpen =
false;
6550 if(m_mpiRecvRequestsOpen) {
6551 std::vector<MBool> waitForCancel(noNeighborDomains(),
false);
6552 for(
MInt i = 0; i < noNeighborDomains(); i++) {
6553 if(m_mpi_receiveRequest[i] != MPI_REQUEST_NULL) {
6555 waitForCancel[i] =
true;
6559 for(
MInt i = 0; i < noNeighborDomains(); i++) {
6560 if(waitForCancel[i]) {
6561 MPI_Wait(&m_mpi_receiveRequest[i], MPI_STATUS_IGNORE, AT_);
6564 m_mpiRecvRequestsOpen =
false;
6570template <MInt nDim_,
class SysEqn>
6573 if(m_nonBlockingComm && noNeighborDomains() > 0) {
6575 if(m_mpiSendRequestsOpen) {
6576 MPI_Waitall((
MInt)m_maxLvlMpiSendNeighbor.size(), m_mpi_sendRequest, MPI_STATUSES_IGNORE, AT_);
6579 for(
MInt i = 0; i < noNeighborDomains(); i++) {
6580 if(m_mpi_receiveRequest !=
nullptr) {
6581 if(m_mpi_receiveRequest[i] != MPI_REQUEST_NULL) {
6583 if(m_mpiRecvRequestsOpen) {
6589 if(m_mpi_sendRequest !=
nullptr) {
6590 if(m_mpi_sendRequest[i] != MPI_REQUEST_NULL) {
6597 m_mpiSendRequestsOpen =
false;
6598 m_mpiRecvRequestsOpen =
false;
6611template <MInt nDim_,
class SysEqn>
6613 if(m_periodicCells > 0 && m_periodicCells != 3) {
6621 if(m_periodicCells == 1) {
6622 for(
MInt d = 0; d < noDomains(); d++) {
6624 for(
MInt c = 0; c < m_noPerCellsToSend[d]; c++) {
6625 const auto sortedId =
static_cast<MInt>(m_periodicDataToSend[d][5 + c * m_noPeriodicData]);
6629 m_periodicDataToSend[d][0 + c * m_noPeriodicData] = F0;
6630 m_periodicDataToSend[d][1 + c * m_noPeriodicData] = F0;
6631 m_periodicDataToSend[d][2 + c * m_noPeriodicData] = F0;
6632 m_periodicDataToSend[d][3 + c * m_noPeriodicData] = F0;
6633 m_periodicDataToSend[d][4 + c * m_noPeriodicData] = F0;
6636 MInt noNeighboursRec =
6637 (m_reconstructionDataPeriodic[off_ + c + 1] - m_reconstructionDataPeriodic[off_ + c]) / 2;
6638 for(
MInt n = (m_reconstructionDataPeriodic[off_ + c] + noNeighboursRec);
6639 n < m_reconstructionDataPeriodic[off_ + c + 1];
6641 n_Id =
static_cast<MInt>(m_reconstructionConstantsPeriodic[n - noNeighboursRec]);
6643 v_comp += m_reconstructionConstantsPeriodic[n] * a_pvariable(n_Id, PV->VV[1]);
6644 w_comp += m_reconstructionConstantsPeriodic[n] * a_pvariable(n_Id, PV->VV[2]);
6646 m_periodicDataToSend[d][0 + c * m_noPeriodicData] +=
6647 m_reconstructionConstantsPeriodic[n] * a_pvariable(n_Id, PV->RHO);
6648 m_periodicDataToSend[d][1 + c * m_noPeriodicData] +=
6649 m_reconstructionConstantsPeriodic[n] * a_pvariable(n_Id, PV->VV[0]);
6650 m_periodicDataToSend[d][4 + c * m_noPeriodicData] +=
6651 m_reconstructionConstantsPeriodic[n] * a_pvariable(n_Id, PV->P);
6655 if(m_periodicCellDataDom[d][4 + sortedId * m_noPeriodicCellData] < 0.0)
6657 rot_times = -m_periodicCellDataDom[d][4 + sortedId * m_noPeriodicCellData];
6658 m_periodicDataToSend[d][2 + c * m_noPeriodicData] =
6659 cos(72.0 / 180.0 * PI * rot_times) * v_comp + sin(72.0 / 180.0 * PI * rot_times) * w_comp;
6660 m_periodicDataToSend[d][3 + c * m_noPeriodicData] =
6661 -sin(72.0 / 180.0 * PI * rot_times) * v_comp + cos(72.0 / 180.0 * PI * rot_times) * w_comp;
6663 rot_times = m_periodicCellDataDom[d][4 + sortedId * m_noPeriodicCellData];
6664 m_periodicDataToSend[d][2 + c * m_noPeriodicData] =
6665 cos(72.0 / 180.0 * PI * rot_times) * v_comp - sin(72.0 / 180.0 * PI * rot_times) * w_comp;
6666 m_periodicDataToSend[d][3 + c * m_noPeriodicData] =
6667 sin(72.0 / 180.0 * PI * rot_times) * v_comp + cos(72.0 / 180.0 * PI * rot_times) * w_comp;
6670 off_ += m_noPerCellsToSend[d];
6672 }
else if(m_periodicCells == 2) {
6673 for(
MInt d = 0; d < noDomains(); d++) {
6674 for(
MInt c = 0; c < m_noPerCellsToSend[d]; c++) {
6675 const auto cell_Id =
static_cast<MInt>(m_periodicDataToSend[d][6 + c * m_noPeriodicData]);
6677 m_periodicDataToSend[d][0 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->RHO);
6678 m_periodicDataToSend[d][1 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->U);
6679 m_periodicDataToSend[d][2 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->V);
6680 m_periodicDataToSend[d][3 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->W);
6681 m_periodicDataToSend[d][4 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->P);
6687 for(
MInt c = 0; c < m_noPerCellsToSend[domainId()]; c++) {
6688 for(
MInt v = 0; v < 7; v++) {
6689 m_periodicDataToReceive[domainId()][v + c * m_noPeriodicData] =
6690 m_periodicDataToSend[domainId()][v + c * m_noPeriodicData];
6698 send_Req.
fill(MPI_REQUEST_NULL);
6699 recv_Req.
fill(MPI_REQUEST_NULL);
6702 for(
MInt snd = 0; snd < domainId(); snd++) {
6703 if(m_noPerCellsToReceive[snd] > 0) {
6704 MInt bufSize = m_noPerCellsToReceive[snd] * m_noPeriodicData;
6705 MPI_Irecv(m_periodicDataToReceive[snd], bufSize, MPI_DOUBLE, snd, 0, mpiComm(), &recv_Req[snd], AT_,
6706 "m_periodicDataToReceive[snd]");
6710 for(
MInt rcv = 0; rcv < noDomains(); rcv++) {
6711 if(m_noPerCellsToSend[rcv] > 0 && rcv != domainId()) {
6712 MInt bufSize = m_noPerCellsToSend[rcv] * m_noPeriodicData;
6713 MPI_Isend(m_periodicDataToSend[rcv], bufSize, MPI_DOUBLE, rcv, 0, mpiComm(), &send_Req[rcv], AT_,
6714 "m_periodicDataToSend[rcv]");
6718 if(domainId() < noDomains() - 1) {
6719 for(
MInt snd = domainId() + 1; snd < noDomains(); snd++) {
6720 if(m_noPerCellsToReceive[snd] > 0) {
6721 MInt bufSize = m_noPerCellsToReceive[snd] * m_noPeriodicData;
6722 MPI_Irecv(m_periodicDataToReceive[snd], bufSize, MPI_DOUBLE, snd, 0, mpiComm(), &recv_Req[snd], AT_,
6723 "m_periodicDataToReceive[snd]");
6729 MPI_Waitall(noDomains(), &recv_Req[0], MPI_STATUSES_IGNORE, AT_);
6730 MPI_Waitall(noDomains(), &send_Req[0], MPI_STATUSES_IGNORE, AT_);
6733 for(
MInt d = 0; d < noDomains(); d++) {
6734 for(
MInt c = 0; c < m_noPerCellsToReceive[d]; c++) {
6735 const auto sortedId =
static_cast<MInt>(m_periodicDataToReceive[d][5 + c * m_noPeriodicData]);
6736 const MInt cell_Id = m_sortedPeriodicCells->a[sortedId];
6738 a_pvariable(cell_Id, PV->RHO) = m_periodicDataToReceive[d][0 + c * m_noPeriodicData];
6739 a_pvariable(cell_Id, PV->U) = m_periodicDataToReceive[d][1 + c * m_noPeriodicData];
6740 a_pvariable(cell_Id, PV->V) = m_periodicDataToReceive[d][2 + c * m_noPeriodicData];
6741 a_pvariable(cell_Id, PV->W) = m_periodicDataToReceive[d][3 + c * m_noPeriodicData];
6742 a_pvariable(cell_Id, PV->P) = m_periodicDataToReceive[d][4 + c * m_noPeriodicData];
6745 computeConservativeVariables();
6748 if(m_periodicCells == 3) {
6759template <MInt nDim_,
class SysEqn>
6761 for(
MInt d = 0; d < noDomains(); d++) {
6762 for(
MInt c = 0; c < m_noPerCellsToSend[d]; c++) {
6763 const auto cell_Id =
static_cast<MInt>(m_periodicDataToSend[d][6 + c * m_noPeriodicData]);
6765 m_periodicDataToSend[d][0 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->RHO);
6766 m_periodicDataToSend[d][1 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->U);
6767 m_periodicDataToSend[d][2 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->V);
6768 m_periodicDataToSend[d][3 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->W);
6769 m_periodicDataToSend[d][4 + c * m_noPeriodicData] = a_pvariable(cell_Id, PV->P);
6774 for(
MInt c = 0; c < m_noPerCellsToSend[domainId()]; c++) {
6775 for(
MInt v = 0; v < 7; v++) {
6776 m_periodicDataToReceive[domainId()][v + c * 7] = m_periodicDataToSend[domainId()][v + c * m_noPeriodicData];
6783 send_Req.
fill(MPI_REQUEST_NULL);
6784 recv_Req.
fill(MPI_REQUEST_NULL);
6789 for(
MInt snd = 0; snd < domainId(); snd++) {
6790 if(m_noPerCellsToReceive[snd] > 0) {
6791 MInt bufSize = m_noPerCellsToReceive[snd] * m_noPeriodicData;
6792 MPI_Irecv(m_periodicDataToReceive[snd], bufSize, MPI_DOUBLE, snd, 0, mpiComm(), &recv_Req[snd], AT_,
6793 "m_periodicDataToReceive[snd]");
6797 for(
MInt rcv = 0; rcv < noDomains(); rcv++) {
6798 if(m_noPerCellsToSend[rcv] > 0 && rcv != domainId()) {
6799 MInt bufSize = m_noPerCellsToSend[rcv] * m_noPeriodicData;
6800 MPI_Isend(m_periodicDataToSend[rcv], bufSize, MPI_DOUBLE, rcv, 0, mpiComm(), &send_Req[rcv], AT_,
6801 "m_periodicDataToSend[rcv]");
6805 if(domainId() < noDomains() - 1) {
6806 for(
MInt snd = domainId() + 1; snd < noDomains(); snd++) {
6807 if(m_noPerCellsToReceive[snd] > 0) {
6808 MInt bufSize = m_noPerCellsToReceive[snd] * m_noPeriodicData;
6809 MPI_Irecv(m_periodicDataToReceive[snd], bufSize, MPI_DOUBLE, snd, 0, mpiComm(), &recv_Req[snd], AT_,
6810 "m_periodicDataToReceive[snd]");
6815 MPI_Waitall(noDomains(), &recv_Req[0], MPI_STATUSES_IGNORE, AT_);
6816 MPI_Waitall(noDomains(), &send_Req[0], MPI_STATUSES_IGNORE, AT_);
6822 MFloat localPressure_1 = 0;
6823 MFloat globalPressure_1 = 0;
6824 MFloat localPressure_2 = 0;
6825 MFloat globalPressure_2 = 0;
6830 MFloat localDensity_2 = 0;
6831 MFloat globalDensity_2 = 0;
6832 MFloat localMeanMach_2 = 0;
6833 MFloat globalMeanMach_2 = 0;
6835 for(
MInt d = 0; d < noDomains(); d++) {
6836 for(
MInt c = 0; c < m_noPerCellsToReceive[d]; c++) {
6837 const auto sortedId =
static_cast<MInt>(m_periodicDataToReceive[d][5 + c * m_noPeriodicData]);
6838 const MInt cell_Id = m_sortedPeriodicCells->a[sortedId];
6841 if(a_hasNeighbor(cell_Id, 0) == 0 && a_isHalo(cell_Id) ==
false) {
6842 MInt nghbrId = c_neighborId(cell_Id, 1);
6843 MInt bndryId = a_bndryId(nghbrId);
6847 MFloat vfrac = m_bndryCells->a[bndryId].m_volume /
POW3(c_cellLengthAtCell(nghbrId));
6848 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[1];
6850 area =
POW2(c_cellLengthAtCell(cell_Id)) * vfrac;
6852 mTerm(1, AT_,
"something went wrong!");
6855 area =
POW2(c_cellLengthAtCell(cell_Id));
6858 localPressure_1 += area * a_pvariable(cell_Id, PV->P);
6859 localMeanMach_2 += area
6860 * sqrt(m_periodicDataToReceive[d][1 + c * m_noPeriodicData]
6861 * m_periodicDataToReceive[d][1 + c * m_noPeriodicData]
6862 + m_periodicDataToReceive[d][2 + c * m_noPeriodicData]
6863 * m_periodicDataToReceive[d][2 + c * m_noPeriodicData]
6864 + m_periodicDataToReceive[d][3 + c * m_noPeriodicData]
6865 * m_periodicDataToReceive[d][3 + c * m_noPeriodicData])
6866 / sqrt(1.4 * m_periodicDataToReceive[d][4 + c * m_noPeriodicData]
6867 / m_periodicDataToReceive[d][0 + c * m_noPeriodicData]);
6868 localPressure_2 += area * m_periodicDataToReceive[d][4 + c * m_noPeriodicData];
6869 localDensity_2 += area * m_periodicDataToReceive[d][0 + c * m_noPeriodicData];
6870 localMass += area * m_periodicDataToReceive[d][1 + c * m_noPeriodicData]
6871 * m_periodicDataToReceive[d][0 + c * m_noPeriodicData];
6872 localUbulk += area * m_periodicDataToReceive[d][1 + c * m_noPeriodicData];
6878 MPI_Allreduce(&localMass, &globalMass, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localMass",
"globalMass");
6879 MPI_Allreduce(&localPressure_1, &globalPressure_1, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localPressure_1",
6880 "globalPressure_1");
6881 MPI_Allreduce(&localPressure_2, &globalPressure_2, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localPressure_2",
6882 "globalPressure_2");
6883 MPI_Allreduce(&localDensity_2, &globalDensity_2, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localDensity_2",
6885 MPI_Allreduce(&localArea, &globalArea, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localArea",
"globalArea");
6886 MPI_Allreduce(&localUbulk, &globalUbulk, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localUbulk",
"globalUbulk");
6887 MPI_Allreduce(&localMeanMach_2, &globalMeanMach_2, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localMeanMach_2",
6888 "globalMeanMach_2");
6890 globalPressure_1 = globalPressure_1 / globalArea;
6891 globalPressure_2 = globalPressure_2 / globalArea;
6892 globalMass = globalMass / globalArea;
6893 globalUbulk = globalUbulk / globalArea;
6894 globalDensity_2 = globalDensity_2 / globalArea;
6895 globalMeanMach_2 = globalMeanMach_2 / globalArea;
6902 MFloat localPressure_3 = 0;
6903 MFloat globalPressure_3 = 0;
6904 MFloat localPressure_4 = 0;
6905 MFloat globalPressure_4 = 0;
6907 for(
MInt d = 0; d < noDomains(); d++) {
6908 for(
MInt c = 0; c < m_noPerCellsToReceive[d]; c++) {
6909 const auto sortedId =
static_cast<MInt>(m_periodicDataToReceive[d][5 + c * m_noPeriodicData]);
6910 const MInt cell_Id = m_sortedPeriodicCells->a[sortedId];
6913 if(a_hasNeighbor(cell_Id, 0) > 0 && a_isHalo(cell_Id) ==
false && a_coordinate(cell_Id, 0) < 1.5) {
6914 MInt nghbrId = c_neighborId(cell_Id, 0);
6915 MInt bndryId = a_bndryId(nghbrId);
6918 MFloat vfrac = m_bndryCells->a[bndryId].m_volume /
POW3(c_cellLengthAtCell(nghbrId));
6919 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[1];
6921 area =
POW2(c_cellLengthAtCell(cell_Id)) * vfrac;
6923 mTerm(1, AT_,
"something went wrong!");
6926 area =
POW2(c_cellLengthAtCell(cell_Id));
6929 localPressure_3 += area * a_pvariable(cell_Id, PV->P);
6930 localPressure_4 += area * m_periodicDataToReceive[d][4 + c * m_noPeriodicData];
6936 MPI_Allreduce(&localPressure_3, &globalPressure_3, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localPressure_3",
6937 "globalPressure_3");
6938 MPI_Allreduce(&localPressure_4, &globalPressure_4, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localPressure_4",
6939 "globalPressure_4");
6940 MPI_Allreduce(&localArea, &globalArea, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localArea",
"globalArea");
6942 globalPressure_3 = globalPressure_3 / globalArea;
6943 globalPressure_4 = globalPressure_4 / globalArea;
6947 MFloat localPressure_5 = 0;
6948 MFloat globalPressure_5 = 0;
6949 MFloat localPressure_6 = 0;
6950 MFloat globalPressure_6 = 0;
6955 for(
MInt d = 0; d < noDomains(); d++) {
6956 for(
MInt c = 0; c < m_noPerCellsToReceive[d]; c++) {
6957 const MInt sortedId =
static_cast<MInt>(m_periodicDataToReceive[d][5 + c * m_noPeriodicData]);
6958 const MInt cell_Id = m_sortedPeriodicCells->a[sortedId];
6961 if(a_hasNeighbor(cell_Id, 1) > 0 && a_isHalo(cell_Id) ==
false && a_coordinate(cell_Id, 0) > 1.5) {
6962 MInt nghbrId = c_neighborId(cell_Id, 1);
6963 MInt bndryId = a_bndryId(nghbrId);
6966 MFloat vfrac = m_bndryCells->a[bndryId].m_volume /
POW3(c_cellLengthAtCell(nghbrId));
6967 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[0];
6969 area =
POW2(c_cellLengthAtCell(cell_Id)) * vfrac;
6971 mTerm(1, AT_,
"something went wrong!");
6974 area =
POW2(c_cellLengthAtCell(cell_Id));
6977 localPressure_5 += area * a_pvariable(cell_Id, PV->P);
6978 localPressure_6 += area * m_periodicDataToReceive[d][4 + c * m_noPeriodicData];
6984 MPI_Allreduce(&localPressure_5, &globalPressure_5, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localPressure_5",
6985 "globalPressure_5");
6986 MPI_Allreduce(&localPressure_6, &globalPressure_6, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localPressure_6",
6987 "globalPressure_6");
6988 MPI_Allreduce(&localArea, &globalArea, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localArea",
"globalArea");
6990 globalPressure_5 = globalPressure_5 / globalArea;
6991 globalPressure_6 = globalPressure_6 / globalArea;
6995 MFloat localPressure_7 = 0;
6996 MFloat globalPressure_7 = 0;
6997 MFloat localPressure_8 = 0;
6998 MFloat globalPressure_8 = 0;
7003 for(
MInt d = 0; d < noDomains(); d++) {
7004 for(
MInt c = 0; c < m_noPerCellsToReceive[d]; c++) {
7005 const MInt sortedId =
static_cast<MInt>(m_periodicDataToReceive[d][5 + c * m_noPeriodicData]);
7006 const MInt cell_Id = m_sortedPeriodicCells->a[sortedId];
7009 if(a_hasNeighbor(cell_Id, 1) == 0 && a_isHalo(cell_Id) ==
false) {
7010 MInt nghbrId = c_neighborId(cell_Id, 0);
7011 MInt bndryId = a_bndryId(nghbrId);
7014 MFloat vfrac = m_bndryCells->a[bndryId].m_volume /
POW3(c_cellLengthAtCell(nghbrId));
7015 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[0];
7017 area =
POW2(c_cellLengthAtCell(cell_Id)) * vfrac;
7019 mTerm(1, AT_,
"something went wrong!");
7022 area =
POW2(c_cellLengthAtCell(cell_Id));
7025 localPressure_7 += area * a_pvariable(cell_Id, PV->P);
7026 localPressure_8 += area * m_periodicDataToReceive[d][4 + c * m_noPeriodicData];
7032 MPI_Allreduce(&localPressure_7, &globalPressure_7, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localPressure_7",
7033 "globalPressure_7");
7034 MPI_Allreduce(&localPressure_8, &globalPressure_8, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localPressure_8",
7035 "globalPressure_8");
7036 MPI_Allreduce(&localArea, &globalArea, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localArea",
"globalArea");
7038 globalPressure_7 = globalPressure_7 / globalArea;
7039 globalPressure_8 = globalPressure_8 / globalArea;
7041 m_TInfinity = 1.0 / (1.0 + F1B2 * 0.4 *
POW2(m_Ma));
7046 for(
MInt d = 0; d < noDomains(); d++) {
7047 for(
MInt c = 0; c < m_noPerCellsToReceive[d]; c++) {
7048 const MInt sortedId =
static_cast<MInt>(m_periodicDataToReceive[d][5 + c * m_noPeriodicData]);
7049 const MInt cell_Id = m_sortedPeriodicCells->a[sortedId];
7051 a_pvariable(cell_Id, PV->RHO) = m_periodicDataToReceive[d][0 + c * m_noPeriodicData];
7052 a_pvariable(cell_Id, PV->U) = m_periodicDataToReceive[d][1 + c * m_noPeriodicData];
7053 a_pvariable(cell_Id, PV->V) = m_periodicDataToReceive[d][2 + c * m_noPeriodicData];
7054 a_pvariable(cell_Id, PV->W) = m_periodicDataToReceive[d][3 + c * m_noPeriodicData];
7055 a_pvariable(cell_Id, PV->P) = m_periodicDataToReceive[d][4 + c * m_noPeriodicData];
7059 m_target_Ubulk = m_Ma * sqrt(m_TInfinity);
7062 m_oldUbulk = globalUbulk;
7063 m_oldPressure_Gradient = m_volumeAcceleration[0];
7067 UbulkDiff = (1 / timeStep()) * ((m_target_Ubulk - 2 * globalUbulk + m_oldUbulk));
7069 MFloat m_delta_P = m_oldPressure_Gradient + UbulkDiff;
7071 m_volumeAcceleration[0] = m_delta_P;
7073 if(domainId() == 0) {
7074 cout <<
" step " <<
globalTimeStep <<
" deltaT " << timeStep() <<
" newPresGrad " << m_delta_P <<
" oldPresGrad "
7075 << m_oldPressure_Gradient <<
" Pinf " << m_PInfinity <<
" meanPres " << globalPressure_2 <<
" meanDens "
7076 << globalDensity_2 <<
" Mass_mean " << globalMass <<
" Umean " << globalUbulk <<
" UTarget "
7077 << m_Ma * sqrt(m_TInfinity) <<
" UmeanDiff" << globalUbulk - m_Ma * sqrt(m_TInfinity) <<
" meanMach "
7078 << globalMeanMach_2 <<
" machDiff" << m_Ma - globalMeanMach_2 << endl;
7081 m_oldPressure_Gradient = m_delta_P;
7082 m_oldUbulk = globalUbulk;
7086 computeConservativeVariables();
7093template <MInt nDim_,
class SysEqn>
7094template <MBool exchangeAll_>
7097 RECORD_TIMER_START(m_tgatherAndSend);
7098 RECORD_TIMER_START(m_tgather);
7099 for(
MInt i = 0; i < noNeighborDomains(); i++) {
7100 MInt sendBufferCounter = 0;
7101 const MInt noWindows = (exchangeAll_) ? noWindowCells(i) : m_noMaxLevelWindowCells[i];
7102 for(
MInt j = 0; j < noWindows; j++) {
7103 const MInt windowCell = (exchangeAll_) ? windowCellId(i, j) : m_maxLevelWindowCells[i][j];
7104 std::copy_n(&a_pvariable(windowCell, 0), m_dataBlockSize, &m_sendBuffers[i][sendBufferCounter]);
7105 sendBufferCounter += m_dataBlockSize;
7108 RECORD_TIMER_STOP(m_tgather);
7109 RECORD_TIMER_STOP(m_tgatherAndSend);
7116template <MInt nDim_,
class SysEqn>
7117template <MBool exchangeAll_>
7120 RECORD_TIMER_START(m_tscatter);
7121 for(
MInt i = 0; i < noNeighborDomains(); i++) {
7122 MInt receiveBufferCounter = 0;
7123 const MInt noHalos = (exchangeAll_) ? noHaloCells(i) : m_noMaxLevelHaloCells[i];
7124 for(
MInt j = 0; j < noHalos; j++) {
7125 const MInt haloCell = (exchangeAll_) ? haloCellId(i, j) : m_maxLevelHaloCells[i][j];
7126 std::copy_n(&m_receiveBuffers[i][receiveBufferCounter], m_dataBlockSize, &a_pvariable(haloCell, 0));
7127 receiveBufferCounter += m_dataBlockSize;
7130 RECORD_TIMER_STOP(m_tscatter);
7137template <MInt nDim_,
class SysEqn>
7140 RECORD_TIMER_START(m_tgatherAndSend);
7141 RECORD_TIMER_START(m_tsend);
7142 for(
MInt i = 0; i < noNeighborDomains(); i++) {
7143 const MInt noWindows = (exchangeAll) ? noWindowCells(i) : m_noMaxLevelWindowCells[i];
7144 const MInt bufSize = noWindows * m_dataBlockSize;
7145 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &m_mpi_request[i], AT_,
7146 "m_sendBuffers[i]");
7148 RECORD_TIMER_STOP(m_tsend);
7149 RECORD_TIMER_STOP(m_tgatherAndSend);
7156template <MInt nDim_,
class SysEqn>
7159 if(noNeighborDomains() == 0) {
7162 RECORD_TIMER_START(m_treceive);
7165 recvRequests.
fill(MPI_REQUEST_NULL);
7167 RECORD_TIMER_START(m_treceiving);
7169 for(
MInt i = 0; i < noNeighborDomains(); i++) {
7170 const MInt noHalos = (exchangeAll) ? noHaloCells(i) : m_noMaxLevelHaloCells[i];
7171 const MInt bufSize = noHalos * m_dataBlockSize;
7173 &recvRequests[i], AT_,
"m_receiveBuffer[i]");
7175 RECORD_TIMER_STOP(m_treceiving);
7177 RECORD_TIMER_START(m_treceiveWait);
7179 MPI_Waitall(noNeighborDomains(), &m_mpi_request[0], MPI_STATUSES_IGNORE, AT_);
7180 MPI_Waitall(noNeighborDomains(), &recvRequests[0], MPI_STATUSES_IGNORE, AT_);
7181 RECORD_TIMER_STOP(m_treceiveWait);
7183 RECORD_TIMER_STOP(m_treceive);
7186template <MInt nDim_,
class SysEqn>
7188 if(m_levelSetMb)
return;
7190 const MUint noSurfaces = a_noSurfaces();
7192 for(
MUint srfcId = 0; srfcId < noSurfaces; srfcId++) {
7193 const MInt orientation = a_surfaceOrientation(srfcId);
7194 const MInt nghbrId0 = a_surfaceNghbrCellId(srfcId, 0);
7195 const MInt nghbrId1 = a_surfaceNghbrCellId(srfcId, 1);
7197 if(a_level(nghbrId1) > a_level(nghbrId0)) {
7198 m_cellSurfaceMapping[nghbrId0][2 * orientation + 1] = -1;
7199 m_cellSurfaceMapping[nghbrId1][2 * orientation] = srfcId;
7201 m_cellSurfaceMapping[nghbrId0][2 * orientation + 1] = srfcId;
7202 m_cellSurfaceMapping[nghbrId1][2 * orientation] = -1;
7205 if(a_level(nghbrId0) == a_level(nghbrId1)) {
7206 m_cellSurfaceMapping[nghbrId0][2 * orientation + 1] = srfcId;
7207 m_cellSurfaceMapping[nghbrId1][2 * orientation] = srfcId;
7212template <MInt nDim_,
class SysEqn>
7213template <
class _, std::enable_if_t<isDetChem<SysEqn>, _*>>
7218 const MInt noDirs = 2 * nDim;
7219 const MUint noPVars = PV->noVariables;
7220 const MUint noSurfaceCoefficients = hasSC ? SC->m_noSurfaceCoefficients : 0;
7221 const MUint surfaceVarMemory = 2 * noPVars;
7222 const MUint noSlopes = nDim * noPVars;
7224 const MInt*
const RESTRICT orientations = ALIGNED_I(&a_surfaceOrientation(0));
7225 const MInt*
const RESTRICT nghbrCellIds = ALIGNED_I(&a_surfaceNghbrCellId(0, 0));
7226 const MFloat*
const RESTRICT surfaceVars = ALIGNED_F(&a_surfaceVariable(0, 0, 0));
7227 const MFloat*
const RESTRICT surfaceCoefficients = hasSC ? ALIGNED_F(&a_surfaceCoefficient(0, 0)) :
nullptr;
7228 const MFloat*
const RESTRICT factor = ALIGNED_F(&a_surfaceFactor(0, 0));
7229 const MFloat*
const RESTRICT slope = ALIGNED_F(&a_slope(0, 0, 0));
7232#pragma omp parallel for
7235 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
7236 vector<vector<MFloat>> J(noDirs, vector<MFloat>(PV->m_noSpecies, F0));
7237 vector<vector<MFloat>> J_noSoret(noDirs, vector<MFloat>(PV->m_noSpecies, F0));
7238 vector<vector<MFloat>> dXdn(noDirs, vector<MFloat>(PV->m_noSpecies, F0));
7239 vector<vector<MFloat>> dXdn_int(nDim, vector<MFloat>(PV->m_noSpecies, F0));
7240 vector<MFloat> dXH2dn1(2, F0);
7241 vector<MFloat> dTdn(noDirs, F0);
7242 vector<MFloat> DH2(noDirs, F0);
7243 vector<vector<MFloat>> J_int(nDim, vector<MFloat>(PV->m_noSpecies, F0));
7244 vector<vector<MFloat>> J_noSoret_int(nDim, vector<MFloat>(PV->m_noSpecies, F0));
7245 vector<MFloat> dTdn_int(nDim, F0);
7248 for(
MInt dir = 0; dir < noDirs; dir++) {
7249 const MInt srfcId = m_cellSurfaceMapping[cellId][dir];
7250 if(srfcId < 0)
continue;
7252 ASSERT((nghbrCellIds[2 * srfcId] == cellId) || (nghbrCellIds[2 * srfcId + 1] == cellId),
"");
7254 const MUint offset = srfcId * surfaceVarMemory;
7255 const MFloat*
const RESTRICT vars0 = ALIGNED_F(surfaceVars + offset);
7256 const MFloat*
const RESTRICT vars1 = ALIGNED_F(vars0 + noPVars);
7257 const MFloat f0 = factor[srfcId * 2];
7258 const MFloat f1 = factor[srfcId * 2 + 1];
7259 const MUint offset0 = nghbrCellIds[2 * srfcId] * noSlopes;
7260 const MUint offset1 = nghbrCellIds[2 * srfcId + 1] * noSlopes;
7261 const MFloat*
const RESTRICT slope0 = ALIGNED_F(slope + offset0);
7262 const MFloat*
const RESTRICT slope1 = ALIGNED_F(slope + offset1);
7263 const MUint coefficientOffset = srfcId * noSurfaceCoefficients;
7264 const MFloat*
const RESTRICT srfcCoeff = hasSC ? ALIGNED_F(surfaceCoefficients + coefficientOffset) :
nullptr;
7266 sysEqn().getSpeciesDiffusionMassFluxes(orientations[srfcId], vars0, vars1, slope0, slope1, srfcCoeff, f0, f1,
7267 J[dir], dXdn[dir], dTdn[dir], sysEqn().m_soretEffect);
7268 sysEqn().getSpeciesDiffusionMassFluxes(orientations[srfcId], vars0, vars1, slope0, slope1, srfcCoeff, f0, f1,
7269 J_noSoret[dir], dXdn[dir], dTdn[dir],
false);
7270 for(
MUint s = 0; s < PV->m_noSpecies; s++) {
7271 if(m_speciesName[s] ==
"H2") DH2[dir] = a_srfcCoeffs(srfcId, SC->D[s]);
7272 if(m_speciesName[s] ==
"H2" && (dir == 0 || dir == 1)) dXH2dn1[dir] = dXdn[dir][s];
7276 for(
MInt dim = 0; dim < nDim; dim++) {
7277 dTdn_int[dim] = dTdn[2 * dim] + F1B2 * (dTdn[2 * dim + 1] - dTdn[2 * dim]);
7278 dtdn[cellId * nDim + dim] = dTdn_int[dim];
7279 for(
MUint s = 0; s < PV->m_noSpecies; s++) {
7280 J_int[dim][s] = J[2 * dim][s] + F1B2 * (J[2 * dim + 1][s] - J[2 * dim][s]);
7281 dXdn_int[dim][s] = dXdn[2 * dim][s] + F1B2 * (dXdn[2 * dim + 1][s] - dXdn[2 * dim][s]);
7282 dXdn[cellId * nDim * PV->m_noSpecies + dim * PV->m_noSpecies + s] = dXdn_int[dim][s];
7283 J[cellId * nDim * PV->m_noSpecies + dim * PV->m_noSpecies + s] = J_int[dim][s];
7289template <MInt nDim_,
class SysEqn>
7294 const MInt noSrfcs = a_noSurfaces();
7295 const MInt noDirs = 2 * nDim;
7298 switch(m_upwindMethod) {
7300 for(
MInt s = 0; s < noSrfcs; s++) {
7302 for(
MInt side = 0; side < 2; side++) {
7303 for(
MInt d = 0; d < noDirs; d++) {
7304 MInt gridcellId = a_surfaceNghbrCellId(s, side);
7305 MInt gridcellId2 = a_surfaceNghbrCellId(s, side);
7306 if(a_hasProperty(gridcellId, SolverCell::IsSplitClone)) {
7307 gridcellId = m_splitChildToSplitCell.find(gridcellId)->second;
7309 if(a_hasProperty(gridcellId2, SolverCell::IsSplitClone)) {
7310 gridcellId2 = m_splitChildToSplitCell.find(gridcellId2)->second;
7312 if(a_isBndryGhostCell(a_surfaceNghbrCellId(s, side)) || c_parentId(gridcellId) == -1) {
7315 if(a_hasNeighbor(gridcellId, d) > 0) {
7318 if(a_hasNeighbor(c_parentId(gridcellId2), d) == 0) {
7321 if(c_noChildren(c_neighborId(c_parentId(gridcellId2), d)) > 0) {
7329 a_surfaceUpwindCoefficient(s) = m_chi;
7331 a_surfaceUpwindCoefficient(s) = m_globalUpwindCoefficient;
7334 if(m_combustion && m_jet) {
7335 m_log <<
"upwinding on coarse level is set to max upwind coefficient 0.5, only valid when the coarse level "
7336 "is not of interest !!!!"
7338 for(
MInt s = 0; s < noSrfcs; s++) {
7339 if(a_isBndryGhostCell(a_surfaceNghbrCellId(s, 0)) || a_isBndryGhostCell(a_surfaceNghbrCellId(s, 1))) {
7342 if(a_surfaceNghbrCellId(s, 0) == -1 || a_surfaceNghbrCellId(s, 1) == -1) {
7345 if(a_level(a_surfaceNghbrCellId(s, 0)) == maxLevel() && a_level(a_surfaceNghbrCellId(s, 1)) == maxLevel()) {
7349 a_surfaceUpwindCoefficient(s) = m_chi;
7358 for(
MInt s = 0; s < noSrfcs; s++) {
7360 for(
MInt side = 0; side < 2; side++) {
7361 MInt gridcellId = a_surfaceNghbrCellId(s, side);
7362 MInt orientation = a_surfaceOrientation(s);
7363 MInt d = 2 * orientation + (1 - side);
7364 TERMM_IF_NOT_COND(gridcellId == a_surfaceNghbrCellId(s, side),
"");
7365 if(a_hasProperty(gridcellId, SolverCell::IsSplitClone)) {
7366 gridcellId = m_splitChildToSplitCell.find(gridcellId)->second;
7368 if(a_isBndryGhostCell(a_surfaceNghbrCellId(s, side)) || c_parentId(gridcellId) == -1) {
7371 if(a_hasNeighbor(gridcellId, d) > 0) {
7374 if(a_hasNeighbor(c_parentId(gridcellId), d) == 0) {
7377 if(c_noChildren(c_neighborId(c_parentId(gridcellId), d)) > 0) {
7383 a_surfaceUpwindCoefficient(s) = m_chi;
7385 a_surfaceUpwindCoefficient(s) = m_globalUpwindCoefficient;
7393 for(
MInt s = 0; s < noSrfcs; s++) {
7395 for(
MInt side = 0; side < 2; side++) {
7396 MInt gridcellId = a_surfaceNghbrCellId(s, side);
7397 MInt orientation = a_surfaceOrientation(s);
7398 TERMM_IF_NOT_COND(gridcellId == a_surfaceNghbrCellId(s, side),
"");
7399 for(
MInt side2 = 0; side2 < 2; ++side2) {
7400 MInt d = 2 * orientation + side2;
7401 if(a_hasProperty(gridcellId, SolverCell::IsSplitClone)) {
7402 gridcellId = m_splitChildToSplitCell.find(gridcellId)->second;
7404 if(a_isBndryGhostCell(a_surfaceNghbrCellId(s, side)) || c_parentId(gridcellId) == -1) {
7407 if(a_hasNeighbor(gridcellId, d) > 0) {
7410 if(a_hasNeighbor(c_parentId(gridcellId), d) == 0) {
7413 if(c_noChildren(c_neighborId(c_parentId(gridcellId), d)) > 0) {
7421 a_surfaceUpwindCoefficient(s) = m_chi;
7423 a_surfaceUpwindCoefficient(s) = m_globalUpwindCoefficient;
7432 if(m_periodicCells == 1) {
7437 for(
MInt s = 0; s < noSrfcs; s++) {
7439 for(
MInt side = 0; side < 2; side++) {
7440 for(
MInt d = 0; d < noDirs; d++) {
7441 cellId = a_surfaceNghbrCellId(s, side);
7442 if(a_isBndryGhostCell(cellId))
continue;
7444 for(
MInt i = 0; i < 2; i++) {
7445 radius += pow(a_coordinate(cellId, i + 1) - m_rotAxisCoord[i], 2.0);
7447 radius = sqrt(radius);
7449 const MFloat halfLength = c_cellLengthAtLevel(minLevel() + 1);
7451 if(a_hasProperty(a_surfaceNghbrCellId(s, side), SolverCell::IsPeriodicWithRot)
7452 && radius < 8.0 * halfLength) {
7456 MInt gridcellId = a_surfaceNghbrCellId(s, side);
7457 MInt gridcellId2 = a_surfaceNghbrCellId(s, side);
7458 if(a_hasProperty(gridcellId, SolverCell::IsSplitClone)) {
7459 gridcellId = m_splitChildToSplitCell.find(gridcellId)->second;
7461 if(a_hasProperty(gridcellId2, SolverCell::IsSplitClone)) {
7462 gridcellId2 = m_splitChildToSplitCell.find(gridcellId2)->second;
7464 if(a_hasNeighbor(gridcellId, d) > 0) {
7465 cellId = c_neighborId(gridcellId, d);
7467 for(
MInt i = 0; i < 2; i++) {
7468 radius += pow(a_coordinate(cellId, i + 1) - m_rotAxisCoord[i], 2.0);
7470 radius = sqrt(radius);
7473 if(a_hasProperty(c_neighborId(gridcellId, d), SolverCell::IsPeriodicWithRot)
7474 && radius < 8.0 * halfLength) {
7482 if(a_hasNeighbor(gridcellId, d) > 0) {
7485 if(c_parentId(gridcellId) == -1) {
7488 if(a_hasNeighbor(c_parentId(gridcellId2), d) == 0) {
7491 if(c_noChildren(c_neighborId(c_parentId(gridcellId2), d)) > 0) {
7494 if(!a_hasProperty(c_neighborId(c_parentId(gridcellId2), d), SolverCell::IsOnCurrentMGLevel)) {
7504 a_surfaceUpwindCoefficient(s) = m_chi;
7506 a_surfaceUpwindCoefficient(s) = m_globalUpwindCoefficient;
7514 for(
MInt s = 0; s < noSrfcs; s++) {
7516 for(
MInt side = 0; side < 2; side++) {
7517 for(
MInt d = 0; d < noDirs; d++) {
7518 MInt gridcellId = a_surfaceNghbrCellId(s, side);
7519 if(a_hasProperty(gridcellId, SolverCell::IsSplitClone)) {
7520 gridcellId = m_splitChildToSplitCell.find(gridcellId)->second;
7522 if(a_hasNeighbor(gridcellId, d) > 0) {
7525 if(c_parentId(gridcellId) == -1) {
7528 if(a_hasNeighbor(c_parentId(gridcellId), d) == 0) {
7535 if(flag ||
ABS(a_surfaceCoordinate(s, 1) - 50) < 10) {
7536 a_surfaceUpwindCoefficient(s) = m_chi;
7538 a_surfaceUpwindCoefficient(s) = m_globalUpwindCoefficient;
7546template <MInt nDim_,
class SysEqn>
7550 for(
MInt cellId = 0; cellId < a_noCells(); ++cellId) {
7551 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
7554 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) {
7557 if(a_isBndryGhostCell(cellId)) {
7560 if(a_hasProperty(cellId, SolverCell::IsSplitClone)) {
7564 for(
MInt dir = 0; dir < m_noDirs; ++dir) {
7565 if(a_hasNeighbor(cellId, dir) > 0) {
7566 const MInt nghbrId = c_neighborId(cellId, dir);
7567 if(c_noChildren(nghbrId) > 0) {
7568 TERMM_IF_COND(a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel),
7569 "Nghbr can't have children & be on curent MG lvl!");
7572 MInt noNghbrChilds = 0;
7573 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
7574 if(c_childId(nghbrId, child) > -1) {
7575 if(childCodePro[dir] & 1 << child) {
7576 TERMM_IF_NOT_COND(a_hasProperty(c_childId(nghbrId, child), SolverCell::IsOnCurrentMGLevel),
7577 "Unkown situation!");
7582 TERMM_IF_COND(!a_isBndryCell(cellId) && noNghbrChilds !=
IPOW2(nDim - 1),
"");
7583 if(noNghbrChilds > 0) {
7585 m_cells.nghbrInterface(cellId, dir, 2);
7587 m_cells.nghbrInterface(cellId, dir, 0);
7590 m_cells.nghbrInterface(cellId, dir, 1);
7592 }
else if(c_parentId(cellId) > -1 && a_hasNeighbor(c_parentId(cellId), dir) > 0
7593 && a_hasProperty(c_neighborId(c_parentId(cellId), dir),
7594 SolverCell::IsOnCurrentMGLevel)) {
7595 const MInt parentId = c_parentId(cellId);
7596 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
7597 if(c_childId(parentId, child) == cellId) {
7598 if((childCodePro[
m_revDir[dir]] & 1 << child) == (uint_fast8_t)0) {
7599 m_cells.nghbrInterface(cellId, dir, 0);
7601 m_cells.nghbrInterface(cellId, dir, 3);
7607 m_cells.nghbrInterface(cellId, dir, 0);
7611 a_hasProperty(cellId, SolverCell::HasCoarseNghbr) =
false;
7612 for(
MInt d = 0; d < nDim; ++d) {
7613 if(m_cells.nghbrInterface(cellId, 2 * d) == 3 || m_cells.nghbrInterface(cellId, 2 * d + 1) == 3) {
7614 a_hasProperty(cellId, SolverCell::HasCoarseNghbr) =
true;
7622template <MInt nDim_,
class SysEqn>
7626 const MInt noFVars = FV->noVariables;
7627 const MInt noCells = a_noCells();
7629 const MInt offset = noInternalCells();
7633#pragma omp parallel for collapse(2)
7635 for(
MInt c = offset; c < noCells; c++) {
7636 for(
MInt varId = 0; varId < noFVars; varId++) {
7637 a_rightHandSide(c, varId) = F0;
7645template <MInt nDim_,
class SysEqn>
7655template <MInt nDim_,
class SysEqn>
7660 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
7661 a_hasProperty(cellId, SolverCell::IsActive) = a_hasProperty(cellId, SolverCell::IsFlux);
7665 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
7666 if(a_hasProperty(cellId, SolverCell::IsActive)) {
7667 for(
MInt c = 0; c < a_noReconstructionNeighbors(cellId); c++) {
7668 a_hasProperty(a_reconstructionNeighborId(cellId, c), SolverCell::IsActive) =
true;
7673 m_noActiveCells = 0;
7674 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
7675 if(a_hasProperty(cellId, SolverCell::IsActive)) {
7676 m_activeCellIds[m_noActiveCells] = cellId;
7680 m_noActiveHaloCellOffset = m_noActiveCells;
7681 for(
MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
7682 if(a_hasProperty(cellId, SolverCell::IsActive)) {
7683 m_activeCellIds[m_noActiveCells] = cellId;
7687 m_log <<
"Time step - Active cells: " <<
globalTimeStep <<
" " << m_noActiveHaloCellOffset <<
" " << m_noActiveCells
7695template <MInt nDim_,
class SysEqn>
7698 const MInt noCells = a_noCells();
7699 const MInt noDirs = 2 * nDim;
7706 for(
MInt cellId = 0; cellId < c_noCells(); cellId++) {
7707 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) =
7708 ((c_isLeafCell(cellId) && a_level(cellId) <= maxRefinementLevel())
7709 || (!c_isLeafCell(cellId) && a_level(cellId) == maxRefinementLevel()))
7710 && !a_hasProperty(cellId, SolverCell::IsInvalid);
7716#pragma omp parallel for simd
7718 for(
MInt c = 0; c < noCells; c++) {
7719 a_isHalo(c) =
false;
7720 a_hasProperty(c, SolverCell::IsNotGradient) =
false;
7724 for(
MInt i = 0; i < noNeighborDomains(); i++) {
7725 for(
MInt c = 0; c < noHaloCells(i); c++) {
7726 a_isHalo(haloCellId(i, c)) =
true;
7730 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
7731 for(
MInt c = 0; c < grid().noAzimuthalHaloCells(i); c++) {
7732 a_isHalo(grid().azimuthalHaloCell(i, c)) =
true;
7735 for(
MInt c = 0; c < grid().noAzimuthalUnmappedHaloCells(); c++) {
7736 a_isHalo(grid().azimuthalUnmappedHaloCell(c)) =
true;
7741 for(
MInt i = 0; i < noNeighborDomains(); i++) {
7742 for(
MInt c = 0; c < noHaloCells(i); c++) {
7743 a_hasProperty(haloCellId(i, c), SolverCell::IsNotGradient) =
true;
7744 if(!a_hasProperty(haloCellId(i, c), SolverCell::IsOnCurrentMGLevel))
continue;
7745 for(
MInt d = 0; d < noDirs; d++) {
7746 if(a_hasNeighbor(haloCellId(i, c), d) > 0) {
7747 if(!a_isHalo(c_neighborId(haloCellId(i, c), d))) {
7748 a_hasProperty(haloCellId(i, c), SolverCell::IsNotGradient) =
false;
7751 MInt parentId = c_parentId(haloCellId(i, c));
7753 if(a_hasNeighbor(parentId, d) > 0) {
7754 if(!a_isHalo(c_neighborId(parentId, d))) {
7755 a_hasProperty(haloCellId(i, c), SolverCell::IsNotGradient) =
false;
7765 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
7766 for(
MInt c = 0; c < grid().noAzimuthalHaloCells(i); c++) {
7767 MInt cellId = grid().azimuthalHaloCell(i, c);
7768 a_hasProperty(cellId, SolverCell::IsNotGradient) =
true;
7769 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
7770 for(
MInt d = 0; d < noDirs; d++) {
7771 if(a_hasNeighbor(cellId, d) > 0) {
7772 if(!a_isHalo(c_neighborId(cellId, d))) {
7773 a_hasProperty(cellId, SolverCell::IsNotGradient) =
false;
7776 MInt parentId = c_parentId(cellId);
7778 if(a_hasNeighbor(parentId, d) > 0) {
7779 if(!a_isHalo(c_neighborId(parentId, d))) {
7780 a_hasProperty(cellId, SolverCell::IsNotGradient) =
false;
7788 for(
MInt c = 0; c < grid().noAzimuthalUnmappedHaloCells(); c++) {
7789 MInt cellId = grid().azimuthalUnmappedHaloCell(c);
7790 a_hasProperty(cellId, SolverCell::IsNotGradient) =
true;
7791 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
7792 for(
MInt d = 0; d < noDirs; d++) {
7793 if(a_hasNeighbor(cellId, d) > 0) {
7794 if(!a_isHalo(c_neighborId(cellId, d))) {
7795 a_hasProperty(cellId, SolverCell::IsNotGradient) =
false;
7798 MInt parentId = c_parentId(cellId);
7800 if(a_hasNeighbor(parentId, d) > 0) {
7801 if(!a_isHalo(c_neighborId(parentId, d))) {
7802 a_hasProperty(cellId, SolverCell::IsNotGradient) =
false;
7811 for(
MInt id = 0;
id < a_noCells(); ++
id) {
7812 if(a_hasProperty(
id, SolverCell::IsSplitChild))
continue;
7813 if(a_isBndryGhostCell(
id))
continue;
7814 if(a_hasProperty(
id, SolverCell::IsSplitClone))
continue;
7815 assertValidGridCellId(
id);
7816 a_isPeriodic(
id) = grid().isPeriodic(
id);
7820 for(
MInt splitId = 0; (unsigned)splitId < m_splitCells.size(); splitId++) {
7821 MInt scId = m_splitCells[splitId];
7822 if(a_isHalo(scId)) {
7823 for(
MInt ssc = 0; (unsigned)ssc < m_splitChilds[splitId].size(); ssc++) {
7824 MInt splitChildId = m_splitChilds[splitId][ssc];
7825 a_isHalo(splitChildId) =
true;
7828 if(a_isPeriodic(scId)) {
7829 for(
MInt ssc = 0; (unsigned)ssc < m_splitChilds[splitId].size(); ssc++) {
7830 MInt splitChildId = m_splitChilds[splitId][ssc];
7831 a_isPeriodic(splitChildId) =
true;
7843template <MInt nDim_,
class SysEqn>
7847 const MInt noCells = a_noCells();
7848 const MInt noDirs = 2 * nDim;
7849 const MFloat epsilon = m_spongeLayerThickness / 10000000.0;
7854 MFloat maxSpongeFactor = 0.0;
7855 MFloat minSpongeFactor = 100.0;
7860 if(!m_createSpongeBoundary) {
7861 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
7862 a_hasProperty(cellId, SolverCell::IsInSpongeLayer) =
false;
7863 a_spongeFactor(cellId) = F0;
7866 m_noCellsInsideSpongeLayer = 0;
7867 if(m_spongeLayerThickness > F0) {
7868 switch(m_spongeLayerLayout) {
7870 for(
MInt cellId = 0; cellId < noCells; cellId++) {
7871 if(a_isBndryGhostCell(cellId)) {
7874 a_hasProperty(cellId, SolverCell::IsInSpongeLayer) =
false;
7875 a_spongeFactor(cellId) = F0;
7876 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
7879 for(
MInt i = 0; i < nDim; i++) {
7881 mMax(F0, (a_coordinate(cellId, i) - m_spongeCoord[2 * i + 1]) * m_spongeCoord[noDirs + 2 * i + 1]);
7882 delta.
p[2 * i + 1] =
7883 mMin(F0, (a_coordinate(cellId, i) - m_spongeCoord[2 * i]) * m_spongeCoord[noDirs + 2 * i]);
7884 delta.
p[2 * i + 1] = fabs(delta.
p[2 * i + 1]);
7885 dis.
p[i] =
mMax(delta.
p[2 * i], delta.
p[2 * i + 1]);
7890 for(
MInt i = 0; i < nDim; i++) {
7891 constant =
mMax(constant,
ABS(dis.
p[i]));
7893 constant = pow(constant, beta);
7894 constant *= m_sigmaSponge;
7896 if(constant > epsilon) {
7897 m_cellsInsideSpongeLayer[m_noCellsInsideSpongeLayer] = cellId;
7898 m_noCellsInsideSpongeLayer++;
7899 a_hasProperty(cellId, SolverCell::IsInSpongeLayer) =
true;
7900 a_spongeFactor(cellId) = constant;
7901 maxSpongeFactor =
mMax(maxSpongeFactor, a_spongeFactor(cellId));
7902 minSpongeFactor =
mMin(minSpongeFactor, a_spongeFactor(cellId));
7908 m_log <<
"*************************************************************" << endl;
7909 m_log <<
"Information for domain sponge: " << endl;
7910 m_log <<
"*************************************************************" << endl;
7912 m_log <<
"number of cells inside sponge layer " << m_noCellsInsideSpongeLayer << endl;
7913 m_log <<
"max sponge factor: " << maxSpongeFactor << endl;
7914 m_log <<
"min sponge factor: " << minSpongeFactor << endl << endl;
7920 IF_CONSTEXPR(nDim == 3) {
7921 for(
MInt cellId = 0; cellId < noCells; cellId++) {
7922 a_hasProperty(cellId, SolverCell::IsInSpongeLayer) =
false;
7923 a_spongeFactor(cellId) = F0;
7924 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
7928 radius = sqrt(
POW2(a_coordinate(cellId, 0)) +
POW2(a_coordinate(cellId, 2)));
7929 delta.
p[0] =
mMax(F0, (radius -
ABS(m_spongeCoord[1])) * m_spongeCoord[noDirs + 1]);
7930 dis.
p[0] = delta.
p[0];
7933 delta.
p[2] =
mMax(F0, (a_coordinate(cellId, 1) - m_spongeCoord[3]) * m_spongeCoord[noDirs + 3]);
7934 delta.
p[3] =
mMin(F0, (a_coordinate(cellId, 1) - m_spongeCoord[2]) * m_spongeCoord[noDirs + 2]);
7935 delta.
p[3] = fabs(delta.
p[3]);
7936 dis.
p[1] =
mMax(delta.
p[2], delta.
p[3]);
7940 for(
MInt i = 0; i < nDim; i++) {
7941 constant =
mMax(constant,
ABS(dis.
p[i]));
7944 constant *= m_sigmaSponge;
7946 if(constant > epsilon) {
7947 m_cellsInsideSpongeLayer[m_noCellsInsideSpongeLayer] = cellId;
7948 m_noCellsInsideSpongeLayer++;
7949 a_hasProperty(cellId, SolverCell::IsInSpongeLayer) =
true;
7950 a_spongeFactor(cellId) = constant;
7956 for(
MInt cellId = 0; cellId < noCells; cellId++) {
7957 a_hasProperty(cellId, SolverCell::IsInSpongeLayer) =
false;
7958 a_spongeFactor(cellId) = F0;
7959 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
7962 radius = sqrt(
POW2(a_coordinate(cellId, 0)) +
POW2(a_coordinate(cellId, 1)));
7964 constant =
mMax(F0, (radius -
ABS(m_spongeCoord[0])) * m_spongeCoord[noDirs]);
7965 constant *= m_sigmaSponge;
7967 if(constant > epsilon) {
7968 m_cellsInsideSpongeLayer[m_noCellsInsideSpongeLayer] = cellId;
7969 m_noCellsInsideSpongeLayer++;
7970 a_hasProperty(cellId, SolverCell::IsInSpongeLayer) =
true;
7971 a_spongeFactor(cellId) = constant;
7980 "FvCartesianSolver::setCellProperties(): switch variable 'm_spongeLayerLayout' not matching any "
7992template <MInt nDim_,
class SysEqn>
7995 const MInt noCells = a_noCells();
7999 nearBnd.
fill(
false);
8003 for(
MInt level = minLevel(); level <= maxLevel(); level++) {
8006 for(
MInt level = minLevel(); level < maxRefinementLevel(); level++) {
8009 for(
MInt cellId = 0; cellId < noCells; cellId++) {
8010 a_hasProperty(cellId, SolverCell::AtStructuredRegion) =
false;
8012 for(
MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
8013 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
8014 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
8015 atBnd(cellId) =
true;
8016 MInt parentId = a_hasProperty(cellId, SolverCell::IsSplitChild) ? c_parentId(getAssociatedInternalCell(cellId))
8017 : c_parentId(cellId);
8018 while(parentId > -1) {
8019 atBnd(parentId) =
true;
8020 parentId = c_parentId(parentId);
8023 for(
MInt cellId = 0; cellId < noCells; cellId++) {
8024 if(a_bndryId(cellId) < -1)
continue;
8025 if(a_hasProperty(cellId, SolverCell::IsCutOff))
continue;
8026 if(a_hasProperty(cellId, SolverCell::IsNotGradient))
continue;
8027 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
8031 nearBnd(cellId) =
true;
8034 MBool nearb =
false;
8035 a_hasProperty(cellId, SolverCell::AtStructuredRegion) =
true;
8036 for(
MInt dir = 0; dir < m_noDirs; dir++) {
8037 if(!a_hasNeighbor(cellId, dir)) {
8038 a_hasProperty(cellId, SolverCell::AtStructuredRegion) =
false;
8039 MInt parentId = c_parentId(cellId);
8040 while(parentId > -1) {
8041 if(a_hasNeighbor(parentId, dir)) {
8042 if(atBnd(c_neighborId(parentId, dir))) {
8047 parentId = c_parentId(parentId);
8049 }
else if(atBnd(c_neighborId(cellId, dir))) {
8050 a_hasProperty(cellId, SolverCell::AtStructuredRegion) =
false;
8057 nearBnd(cellId) =
true;
8060 if(a_hasProperty(cellId, SolverCell::AtStructuredRegion)) {
8063 MInt parentId = c_parentId(cellId);
8065 if(!a_hasProperty(parentId, SolverCell::AtStructuredRegion)) {
8066 a_hasProperty(parentId, SolverCell::AtStructuredRegion) =
true;
8067 for(
MInt dir = 0; dir < m_noDirs; dir++) {
8068 if(!a_hasNeighbor(parentId, dir)) {
8069 a_hasProperty(parentId, SolverCell::AtStructuredRegion) =
false;
8073 if(a_hasProperty(parentId, SolverCell::AtStructuredRegion)) {
8076 mTerm(1,
"strange grid configuration (1).");
8080 cerr << c_globalId(cellId) <<
" " << a_hasProperty(cellId, Cell::IsHalo) << endl;
8081 mTerm(1,
"strange grid configuration (2).");
8090template <MInt nDim_,
class SysEqn>
8094 const MInt noCells = a_noCells();
8095 const MInt noDirs = 2 * nDim;
8096 const MInt noSurfaces = a_noSurfaces();
8100 for(
MInt cellId = 0; cellId < noCells; cellId++) {
8101 a_hasProperty(cellId, SolverCell::IsDummy) =
false;
8102 a_hasProperty(cellId, SolverCell::IsFlux) =
false;
8107 for(
MInt s = 0; s < noSurfaces; s++) {
8108 ASSERT(a_surfaceNghbrCellId(s, 0) > -1 && a_surfaceNghbrCellId(s, 1) > -1, to_string(s));
8109 a_hasProperty(a_surfaceNghbrCellId(s, 0), SolverCell::IsFlux) =
true;
8110 a_hasProperty(a_surfaceNghbrCellId(s, 1), SolverCell::IsFlux) =
true;
8113 for(
MInt addLayer = 0; addLayer < 2; addLayer++) {
8114 for(
MInt cellId = 0; cellId < noCells; cellId++) {
8115 if(a_hasProperty(cellId, SolverCell::IsFlux) && !a_isBndryGhostCell(cellId)) {
8116 for(
MInt dir = 0; dir < noDirs; dir++) {
8117 MInt gridcellId = cellId;
8118 if(a_hasProperty(cellId, SolverCell::IsSplitClone)) {
8119 gridcellId = m_splitChildToSplitCell.find(cellId)->second;
8121 if(a_hasNeighbor(gridcellId, dir) > 0) {
8122 a_hasProperty(c_neighborId(gridcellId, dir), SolverCell::IsDummy) =
true;
8128 for(
MInt cellId = 0; cellId < noCells; cellId++) {
8129 if(a_hasProperty(cellId, SolverCell::IsDummy)) {
8130 a_hasProperty(cellId, SolverCell::IsFlux) =
true;
8143template <MInt nDim_,
class SysEqn>
8146 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8147 const MBool isGhost = a_isBndryGhostCell(cellId);
8148 const MInt boundaryId = a_bndryId(cellId);
8149 if((isGhost && boundaryId != -2) || (!isGhost && boundaryId == -2)) {
8150 cout <<
"ERROR: globalId: " << c_globalId(cellId) <<
" " << isGhost <<
" " << boundaryId << endl;
8151 mTerm(1, AT_,
"ERROR in checkGhostCellIntegrity");
8158template <MInt nDim_,
class SysEqn>
8161 ASSERT(exId > -1 && exId < m_extractedCells->size() && node > -1 && node <
IPOW2(nDim),
"");
8162 MInt gridPointId = m_extractedCells->a[exId].m_pointIds[node];
8163 ASSERT(gridPointId > -1 && gridPointId < m_gridPoints->size(),
"");
8164 for(
MInt i = 0; i < nDim; i++) {
8165 x[i] = m_gridPoints->a[gridPointId].m_coordinates[i];
8167 return m_geometry->pointIsInside2(x);
8180template <MInt nDim_,
class SysEqn>
8186 ParallelIo parallelIo(outputDir() + grid().gridInputFileName(), PIO_APPEND, mpiComm());
8190 if(parallelIo.hasDataset(
"cutCellIds", 1)) {
8196 MInt noBndryCells = 0;
8197 for(
MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
8198 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
8199 if(!a_isHalo(cellId)) {
8206 MInt localNoCutPoints = 0;
8208 for(
MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
8209 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
8210 if(a_isHalo(cellId))
continue;
8211 noCutPoints[bcnt] = m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints;
8212 localNoCutPoints += noCutPoints[bcnt];
8221 for(
MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
8222 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
8223 if(a_isHalo(cellId))
continue;
8225 MInt edgeChecked[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
8226 for(
MInt cutId = 0; cutId < m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints; cutId++) {
8228 edge = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[cutId];
8231 if(edgeChecked[edge]) {
8235 cutEdges[ccId] = edge;
8236 edgeChecked[edge] = 1;
8238 for(
MInt dim = 0; dim < nDim; dim++) {
8239 cutCoordinates(ccId, dim) = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutId][dim];
8249 const MFloat signStencil[8][3] = {{-F1, -F1, -F1}, {F1, -F1, -F1}, {-F1, F1, -F1}, {F1, F1, -F1},
8250 {-F1, -F1, F1}, {F1, -F1, F1}, {-F1, F1, F1}, {F1, F1, F1}};
8252 vector<MFloat> cellLengths(maxRefinementLevel() + 1);
8253 for(vector<MFloat>::size_type i = 0; i < cellLengths.size(); i++) {
8254 cellLengths[i] = c_cellLengthAtLevel(i);
8259 for(
MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
8260 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
8261 if(a_isHalo(cellId))
continue;
8262 for(
MInt pointId = 0; pointId <
IPOW2(nDim); pointId++) {
8265 MFloat pointCoordinates[MAX_SPACE_DIMENSIONS];
8266 for(
MInt dir = 0; dir < nDim; dir++) {
8267 const MFloat cellCenterCoord = a_coordinate(cellId, dir);
8268 const MFloat cellLength = cellLengths[a_level(cellId)];
8269 pointCoordinates[dir] = cellCenterCoord + signStencil[pointId][dir] * F1B2 * cellLength;
8271 pointInside(bcnt, pointId) = m_geometry->pointIsInside2(pointCoordinates);
8277 ParallelIo::size_type cellOffset, bndryCellOffset, cutPointOffset;
8278 ParallelIo::size_type globalNoCells, globalNoBndryCells, globalNoCutPoints;
8279 parallelIo.calcOffset(noInternalCells(), &cellOffset, &globalNoCells, mpiComm());
8280 parallelIo.calcOffset(noBndryCells, &bndryCellOffset, &globalNoBndryCells, mpiComm());
8281 parallelIo.calcOffset(localNoCutPoints, &cutPointOffset, &globalNoCutPoints, mpiComm());
8284 parallelIo.defineArray(PIO_INT,
"cutCellIds", globalNoCells);
8285 parallelIo.defineArray(PIO_INT,
"noCutPoints", globalNoBndryCells);
8286 parallelIo.defineArray(PIO_INT,
"cutEdges", globalNoCutPoints);
8287 parallelIo.defineArray(PIO_FLOAT,
"cutCoordinates", globalNoCutPoints * nDim);
8288 parallelIo.defineArray(PIO_INT,
"pointIsInside", globalNoBndryCells *
IPOW2(nDim));
8292 parallelIo.setOffset(noInternalCells(), cellOffset);
8293 parallelIo.writeArray(&a_bndryId(0),
"cutCellIds");
8295 parallelIo.setOffset(noBndryCells, bndryCellOffset);
8296 parallelIo.writeArray(noCutPoints.
getPointer(),
"noCutPoints");
8298 parallelIo.setOffset(localNoCutPoints, cutPointOffset);
8299 parallelIo.writeArray(cutEdges.
getPointer(),
"cutEdges");
8301 parallelIo.setOffset(localNoCutPoints * nDim, cutPointOffset * nDim);
8302 parallelIo.writeArray(cutCoordinates.
getPointer(),
"cutCoordinates");
8304 parallelIo.setOffset(noBndryCells *
IPOW2(nDim), bndryCellOffset *
IPOW2(nDim));
8305 parallelIo.writeArray(pointInside.
getPointer(),
"pointIsInside");
8309template <MInt nDim_,
class SysEqn>
8313 MInt offset = a_noCells();
8314 for(
MInt c = 0; c < noInternalCells(); c++) {
8315 vorticity[c] = F1B2 * (a_slope(c, PV->W, 1) - a_slope(c, PV->V, 2));
8316 vorticity[offset + c] = F1B2 * (a_slope(c, PV->U, 2) - a_slope(c, PV->W, 0));
8317 vorticity[offset * 2 + c] = F1B2 * (a_slope(c, PV->V, 0) - a_slope(c, PV->U, 1));
8321template <MInt nDim_,
class SysEqn>
8325 for(
MInt c = 0; c < noInternalCells(); c++) {
8326 vorticity[c] = F1B2 * (a_slope(c, PV->V, 0) - a_slope(c, PV->U, 1));
8340template <MInt nDim_,
class SysEqn>
8344 for(
MInt c = 0; c < noInternalCells(); c++) {
8345 vorticity[3 * c + 0] = F1B2 * (a_slope(c, PV->W, 1) - a_slope(c, PV->V, 2));
8346 vorticity[3 * c + 1] = F1B2 * (a_slope(c, PV->U, 2) - a_slope(c, PV->W, 0));
8347 vorticity[3 * c + 2] = F1B2 * (a_slope(c, PV->V, 0) - a_slope(c, PV->U, 1));
8352template <MInt nDim_,
class SysEqn>
8357 MInt offsetS = nDim * nDim;
8358 MInt tmpSize = offsetS + offsetS;
8362 for(
MInt c = 0; c < noInternalCells(); c++) {
8364 for(
MInt i = 0; i < nDim; i++) {
8365 for(
MInt j = 0; j < nDim; j++) {
8366 grad.
p[i * nDim + j] = a_slope(c, PV->VV[i], j);
8370 for(
MInt i = 0; i < nDim; i++) {
8371 for(
MInt j = 0; j < nDim; j++) {
8372 q.
p[j + i * nDim] = F1B2 * (grad.
p[i * nDim + j] + grad.
p[j * nDim + i]);
8373 q.
p[j + i * nDim + offsetS] = F1B2 * (grad.
p[i * nDim + j] - grad.
p[j * nDim + i]);
8379 for(
MInt i = 0; i < nDim; i++) {
8380 for(
MInt j = 0; j < nDim; j++) {
8381 normS +=
POW2(q.
p[i * nDim + j]);
8382 normO +=
POW2(q.
p[i * nDim + offsetS + j]);
8385 qCriterion.
p[c] = F1B2 * (normO - normS);
8402template <MInt nDim_,
class SysEqn>
8405 vector<MString>& dbVariablesName,
MInt noDbVars,
MIntScratchSpace& idVariables, vector<MString>& idVariablesName,
8407 vector<MString>& idParametersName,
const MInt* recalcIds) {
8410 IF_CONSTEXPR(nDim != 2 && nDim != 3) {
8411 stringstream errorMessage;
8412 errorMessage <<
" In global function saveGridFlowVarsPar: wrong number of dimensions !" << endl;
8413 mTerm(1, AT_, errorMessage.str());
8419 noDbVars = dbVariablesName.size();
8420 noIdVars = idVariablesName.size();
8421 MInt noIdPars = idParametersName.size();
8422 MInt noDbPars = dbParametersName.size();
8423 vector<MString> ncVariablesName;
8425 MInt* tmpIdVariables;
8427 using namespace parallel_io;
8428 ParallelIo parallelIo(fileName, PIO_REPLACE, mpiComm());
8432 auto longNoInternalCells = (
MLong)noInternalCellIds;
8433 MPI_Allreduce(&longNoInternalCells, &num, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"longNoInternalCells",
"num");
8434 parallelIo.setAttribute(num,
"noCells");
8436 parallelIo.setAttribute(solverId(),
"solverId");
8439 for(
MInt j = 0; j < noDbVars; j++) {
8440 tmpNcVariablesName =
"variables" + to_string(j);
8441 ncVariablesName.push_back(tmpNcVariablesName);
8443 parallelIo.defineArray(PIO_FLOAT, ncVariablesName[j], num);
8444 m_log << dbVariablesName[j].c_str() << endl;
8445 parallelIo.setAttribute(dbVariablesName[j],
"name", ncVariablesName[j]);
8448 for(
MInt j = 0; j < noIdVars; j++) {
8449 MInt k = j + noDbVars;
8450 tmpNcVariablesName =
"variables" + to_string(k);
8451 ncVariablesName.push_back(tmpNcVariablesName);
8453 parallelIo.defineArray(PIO_INT, ncVariablesName[k], num);
8454 parallelIo.setAttribute(idVariablesName[j],
"name", ncVariablesName[k]);
8457 MString XString =
"variables" + to_string(noDbVars + noIdVars + (
MInt)isDetChem<SysEqn> + 1);
8458 MString YString =
"variables" + to_string(noDbVars + noIdVars + (
MInt)isDetChem<SysEqn> + 2);
8460 IF_CONSTEXPR(isDetChem<SysEqn>) {
8461 parallelIo.defineArray(PIO_FLOAT, XString, num);
8462 parallelIo.defineArray(PIO_FLOAT, YString, num);
8463 parallelIo.setAttribute(
"XCoord",
"name", XString);
8464 parallelIo.setAttribute(
"YCoord",
"name", YString);
8467 for(
MInt j = 0; j < noIdPars; j++) {
8469 parallelIo.setAttribute(idParameters.
p[j], idParametersName[j]);
8472 for(
MInt j = 0; j < noDbPars; j++) {
8474 parallelIo.setAttribute(dbParameters.
p[j], dbParametersName[j]);
8476 parallelIo.setAttribute(m_currentGridFileName,
"gridFile");
8478 if(m_initialCondition == 16) {
8479 parallelIo.setAttributes(&m_Re,
"Re", 1);
8480 parallelIo.setAttributes(&sysEqn().m_Re0,
"Re0", 1);
8481 parallelIo.setAttributes(&m_randomDeviceSeed,
"randomDeviceSeed", 1);
8484 ParallelIo::size_type start = 0;
8485 ParallelIo::size_type count = 1;
8488 MPI_Exscan(&noInternalCellIds, &start, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"noInternalCells",
"start");
8489 count = noInternalCellIds;
8490 parallelIo.setOffset(count, start);
8492 for(
MInt j = 0; j < noDbVars; j++) {
8493 tmpDbVariables = &(dbVariables.
p[j * noTotalCells]);
8495 if(m_recalcIds !=
nullptr) {
8497 for(
MInt l = 0; l < count; ++l) {
8498 tmpDouble[l] = tmpDbVariables[recalcIds[l]];
8500 parallelIo.writeArray(tmpDouble.
begin(), ncVariablesName[j]);
8502 parallelIo.writeArray(tmpDbVariables, ncVariablesName[j]);
8506 IF_CONSTEXPR(isDetChem<SysEqn>) {
8509 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8510 tmpX[cellId] = a_coordinate(cellId, 0);
8512 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8513 tmpY[cellId] = a_coordinate(cellId, 1);
8515 parallelIo.writeArray(&tmpX[0], XString);
8516 parallelIo.writeArray(&tmpY[0], YString);
8519 for(
MInt j = 0; j < noIdVars; j++) {
8520 tmpIdVariables = &(idVariables.
p[j * noTotalCells]);
8521 if(m_recalcIds !=
nullptr) {
8523 for(
MInt l = 0; l < count; ++l) {
8524 tmpInt[l] = tmpIdVariables[recalcIds[l]];
8526 parallelIo.writeArray(tmpInt.
begin(), ncVariablesName[j + noDbVars]);
8528 parallelIo.writeArray(tmpIdVariables, ncVariablesName[j + noDbVars]);
8537template <MInt nDim_,
class SysEqn>
8542 if(!m_useNonSpecifiedRestartFile) {
8543 mTerm(1,
"determineRestartTimeStep should only be used with useNonSpecifiedRestartFile enabled!");
8546 std::stringstream varFileName;
8547 if(!m_multipleFvSolver) {
8548 varFileName << restartDir() <<
"restartVariables" << ParallelIo::fileExt();
8550 varFileName << restartDir() <<
"restartVariables" << m_solverId <<
"_" << ParallelIo::fileExt();
8552 ParallelIo parallelIo(varFileName.str(), PIO_READ, MPI_COMM_SELF);
8554 parallelIo.getAttribute(&timeStep,
"globalTimeStep");
8564template <MInt nDim_,
class SysEqn>
8579 parallelIo.getAttribute(&globalTimeStepInput, CN.
globalTimeStep);
8581 parallelIo.getAttribute(&timeInput, CN.
time);
8583 parallelIo.getAttribute(&physicalTimeInput, CN.
physicalTime);
8587template <MInt nDim_,
class SysEqn>
8591 cerr <<
"**********************************************************" << endl;
8592 cerr <<
"Writing cell data for cell " << c <<
" at time step " <<
globalTimeStep <<
", " << m_RKStep <<
"> at level "
8593 << a_level(c) << endl;
8594 cerr <<
"Primitive cell variables: " << endl;
8595 for(
MInt v = 0; v < PV->noVariables; v++) {
8596 cerr << a_pvariable(c, v) <<
" ";
8599 cerr <<
"Conservative cell variables: " << endl;
8600 for(
MInt v = 0; v < CV->noVariables; v++) {
8601 cerr << a_variable(c, v) <<
" ";
8603 cerr <<
"Cell slopes: " << endl;
8604 for(
MInt v = 0; v < PV->noVariables; v++) {
8605 for(
MInt i = 0; i < 3; i++) {
8606 cerr << a_slope(c, v, i) <<
" ";
8610 cerr <<
"**********************************************************" << endl;
8614template <MInt nDim_,
class SysEqn>
8618 std::fill(m_timers.begin(), m_timers.end(), -1);
8621 NEW_TIMER_GROUP_NOCREATE(m_timerGroup,
"FvCartesianSolver (solverId = " + to_string(m_solverId) +
")");
8622 NEW_TIMER_NOCREATE(m_timers[Timers::SolverType],
"total object lifetime", m_timerGroup);
8623 RECORD_TIMER_START(m_timers[Timers::SolverType]);
8625 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::TimeInt],
"Time-integration", m_timers[Timers::SolverType]);
8627 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Rhs],
"rhs", m_timers[Timers::TimeInt]);
8629 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Muscl],
"MUSCL", m_timers[Timers::Rhs]);
8630 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Ausm],
"AUSM", m_timers[Timers::Rhs]);
8631 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ViscFlux],
"Viscous flux", m_timers[Timers::Rhs]);
8632 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::DistFlux],
"Distribute flux", m_timers[Timers::Rhs]);
8633 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::RhsMisc],
"Misc", m_timers[Timers::Rhs]);
8634 if(m_useSandpaperTrip) {
8635 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SandpaperTrip],
"SandpaperTrip", m_timers[Timers::Rhs]);
8638 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::WMExchange],
"WMExchange", m_timers[Timers::Rhs]);
8639 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::WMSurfaceLoop],
"WMSurfaceLoop", m_timers[Timers::Rhs]);
8640 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::WMFluxCorrection],
"WMFluxCorrection", m_timers[Timers::Rhs]);
8642 IF_CONSTEXPR(isDetChem<SysEqn>) {
8643 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SurfaceCoefficients],
"Surface Coefficients", m_timers[Timers::Rhs]);
8644 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SurfaceMeanMolarWeight],
"Surface Mean Molar Weight",
8645 m_timers[Timers::SurfaceCoefficients]);
8646 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SurfaceTransportCoefficients],
"Surface Transport Coefficients",
8647 m_timers[Timers::SurfaceCoefficients]);
8648 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::CellCenterCoefficients],
"Cell Center Coefficients", m_timers[Timers::Rhs]);
8649 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SpeciesReactionRates],
"Species Reaction Rates", m_timers[Timers::Rhs]);
8652 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MusclReconst],
"LSReconstructCellCenter", m_timers[Timers::Muscl]);
8653 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MusclCopy],
"copySlopesToSmallCells", m_timers[Timers::Muscl]);
8654 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MusclGhostSlopes],
"updateGhostCellSlopesInviscid", m_timers[Timers::Muscl]);
8655 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MusclCutSlopes],
"updateCutOffSlopesInviscid", m_timers[Timers::Muscl]);
8656 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::MusclReconstSrfc],
"reconstructSurfaceData", m_timers[Timers::Muscl]);
8658 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ReconstSrfcCompValues],
"computeSurfaceValues",
8659 m_timers[Timers::MusclReconstSrfc]);
8660 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ReconstSrfcCorrVars],
"correctSurfaceVariables",
8661 m_timers[Timers::MusclReconstSrfc]);
8662 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ReconstSrfcUpdateGhost],
"updateGhost", m_timers[Timers::MusclReconstSrfc]);
8663 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ReconstSrfcUpdateCutOff],
"updateCutOff", m_timers[Timers::MusclReconstSrfc]);
8665 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::RhsBnd],
"rhsBnd", m_timers[Timers::TimeInt]);
8667 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Lhs],
"lhs", m_timers[Timers::TimeInt]);
8669 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::LhsBnd],
"lhsBnd", m_timers[Timers::TimeInt]);
8672 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SmallCellCorr],
"small cell correction", m_timers[Timers::LhsBnd]);
8673 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ComputePV],
"compute PV", m_timers[Timers::LhsBnd]);
8674 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Exchange],
"exchange", m_timers[Timers::LhsBnd]);
8675 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::CutOff],
"cut off", m_timers[Timers::LhsBnd]);
8676 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::BndryCnd],
"boundary conditions", m_timers[Timers::LhsBnd]);
8679 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SCCorrInit],
"init", m_timers[Timers::SmallCellCorr]);
8680 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SCCorrExchange1],
"first exchange", m_timers[Timers::SmallCellCorr]);
8681 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SCCorrExchange1Wait],
"waiting/blocking MPI",
8682 m_timers[Timers::SCCorrExchange1]);
8683 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SCCorrInterp],
"interpolation", m_timers[Timers::SmallCellCorr]);
8684 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SCCorrRedist],
"redistribution", m_timers[Timers::SmallCellCorr]);
8685 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SCCorrExchange2],
"second exchange", m_timers[Timers::SmallCellCorr]);
8686 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SCCorrExchange2Wait],
"waiting/blocking MPI",
8687 m_timers[Timers::SCCorrExchange2]);
8689 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Residual],
"Residual", m_timers[Timers::TimeInt]);
8690 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ResidualMpi],
"MPI", m_timers[Timers::Residual]);
8695 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::PreTime],
"PreTimeStep", m_timers[Timers::SolverType]);
8696 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ReinitSolu],
"ReinitSolutionStep", m_timers[Timers::PreTime]);
8697 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::BndryMb],
"generateBndryCells", m_timers[Timers::ReinitSolu]);
8698 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::NearBndry],
"initNearBndryExc", m_timers[Timers::ReinitSolu]);
8699 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::InitSmallCorr],
"initSmallCellCor", m_timers[Timers::ReinitSolu]);
8700 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::GhostCells],
"ghostCells", m_timers[Timers::ReinitSolu]);
8701 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::PostTime],
"PostTimeStep", m_timers[Timers::SolverType]);
8702 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::PostSolu],
"PostSolutionStep", m_timers[Timers::PostTime]);
8703 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ResidualMb],
"Residual-MB", m_timers[Timers::PostSolu]);
8704 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SurfaceForces],
"SurfaceForces", m_timers[Timers::PostSolu]);
8705 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::LevelSetCorr],
"LevelSetCorr", m_timers[Timers::PostSolu]);
8718 NEW_TIMER_GROUP_NOCREATE(m_tgfv,
"FV Exchange");
8719 NEW_TIMER_NOCREATE(m_tcomm,
"Communication", m_tgfv);
8721 NEW_SUB_TIMER_NOCREATE(m_texchange,
"exchange", m_tcomm);
8723 NEW_SUB_TIMER_NOCREATE(m_tgatherAndSend,
"gather and send", m_texchange);
8724 NEW_SUB_TIMER_NOCREATE(m_tgather,
"gather", m_tgatherAndSend);
8725 NEW_SUB_TIMER_NOCREATE(m_tsend,
"send", m_tgatherAndSend);
8726 NEW_SUB_TIMER_NOCREATE(m_tgatherAndSendWait,
"wait", m_tgatherAndSend);
8727 NEW_SUB_TIMER_NOCREATE(m_treceive,
"receive", m_texchange);
8728 NEW_SUB_TIMER_NOCREATE(m_tscatter,
"scatter", m_texchange);
8729 NEW_SUB_TIMER_NOCREATE(m_tscatterWaitSome,
"wait some", m_tscatter);
8730 NEW_SUB_TIMER_NOCREATE(m_treceiving,
"receiving", m_treceive);
8731 NEW_SUB_TIMER_NOCREATE(m_treceiveWait,
"waiting", m_treceive);
8733 NEW_SUB_TIMER_NOCREATE(m_texchangeDt,
"exchange time-step", m_tcomm);
8738template <MInt nDim_,
class SysEqn>
8742 setRungeKuttaProperties();
8757template <MInt nDim_,
class SysEqn>
8759 m_loadSampleVariables =
true;
8760 m_restartTimeStep = timeStep;
8762 m_loadSampleVariables =
false;
8776template <MInt nDim_,
class SysEqn>
8778 vars = &a_pvariable(cellId, 0);
8781template <MInt nDim_,
class SysEqn>
8783 const MInt noVars = vars.size();
8784 ASSERT(noVars <= noVariables(),
"noVars > noVariables()");
8785 for(
MInt varId = 0; varId < noVars; varId++) {
8786 vars[varId] = a_pvariable(cellId, varId);
8791template <MInt nDim_,
class SysEqn>
8794 for(
MInt i = 0; i < PV->noVariables; i++) {
8795 varNames.push_back(PV->varNames[i]);
8806template <MInt nDim_,
class SysEqn>
8808 vars = &a_slope(cellId, 0, 0);
8811template <MInt nDim_,
class SysEqn>
8813 std::memcpy(&vars[0], &a_slope(cellId, 0, 0),
sizeof(
MFloat) * (nDim * PV->noVariables));
8825template <MInt nDim_,
class SysEqn>
8827 IF_CONSTEXPR(isDetChem<SysEqn>) {
8828 for(
MInt cellId = 0; cellId < a_noCells(); ++cellId) {
8829 const MFloat dampeningFactor = m_heatReleaseDamp ? m_dampFactor[cellId] : F1;
8830 m_heatRelease[cellId] = F0;
8831 for(
MInt s = 0; s < m_noSpecies; ++s) {
8832 m_heatRelease[cellId] -= dampeningFactor * a_speciesReactionRate(cellId, s) * m_standardHeatFormation[s];
8837 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8838 m_heatRelease[cellId] = a_reactionRate(cellId, 0) * a_cellVolume(cellId) * (m_burntUnburntTemperatureRatio - F1)
8839 * (F1 / (m_gamma - F1));
8852template <MInt nDim_,
class SysEqn>
8854 heatRelease = m_heatRelease;
8866template <MInt nDim_,
class SysEqn>
8868 MInt bndryId = a_bndryId(cellId);
8870 if(m_bndryCells->a[bndryId].m_noSrfcs > 1) {
8871 mTerm(1, AT_,
"lineOutput not implemented for split cells or such");
8874 MFloat drhodn = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_normalDeriv[PV->RHO];
8875 MFloat rhoW = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_primVars[PV->RHO];
8876 MFloat pW = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_primVars[PV->P];
8877 return (-m_gamma * pW * drhodn / pow(rhoW, F2));
8879 return std::numeric_limits<MFloat>::max();
8890template <MInt nDim_,
class SysEqn>
8906template <MInt nDim_,
class SysEqn>
8910 IF_CONSTEXPR(nDim == 3) { computeVorticity3D(vorticity); }
8911 else IF_CONSTEXPR(nDim == 2) {
8912 computeVorticity2D(vorticity);
8919template <MInt nDim_,
class SysEqn>
8923 IF_CONSTEXPR(!hasE<SysEqn>)
8924 mTerm(1, AT_,
"Not compatible with SysEqn without RHO_E!");
8927 for(
MInt c = 0; c < noInternalCells(); c++) {
8928 const MFloat rho = a_oldVariable(c, CV->RHO);
8929 const MFloat rhoE = a_oldVariable(c, CV->RHO_E);
8930 IF_CONSTEXPR(nDim == 2) {
8932 sysEqn().pressure(rho,
POW2(a_oldVariable(c, CV->RHO_VV[0])) +
POW2(a_oldVariable(c, CV->RHO_VV[1])), rhoE);
8934 IF_CONSTEXPR(nDim == 3) {
8935 p[c] = sysEqn().pressure(rho,
8936 POW2(a_oldVariable(c, CV->RHO_VV[0])) +
POW2(a_oldVariable(c, CV->RHO_VV[1]))
8937 +
POW2(a_oldVariable(c, CV->RHO_VV[2])),
8955template <MInt nDim_,
class SysEqn>
8959 IF_CONSTEXPR(nDim == 3) { computeVorticity3DT(vorticity); }
8960 else IF_CONSTEXPR(nDim == 2) {
8961 computeVorticity2D(vorticity);
8966template <MInt nDim_,
class SysEqn>
8968 ASSERT(m_vorticity !=
nullptr,
"Vorticity not initialized");
8969 return m_vorticity[cellId][dir];
8980template <MInt nDim_,
class SysEqn>
8985 dimParams.push_back(make_pair(m_Re,
"Re"));
8986 dimParams.push_back(make_pair(m_Ma,
"Ma"));
8987 dimParams.push_back(make_pair(sysEqn().gamma_Ref(),
"gamma"));
8988 dimParams.push_back(make_pair(m_gasConstant,
"R"));
8989 dimParams.push_back(make_pair(m_referenceTemperature,
"T_ref"));
9017template <MInt nDim_,
class SysEqn>
9021 const MInt weightMode,
const MInt fallBackMode,
9022 const std::array<MBool, nDim> dirs,
9023 const MBool relocateCenter) {
9024 const MBool allDirs = std::all_of(dirs.begin(), dirs.end(), [](
const MBool _) { return _ == false; });
9025 const MInt noDirs = std::accumulate(dirs.begin(), dirs.end(), 0);
9026 MInt currentSlopeDir = -1;
9028 for(
MInt d = 0; d < nDim; ++d) {
9030 currentSlopeDir = d;
9035 ASSERT(a_hasProperty(cellId, SolverCell::IsSplitChild) || a_hasProperty(cellId, SolverCell::IsSplitClone)
9036 || c_isLeafCell(cellId),
9038 ASSERT(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel),
"");
9039 ASSERT(a_hasProperty(cellId, SolverCell::IsFlux),
"");
9040 ASSERT(!a_hasProperty(cellId, SolverCell::IsNotGradient),
"");
9041 ASSERT(!a_isBndryGhostCell(cellId),
"");
9042 const MInt noNghbrIds = a_noReconstructionNeighbors(cellId);
9043 if(noNghbrIds == 0) {
9046 ASSERT(tmpA.
size0() >= noNghbrIds && tmpA.
size1() >= recDim,
"");
9047 ASSERT(tmpC.
size0() >= recDim && tmpC.
size1() >= noNghbrIds,
"");
9048 ASSERT(weights.
size0() >= noNghbrIds,
"");
9049 ASSERT(noNghbrIds <= m_cells.noRecNghbrs(),
"");
9051 const MInt rootCell = (a_hasProperty(cellId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(cellId) : cellId;
9052 const MFloat cellLength = c_cellLengthAtCell(cellId);
9054 ASSERT(rootCell > -1 && rootCell < a_noCells(),
"");
9057 if((weightMode == 3 || weightMode == 4) && allDirs) {
9058 std::array<MBool, nDim> dirsJmp = {};
9059 for(
MInt d = 0; d < nDim; ++d) {
9060 const MBool coarseNghbr =
9061 m_cells.nghbrInterface(cellId, 2 * d) == 3 || m_cells.nghbrInterface(cellId, 2 * d + 1) == 3;
9062 const MBool fineNghbr =
9063 m_cells.nghbrInterface(cellId, 2 * d) == 2 || m_cells.nghbrInterface(cellId, 2 * d + 1) == 2;
9064 if(coarseNghbr || fineNghbr) {
9072 MBool hasBndryInStencil =
false;
9073 for(
MInt n = 0; n < noNghbrIds; n++) {
9074 if(a_isBndryCell(a_reconstructionNeighborId(cellId, n))) {
9075 hasBndryInStencil =
true;
9081 if(a_isBndryCell(cellId) || a_isBndryGhostCell(cellId) || hasBndryInStencil) {
9082 std::fill_n(&dirsJmp[0], nDim,
false);
9086 if(weightMode == 4 && m_relocateCenter) {
9087 if(hasBndryInStencil && !a_isBndryCell(cellId)) {
9088 std::array<MBool, nDim> dir;
9089 std::fill_n(&dir[0], nDim,
true);
9090 computeRecConstSVD(cellId, offset, tmpA, tmpC, weights, recDim, weightMode, fallBackMode, dir);
9094 MFloat condNumMax = std::numeric_limits<MFloat>::lowest();
9095 std::array<MBool, nDim> dir = dirsJmp;
9096 for(
auto& d : dir) {
9099 if(std::any_of(dir.begin(), dir.end(), [](
MBool _) { return _ == true; })) {
9100 auto condNum = computeRecConstSVD(cellId, offset, tmpA, tmpC, weights, recDim, weightMode, fallBackMode, dir,
9101 !a_isBndryCell(cellId) && m_relocateCenter);
9102 condNumMax =
mMax(condNum, condNumMax);
9105 if(weightMode == 3) {
9106 if(std::any_of(dirsJmp.begin(), dirsJmp.end(), [](
MBool _) { return _ == true; })) {
9108 computeRecConstSVD(cellId, offset, tmpA, tmpC, weights, recDim, weightMode, fallBackMode, dirsJmp);
9109 condNumMax =
mMax(condNum, condNumMax);
9112 if(weightMode == 4) {
9113 for(
MInt d = 0; d < nDim; ++d) {
9115 std::array<MBool, nDim> dirsJmp_ = {};
9117 auto condNum = computeRecConstSVD(cellId, offset, tmpA, tmpC, weights, recDim, weightMode, fallBackMode,
9118 dirsJmp_, !a_isBndryCell(cellId) && m_relocateCenter);
9119 condNumMax =
mMax(condNum, condNumMax);
9128 constexpr MFloat EPS = 1e-10;
9131 auto isDirectNghbr = [=](
const MInt nghbrId) {
9132 if(a_isBndryCell(cellId) && a_isBndryGhostCell(nghbrId)) {
9135 for(
MInt d = 0; d < nDim; ++d) {
9139 for(
MInt side = 0; side < 2; ++side) {
9140 const MInt orientation = 2 * d + side;
9141 if(a_level(nghbrId) == a_level(cellId)) {
9142 if(checkNeighborActive(cellId, orientation) && a_hasNeighbor(cellId, orientation)
9143 && c_neighborId(cellId, orientation) == nghbrId) {
9146 }
else if(a_level(nghbrId) < a_level(cellId)) {
9147 if(c_neighborId(c_parentId(cellId), orientation) == nghbrId) {
9150 }
else if(a_level(nghbrId) > a_level(cellId)) {
9151 if(checkNeighborActive(cellId, orientation) && a_hasNeighbor(cellId, orientation)) {
9152 const MInt nghbrParentId = c_neighborId(cellId, orientation);
9153 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
9154 if(c_childId(nghbrParentId, child) == nghbrId) {
9155 if(childCodePro[orientation] & 1 << child) {
9171 set<MInt> nextNghbrs;
9173 if(weightMode == 1) {
9174 for(
MInt dir = 0; dir < m_noDirs; dir++) {
9175 if(checkNeighborActive(rootCell, dir) && a_hasNeighbor(rootCell, dir) > 0) {
9176 const MInt nghbrId = c_neighborId(rootCell, dir);
9177 if(a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel)) {
9178 nextNghbrs.insert(nghbrId);
9185 array<MInt, 2 * nDim> noFineNghbrs{};
9186 MBool hasBndryInStencil =
false;
9187 for(
MInt n = 0; n < noNghbrIds; n++) {
9188 const MInt nghbrId = a_reconstructionNeighborId(cellId, n);
9189 const MInt nghbrRootId =
9190 (a_hasProperty(nghbrId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(nghbrId) : nghbrId;
9192 hasBndryInStencil = hasBndryInStencil || a_isBndryCell(nghbrId);
9196 for(
MInt i = 0; i < nDim; i++) {
9197 dxdx +=
POW2(a_coordinate(nghbrId, i) - a_coordinate(cellId, i));
9204 if(weightMode == 2 && !a_isBndryGhostCell(nghbrId) && a_isBndryCell(nghbrId)) {
9205 const MFloat vf = a_cellVolume(nghbrId) / c_cellVolumeAtLevel(a_level(nghbrId));
9210 fac = fac * 0.5 + 0.5;
9219 if(weightMode == 1 && !a_isBndryGhostCell(nghbrId)) {
9220 fac = (nextNghbrs.count(nghbrRootId) == 0) ? F0 : fac;
9226 if(weightMode == 3 || weightMode == 4) {
9228 const MInt orientation = isDirectNghbr(nghbrId);
9229 if(((!a_isBndryCell(cellId) && !a_isBndryGhostCell(nghbrId)) || m_reExcludeBndryDiagonals) && orientation == -2) {
9231 }
else if(m_2ndOrderWeights && (!a_isBndryCell(cellId) || m_reExcludeBndryDiagonals)
9232 && a_level(nghbrId) > a_level(cellId)) {
9233 TERMM_IF_NOT_COND(orientation >= 0 && orientation < 2 * nDim,
"");
9234 ++noFineNghbrs[orientation];
9245 if((weightMode == 3 || weightMode == 4) && m_2ndOrderWeights
9246 && (!a_isBndryCell(cellId) || m_reExcludeBndryDiagonals)) {
9247 for(
MInt n = 0; n < noNghbrIds; n++) {
9248 const MInt nghbrId = a_reconstructionNeighborId(cellId, n);
9249 if(
approx(weights[n], 0.0, EPS)) {
9254 if(relocateCenter) {
9255 const MInt d = (
MInt)isDirectNghbr(nghbrId) / 2;
9256 TERMM_IF_NOT_COND(d >= 0 && d < nDim,
"Try setting reExcludeBndryDiagonals==true and retry!");
9257 dxdx =
POW2(a_coordinate(nghbrId, d) - a_coordinate(cellId, d));
9259 for(
MInt i = 0; i < nDim; i++) {
9261 dxdx +=
POW2(a_coordinate(nghbrId, i) - a_coordinate(cellId, i));
9267 const MFloat exp = hasBndryInStencil ? 0.0 : 0.75;
9268 weights[n] = 1.0 / pow(fabs(dxdx), exp);
9269 if(a_level(nghbrId) > a_level(cellId)) {
9270 const MInt orientation = isDirectNghbr(nghbrId);
9271 TERMM_IF_NOT_COND(orientation >= 0 && orientation < 2 * nDim,
"");
9272 weights[n] *= 1.0 / sqrt(noFineNghbrs[orientation]);
9278 if(fallBackMode == 1) {
9280 MFloat dirTest[3] = {F0, F0, F0};
9281 for(
MInt n = 0; n < a_noReconstructionNeighbors(cellId); n++) {
9282 const MInt nghbrId = a_reconstructionNeighborId(cellId, n);
9283 ASSERT(!a_hasProperty(nghbrId, SolverCell::IsSplitCell),
"");
9284 for(
MInt i = 0; i < nDim; i++) {
9286 mMax(dirTest[i], weights(n) * fabs(a_coordinate(nghbrId, i) - a_coordinate(cellId, i)) / cellLength);
9289 MFloat stencilCheck = F1;
9290 for(
MInt i = 0; i < nDim; i++) {
9291 stencilCheck =
mMin(stencilCheck, dirTest[i]);
9294 if(stencilCheck < 0.1) {
9295 extendStencil(cellId);
9298 return computeRecConstSVD(cellId, offset, tmpA, tmpC, weights, recDim, weightMode, 2);
9302 const MFloat normalizationFactor =
FPOW2(a_level(cellId)) / c_cellLengthAtLevel(0);
9305 std::vector<MBool> zeroColumns(recDim,
true);
9306 std::array<MInt, nDim> recNghbrsRfn;
9307 std::fill_n(&recNghbrsRfn[0], nDim, -1);
9308 std::array<
MFloat, nDim - 1> recConstantsRfn = {};
9309 MBool foundCoarseNghbr =
false;
9310 for(
MInt n = 0; n < noNghbrIds; n++) {
9311 const MInt nghbrId = a_reconstructionNeighborId(cellId, n);
9312 std::array<MFloat, nDim> dx;
9314 if(weightMode == 4) {
9315 if(!a_isBndryCell(cellId) && weights[n] > EPS && a_level(nghbrId) < a_level(cellId)
9316 && currentSlopeDir != -1) {
9317 TERMM_IF_NOT_COND(currentSlopeDir != -1,
"Only one direction at a time should be considered");
9318 TERMM_IF_NOT_COND(!foundCoarseNghbr,
"Only one coarse nghbr per direction is allowed!");
9319 recNghbrsRfn[0] = n;
9320 MInt dimN = currentSlopeDir;
9321 array<
MInt, nDim - 1> dimT{};
9324 for(
MInt i = 0; i < nDim; ++i) {
9326 const MInt dir = a_coordinate(cellId, i) > a_coordinate(nghbrId, i) ? 0 : 1;
9327 if(checkNeighborActive(cellId, 2 * i + dir) && a_hasNeighbor(cellId, 2 * i + dir),
"") {
9328 const MInt nghbrId_ = c_neighborId(cellId, 2 * i + dir);
9329 for(
MInt nn = 0; nn < noNghbrIds; nn++) {
9330 if(a_reconstructionNeighborId(cellId, nn) == nghbrId_) {
9331 recNghbrsRfn[noTDims + 1] = nn;
9334 TERMM_IF_NOT_COND(recNghbrsRfn[noTDims + 1] != -1,
"This nghbr must exist in rec-stencil!");
9335 TERMM_IF_NOT_COND(a_hasProperty(nghbrId_, SolverCell::IsOnCurrentMGLevel),
"");
9337 for(
MInt d = 0, dd = 0; d < nDim; ++d) {
9339 dxT(dd++, noTDims) = a_coordinate(nghbrId_, d) - a_coordinate(cellId, d);
9347 dx[dimN] = a_coordinate(nghbrId, dimN) - a_coordinate(cellId, dimN);
9348 if(noTDims == nDim - 1) {
9351 for(
MInt i = 0; i < nDim - 1; ++i) {
9352 recConstantsRfn[i] = 0;
9353 for(
MInt d = 0; d < nDim - 1; ++d) {
9354 recConstantsRfn[i] += dxT_inv(i, d) * (a_coordinate(nghbrId, dimT[d]) - a_coordinate(cellId, dimT[d]));
9356 if(!a_isBndryCell(nghbrId) && !a_isBndryCell(a_reconstructionNeighborId(cellId, recNghbrsRfn[1]))
9357 && !a_isBndryCell(a_reconstructionNeighborId(cellId, recNghbrsRfn[nDim - 1]))) {
9358 TERMM_IF_NOT_COND(
approx(recConstantsRfn[i], 0.5, EPS),
"");
9361 for(
MInt i = 0; i < nDim - 1; ++i) {
9362 const MInt nghbrId_ = a_reconstructionNeighborId(cellId, recNghbrsRfn[i + 1]);
9363 dx[dimN] += (a_coordinate(cellId, dimN) - a_coordinate(nghbrId_, dimN)) * recConstantsRfn[i];
9366 if(nDim == 3 && noTDims == 1) {
9367 for(
MInt d = 0, dd = 0; d < nDim; ++d) {
9369 dxT(dd, noTDims) = dxT(1 - dd, 0);
9373 dxT(0, noTDims) *= -1;
9376 recConstantsRfn[0] = 0;
9377 for(
MInt d = 0; d < nDim - 1; ++d) {
9378 recConstantsRfn[0] += dxT_inv(0, d) * (a_coordinate(nghbrId, dimT[d]) - a_coordinate(cellId, dimT[d]));
9381 (a_coordinate(cellId, dimN) - a_coordinate(a_reconstructionNeighborId(cellId, recNghbrsRfn[1]), dimN))
9382 * recConstantsRfn[0];
9384 dx[dimN] *= normalizationFactor;
9385 foundCoarseNghbr =
true;
9391 if(relocateCenter) {
9392 const MInt d = (
MInt)isDirectNghbr(nghbrId) / 2;
9394 dx[d] = (a_coordinate(nghbrId, d) - a_coordinate(cellId, d)) * normalizationFactor;
9397 for(
MInt i = 0; i < nDim; i++) {
9399 dx[i] = (a_coordinate(nghbrId, i) - a_coordinate(cellId, i)) * normalizationFactor;
9404 }
else if(weightMode == 3) {
9405 for(
MInt i = 0; i < nDim; i++) {
9407 dx[i] = (a_coordinate(nghbrId, i) - a_coordinate(cellId, i)) * normalizationFactor;
9411 for(
MInt i = 0; i < nDim; i++) {
9412 dx[i] = (a_coordinate(nghbrId, i) - a_coordinate(cellId, i)) * normalizationFactor;
9416 for(
MInt i = 0; i < nDim; i++) {
9418 if(fabs(tmpA(n, i)) > EPS && fabs(weights[n]) > EPS) {
9419 zeroColumns[i] =
false;
9423 for(
MInt i = 0; i < nDim; i++) {
9425 tmpA(n, cnt) = F1B2 *
POW2(dx[i]);
9426 if(fabs(tmpA(n, cnt)) > EPS && fabs(weights[n]) > EPS) {
9427 zeroColumns[cnt] =
false;
9432 for(
MInt i = 0; i < nDim; i++) {
9433 for(
MInt j = i + 1; j < nDim; j++) {
9435 tmpA(n, cnt) = dx[i] * dx[j];
9436 if(fabs(tmpA(n, cnt)) > EPS && fabs(weights[n]) > EPS) {
9437 zeroColumns[cnt] =
false;
9446 for(
MInt n = 0; n < noNghbrIds; n++) {
9447 for(
MInt i = 0, ii = 0; i < recDim; ++i) {
9448 if(!allDirs && !dirs[i]) {
9449 zeroColumns[i] =
true;
9451 if(!zeroColumns[i]) {
9452 tmpA(n, ii) = tmpA(n, i);
9458 const MInt recDimSignificant = std::count(zeroColumns.begin(), zeroColumns.end(),
false);
9459 TERMM_IF_COND(recDimSignificant == 0,
9460 std::to_string(dirs[0]) +
" " + std::to_string(dirs[1]) +
" " + std::to_string(allDirs));
9463 if(rank < min(noNghbrIds, recDimSignificant)) {
9465 cerr << domainId() <<
": QRD failed for cell " << cellId <<
" " << c_globalId(cellId) <<
" " << a_level(cellId)
9466 <<
" " << a_isHalo(cellId) <<
" " << a_hasProperty(cellId, SolverCell::IsNotGradient) <<
" /split "
9467 << a_hasProperty(cellId, SolverCell::IsSplitCell) <<
" " << a_hasProperty(cellId, SolverCell::IsSplitChild)
9468 <<
" " << a_hasProperty(cellId, SolverCell::HasSplitFace) << endl;
9469 for(
MInt n = 0; n < noNghbrIds; n++) {
9470 cerr << weights[n] <<
" ";
9473 for(
MInt dir = 0; dir < 2 * nDim; dir++) {
9474 if(checkNeighborActive(cellId, dir)) {
9475 cerr << a_hasNeighbor(cellId, dir) <<
"/" << c_neighborId(cellId, dir) <<
" ";
9484 a_reconstructionData(cellId) = offset;
9485 if((
signed)m_reconstructionConstants.size() < nDim * (offset + noNghbrIds)) {
9486 m_reconstructionConstants.resize(nDim * (offset + noNghbrIds));
9487 m_reconstructionCellIds.resize(offset + noNghbrIds);
9488 m_reconstructionNghbrIds.resize(offset + noNghbrIds);
9490 std::vector<MFloat> reConstants;
9491 if(weightMode == 4 && relocateCenter && hasBndryInStencil) {
9492 reConstants.resize(nDim * noNghbrIds);
9493 std::copy_n(&m_reconstructionConstants[nDim * offset], nDim * noNghbrIds, &reConstants[0]);
9495 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
9496 const MInt nghbrId = a_reconstructionNeighborId(cellId, nghbr);
9497 m_reconstructionCellIds[offset + nghbr] = cellId;
9498 m_reconstructionNghbrIds[offset + nghbr] = nghbrId;
9499 for(
MInt i = 0, ii = -1; i < nDim; i++) {
9500 if(zeroColumns[i]) {
9504 if(!allDirs && !dirs[i]) {
9507 m_reconstructionConstants[nDim * (offset + nghbr) + i] = tmpC(ii, nghbr) * normalizationFactor;
9511 if(weightMode == 4 && relocateCenter && hasBndryInStencil) {
9512 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
9513 const MInt nghbrId = a_reconstructionNeighborId(cellId, nghbr);
9515 const MInt d = (
MInt)isDirectNghbr(nghbrId) / 2;
9516 if(a_isBndryCell(nghbrId) && a_level(nghbrId) >= a_level(cellId) && d > -1) {
9517 array<MFloat, nDim> dx{};
9518 for(
MInt dd = 0; dd < nDim; ++dd) {
9520 dx[dd] = a_coordinate(nghbrId, dd) - a_coordinate(cellId, dd);
9523 for(
MInt nghbr2 = 0; nghbr2 < noNghbrIds; nghbr2++) {
9524 for(
MInt i = 0; i < nDim; ++i) {
9525 if(zeroColumns[i]) {
9528 if(!allDirs && !dirs[i]) {
9531 for(
MInt dd = 0; dd < nDim; ++dd) {
9532 m_reconstructionConstants[nDim * (offset + nghbr2) + i] -=
9533 m_reconstructionConstants[nDim * (offset + nghbr) + i] * (reConstants[nDim * nghbr2 + dd] * dx[dd]);
9541 if(foundCoarseNghbr) {
9542 const MInt nghbr = recNghbrsRfn[0];
9543 for(
MInt i = 0; i < nDim; i++) {
9544 if(zeroColumns[i]) {
9547 if(!allDirs && !dirs[i]) {
9550 for(
MInt n = 0; n < nDim - 1; ++n) {
9551 if(recNghbrsRfn[n + 1] != -1) {
9552 const MInt nghbr_ = recNghbrsRfn[n + 1];
9553 TERMM_IF_NOT_COND(
approx(m_reconstructionConstants[nDim * (offset + nghbr_) + i], 0.0, MFloatEps),
"");
9554 m_reconstructionConstants[nDim * (offset + nghbr_) + i] =
9555 -recConstantsRfn[n] * m_reconstructionConstants[nDim * (offset + nghbr) + i];
9562 if(condNum < F0 || condNum > 1e6 || std::isnan(condNum)) {
9564 if(fallBackMode > 0) {
9565 extendStencil(cellId);
9566 return computeRecConstSVD(cellId, offset, tmpA, tmpC, weights, recDim, weightMode, -1);
9570 cerr << domainId() <<
" " <<
globalTimeStep <<
" SVD decomposition for cell " << cellId <<
"/" << c_globalId(cellId)
9571 <<
" level " << a_level(cellId) <<
" with large condition number: " << condNum <<
" " << noNghbrIds <<
"x"
9572 << recDim <<
" " << a_cellVolume(cellId) / pow(cellLength, (
MFloat)nDim) <<
" coords "
9573 << a_coordinate(cellId, 0) <<
", " << a_coordinate(cellId, 1) <<
", " << a_coordinate(cellId, 2) <<
" bndryId "
9574 << a_bndryId(cellId) << endl;
9575 for(
MInt n = 0; n < noNghbrIds; n++) {
9576 cerr << c_globalId(a_reconstructionNeighborId(cellId, n)) <<
"(" << weights[n] <<
") ";
9590template <MInt nDim_,
class SysEqn>
9597 const MInt rootCell = (a_hasProperty(cellId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(cellId) : cellId;
9600 a_noReconstructionNeighbors(cellId) = (a_isBndryCell(cellId)) ? m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs : 0;
9602 const MInt counter2 = getAdjacentLeafCells_d2_c(rootCell, 1, nghbrList, layerId);
9604 for(
MInt n = 0; n < counter2; n++) {
9605 if(nghbrList[n] < 0)
continue;
9606 if(a_hasProperty(nghbrList[n], SolverCell::IsInactive))
continue;
9607 if(a_noReconstructionNeighbors(cellId) < m_cells.noRecNghbrs()) {
9608 a_reconstructionNeighborId(cellId, a_noReconstructionNeighbors(cellId)) = nghbrList[n];
9609 a_noReconstructionNeighbors(cellId)++;
9611 cerr <<
"Warning: too many reconstruction neighbors for cell " << cellId << endl;
9622template <MInt nDim_,
class SysEqn>
9627 const MFloat tInfRestart = sysEqn().temperature_IR(m_previousMa);
9628 const MFloat pInfRestart = sysEqn().pressure_IR(tInfRestart);
9629 const MFloat uInfRestart = m_previousMa * sqrt(tInfRestart);
9630 const MFloat rhoInfRestart = sysEqn().density_IR(tInfRestart);
9633 const MFloat tInf = sysEqn().temperature_IR(m_Ma);
9634 const MFloat pInf = sysEqn().pressure_IR(tInf);
9635 const MFloat uInf = m_Ma * sqrt(tInf);
9636 const MFloat rhoInf = sysEqn().density_IR(tInf);
9639 const MFloat velRatio = uInf / uInfRestart;
9640 const MFloat densityRatio = rhoInf / rhoInfRestart;
9641 const MFloat pressureRatio = pInf / pInfRestart;
9644 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
9646 for(
MInt i = 0; i < nDim; i++) {
9647 a_pvariable(cellId, PV->VV[i]) *= velRatio;
9651 a_pvariable(cellId, PV->RHO) *= densityRatio;
9654 a_pvariable(cellId, PV->P) *= pressureRatio;
9662template <MInt nDim_,
class SysEqn>
9666 ASSERT(m_hasExternalSource,
"");
9669 if(noDomains() > 1) {
9671 m_externalSource, CV->noVariables);
9675 MBool filter =
false;
9678 grid().smoothFilter(maxRefinementLevel() - 1, m_externalSource);
9685template <MInt nDim_,
class SysEqn>
9689 for(
MInt ac = 0; ac < m_noActiveCells; ac++) {
9690 const MInt cellId = m_activeCellIds[ac];
9691 for(
MInt var = 0; var < CV->noVariables; var++) {
9692 a_rightHandSide(cellId, var) += a_externalSource(cellId, var);
9700template <MInt nDim_,
class SysEqn>
9704 ASSERT(m_hasExternalSource,
"");
9706 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
9707 for(
MInt var = 0; var < CV->noVariables; var++) {
9708 a_externalSource(cellId, var) = 0;
9713template <MInt nDim_,
class SysEqn>
9715 const MInt noPVars = PV->noVariables;
9717 for(
MInt vari = 0; vari < noPVars; vari++)
9718 vars[vari] = a_pvariable(cellId, vari);
9720 if(order == 0)
return;
9722 for(
MInt vari = 0; vari < noPVars; vari++)
9723 for(
MInt dimi = 0; dimi < nDim; dimi++)
9724 vars[vari] += a_slope(cellId, vari, dimi) * (Xp[dimi] - a_coordinate(cellId, dimi));
9728template <MInt nDim_,
class SysEqn>
9730 if(m_timeStepComputationInterval == -1 && m_restart) {
9733 && Context::getSolverProperty<MBool>(
"consistentRestart", m_solverId, AT_)) {
9741template <MInt nDim_,
class SysEqn>
9743 switch(m_timeStepComputationInterval) {
9749 if(m_timeStepComputationInterval < 0) {
9751 "timeStepComputationInterval is " + to_string(m_timeStepComputationInterval)
9752 +
" and out-of-range [-1, infinity)");
9759template <MInt nDim_,
class SysEqn>
9762 if((m_timeStepMethod == 17511 && nDim == 2) || m_timeStepMethod == 6) {
9765 m_restartFileOutputTimeStep = timeStep();
9771template <MInt nDim_,
class SysEqn>
9774 RECORD_TIMER_START(m_timers[Timers::TimeInt]);
9775 RECORD_TIMER_START(m_timers[Timers::Rhs]);
9779 IF_CONSTEXPR(isDetChem<SysEqn>) {
9780 RECORD_TIMER_START(m_timers[Timers::CellCenterCoefficients]);
9781 computeMeanMolarWeights_CV();
9782 RECORD_TIMER_STOP(m_timers[Timers::CellCenterCoefficients]);
9785 RECORD_TIMER_START(m_timers[Timers::Muscl]);
9787 RECORD_TIMER_STOP(m_timers[Timers::Muscl]);
9789#if defined(WITH_CANTERA)
9790 if(m_detChem.hasChemicalReaction && (m_RKStep == 0)) {
9791 IF_CONSTEXPR(isDetChem<SysEqn>) {
9792 RECORD_TIMER_START(m_timers[Timers::SpeciesReactionRates]);
9793 computeSpeciesReactionRates();
9794 RECORD_TIMER_STOP(m_timers[Timers::SpeciesReactionRates]);
9797 IF_CONSTEXPR(isDetChem<SysEqn>) {
9798 RECORD_TIMER_START(m_timers[Timers::SurfaceCoefficients]);
9799 computeDetailedChemistryVariables();
9800 RECORD_TIMER_STOP(m_timers[Timers::SurfaceCoefficients]);
9804 RECORD_TIMER_START(m_timers[Timers::Ausm]);
9806 RECORD_TIMER_STOP(m_timers[Timers::Ausm]);
9808 RECORD_TIMER_START(m_timers[Timers::ViscFlux]);
9812 IF_CONSTEXPR(nDim == 2) {
9815 mTerm(1,
"Move to sysEqn!");
9816 viscousFlux_Gequ_Pv_Plenum();
9817 }
else if(m_divergenceTreatment) {
9818 mTerm(1,
"Move to sysEqn!");
9819 viscousFlux_Gequ_Pv();
9824 RECORD_TIMER_STOP(m_timers[Timers::ViscFlux]);
9826 RECORD_TIMER_START(m_timers[Timers::DistFlux]);
9827 distributeFluxToCells();
9828 RECORD_TIMER_STOP(m_timers[Timers::DistFlux]);
9830 RECORD_TIMER_START(m_timers[Timers::RhsMisc]);
9832 computeSourceTerms();
9835 IF_CONSTEXPR(isDetChem<SysEqn>) {
9836 if(m_detChem.hasChemicalReaction) {
9837 addSpeciesReactionRatesAndHeatRelease();
9841 if(m_considerVolumeForces) {
9842 computeVolumeForces();
9846 computeVolumeForcesRANS();
9849 if(m_considerRotForces) {
9853 if(m_dualTimeStepping) {
9857 IF_CONSTEXPR(isEEGas<SysEqn>) rhsEEGas();
9859 if(m_hasExternalSource) {
9860 applyExternalSource();
9862 RECORD_TIMER_STOP(m_timers[Timers::RhsMisc]);
9864 RECORD_TIMER_STOP(m_timers[Timers::Rhs]);
9865 RECORD_TIMER_STOP(m_timers[Timers::TimeInt]);
9872template <MInt nDim_,
class SysEqn>
9875 RECORD_TIMER_START(m_timers[Timers::TimeInt]);
9876 RECORD_TIMER_START(m_timers[Timers::RhsBnd]);
9878 updateSpongeLayer();
9882 resetRHSNonInternalCells();
9884 resetRHSCutOffCells();
9886 correctMasterCells();
9888 nonReflectingBCCutOff();
9890 if(m_fvBndryCnd->m_smallCellRHSCorrection) {
9891 smallCellRHSCorrection();
9892 updateSplitParentVariables();
9895 RECORD_TIMER_STOP(m_timers[Timers::RhsBnd]);
9896 RECORD_TIMER_STOP(m_timers[Timers::TimeInt]);
9902template <MInt nDim_,
class SysEqn>
9904 RECORD_TIMER_START(m_timers[Timers::TimeInt]);
9905 RECORD_TIMER_START(m_timers[Timers::Lhs]);
9915 if(m_levelSet && !m_levelSetMb && !m_combustion && !m_levelSetRans) {
9916 RECORD_TIMER_STOP(m_timers[Timers::Lhs]);
9917 RECORD_TIMER_STOP(m_timers[Timers::TimeInt]);
9922 if(isMultilevel() && !isMultilevelPrimary()) {
9923 applyCoarseLevelCorrection();
9927 const MBool step = rungeKuttaStep();
9929 IF_CONSTEXPR(isDetChem<SysEqn>) { correctMajorSpeciesMassFraction(); }
9931 nonReflectingBCAfterTreatmentCutOff();
9934 if(step && requiresTimeStepUpdate()) {
9935#if defined(WITH_CANTERA)
9936 IF_CONSTEXPR(isDetChem<SysEqn>) { computeGamma(); }
9941 RECORD_TIMER_STOP(m_timers[Timers::Lhs]);
9942 RECORD_TIMER_STOP(m_timers[Timers::TimeInt]);
9952template <MInt nDim_,
class SysEqn>
9957 m_statisticCombustionAnalysis =
false;
9959 m_statisticCombustionAnalysis =
9960 Context::getBasicProperty<MBool>(
"statisticCombustionAnalysis", AT_, &m_statisticCombustionAnalysis);
9961 if(m_statisticCombustionAnalysis || isDetChem<SysEqn>) {
9962 mAlloc(m_heatRelease, maxNoGridCells(),
"m_heatRelease", F0, AT_);
9966 if(!isActive())
return;
9968 const MFloat time0 = MPI_Wtime();
9970 IF_CONSTEXPR(isEEGas<SysEqn>)
9971 if(m_EEGas.depthCorrection) initDepthCorrection();
9973 applyInitialCondition();
9977 resetZonalSolverData();
9978 if(m_restart || (m_resetInitialCondition && m_solverId == m_zonalRestartInterpolationSolverId)) {
9983 if(m_STGSponge) initSTGSponge();
9985 if(noNeighborDomains() > 0) {
9986 exchangeDataFV(&a_variable(0, 0), CV->noVariables,
false, m_rotIndVarsCV);
9987 exchangeDataFV(&a_oldVariable(0, 0), CV->noVariables,
false, m_rotIndVarsCV);
9988 exchangeDataFV(&a_pvariable(0, 0), PV->noVariables,
false, m_rotIndVarsPV);
9991 const MFloat time1 = MPI_Wtime();
9992 if(domainId() == 0)
m_log <<
"Init solution time " << time1 - time0 << endl;
10000template <MInt nDim_,
class SysEqn>
10005 if(!isActive())
return;
10008 if(m_restart && !(m_zonal || grid().azimuthalPeriodicity())) {
10013 reInitSmallCellIdsMemory();
10016 initSolutionStep(-1);
10019 reInitActiveCellIdsMemory();
10020 writeListOfActiveFlowCells();
10022 initializeMaxLevelExchange();
10025 MLong maxNoCells = noInternalCells();
10028 MLong maxNoTotalCells = a_noCells();
10030 "MPI_IN_PLACE",
"maxNoTotalCells");
10032 message <<
"Solver #" << solverId() <<
" - maximum number of internal cells among ranks: " << maxNoCells
10034 message <<
"Solver #" << solverId() <<
" - maximum number of cells among ranks: " << maxNoTotalCells << std::endl;
10039 IF_CONSTEXPR(isEEGas<SysEqn>)
10040 if(m_EEGas.depthCorrection) initDepthCorrection();
10043 applyInitialCondition();
10050#if defined(WITH_CANTERA)
10051 IF_CONSTEXPR(isDetChem<SysEqn>) { computeGamma(); }
10055 initializeRungeKutta();
10060 if(m_periodicCells == 3) {
10062 exchangePeriodic();
10068 if(m_calcLESAverage) {
10069 determineLESAverageCells();
10071 finalizeLESAverage();
10075 initSTGSpongeExchange();
10076 if(m_preliminarySponge) {
10077 readPreliminarySTGSpongeData();
10086 cutOffBoundaryCondition();
10089 applyBoundaryCondition();
10091 computeConservativeVariables();
10097 if(calcSlopesAfterStep()) {
10098 LSReconstructCellCenter();
10099 m_fvBndryCnd->copySlopesToSmallCells();
10100 m_fvBndryCnd->updateGhostCellSlopesInviscid();
10101 m_fvBndryCnd->updateCutOffSlopesInviscid();
10104 if(m_combustion && !m_LSSolver) {
10105 setCellProperties();
10106 computePrimitiveVariablesCoarseGrid();
10107 computeConservativeVariables();
10110 if((m_levelSet || m_levelSetRans) && !m_combustion && !m_LSSolver) {
10111 setCellProperties();
10114 IF_CONSTEXPR(isEEGas<SysEqn>) {
10115 if(m_EEGas.gasSource != 0) initSourceCells();
10116 grid().findEqualLevelNeighborsParDiagonal(
false);
10124template <MInt nDim,
class SysEqn>
10125template <
class _, std::enable_if_t<isEEGas<SysEqn>, _*>>
10127 MFloat sourceCellVolume = 0.0;
10128 switch(m_EEGas.gasSource) {
10134 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
10135 if(a_level(cellId) != maxLevel() || a_isBndryGhostCell(cellId))
continue;
10136 MBool isInAnyBox =
false;
10137 for(
MInt box = 0; box < m_EEGas.noGasSourceBoxes; box++) {
10138 MBool isInThisBox =
true;
10139 for(
MInt i = 0; i < nDim; i++) {
10140 if(a_coordinate(cellId, i) < m_EEGas.gasSourceBox[i + box * nDim * 2]
10141 || a_coordinate(cellId, i) > m_EEGas.gasSourceBox[i + nDim + box * nDim * 2]) {
10142 isInThisBox =
false;
10152 m_EEGas.gasSourceCells.push_back(cellId);
10153 if(!a_isHalo(cellId)) sourceCellVolume += a_cellVolume(cellId);
10162 "MPI_IN_PLACE",
"totalSourceCellVolume");
10164 MFloat massFlow = m_EEGas.gasSourceMassFlow;
10165 m_EEGas.massSource = massFlow / sourceCellVolume;
10167 if(domainId() == 0)
10168 std::cerr <<
"Volume of gas mass source cells: " << sourceCellVolume
10169 <<
" \tmass source (rho): " << m_EEGas.massSource << std::endl;
10177template <MInt nDim_,
class SysEqn>
10181 RECORD_TIMER_START(m_timers[Timers::TimeInt]);
10182 RECORD_TIMER_START(m_timers[Timers::LhsBnd]);
10185 mTerm(1,
"lhsBndFinish() should only be used with split MPI communication "
10186 "(splitMpiComm) activated.");
10189 RECORD_TIMER_START(m_timers[Timers::Exchange]);
10191 RECORD_TIMER_START(m_tcomm);
10192 RECORD_TIMER_START(m_texchange);
10193 finishMpiExchange();
10194 RECORD_TIMER_STOP(m_texchange);
10195 RECORD_TIMER_STOP(m_tcomm);
10197 RECORD_TIMER_STOP(m_timers[Timers::Exchange]);
10203 computePrimitiveVariablesCoarseGrid();
10205 RECORD_TIMER_START(m_timers[Timers::CutOff]);
10206 cutOffBoundaryCondition();
10207 RECORD_TIMER_STOP(m_timers[Timers::CutOff]);
10209 RECORD_TIMER_START(m_timers[Timers::BndryCnd]);
10210 applyBoundaryCondition();
10211 RECORD_TIMER_STOP(m_timers[Timers::BndryCnd]);
10213 computePrimitiveVariablesCoarseGrid();
10216 if(calcSlopesAfterStep()) {
10217 RECORD_TIMER_STOP(m_timers[Timers::LhsBnd]);
10219 RECORD_TIMER_START(m_timers[Timers::Rhs]);
10220 RECORD_TIMER_START(m_timers[Timers::Muscl]);
10222 RECORD_TIMER_START(m_timers[Timers::MusclReconst]);
10223 LSReconstructCellCenter();
10224 RECORD_TIMER_STOP(m_timers[Timers::MusclReconst]);
10227 RECORD_TIMER_START(m_timers[Timers::MusclCopy]);
10228 m_fvBndryCnd->copySlopesToSmallCells();
10229 RECORD_TIMER_STOP(m_timers[Timers::MusclCopy]);
10233 RECORD_TIMER_START(m_timers[Timers::MusclGhostSlopes]);
10234 m_fvBndryCnd->updateGhostCellSlopesInviscid();
10235 RECORD_TIMER_STOP(m_timers[Timers::MusclGhostSlopes]);
10237 RECORD_TIMER_START(m_timers[Timers::MusclCutSlopes]);
10238 m_fvBndryCnd->updateCutOffSlopesInviscid();
10239 RECORD_TIMER_STOP(m_timers[Timers::MusclCutSlopes]);
10242 RECORD_TIMER_STOP(m_timers[Timers::Muscl]);
10243 RECORD_TIMER_STOP(m_timers[Timers::Rhs]);
10245 RECORD_TIMER_START(m_timers[Timers::LhsBnd]);
10248 RECORD_TIMER_STOP(m_timers[Timers::LhsBnd]);
10249 RECORD_TIMER_STOP(m_timers[Timers::TimeInt]);
10256template <MInt nDim_,
class SysEqn>
10260 RECORD_TIMER_START(m_timers[Timers::TimeInt]);
10261 RECORD_TIMER_START(m_timers[Timers::LhsBnd]);
10263#if defined _MB_DEBUG_ || !defined NDEBUG
10267 if(m_noSpecies > 0) {
10271 RECORD_TIMER_START(m_timers[Timers::SmallCellCorr]);
10272 smallCellCorrection();
10273 RECORD_TIMER_STOP(m_timers[Timers::SmallCellCorr]);
10274 updateSplitParentVariables();
10276#if defined _MB_DEBUG_
10280 RECORD_TIMER_START(m_timers[Timers::ComputePV]);
10282 RECORD_TIMER_STOP(m_timers[Timers::ComputePV]);
10284 RECORD_TIMER_START(m_timers[Timers::Exchange]);
10286 if(m_periodicCells == 3) {
10288 exchangePeriodic();
10292 if(grid().azimuthalPeriodicity()) {
10293 cutOffBoundaryCondition();
10294 if(!m_fvBndryCnd->m_cbcSmallCellCorrection) {
10295 for(
MInt cellId = 0; cellId < c_noCells(); cellId++) {
10296 if(a_hasProperty(cellId, SolverCell::IsCutOff)) {
10297 sysEqn().computeConservativeVariables(&a_pvariable(cellId, 0), &a_variable(cellId, 0), 0);
10304 RECORD_TIMER_START(m_tcomm);
10305 RECORD_TIMER_START(m_texchange);
10306 startMpiExchange();
10307 RECORD_TIMER_STOP(m_texchange);
10308 RECORD_TIMER_STOP(m_tcomm);
10312 RECORD_TIMER_STOP(m_timers[Timers::Exchange]);
10315 if(m_periodicCells == 1 || m_periodicCells == 2) {
10316 RECORD_TIMER_START(m_timers[Timers::CutOff]);
10317 cutOffBoundaryCondition();
10318 RECORD_TIMER_STOP(m_timers[Timers::CutOff]);
10320 RECORD_TIMER_START(m_timers[Timers::Exchange]);
10321 exchangePeriodic();
10322 RECORD_TIMER_STOP(m_timers[Timers::Exchange]);
10328 computePrimitiveVariablesCoarseGrid();
10331 RECORD_TIMER_START(m_timers[Timers::CutOff]);
10332 cutOffBoundaryCondition();
10333 RECORD_TIMER_STOP(m_timers[Timers::CutOff]);
10335 RECORD_TIMER_START(m_timers[Timers::BndryCnd]);
10336 applyBoundaryCondition();
10337 RECORD_TIMER_STOP(m_timers[Timers::BndryCnd]);
10339 computePrimitiveVariablesCoarseGrid();
10345 if(calcSlopesAfterStep()) {
10346 RECORD_TIMER_STOP(m_timers[Timers::LhsBnd]);
10348 RECORD_TIMER_START(m_timers[Timers::Rhs]);
10349 RECORD_TIMER_START(m_timers[Timers::Muscl]);
10351 RECORD_TIMER_START(m_timers[Timers::MusclReconst]);
10352 LSReconstructCellCenter();
10353 RECORD_TIMER_STOP(m_timers[Timers::MusclReconst]);
10356 RECORD_TIMER_START(m_timers[Timers::MusclCopy]);
10357 m_fvBndryCnd->copySlopesToSmallCells();
10358 RECORD_TIMER_STOP(m_timers[Timers::MusclCopy]);
10362 RECORD_TIMER_START(m_timers[Timers::MusclGhostSlopes]);
10363 m_fvBndryCnd->updateGhostCellSlopesInviscid();
10364 RECORD_TIMER_STOP(m_timers[Timers::MusclGhostSlopes]);
10366 RECORD_TIMER_START(m_timers[Timers::MusclCutSlopes]);
10367 m_fvBndryCnd->updateCutOffSlopesInviscid();
10368 RECORD_TIMER_STOP(m_timers[Timers::MusclCutSlopes]);
10371 RECORD_TIMER_STOP(m_timers[Timers::Muscl]);
10372 RECORD_TIMER_STOP(m_timers[Timers::Rhs]);
10374 RECORD_TIMER_START(m_timers[Timers::LhsBnd]);
10378 RECORD_TIMER_STOP(m_timers[Timers::LhsBnd]);
10379 RECORD_TIMER_STOP(m_timers[Timers::TimeInt]);
10384template <MInt nDim_,
class SysEqn>
10386 std::vector<MInt>& NotUsed(globalIdVars)) {
10390 globalFloatVars.push_back(m_time);
10391 globalFloatVars.push_back(m_timeStep);
10392 globalFloatVars.push_back(m_physicalTime);
10398template <MInt nDim_,
class SysEqn>
10400 std::vector<MInt>& NotUsed(globalIdVars)) {
10404 m_time = globalFloatVars[0];
10405 m_timeStep = globalFloatVars[1];
10406 m_physicalTime = globalFloatVars[2];
10414template <MInt nDim_,
class SysEqn>
10416 const MBool allTimings) {
10419 const MString namePrefix =
"b" + std::to_string(solverId()) +
"_";
10421 const MFloat load = returnLoadRecord();
10422 const MFloat idle = returnIdleRecord();
10424 solverTimings.emplace_back(namePrefix +
"loadFvCartesianSolver", load);
10425 solverTimings.emplace_back(namePrefix +
"idleFvCartesianSolver", idle);
10427#ifdef MAIA_TIMER_FUNCTION
10428 solverTimings.emplace_back(namePrefix +
"timeIntegration", RETURN_TIMER_TIME(m_timers[Timers::TimeInt]));
10432 solverTimings.emplace_back(namePrefix +
"rhs", RETURN_TIMER_TIME(m_timers[Timers::Rhs]));
10433 solverTimings.emplace_back(namePrefix +
"MUSCL", RETURN_TIMER_TIME(m_timers[Timers::Muscl]));
10434 solverTimings.emplace_back(namePrefix +
"reconstructCellCenter", RETURN_TIMER_TIME(m_timers[Timers::MusclReconst]));
10435 solverTimings.emplace_back(namePrefix +
"reconstructSrfcData",
10436 RETURN_TIMER_TIME(m_timers[Timers::MusclReconstSrfc]));
10437 if(m_useSandpaperTrip) {
10438 solverTimings.emplace_back(namePrefix +
"SandpaperTrip", RETURN_TIMER_TIME(m_timers[Timers::SandpaperTrip]));
10441 solverTimings.emplace_back(namePrefix +
"WMFluxCorrection",
10442 RETURN_TIMER_TIME(m_timers[Timers::WMFluxCorrection]));
10443 solverTimings.emplace_back(namePrefix +
"WMSurfaceLoop", RETURN_TIMER_TIME(m_timers[Timers::WMSurfaceLoop]));
10444 solverTimings.emplace_back(namePrefix +
"WMExchange", RETURN_TIMER_TIME(m_timers[Timers::WMExchange]));
10447 IF_CONSTEXPR(isDetChem<SysEqn>) {
10448 solverTimings.emplace_back(namePrefix +
"SurfaceCoefficients",
10449 RETURN_TIMER_TIME(m_timers[Timers::SurfaceCoefficients]));
10450 solverTimings.emplace_back(namePrefix +
"SurfaceMeanMolarWeight",
10451 RETURN_TIMER_TIME(m_timers[Timers::SurfaceMeanMolarWeight]));
10452 solverTimings.emplace_back(namePrefix +
"SurfaceTransportCoefficients",
10453 RETURN_TIMER_TIME(m_timers[Timers::SurfaceTransportCoefficients]));
10454 solverTimings.emplace_back(namePrefix +
"CellCenterCoefficients",
10455 RETURN_TIMER_TIME(m_timers[Timers::CellCenterCoefficients]));
10456 solverTimings.emplace_back(namePrefix +
"SpeciesReactionRates",
10457 RETURN_TIMER_TIME(m_timers[Timers::SpeciesReactionRates]));
10460 solverTimings.emplace_back(namePrefix +
"AUSM", RETURN_TIMER_TIME(m_timers[Timers::Ausm]));
10461 solverTimings.emplace_back(namePrefix +
"viscFlux", RETURN_TIMER_TIME(m_timers[Timers::ViscFlux]));
10462 solverTimings.emplace_back(namePrefix +
"distrFlux", RETURN_TIMER_TIME(m_timers[Timers::DistFlux]));
10464 solverTimings.emplace_back(namePrefix +
"rhsBnd", RETURN_TIMER_TIME(m_timers[Timers::RhsBnd]));
10465 solverTimings.emplace_back(namePrefix +
"lhs", RETURN_TIMER_TIME(m_timers[Timers::Lhs]));
10467 solverTimings.emplace_back(namePrefix +
"lhsBnd", RETURN_TIMER_TIME(m_timers[Timers::LhsBnd]));
10468 solverTimings.emplace_back(namePrefix +
"smallCellCorr", RETURN_TIMER_TIME(m_timers[Timers::SmallCellCorr]));
10469 solverTimings.emplace_back(namePrefix +
"computePV", RETURN_TIMER_TIME(m_timers[Timers::ComputePV]));
10470 solverTimings.emplace_back(namePrefix +
"exchange", RETURN_TIMER_TIME(m_timers[Timers::Exchange]));
10471 solverTimings.emplace_back(namePrefix +
"cutOff", RETURN_TIMER_TIME(m_timers[Timers::CutOff]));
10472 solverTimings.emplace_back(namePrefix +
"bndryCnd", RETURN_TIMER_TIME(m_timers[Timers::BndryCnd]));
10473 solverTimings.emplace_back(namePrefix +
"SCC-init", RETURN_TIMER_TIME(m_timers[Timers::SCCorrInit]));
10476 solverTimings.emplace_back(namePrefix +
"SCC-Ex1", RETURN_TIMER_TIME(m_timers[Timers::SCCorrExchange1]));
10477 solverTimings.emplace_back(namePrefix +
"SCC-Wait1", RETURN_TIMER_TIME(m_timers[Timers::SCCorrExchange1Wait]));
10478 solverTimings.emplace_back(namePrefix +
"SCC-int", RETURN_TIMER_TIME(m_timers[Timers::SCCorrInterp]));
10479 solverTimings.emplace_back(namePrefix +
"SCC-redist", RETURN_TIMER_TIME(m_timers[Timers::SCCorrRedist]));
10480 solverTimings.emplace_back(namePrefix +
"SCC-Ex2", RETURN_TIMER_TIME(m_timers[Timers::SCCorrExchange2]));
10481 solverTimings.emplace_back(namePrefix +
"SCC-wait2", RETURN_TIMER_TIME(m_timers[Timers::SCCorrExchange2Wait]));
10485 solverTimings.emplace_back(namePrefix +
"smallCellCorr", RETURN_TIMER_TIME(m_timers[Timers::SmallCellCorr]));
10486 solverTimings.emplace_back(namePrefix +
"exchange", RETURN_TIMER_TIME(m_timers[Timers::Exchange]));
10494template <MInt nDim_,
class SysEqn>
10502 const MInt cellId = grid().tree().grid2solver(gridCellId);
10503 if(cellId < 0 || cellId >= noInternalCells()) {
10511 dataSize = CV->noVariables;
10517 mTerm(1,
"Unknown data id.");
10527template <MInt nDim_,
class SysEqn>
10531 const MInt _noInternalCells = grid().noInternalCells();
10532 const MInt noCVars = CV->noVariables;
10533 for(
MInt cellId = 0; cellId < _noInternalCells; cellId++) {
10534 for(
MInt varId = 0; varId < noCVars; varId++) {
10535 a_rightHandSide(cellId, varId) -= a_tau(cellId, varId);
10542template <MInt nDim_,
class SysEqn>
10544 std::vector<MInt>& samplingVarIds, std::vector<MInt>& noSamplingVars,
10545 std::vector<std::vector<MString>>& samplingVarNames,
const MString featureName) {
10549 std::vector<MString> varNamesList;
10550 MInt noVars = readSolverSamplingVarNames(varNamesList, featureName);
10554 varNamesList.emplace_back(
"FV_PV");
10558 for(
MInt i = 0; i < noVars; i++) {
10560 std::vector<MString> varNames;
10562 auto samplingVarIt = std::find(samplingVarIds.begin(), samplingVarIds.end(), samplingVar);
10563 if(samplingVarIt != samplingVarIds.end()) {
10564 mTerm(1,
"Sampling variable '" + varNamesList[i] +
"' already specified.");
10567 switch(samplingVar) {
10569 samplingVarIds.push_back(
FV_PV);
10570 noSamplingVars.push_back(PV->noVariables);
10572 varNames.resize(PV->noVariables);
10573 varNames[PV->U] =
"u";
10574 varNames[PV->V] =
"v";
10575 IF_CONSTEXPR(nDim == 3) { varNames[PV->W] =
"w"; }
10576 varNames[PV->P] =
"p";
10577 varNames[PV->RHO] =
"rho";
10578 MInt varCount = nDim + 2;
10580 IF_CONSTEXPR(isDetChem<SysEqn>) {
10581 if(PV->m_noSpecies > 0) {
10582 for(
MUint s = 0; s < PV->m_noSpecies; s++) {
10583 MString str = (
"Y" + m_speciesName[s]);
10585 strcpy(c, str.c_str());
10586 varNames[PV->Y[s]] = c;
10593 if(PV->m_noSpecies > 0) {
10594 varNames[PV->C] =
"c";
10599 TERMM_IF_NOT_COND(PV->noVariables == varCount,
"Error: variable count mismatch");
10601 samplingVarNames.push_back(varNames);
10607 samplingVarIds.push_back(
FV_VORT);
10609 const MInt noVorticities = (nDim == 2) ? 1 : 3;
10610 noSamplingVars.push_back(noVorticities);
10612 varNames.resize(noVorticities);
10613 IF_CONSTEXPR(nDim == 2) { varNames[0] =
"vort_z"; }
10615 varNames[0] =
"vort_x";
10616 varNames[1] =
"vort_y";
10617 varNames[2] =
"vort_z";
10619 samplingVarNames.push_back(varNames);
10625 noSamplingVars.push_back(1);
10626 varNames.resize(1);
10628 samplingVarNames.push_back(varNames);
10632 mTerm(1,
"Unknown sampling variable: " + varNamesList[i]);
10641template <MInt nDim_,
class SysEqn>
10643 const std::vector<MInt>& noSamplingVars) {
10646 m_samplingVariablesStatus.fill(-1);
10649 for(
MUint i = 0; i < varIds.size(); i++) {
10651 if(varIds[i] ==
FV_PV) {
10655 if(m_samplingVariables[varIds[i]] !=
nullptr) {
10659 MFloat** varPointer =
nullptr;
10660 const MInt dataBlockSize = noSamplingVars[i];
10661 mAlloc(varPointer, a_noCells(), dataBlockSize,
"m_samplingVariables_" + std::to_string(varIds[i]), 0.0, AT_);
10662 m_samplingVariables[varIds[i]] = varPointer;
10669template <MInt nDim_,
class SysEqn>
10671 for(
MUint i = 0; i < varIds.size(); i++) {
10672 const MInt varId = varIds[i];
10676 const MInt statusCalc = m_samplingVariablesStatus[2 * varId];
10677 const MInt statusExchange = m_samplingVariablesStatus[2 * varId + 1];
10678 TERMM_IF_COND(statusExchange == statusCurr && statusCalc != statusCurr,
10679 "Error: invalid compute/exchange order " + std::to_string(statusCurr) +
" "
10680 + std::to_string(statusCalc) +
" " + std::to_string(statusExchange));
10688 MFloat* vortPointer = m_samplingVariables[varId][0];
10689 if(statusCurr != statusCalc) {
10690 m_log <<
"DEBUG calcSamplingVariables calc FV_VORT " << statusCurr <<
" " << statusCalc << std::endl;
10691 IF_CONSTEXPR(nDim == 3) { computeVorticity3DT(vortPointer); }
10693 computeVorticity2D(vortPointer);
10695 m_samplingVariablesStatus[2 * varId] = statusCurr;
10698 if(exchange && statusCurr != statusExchange) {
10699 constexpr MInt noVort = (nDim == 2) ? 1 : 3;
10700 exchangeDataFV(vortPointer, noVort);
10701 m_samplingVariablesStatus[2 * varId + 1] = statusCurr;
10710 mTerm(1,
"Invalid variable id");
10724template <MInt nDim_,
class SysEqn>
10726 std::vector<std::bitset<64>>& sensorCellFlag,
10727 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
10729 m_log <<
" - Sensor preparation for the entropy sensor" << endl;
10733 for(
MInt l = 0; l <= maxRefinementLevel(); l++)
10734 lengthFactor.
p[l] = pow(c_cellLengthAtLevel(l), F3B2);
10736 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
10737 ASSERT(!c_isToDelete(cellId),
"");
10739 if(a_bndryId(cellId) != -1)
continue;
10740 if(a_isBndryGhostCell(cellId))
continue;
10741 if(c_noChildren(cellId) > 0)
continue;
10742 if(a_isHalo(cellId))
continue;
10744 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
10748 const MInt level = a_level(cellId);
10749 const MInt gridId = grid().tree().solver2grid(cellId);
10752 MFloat a2 = sysEqn().temperature_ES(a_pvariable(cellId, PV->RHO), a_pvariable(cellId, PV->P));
10754 for(
MInt i = 0; i < nDim; i++) {
10755 tau +=
POW2(a_slope(cellId, PV->P, i) - a_slope(cellId, PV->RHO, i) * a2);
10758 tau *= lengthFactor.
p[level];
10759 sensors[sensorOffset + sen][gridId] = tau;
10760 sensorCellFlag[gridId][sensorOffset + sen] = 1;
10763 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
10772template <MInt nDim_,
class SysEqn>
10774 std::vector<std::bitset<64>>& sensorCellFlag,
10775 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
10777 m_log <<
" - Sensor preparation for the entropy sensor" << endl;
10781 for(
MInt l = 0; l <= maxRefinementLevel(); l++)
10782 lengthFactor.
p[l] = pow(c_cellLengthAtLevel(l), F3B2);
10784 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
10785 ASSERT(!c_isToDelete(cellId),
"");
10787 if(a_bndryId(cellId) != -1)
continue;
10788 if(a_isBndryGhostCell(cellId))
continue;
10789 if(c_noChildren(cellId) > 0)
continue;
10790 if(a_isHalo(cellId))
continue;
10792 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
10796 const MInt level = a_level(cellId);
10797 const MInt gridId = grid().tree().solver2grid(cellId);
10800 tau = pow(
mMax(F0, ((entropy(cellId) - m_SInfinity) / m_SInfinity)), 1.2);
10801 tau *= lengthFactor.
p[level];
10802 sensors[sensorOffset + sen][gridId] = tau;
10803 sensorCellFlag[gridId][sensorOffset + sen] = 1;
10806 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
10815template <MInt nDim_,
class SysEqn>
10817 std::vector<std::bitset<64>>& sensorCellFlag,
10818 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
10820 m_log <<
" - Sensor preparation for the vorticity sensor" << endl;
10824 for(
MInt l = 0; l <= maxRefinementLevel(); l++)
10825 lengthFactor.
p[l] = pow(c_cellLengthAtLevel(l), F3B2);
10827 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
10828 ASSERT(!c_isToDelete(cellId),
"");
10831 if(a_bndryId(cellId) != -1)
continue;
10832 if(a_isBndryGhostCell(cellId))
continue;
10833 if(c_noChildren(cellId) > 0)
continue;
10834 if(a_isHalo(cellId))
continue;
10835 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
10839 const MInt level = a_level(cellId);
10840 const MInt gridId = this->grid().tree().solver2grid(cellId);
10844 tau = sqrt(
mMax(F1, (entropy(cellId) / m_SInfinity))) - F1;
10846 IF_CONSTEXPR(nDim == 2) { tau = fabs(a_slope(cellId, PV->V, 0) - a_slope(cellId, PV->U, 1)); }
10848 tau = sqrt(
POW2(a_slope(cellId, PV->W, 1) - a_slope(cellId, PV->V, 2))
10849 +
POW2(a_slope(cellId, PV->U, 2) - a_slope(cellId, PV->W, 0))
10850 +
POW2(a_slope(cellId, PV->V, 0) - a_slope(cellId, PV->U, 1)));
10854 tau *= lengthFactor.
p[level];
10855 sensors[sensorOffset + sen][gridId] = tau;
10856 sensorCellFlag[gridId][sensorOffset + sen] =
true;
10859 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
10882template <MInt nDim_,
class SysEqn>
10884 std::vector<std::bitset<64>>& sensorCellFlag,
10885 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
10887 m_log <<
" - Sensor preparation for the derivative sensor" << endl;
10891 for(
MInt l = 0; l <= maxRefinementLevel(); l++) {
10892 lengthFactor[l] = pow(c_cellLengthAtLevel(l), F3B2);
10895 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
10896 ASSERT(!c_isToDelete(cellId),
"");
10899 if(a_bndryId(cellId) != -1)
continue;
10900 if(a_isBndryGhostCell(cellId))
continue;
10901 if(c_noChildren(cellId) > 0)
continue;
10902 if(a_isHalo(cellId))
continue;
10904 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
10907 if(a_level(cellId) > this->m_maxSensorRefinementLevel[sen]) {
10911 const MInt gridId = this->grid().tree().solver2grid(cellId);
10914 if(m_engineSetup) {
10915 if(a_coordinate(cellId, 0) < -0.5 || a_coordinate(cellId, 0) > 0.5)
continue;
10921 if((
MInt)this->m_sensorDerivativeVariables[sen] == 10) {
10923 for(
MInt d = 0; d < nDim; d++) {
10925 for(
MInt i = 0; i < nDim; i++) {
10926 grad +=
POW2(a_slope(cellId, PV->VV[d], i));
10928 if(grad > gradMax) gradMax = grad;
10930 tau = sqrt(gradMax);
10931 }
else if((
MInt)this->m_sensorDerivativeVariables[sen] == 9) {
10933 if(a_pvariable(cellId, PV->Y[0]) > 0.001) {
10935 for(
MInt d = 0; d < nDim; d++) {
10937 for(
MInt i = 0; i < nDim; i++) {
10938 grad +=
POW2(a_slope(cellId, PV->Y[0], i));
10940 if(grad > gradMax) gradMax = grad;
10942 tau = sqrt(gradMax);
10947 for(
MInt d = 0; d < nDim; d++) {
10948 MFloat grad = a_slope(cellId, this->m_sensorDerivativeVariables[sen], d);
10954 tau *= lengthFactor[a_level(cellId)];
10956 sensors[sensorOffset + sen][gridId] = tau;
10957 sensorCellFlag[gridId][sensorOffset + sen] =
true;
10960 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
10963template <MInt nDim_,
class SysEqn>
10965 std::vector<std::bitset<64>>& sensorCellFlag,
10966 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
MInt sen) {
10976 MFloat speciesLimit = 0.0001;
10977 speciesLimit = Context::getSolverProperty<MFloat>(
"speciesConLimit", m_solverId, AT_, &speciesLimit);
10979 std::function<
MFloat(
const MInt)> species = [&](
const MInt cellId) {
return a_pvariable(cellId, PV->Y[0]); };
10982 sensors, sensorCellFlag, sensorWeight, sensorOffset, sen, species, speciesLimit, &m_bandWidth[0],
10983 m_refineDiagonals);
10988 if(m_linerLvlJump && (a_coordinate(cellId, 0) < -0.515 || a_coordinate(cellId, 0) > 0.515)) {
10989 const MInt gridCellId = grid().tree().solver2grid(cellId);
10990 if(sensors[sensorOffset + sen][gridCellId] > 0) {
10991 sensors[sensorOffset + sen][gridCellId] = 0;
10992 sensorCellFlag[gridCellId][sensorOffset + sen] =
false;
10995 if(!a_isInactive(cellId))
continue;
10996 if(a_levelSetValuesMb(cellId, 0) > -(m_maxLsValue - m_eps))
continue;
10997 const MInt gridCellId = grid().tree().solver2grid(cellId);
10998 if(sensors[sensorOffset + sen][gridCellId] > 0) {
10999 sensors[sensorOffset + sen][gridCellId] = 0;
11000 sensorCellFlag[gridCellId][sensorOffset + sen] =
false;
11013template <MInt nDim_,
class SysEqn>
11015 std::vector<std::bitset<64>>& sensorCellFlag,
11016 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
11018 static constexpr MInt particleLimit = 1;
11020 std::function<
MFloat(
const MInt)> noPart = [&](
const MInt cellId) {
return static_cast<MFloat>(a_noPart(cellId)); };
11023 sensors, sensorCellFlag, sensorWeight, sensorOffset, sen, noPart, particleLimit, &m_particleWidth[0],
11024 m_refineDiagonals);
11028 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
11029 if(m_engineSetup && (a_coordinate(cellId, 0) < -0.515 || a_coordinate(cellId, 0) > 0.515)) {
11030 const MInt gridCellId = grid().tree().solver2grid(cellId);
11031 if(sensors[sensorOffset + sen][gridCellId] > 0) {
11032 sensors[sensorOffset + sen][gridCellId] = 0;
11033 sensorCellFlag[gridCellId][sensorOffset + sen] =
false;
11036 if(!a_isInactive(cellId))
continue;
11037 if(a_levelSetValuesMb(cellId, 0) > -(m_maxLsValue - m_eps))
continue;
11038 const MInt gridCellId = grid().tree().solver2grid(cellId);
11039 if(sensors[sensorOffset + sen][gridCellId] > 0) {
11040 sensors[sensorOffset + sen][gridCellId] = 0;
11041 sensorCellFlag[gridCellId][sensorOffset + sen] =
false;
11051template <MInt nDim_,
class SysEqn>
11054 interfaceCell.
fill(0);
11055 vector<MInt> bndCndIds;
11056 bndCndIds.push_back(3003);
11058 this->identifyBoundaryCells(&interfaceCell[0], bndCndIds);
11060 this->setBoundaryDistance(&interfaceCell[0], &m_outerBandWidth[0], distance);
11062 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
11064 const MInt parentId = c_parentId(cellId);
11065 const MBool isPartLvlShift = (parentId > -1 && a_isHalo(parentId));
11067 if(a_level(cellId) != minLevel() && !isPartLvlShift) {
11073 reduceData(cellId, &distance(0));
11075 exchangeDataFV(distance.data());
11083template <MInt nDim_,
class SysEqn>
11085 const MBool average) {
11086 MFloat vol = a_cellVolume(cellId);
11087 if(c_noChildren(cellId) > 0) {
11089 for(
MInt d = 0; d < dataBlockSize; d++) {
11090 data[dataBlockSize * cellId + d] = F0;
11092 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
11093 MInt childId = c_childId(cellId, child);
11094 if(childId < 0)
continue;
11095 if(c_noChildren(childId) == 0 && !a_hasProperty(childId, SolverCell::IsOnCurrentMGLevel))
continue;
11096 MFloat volc = reduceData(childId, data, dataBlockSize);
11097 for(
MInt d = 0; d < dataBlockSize; d++) {
11098 data[dataBlockSize * cellId + d] += volc * data[dataBlockSize * childId + d];
11103 for(
MInt d = 0; d < dataBlockSize; d++) {
11104 data[dataBlockSize * cellId + d] /=
mMax(1e-14, vol);
11117template <MInt nDim_,
class SysEqn>
11121 NEW_TIMER_GROUP_STATIC(tg_solutionStep,
"solution step");
11122 NEW_TIMER_STATIC(t_solutionStep,
"solution step", tg_solutionStep);
11123 NEW_SUB_TIMER_STATIC(t_timeIntegration,
"time integration", t_solutionStep);
11124 NEW_SUB_TIMER_STATIC(t_lhs,
"lhs", t_timeIntegration);
11125 NEW_SUB_TIMER_STATIC(t_lhsBnd,
"lhsBnd", t_timeIntegration);
11126 NEW_SUB_TIMER_STATIC(t_rhs,
"rhs", t_timeIntegration);
11127 NEW_SUB_TIMER_STATIC(t_rhsBnd,
"rhsBnd", t_timeIntegration);
11130 RECORD_TIMER_START(t_solutionStep);
11131 RECORD_TIMER_START(t_timeIntegration);
11136 RECORD_TIMER_START(t_lhsBnd);
11138 RECORD_TIMER_STOP(t_lhsBnd);
11141 m_splitMpiCommRecv =
true;
11144 RECORD_TIMER_START(t_rhs);
11146 RECORD_TIMER_STOP(t_rhs);
11149 RECORD_TIMER_START(t_rhsBnd);
11151 RECORD_TIMER_STOP(t_rhsBnd);
11154 RECORD_TIMER_START(t_lhs);
11155 const MBool timeStepCompleted = solverStep();
11156 RECORD_TIMER_STOP(t_lhs);
11159 RECORD_TIMER_START(t_lhsBnd);
11161 RECORD_TIMER_STOP(t_lhsBnd);
11163 RECORD_TIMER_STOP(t_timeIntegration);
11164 RECORD_TIMER_STOP(t_solutionStep);
11166 return timeStepCompleted;
11174template <MInt nDim_,
class SysEqn>
11178 if(m_calcLESAverage) {
11184 if(m_STGSponge || m_preliminarySponge) {
11185 calcPeriodicSpongeAverage();
11190 m_timeStepConverged = maxResidual();
11196 m_splitMpiCommRecv =
false;
11199 m_forceAdaptation = adaptationTrigger();
11209template <MInt nDim_,
class SysEqn>
11212 if(m_isEEGas)
return;
11214 if(m_hasExternalSource)
return;
11216 const MInt noCVars = CV->noVariables;
11218 auto* var = (
MFloat*)(&(a_variable(0, 0)));
11221 for(
MInt id = 0;
id < m_noActiveCells;
id++) {
11222 cellId = m_activeCellIds[
id];
11223 for(
MInt i = 0; i < m_noSpecies; i++)
11224 var[cellId * noCVars + CV->RHO_Y[i]] =
11225 mMin(var[cellId * noCVars + CV->RHO],
mMax(var[cellId * noCVars + CV->RHO_Y[i]], F0));
11229template <MInt nDim_,
class SysEqn>
11231 const MFloat dt = timeStep(
true);
11233 m_physicalTime -= dt * m_timeRef;
11237template <MInt nDim_,
class SysEqn>
11242#pragma omp parallel for collapse(2)
11245 for(
MInt i = 0; i < a_noCells(); i++) {
11246 for(
MInt j = 0; j < 2 * nDim; j++) {
11247 a_implicitCoefficient(i, j) = F0;
11252template <MInt nDim_,
class SysEqn>
11253template <
class _, std::enable_if_t<isEEGas<SysEqn>, _*>>
11256 if(nDim != 3)
mTerm(1, AT_,
"nDim has to be 3 for EEGas simulations");
11259 if(m_EEGas.gasSource != 0) {
11260 for(
auto& sourceCell : m_EEGas.gasSourceCells) {
11261 a_rightHandSide(sourceCell, CV->A_RHO) -= m_EEGas.massSource * a_cellVolume(sourceCell);
11268#pragma omp parallel for
11270 for(
MInt ac = 0; ac < m_noActiveCells; ac++) {
11271 for(
MInt i = 0; i < nDim; i++) {
11272 a_rightHandSide(m_activeCellIds[ac], CV->A_RHO_VV[i]) -=
11273 a_pvariable(m_activeCellIds[ac], PV->RHO) * m_volumeAcceleration[i] * a_cellVolume(m_activeCellIds[ac])
11274 * a_pvariable(m_activeCellIds[ac], PV->A);
11275 IF_CONSTEXPR(hasE<SysEqn>)
11276 a_rightHandSide(m_activeCellIds[ac], CV->A_RHO_E) -=
11277 a_pvariable(m_activeCellIds[ac], PV->VV[i]) * a_pvariable(m_activeCellIds[ac], PV->RHO)
11278 * m_volumeAcceleration[i] * a_cellVolume(m_activeCellIds[ac]) * a_pvariable(m_activeCellIds[ac], PV->A);
11284 static const MFloat Eo_factor = m_EEGas.Eo0 / (m_EEGas.liquidDensity - m_rhoInfinity);
11285 const MFloat F_D_factor = F3B4 * m_EEGas.liquidDensity / m_EEGas.bubbleDiameter;
11286 const MFloat F1Bdt = F1 / timeStep(
true);
11287 const MFloat F1BdtLiquid =
11290 * (m_EEGas.interpolationFactor > 0.0 ? m_EEGas.interpolationFactor * m_RKalpha[m_RKStep] : 1.0));
11291 const MFloat*
const RESTRICT cellVol = &a_cellVolume(0);
11293#pragma omp parallel for
11295 for(
MInt ac = 0; ac < m_noActiveCells; ac++) {
11296 const MInt cellId = m_activeCellIds[ac];
11297 if(a_isBndryGhostCell(cellId))
continue;
11298 MFloat F_D_factorCell = 0.0;
11300 if(m_EEGas.dragModel == 0) {
11301 const MFloat Eo = Eo_factor * (m_EEGas.liquidDensity - a_pvariable(cellId, PV->RHO));
11302 C_D = F2B3 * sqrt(Eo);
11303 F_D_factorCell = F_D_factor * C_D;
11304 }
else if(m_EEGas.dragModel == 1) {
11306 for(
MInt i = 0; i < nDim; i++) {
11307 uSlip =
mMax(uSlip, abs(a_uOtherPhase(cellId, i) - a_pvariable(cellId, PV->VV[i])));
11309 const MFloat nu_l = a_nuEffOtherPhase(cellId) - a_nuTOtherPhase(cellId);
11310 const MFloat l_bubbleDiameter = m_EEGas.bubbleDiameter;
11311 C_D = 24.0 * nu_l / (sysEqn().m_Re0 * uSlip * l_bubbleDiameter);
11312 F_D_factorCell = F_D_factor * C_D;
11313 }
else if(m_EEGas.dragModel == 2) {
11315 F_D_factorCell = F_D_factor * C_D;
11316 }
else if(m_EEGas.dragModel == 3) {
11317 F_D_factorCell = a_alphaGas(cellId) * 18.0 / sysEqn().m_Re0
11318 * (a_nuEffOtherPhase(cellId) - a_nuTOtherPhase(cellId)) * m_EEGas.liquidDensity
11319 /
mMin(10.0, 1 - a_alphaGas(cellId)) / m_EEGas.bubbleDiameter / m_EEGas.bubbleDiameter;
11324 for(
MInt i = 0; i < 3; i++) {
11325 u_d[i] = a_pvariable(cellId, PV->VV[i]) - a_uOtherPhase(cellId, i);
11329 const MFloat F_L_factorCell = m_EEGas.CL * a_alphaGas(cellId) * m_EEGas.liquidDensity;
11331 MFloat F1BOldrhoAlpha = F0;
11332 if(a_oldVariable(cellId, CV->A_RHO) > -m_EEGas.eps) {
11333 F1BOldrhoAlpha = F1 / max(m_EEGas.eps, a_oldVariable(cellId, CV->A_RHO));
11335 F1BOldrhoAlpha = F1 / a_oldVariable(cellId, CV->A_RHO);
11337 const MFloat F_VM_factorCell = 0.5 * a_alphaGas(cellId) * m_EEGas.liquidDensity;
11339 const MFloat Sc = m_EEGas.schmidtNumber;
11340 MFloat F_TD_factorCell = 0.0;
11341 if(m_EEGas.dragModel == 3) {
11342 F_TD_factorCell = -18.0 / sysEqn().m_Re0 / sysEqn().m_Re0 / Sc * m_EEGas.liquidDensity / m_EEGas.bubbleDiameter
11343 / m_EEGas.bubbleDiameter * a_nuEffOtherPhase(cellId)
11344 * (a_nuEffOtherPhase(cellId) - a_nuTOtherPhase(cellId)) /
mMin(10.0, 1 - a_alphaGas(cellId));
11346 F_TD_factorCell = -F1 / sysEqn().m_Re0 * F_D_factorCell / Sc * a_nuEffOtherPhase(cellId);
11349 const MInt dragModel = m_EEGas.dragModel;
11351 const MFloat C_D0 = F_D_factorCell * m_EEGas.RKSemiImplicitFactor;
11352 const MFloat dt = timeStep(
true) * m_RKalpha[m_RKStep];
11353 const MFloat C_VM0 = F_VM_factorCell / dt * m_EEGas.RKSemiImplicitFactor;
11355 for(
MInt i = 0; i < nDim; i++) {
11358 const MInt sign = (0.0 < (-u_d[i])) - ((-u_d[i]) < 0.0);
11359 if(dragModel == 3) {
11360 C_D1 = C_D0 * a_uOtherPhase(cellId, i);
11364 C_D0 * a_alphaGas(cellId) * sign * (
POW2(a_uOtherPhase(cellId, i)) -
POW2(a_pvariable(cellId, PV->VV[i])));
11365 C_D2 = 2.0 * C_D0 * a_alphaGas(cellId) * sign * u_d[i];
11367 const MFloat gradAlpha = a_slope(cellId, PV->A, i);
11368 const MFloat C_TD0 = -F1 / sysEqn().m_Re0 * C_D0 / Sc * a_nuEffOtherPhase(cellId) * gradAlpha;
11370 if(dragModel == 3) {
11374 C_TD1 = C_TD0 * a_uOtherPhase(cellId, i) * sign;
11375 C_TD2 = -C_TD0 * sign;
11377 const MFloat C_VM1 = C_VM0 * a_pvariable(cellId, PV->VV[i]);
11378 const MFloat C_VM2 = -C_VM0;
11379 a_implicitCoefficient(cellId, i * 2) = (C_D1 + C_TD1 + C_VM1) * cellVol[cellId];
11380 a_implicitCoefficient(cellId, i * 2 + 1) = (C_D2 + C_TD2 + C_VM2) * cellVol[cellId];
11383 if(m_EEGas.dragModel == 3) {
11384 F_D = F_D_factorCell * -u_d[i];
11386 F_D = F_D_factorCell * a_alphaGas(cellId) * -u_d[i] * abs(u_d[i]);
11391 const MFloat F_L = F_L_factorCell * liftV[i];
11396 m_EEGas.depthCorrection ? -a_alphaGas(cellId) * m_EEGas.liquidDensity * m_EEGas.gravity[i] : 0.0;
11400 MFloat duOtherPhaseDt = (a_uOtherPhase(cellId, i) - a_uOtherPhaseOld(cellId, i)) * F1BdtLiquid;
11402 if(m_RKStep == 0) {
11403 duDt = (a_pvariable(cellId, PV->VV[i]) - a_oldVariable(cellId, CV->A_RHO_VV[i]) * F1BOldrhoAlpha) * F1Bdt;
11405 duDt = (a_pvariable(cellId, PV->VV[i]) - a_oldVariable(cellId, CV->A_RHO_VV[i]) * F1BOldrhoAlpha) * F1Bdt
11406 / m_RKalpha[m_RKStep - 1];
11408 const MFloat F_VM_I = (F1BOldrhoAlpha > F1 / m_EEGas.eps * 0.999 || F1BOldrhoAlpha < -F1 / m_EEGas.eps * 0.999)
11410 : -F_VM_factorCell * duDt;
11411 const MFloat F_VM_E = F_VM_factorCell
11412 * ((duOtherPhaseDt + a_uOtherPhase(cellId, 0) * a_gradUOtherPhase(cellId, i, 0)
11413 + a_uOtherPhase(cellId, 1) * a_gradUOtherPhase(cellId, i, 1)
11414 + a_uOtherPhase(cellId, 2) * a_gradUOtherPhase(cellId, i, 2))
11415 - (a_pvariable(cellId, PV->VV[0]) * a_slope(cellId, PV->VV[i], 0)
11416 + a_pvariable(cellId, PV->VV[1]) * a_slope(cellId, PV->VV[i], 1)
11417 + a_pvariable(cellId, PV->VV[2]) * a_slope(cellId, PV->VV[i], 2)));
11422 if(m_EEGas.dragModel == 3) {
11423 F_TD = F_TD_factorCell * a_slope(cellId, PV->A, i);
11425 F_TD = F_TD_factorCell * abs(u_d[i]) * a_slope(cellId, PV->A, i);
11427 const MFloat explicitFF = 1.0 - m_EEGas.RKSemiImplicitFactor;
11429 a_rightHandSide(cellId, CV->A_RHO_VV[i]) -=
11430 (F_D * explicitFF + F_L + F_VM_I * explicitFF + F_VM_E + F_TD * (m_EEGas.dragModel == 3 ? 1.0 : explicitFF)
11432 * a_cellVolume(cellId);
11439template <MInt nDim_,
class SysEqn>
11443 const MInt noCells = a_noCells();
11445 MFloat factor, Psi, xi = F0, cbar,
a = F0, a1 = F0, a2 = F0,
b = F0, b2 = F0, b1 = F0, c1 = F0, FD, Rr,
11447 MFloat reactionEnthalpy;
11448 const MFloat gammaMinusOne = m_gamma - F1;
11449 const MFloat FgammaMinusOne = F1 / gammaMinusOne;
11451 MFloat FlaminarFlameThickness = F1 / m_laminarFlameThickness;
11453 MFloat rhoUFrhoB = m_burntUnburntTemperatureRatio;
11455 MFloat rhoJump = F1 / m_burntUnburntTemperatureRatio - F1;
11457 MFloat factor1 = m_c0 / (F1 - m_c0);
11458 MFloat echekkiFerzigerPrefactor = F1 / (F1 - m_c0) * (F1 / (F1 - m_c0) - F1);
11459 const MFloat sq1F2 = sqrt(F1B2);
11460 const MFloat eps = c_cellLengthAtLevel(maxRefinementLevel()) * 0.00000000001;
11465 m_maxReactionRate = F0;
11466 m_totalHeatReleaseRate = F0;
11468 reactionEnthalpy = (m_burntUnburntTemperatureRatio - F1) * FgammaMinusOne;
11470 if(m_RKStep == 0) {
11472 memcpy(&a_reactionRateBackup(0, 0), &a_reactionRate(0, 0),
sizeof(
MFloat) * noInternalCells());
11475 for(
MInt c = 0; c < noCells; c++) {
11476 a_reactionRate(c, 0) = F0;
11479 sigma = m_subfilterVariance * c_cellLengthAtLevel(maxLevel());
11480 factor = F1 / (sqrt(F2) * sigma);
11482 if(reactionEnthalpy < m_rhoEInfinity * 0.00001) {
11485 switch(m_initialCondition) {
11493 MFloat diffTimeStep = 50000;
11494 if(m_temperatureChange && (
globalTimeStep - m_restartTimeStep) <= diffTimeStep) {
11495 MFloat diffTemp = (m_burntUnburntTemperatureRatioEnd - m_burntUnburntTemperatureRatioStart);
11496 m_burntUnburntTemperatureRatio =
11497 (diffTemp / diffTimeStep) * (
globalTimeStep - m_restartTimeStep) + m_burntUnburntTemperatureRatioStart;
11501 rhoJump = F1 - m_burntUnburntTemperatureRatio;
11502 for(
MInt c = 0; c < m_bndryGhostCellsOffset; c++) {
11503 if(grid().tree().hasProperty(c, Cell::IsHalo)) {
11506 if(!a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) {
11516 if(a_levelSetFunction(c, 0) < -999998) {
11524 FD = F1 / m_DthInfinity;
11530 Rr = echekkiFerzigerPrefactor *
POW2(a_flameSpeed(gc, 0) * (F1 - a_curvatureG(gc, 0) * m_marksteinLength)) * FD;
11533 if(m_heatReleaseDamp) {
11534 if(c_coordinate(gc, 1) < (0.0234 + m_dampingDistanceFlameBase)) {
11535 if(c_coordinate(gc, 1) > 0.0234) {
11536 Rr *= 1. / m_dampingDistanceFlameBase * (c_coordinate(gc, 1) - 0.0234);
11539 if(c_coordinate(gc, 1) < 0.0234) {
11545 xi = a_levelSetFunction(gc, 0) * factor;
11548 a = xi - sq1F2 * factor1 * sigma * FlaminarFlameThickness;
11549 a1 = F1B2 * (
POW2(sigma * factor1 * FlaminarFlameThickness))
11550 - SQRT2 * xi * sigma * factor1 * FlaminarFlameThickness;
11552 a2 = (F1 - m_c0) * exp(a1) * F1B2 * (-erfc(
a) + F2);
11554 a2 = (F1 - m_c0) * exp(a1) * F1B2 * (erf(
a) + F1);
11556 b = xi + sq1F2 * sigma * FlaminarFlameThickness;
11557 b1 = F1B2 *
POW2(sigma * FlaminarFlameThickness) + SQRT2 * xi * sigma * FlaminarFlameThickness;
11559 b2 = m_c0 * exp(b1) * F1B2 * (-erfc(
b));
11561 b2 = m_c0 * exp(b1) * F1B2 * (erf(
b) - F1);
11563 c1 = F1B2 * (erf(xi) - F1);
11564 cbar = F1 - (a2 + b2 - c1);
11567 if(
ABS(F1 - cbar) < eps) {
11570 Psi = a2 / ((F1 - cbar) *
POW2((rhoUFrhoB + cbar * rhoJump)));
11577 const MFloat rhoBar = m_rhoUnburnt / (1 - a_pvariable(c, PV->C) * rhoJump);
11580 a_reactionRate(c, 0) = sysEqn().m_Re0 * rhoBar * rhoUFrhoB * Rr * (F1 - a_pvariable(c, PV->C)) * Psi;
11584 if(!(a_reactionRate(c, 0) >= F0) && !(a_reactionRate(c, 0) <= F0)) {
11586 cerr <<
"reaction rate is nan!!!" << endl;
11591 a_rightHandSide(c, CV->RHO_C) -= a_reactionRate(c, 0) * a_cellVolume(c);
11592 a_rightHandSide(c, CV->RHO_E) -= a_reactionRate(c, 0) * a_cellVolume(c) * reactionEnthalpy;
11595 if(!a_hasProperty(c, Cell::IsHalo)) {
11596 m_maxReactionRate =
mMax(a_reactionRate(c, 0), m_maxReactionRate);
11597 m_totalHeatReleaseRate += a_reactionRate(c, 0) * a_cellVolume(c) * reactionEnthalpy;
11600 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"diverged");
11601 if(diverged == 1) {
11602 cerr <<
"Solution diverged (computeSourceTerms)" << endl;
11603 MString errorMessage =
"reaction rate is nan";
11604 mTerm(1, AT_, errorMessage);
11611 MFloat diffTimeStep = 50000;
11612 if(m_temperatureChange && (
globalTimeStep - m_restartTimeStep) <= diffTimeStep) {
11613 MFloat diffTemp = (m_burntUnburntTemperatureRatioEnd - m_burntUnburntTemperatureRatioStart);
11614 m_burntUnburntTemperatureRatio =
11615 (diffTemp / diffTimeStep) * (
globalTimeStep - m_restartTimeStep) + m_burntUnburntTemperatureRatioStart;
11619 rhoJump = F1 - m_burntUnburntTemperatureRatio;
11620 for(
MInt c = 0; c < m_bndryGhostCellsOffset; c++) {
11621 if(grid().tree().hasProperty(c, Cell::IsHalo)) {
11624 if(!a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) {
11637 if(a_levelSetFunction(gc, 0) < -99998) {
11645 FD = F1 / m_DthInfinity;
11650 Rr = echekkiFerzigerPrefactor *
POW2(a_flameSpeed(gc, 0) * (F1 - a_curvatureG(gc, 0) * m_marksteinLength)) * FD;
11653 if(m_heatReleaseDamp) {
11654 if(c_coordinate(gc, 1) < (m_yOffsetFlameTube + m_dampingDistanceFlameBase)) {
11655 if(c_coordinate(gc, 1) > m_yOffsetFlameTube) {
11656 Rr *= 1. / m_dampingDistanceFlameBase * (c_coordinate(gc, 1) - m_yOffsetFlameTube);
11659 if(c_coordinate(gc, 1) < m_yOffsetFlameTube) {
11664 xi = a_levelSetFunction(gc, 0) * factor;
11667 a = xi - sq1F2 * factor1 * sigma * FlaminarFlameThickness;
11668 a1 = F1B2 * (
POW2(sigma * factor1 * FlaminarFlameThickness))
11669 - SQRT2 * xi * sigma * factor1 * FlaminarFlameThickness;
11671 a2 = (F1 - m_c0) * exp(a1) * F1B2 * (-erfc(
a) + F2);
11673 a2 = (F1 - m_c0) * exp(a1) * F1B2 * (erf(
a) + F1);
11675 b = xi + sq1F2 * sigma * FlaminarFlameThickness;
11676 b1 = F1B2 *
POW2(sigma * FlaminarFlameThickness) + SQRT2 * xi * sigma * FlaminarFlameThickness;
11678 b2 = m_c0 * exp(b1) * F1B2 * (-erfc(
b));
11680 b2 = m_c0 * exp(b1) * F1B2 * (erf(
b) - F1);
11682 c1 = F1B2 * (erf(xi) - F1);
11683 cbar = F1 - (a2 + b2 - c1);
11686 if(
ABS(F1 - cbar) < eps) {
11689 Psi = a2 / ((F1 - cbar) *
POW2((rhoUFrhoB + cbar * rhoJump)));
11696 const MFloat rhoBar = m_rhoUnburnt / (1 - a_pvariable(c, PV->C) * rhoJump);
11699 a_reactionRate(c, 0) = sysEqn().m_Re0 * rhoBar * rhoUFrhoB * Rr * (F1 - a_pvariable(c, PV->C)) * Psi;
11703 if(!(a_reactionRate(c, 0) >= F0) && !(a_reactionRate(c, 0) <= F0)) {
11709 a_rightHandSide(c, CV->RHO_C) -= a_reactionRate(c, 0) * a_cellVolume(c);
11710 a_rightHandSide(c, CV->RHO_E) -= a_reactionRate(c, 0) * a_cellVolume(c) * reactionEnthalpy;
11713 if(!a_hasProperty(c, Cell::IsHalo)) {
11714 m_maxReactionRate =
mMax(a_reactionRate(c, 0), m_maxReactionRate);
11715 m_totalHeatReleaseRate += a_reactionRate(c, 0) * a_cellVolume(c) * reactionEnthalpy;
11718 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"diverged");
11719 if(diverged == 1) {
11721 MString errorMessage =
"reaction rate is nan";
11722 mTerm(1, AT_, errorMessage);
11730 cerr <<
"dont use the default in computeSourceTerms (FV) !!!" << endl;
11734 if(noDomains() > 1) {
11735 MPI_Allreduce(MPI_IN_PLACE, &m_totalHeatReleaseRate, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
11736 "m_totalHeatReleaseRate");
11737 MPI_Allreduce(MPI_IN_PLACE, &m_maxReactionRate, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
11738 "m_maxReactionRate");
11742template <MInt nDim_,
class SysEqn>
11746 const MFloat kappa = 0.4;
11749 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
11750 const MInt bndrySrfcId = m_wmSurfaces[wmSrfcId].m_bndrySrfcId;
11751 const MInt cellId = m_bndryCells->a[bndryCellId].m_cellId;
11753 if(!m_wmSurfaces[wmSrfcId].m_wmHasImgCell) {
11760 MFloat nx = m_bndryCells->a[bndryCellId].m_srfcs[bndrySrfcId]->m_normalVector[0];
11761 MFloat ny = m_bndryCells->a[bndryCellId].m_srfcs[bndrySrfcId]->m_normalVector[1];
11765 MFloat u_II_bndry = 0.0;
11766 MFloat dn_img = m_wmDistance;
11768 u_img = m_wmSurfaces[wmSrfcId].m_wmImgVars[PV->VV[0]];
11769 v_img = m_wmSurfaces[wmSrfcId].m_wmImgVars[PV->VV[1]];
11772 if(abs(ny) < m_eps)
return F0;
11775 u_II_bndry =
maia::math::sgn(ny) * (a_pvariable(cellId, PV->U) * ny - a_pvariable(cellId, PV->V) * nx);
11777 if(u_II > 0.0 && u_II_bndry > 0.0) {
11778 const MInt ghostCellId = m_bndryCells->a[bndryCellId].m_srfcVariables[bndrySrfcId]->m_ghostCellId;
11779 const MFloat rho_surf = F1B2 * (a_pvariable(cellId, PV->RHO) + a_pvariable(ghostCellId, PV->RHO));
11780 const MFloat p_surf = F1B2 * (a_pvariable(cellId, PV->P) + a_pvariable(ghostCellId, PV->P));
11781 const MFloat T_surf = sysEqn().temperature_ES(rho_surf, p_surf);
11782 const MFloat mue = SUTHERLANDLAW(T_surf);
11784 const MFloat Re0 = sysEqn().m_Re0;
11787 MFloat u_tau = m_wmSurfaces[wmSrfcId].m_wmUTAU;
11789 if(m_wmTimeFilter) {
11791 const MFloat theta = 1.0;
11792 const MFloat twall = theta * m_wmDistance / (kappa * u_tau);
11793 const MFloat E = m_timeStep / twall;
11794 const MFloat u_II_last = m_wmSurfaces[wmSrfcId].m_wmUII;
11797 u_II = E * u_II + (F1 - E) * u_II_last;
11801 m_wmSurfaces[wmSrfcId].m_wmUII = u_II;
11805 const MFloat b = sysEqn().vanDriest(m_Ma);
11806 u_II = m_UInfinity /
b * asin(
b * u_II / m_UInfinity);
11811 while(res > 1e-6) {
11812 MFloat eKB = exp(-kappa * B);
11813 MFloat spalding = u_II / u_tau
11815 * (exp(kappa * u_II / u_tau) - 1 - (kappa * u_II / u_tau)
11816 - 1.0 / 2.0 * pow(kappa * u_II / u_tau, 2) - 1.0 / 6.0 * pow(kappa * u_II / u_tau, 3))
11817 - abs(dn_img) * u_tau * (rho_surf / mue) * Re0;
11819 -u_II / pow(u_tau, 2)
11821 * ((-kappa * u_II / pow(u_tau, 2)) * exp(kappa * u_II / u_tau) + (kappa * u_II / u_tau) / u_tau
11822 + pow(kappa * u_II / u_tau, 2) / u_tau + 1.0 / 2.0 * pow(kappa * u_II / u_tau, 3) / u_tau)
11823 - abs(dn_img) * (rho_surf / mue) * Re0;
11825 MFloat delta = -spalding / d_spalding;
11828 res = abs(delta / u_tau);
11833 m_wmSurfaces[wmSrfcId].m_wmUTAU = u_tau;
11835 if(std::isnan(u_tau)) {
11836 cout <<
"WARNING: Wall model u_tau is NaN!" << endl;
11840 tau_wm = rho_surf * pow(u_tau, 2);
11842 MFloat dudn = m_bndryCells->a[bndryCellId].m_srfcVariables[bndrySrfcId]->m_normalDeriv[PV->VV[0]];
11843 MFloat dvdn = m_bndryCells->a[bndryCellId].m_srfcVariables[bndrySrfcId]->m_normalDeriv[PV->VV[1]];
11845 MFloat tau_w = mue * grad / Re0;
11847 if(tau_w / tau_wm > m_eps) mue_wm = ((tau_wm / tau_w) - 1.0) * mue;
11848 if(mue_wm > 50.0 * mue) mue_wm = 50.0 * mue;
11851 m_wmSurfaces[wmSrfcId].m_wmTauW = tau_wm;
11852 m_wmSurfaces[wmSrfcId].m_wmMUEWM = mue_wm;
11858template <MInt nDim_,
class SysEqn>
11862 const MFloat kappa = 0.4;
11865 MInt bndryCellId = a_bndryId(cellId);
11866 if(!m_bndryCells->a[bndryCellId].m_wmBCVars->m_wmHasImgCell)
return F0;
11871 MFloat* normalVec = m_bndryCells->a[bndryCellId].m_srfcs[0]->m_normalVector;
11872 MFloat* imgVar = m_bndryCells->a[bndryCellId].m_wmBCVars->m_wmImgVars;
11873 MFloat* normalDeriv = m_bndryCells->a[bndryCellId].m_srfcVariables[0]->m_normalDeriv;
11875 MFloat vvII[3] = {0.0, 0.0, 0.0};
11876 MFloat vvn[3] = {0.0, 0.0, 0.0};
11877 MFloat dvvII_dn[3] = {0.0, 0.0, 0.0};
11878 MFloat dvvn_dn[3] = {0.0, 0.0, 0.0};
11885 MFloat dn_img = m_wmDistance;
11888 for(
MInt d = 0; d < nDim; d++) {
11889 Vn += imgVar[PV->VV[d]] * normalVec[d];
11890 dVn_dn += normalDeriv[PV->VV[d]] * normalVec[d];
11893 for(
MInt d = 0; d < nDim; d++) {
11894 vvn[d] = Vn * normalVec[d];
11895 vvII[d] = imgVar[PV->VV[d]] - vvn[d];
11897 dvvn_dn[d] = dVn_dn * normalVec[d];
11898 dvvII_dn[d] = normalDeriv[PV->VV[d]] - dvvn_dn[d];
11901 for(
MInt d = 0; d < nDim; d++) {
11902 VII +=
POW2(vvII[d]);
11903 dVII_dn +=
POW2(dvvII_dn[d]);
11907 dVII_dn = sqrt(dVII_dn);
11910 if(F1 - abs(normalVec[0]) < m_eps)
return F0;
11913 if(vvII[0] > 0.0 && dvvII_dn[0] > 0.0) {
11914 const MInt ghostCellId = m_bndryCells->a[bndryCellId].m_srfcVariables[0]->m_ghostCellId;
11915 const MFloat rho_surf = F1B2 * (a_pvariable(cellId, PV->RHO) + a_pvariable(ghostCellId, PV->RHO));
11916 const MFloat p_surf = F1B2 * (a_pvariable(cellId, PV->P) + a_pvariable(ghostCellId, PV->P));
11917 const MFloat T_surf = sysEqn().temperature_ES(rho_surf, p_surf);
11918 const MFloat mue = SUTHERLANDLAW(T_surf);
11920 const MFloat Re0 = sysEqn().m_Re0;
11924 const MFloat b = sysEqn().vanDriest(m_Ma);
11925 VII = m_UInfinity /
b * asin(
b * VII / m_UInfinity);
11929 MFloat u_tau = m_bndryCells->a[bndryCellId].m_wmBCVars->m_wmUTAU;
11932 while(res > 1e-6) {
11933 MFloat eKB = exp(-kappa * B);
11934 MFloat spalding = VII / u_tau
11936 * (exp(kappa * VII / u_tau) - 1 - (kappa * VII / u_tau)
11937 - 1.0 / 2.0 * pow(kappa * VII / u_tau, 2) - 1.0 / 6.0 * pow(kappa * VII / u_tau, 3))
11938 - abs(dn_img) * u_tau * (rho_surf / mue) * Re0;
11940 -VII / pow(u_tau, 2)
11942 * ((-kappa * VII / pow(u_tau, 2)) * exp(kappa * VII / u_tau) + (kappa * VII / u_tau) / u_tau
11943 + pow(kappa * VII / u_tau, 2) / u_tau + 1.0 / 2.0 * pow(kappa * VII / u_tau, 3) / u_tau)
11944 - abs(dn_img) * (rho_surf / mue) * Re0;
11945 MFloat delta = -spalding / d_spalding;
11947 res = abs(delta / u_tau);
11951 tau_wm = rho_surf * pow(u_tau, 2);
11953 m_bndryCells->a[bndryCellId].m_wmBCVars->m_wmUTAU = u_tau;
11955 MFloat tau_w = mue * dVII_dn / Re0;
11957 if(tau_w / tau_wm > m_eps) mue_wm = ((tau_wm / tau_w) - 1.0) * mue;
11958 if(mue_wm > 50.0 * mue) mue_wm = 50.0 * mue;
11962 m_bndryCells->a[bndryCellId].m_wmBCVars->m_wmUII = VII;
11963 m_bndryCells->a[bndryCellId].m_wmBCVars->m_wmTauW = tau_wm;
11964 m_bndryCells->a[bndryCellId].m_wmBCVars->m_wmMUEWM = mue_wm;
11970template <MInt nDim_,
class SysEqn>
11974 m_wmLES = Context::getSolverProperty<MBool>(
"wmLES", m_solverId, AT_, &m_wmLES);
11977 m_log << endl <<
"Reading WM properties ... " << endl;
11980 m_wmUseInterpolation =
11981 Context::getSolverProperty<MBool>(
"wmUseInterpolation", m_solverId, AT_, &m_wmUseInterpolation);
11983 m_wmUseInterpolation =
true;
11987 m_wmDistance = Context::getSolverProperty<MFloat>(
"wmDistance", m_solverId, AT_, &m_wmDistance);
11989 m_wmDistance = 2.0 * c_cellLengthAtLevel(maxLevel());
11993 m_wmOutput = Context::getSolverProperty<MBool>(
"wmOutput", m_solverId, AT_, &m_wmOutput);
11995 m_wmOutput =
false;
11999 m_wmSurfaceProbeInterval =
12000 Context::getSolverProperty<MInt>(
"wmSurfaceProbeInterval", m_solverId, AT_, &m_wmSurfaceProbeInterval);
12002 m_wmSurfaceProbeInterval = 0;
12006 m_wmTimeFilter = Context::getSolverProperty<MBool>(
"wmTimeFilter", m_solverId, AT_, &m_wmTimeFilter);
12008 m_wmTimeFilter =
false;
12011 m_log <<
"wmDistance = " << m_wmDistance << endl;
12012 m_log <<
"wmUseInterpolation = " << m_wmUseInterpolation << endl;
12013 m_log <<
"wmOutput = " << m_wmOutput << endl;
12014 m_log <<
"wmSurfaceProbeInterval = " << m_wmSurfaceProbeInterval << endl;
12019template <MInt nDim_,
class SysEqn>
12023 const MInt noPVars = PV->noVariables;
12029 MInt sendBufSize = 0;
12030 MInt sendOffset = 0;
12032 for(
MInt dom = 0; dom < m_wmNoDomains; dom++) {
12033 sendBufSize = m_noWMImgPointsSend[dom] * noPVars;
12034 MPI_Issend(&m_wmImgSendBuffer[sendOffset], sendBufSize, MPI_DOUBLE, dom, 0, m_comm_wm, &m_mpi_wmSendReq[dom], AT_,
12035 "m_wmImgSendBuffer[sendOffset]");
12036 sendOffset += sendBufSize;
12040 MInt recvOffset = 0;
12041 MInt recvBufSize = 0;
12043 for(
MInt dom = 0; dom < m_wmNoDomains; dom++) {
12044 recvBufSize = m_noWMImgPointsRecv[dom] * noPVars;
12045 MPI_Irecv(&m_wmImgRecvBuffer[recvOffset], recvBufSize, MPI_DOUBLE, dom, 0, m_comm_wm, &m_mpi_wmRecvReq[dom], AT_,
12046 "m_wmImgRecvBuffer[recvOffset]");
12047 recvOffset += recvBufSize;
12049 MPI_Waitall(m_wmNoDomains, &m_mpi_wmSendReq[0], MPI_STATUSES_IGNORE, AT_);
12050 MPI_Waitall(m_wmNoDomains, &m_mpi_wmRecvReq[0], MPI_STATUSES_IGNORE, AT_);
12057template <MInt nDim_,
class SysEqn>
12060 const MInt noPVars = PV->noVariables;
12061 MInt sendBufferCounter = 0;
12063 if(m_wmUseInterpolation) {
12065 for(
MInt dom = 0; dom < m_wmNoDomains; dom++) {
12067#pragma omp parallel for
12069 for(
MInt ip = 0; ip < m_noWMImgPointsSend[dom]; ip++) {
12070 const MInt imgCellId = m_wmImgCellIds[dom][ip];
12071 const MFloat* imgCoords = &m_wmImgCoords[dom][nDim * ip];
12072 getInterpolatedVariablesInCell(imgCellId, &imgCoords[0], &interpolatedVars[0]);
12073 for(
MInt v = 0; v < noPVars; v++) {
12074 m_wmImgSendBuffer[sendBufferCounter + (ip * noPVars) + v] = interpolatedVars[v];
12078 sendBufferCounter += m_noWMImgPointsSend[dom] * noPVars;
12081 for(
MInt dom = 0; dom < m_wmNoDomains; dom++) {
12082 for(
MInt ip = 0; ip < m_noWMImgPointsSend[dom]; ip++) {
12083 const MInt imgCellId = m_wmImgCellIds[dom][ip];
12084 for(
MInt v = 0; v < noPVars; v++) {
12085 m_wmImgSendBuffer[sendBufferCounter + (ip * noPVars) + v] = a_pvariable(imgCellId, v);
12089 sendBufferCounter += m_noWMImgPointsSend[dom] * noPVars;
12095template <MInt nDim_,
class SysEqn>
12098 const MInt noPVars = PV->noVariables;
12102 for(
MInt dom = 0; dom < noDomains(); dom++) {
12103 bufSize = m_noWMImgPointsSend[dom] * noPVars;
12104 MPI_Issend(&m_wmImgSendBuffer[offset], bufSize, MPI_DOUBLE, dom, 0, mpiComm(), &m_mpi_wmRequest[dom], AT_,
12105 "m_wmImgSendBuffer[offset]");
12110template <MInt nDim_,
class SysEqn>
12113 const MInt noPVars = PV->noVariables;
12119 for(
MInt dom = 0; dom < noDomains(); dom++) {
12120 bufSize = m_noWMImgPointsRecv[dom] * noPVars;
12121 MPI_Recv(&m_wmImgRecvBuffer[offset], bufSize, MPI_DOUBLE, dom, 0, mpiComm(), &status, AT_,
12122 "m_wmImgRecvBuffer[offset]");
12125 for(
MInt dom = 0; dom < noDomains(); dom++) {
12126 MPI_Wait(&m_mpi_wmRequest[dom], &status, AT_);
12130template <MInt nDim_,
class SysEqn>
12134 if(PV->noVariables > 5)
mTerm(1, AT_,
"WMLES not implemented for noPVars > 5");
12136 const MInt noPVars =
mMin(PV->noVariables, 5);
12137 MInt ipCounter = 0;
12139 for(
MInt dom = 0; dom < m_wmNoDomains; dom++) {
12141#pragma omp parallel for
12143 for(
MInt ip = 0; ip < m_noWMImgPointsRecv[dom]; ip++) {
12144 const MInt wmSrfcId = m_wmImgRecvIdMap[ipCounter + ip];
12145 for(
MInt v = 0; v < noPVars; v++) {
12146 m_wmSurfaces[wmSrfcId].m_wmImgVars[v] = m_wmImgRecvBuffer[noPVars * (ipCounter + ip) + v];
12151 ipCounter += m_noWMImgPointsRecv[dom];
12155template <MInt nDim_,
class SysEqn>
12168 m_wmImgCellIds.clear();
12169 m_wmImgWMSrfcIds.clear();
12170 m_wmImgCoords.clear();
12172 const MInt noPVars = PV->noVariables;
12173 const MInt noWMSurfaces = m_wmSurfaces.size();
12175 std::vector<MFloat> localWMImgCoords;
12176 std::vector<MInt> localWMImgPointRootIds;
12177 std::vector<MInt> localWMSrfcIds;
12179 for(
MInt wmSrfcId = 0; wmSrfcId < noWMSurfaces; wmSrfcId++) {
12180 MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
12181 MInt bndrySrfcId = m_wmSurfaces[wmSrfcId].m_bndrySrfcId;
12183 for(
MInt dim = 0; dim < nDim; dim++) {
12185 imgCoord += m_bndryCells->a[bndryCellId].m_srfcs[bndrySrfcId]->m_coordinates[dim];
12186 imgCoord += m_wmDistance * m_bndryCells->a[bndryCellId].m_srfcs[bndrySrfcId]->m_normalVector[dim];
12187 localWMImgCoords.push_back(imgCoord);
12189 localWMImgPointRootIds.push_back(domainId());
12190 localWMSrfcIds.push_back(wmSrfcId);
12194 localNoWMImgPoints.
fill(0);
12196 localNoWMImgCoords.
fill(0);
12198 localNoWMImgPoints[domainId()] = localWMImgPointRootIds.
size();
12200 MPI_Allgather(&localNoWMImgPoints[domainId()], 1, MPI_INT, &localNoWMImgPoints[0], 1, MPI_INT, mpiComm(), AT_,
12201 "localNoWMImgPoints",
"localNoWMImgPoints");
12203 for(
MInt dom = 0; dom < noDomains(); dom++) {
12204 localNoWMImgCoords[dom] = localNoWMImgPoints[dom] * nDim;
12208 MInt globalNoWMImgPoints = 0;
12209 for(
MInt dom = 0; dom < noDomains(); dom++) {
12210 globalNoWMImgPoints += localNoWMImgPoints[dom];
12213 if(!(globalNoWMImgPoints > 0)) {
12214 mTerm(-1,
"No WM Image Points were found within the entire geometry! Please check if you have assigned any WM-BC "
12215 "in the geometry file");
12218 std::vector<std::vector<MInt>> wmImgCellIds;
12219 std::vector<std::vector<MInt>> wmImgWMSrfcIds;
12220 std::vector<std::vector<MFloat>> wmImgCoords;
12222 wmImgCellIds.resize(noDomains());
12223 wmImgWMSrfcIds.resize(noDomains());
12224 wmImgCoords.resize(noDomains());
12227 noWMImgPointsSend.
fill(0);
12229 noWMImgPointsRecv.
fill(0);
12232 MInt totalNoWMImgPointsSend = 0;
12233 MInt outsideImagePoints = 0;
12234 for(
MInt dom = 0; dom < noDomains(); dom++) {
12235 if(localNoWMImgPoints[dom] == 0)
continue;
12239 ScratchSpace<MInt> domWMImgPointRootIds(localNoWMImgPoints[dom], AT_,
"domWMImgPointRootIds");
12242 if(domainId() == dom) {
12244 for(
MInt ip = 0; ip < localNoWMImgPoints[dom]; ip++) {
12245 for(
MInt dim = 0; dim < nDim; dim++) {
12246 domWMImgCoords[nDim * ip + dim] = localWMImgCoords[nDim * ip + dim];
12248 domWMImgPointRootIds[ip] = localWMImgPointRootIds[ip];
12249 domWMSrfcIds[ip] = localWMSrfcIds[ip];
12253 domWMImgCoords.
fill(-9999.9999);
12254 domWMImgPointRootIds.
fill(-1);
12255 domWMSrfcIds.
fill(-1);
12259 MPI_Bcast(&domWMImgCoords[0], localNoWMImgCoords[dom], MPI_DOUBLE, dom, mpiComm(), AT_,
"domWMImgCoords[0]");
12260 MPI_Bcast(&domWMImgPointRootIds[0], localNoWMImgPoints[dom], MPI_INT, dom, mpiComm(), AT_,
12261 "domWMImgPointRootIds[0]");
12262 MPI_Bcast(&domWMSrfcIds[0], localNoWMImgPoints[dom], MPI_INT, dom, mpiComm(), AT_,
"domWMSrfcIds[0]");
12265 for(
MInt ip = 0; ip < localNoWMImgPoints[dom]; ip++) {
12268 for(
MInt dim = 0; dim < nDim; dim++) {
12269 imgCoords[dim] = domWMImgCoords[nDim * ip + dim];
12271 dummyId = grid().findContainingLeafCell(imgCoords);
12273 wmImgCellIds[dom].push_back(dummyId);
12274 wmImgWMSrfcIds[dom].push_back(domWMSrfcIds[ip]);
12275 for(
MInt dim = 0; dim < nDim; dim++) {
12276 wmImgCoords[dom].push_back(imgCoords[dim]);
12278 if(m_wmUseInterpolation) initInterpolationForCell(dummyId);
12279 a_isWMImgCell(dummyId) =
true;
12280 noWMImgPointsSend[dom]++;
12281 totalNoWMImgPointsSend++;
12282 if(dom != domainId()) outsideImagePoints++;
12287 MPI_Gather(&noWMImgPointsSend[dom], 1, MPI_INT, &noWMImgPointsRecv[0], 1, MPI_INT, dom, mpiComm(), AT_,
12288 "&noWMImgPointsSend[dom]",
"noWMImgPointsRecv[0]");
12291 MPI_Allreduce(MPI_IN_PLACE, &outsideImagePoints, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
12292 "outsideImagePoints");
12294 m_log <<
"initWMExchange() found " << outsideImagePoints <<
" non-local image points!";
12296 MInt totalNoWMImgPointsRecv = 0;
12297 for(
MInt dom = 0; dom < noDomains(); dom++) {
12298 totalNoWMImgPointsRecv += noWMImgPointsRecv[dom];
12303 if(totalNoWMImgPointsRecv > 0 || totalNoWMImgPointsSend > 0) {
12305 MPI_Comm_rank(m_comm_wm, &m_wmDomainId);
12306 MPI_Comm_size(m_comm_wm, &m_wmNoDomains);
12308 MPI_Comm_split(mpiComm(), MPI_UNDEFINED, 0, &m_comm_wm, AT_,
"m_comm_wm");
12314 if(m_wmDomainId < 0)
return;
12322 MInt domId = domainId();
12323 MPI_Allgather(&domId, 1, MPI_INT, &wmIdToWorldId[0], 1, MPI_INT, m_comm_wm, AT_,
"domId",
"wmIdToWorldId");
12325 if(totalNoWMImgPointsSend > 0) {
12326 mAlloc(m_wmImgSendBuffer, noPVars * totalNoWMImgPointsSend,
"m_wmImgSendBuffer", 0.0, AT_);
12329 if(totalNoWMImgPointsRecv > 0) {
12330 mAlloc(m_wmImgRecvBuffer, noPVars * totalNoWMImgPointsRecv,
"m_wmImgPointsRecvBuffer", 0.0, AT_);
12331 mAlloc(m_wmImgRecvIdMap, totalNoWMImgPointsRecv,
"m_wmImgRecvIdMap", -1, AT_);
12334 m_wmImgCellIds.resize(m_wmNoDomains);
12335 m_wmImgWMSrfcIds.resize(m_wmNoDomains);
12336 m_wmImgCoords.resize(m_wmNoDomains);
12338 mAlloc(m_noWMImgPointsSend, m_wmNoDomains,
"m_noWMImgPointsSend", 0, AT_);
12339 mAlloc(m_noWMImgPointsRecv, m_wmNoDomains,
"m_noWMImgPointsRecv", 0, AT_);
12340 mAlloc(m_mpi_wmRequest, m_wmNoDomains,
"m_mpi_wmRequest", AT_);
12341 mAlloc(m_mpi_wmSendReq, m_wmNoDomains,
"m_mpi_wmSendReq", AT_);
12342 mAlloc(m_mpi_wmRecvReq, m_wmNoDomains,
"m_mpi_wmRecvReq", AT_);
12345 for(
MInt wmDom = 0; wmDom < m_wmNoDomains; wmDom++) {
12346 const MInt dom = wmIdToWorldId[wmDom];
12347 m_noWMImgPointsSend[wmDom] = noWMImgPointsSend[dom];
12348 m_noWMImgPointsRecv[wmDom] = noWMImgPointsRecv[dom];
12349 for(
MInt ip = 0; ip < noWMImgPointsSend[dom]; ip++) {
12350 m_wmImgCellIds[wmDom].push_back(wmImgCellIds[dom][ip]);
12351 m_wmImgWMSrfcIds[wmDom].push_back(wmImgWMSrfcIds[dom][ip]);
12352 for(
MInt dim = 0; dim < nDim; dim++) {
12353 m_wmImgCoords[wmDom].push_back(wmImgCoords[dom][nDim * ip + dim]);
12359 for(
MInt wmDom = 0; wmDom < m_wmNoDomains; wmDom++) {
12360 MPI_Issend(&m_wmImgWMSrfcIds[wmDom][0], m_noWMImgPointsSend[wmDom], MPI_INT, wmDom, 0, m_comm_wm,
12361 &m_mpi_wmRequest[wmDom], AT_,
"&m_wmImgSrfcIds[wmDom][0]");
12366 for(
MInt wmDom = 0; wmDom < m_wmNoDomains; wmDom++) {
12367 MPI_Recv(&m_wmImgRecvIdMap[offset], m_noWMImgPointsRecv[wmDom], MPI_INT, wmDom, 0, m_comm_wm, &status, AT_,
12368 "&m_wmImgRecvIdMap[offset]");
12369 offset += m_noWMImgPointsRecv[wmDom];
12372 for(
MInt wmDom = 0; wmDom < m_wmNoDomains; wmDom++) {
12373 MPI_Wait(&m_mpi_wmRequest[wmDom], &status, AT_);
12378 MInt ipCounter = 0;
12379 for(
MInt dom = 0; dom < m_wmNoDomains; dom++) {
12381#pragma omp parallel for
12383 for(
MInt ip = 0; ip < m_noWMImgPointsRecv[dom]; ip++) {
12384 const MInt wmSrfcId = m_wmImgRecvIdMap[ipCounter + ip];
12385 m_wmSurfaces[wmSrfcId].m_wmHasImgCell =
true;
12387 ipCounter += m_noWMImgPointsRecv[dom];
12389 m_log <<
"ok." << endl;
12394template <MInt nDim_,
class SysEqn>
12404 mTerm(1,
"no of coordinates for WM Surface probes must be equal for X and Z");
12406 for(
MInt p = 0; p < noSurfaceProbes; p++) {
12407 MFloat probeCoord[3] = {0.0, 0.0, 0.0};
12408 probeCoord[0] = Context::getSolverProperty<MFloat>(
"wmSurfaceProbesX", m_solverId, AT_, &probeCoord[0], p);
12409 probeCoord[2] = Context::getSolverProperty<MFloat>(
"wmSurfaceProbesZ", m_solverId, AT_, &probeCoord[2], p);
12411 for(
MInt bCellId = 0; bCellId < m_bndryCells->size(); bCellId++) {
12412 MInt cellId = m_bndryCells->a[bCellId].m_cellId;
12413 MFloat cellCoord[3] = {0.0, 0.0, 0.0};
12414 for(
MInt dim = 0; dim < nDim; dim++) {
12415 cellCoord[dim] = a_coordinate(cellId, dim);
12417 if(abs(cellCoord[0] - probeCoord[0]) < F1B2 * c_cellLengthAtLevel(maxRefinementLevel()) + m_eps
12418 && abs(cellCoord[2] - probeCoord[2]) < F1B2 * c_cellLengthAtLevel(maxRefinementLevel()) + m_eps) {
12419 if(!a_isHalo(cellId)) {
12420 for(
MInt srfc = 0; srfc < m_bndryCells->a[bCellId].m_noSrfcs; srfc++) {
12421 if(m_bndryCells->a[bCellId].m_srfcs[srfc]->m_bndryCndId == 3399) {
12422 m_wmSurfaceProbeIds.push_back(cellId);
12423 m_wmSurfaceProbeSrfcs.push_back(srfc);
12432 mAlloc(m_wmLocalNoSrfcProbeIds, noDomains(),
"m_wmLocalNoSrfcProbeIds", 0, AT_);
12433 m_wmLocalNoSrfcProbeIds[domainId()] = m_wmSurfaceProbeIds.size();
12434 MPI_Allgather(&m_wmLocalNoSrfcProbeIds[domainId()], 1, MPI_INT, &m_wmLocalNoSrfcProbeIds[0], 1, MPI_INT, mpiComm(),
12435 AT_,
"m_wmLocalNoSrfcProbeIds",
"m_wmLocalNoSrfcProbeIds");
12437 m_wmGlobalNoSrfcProbeIds = 0;
12438 for(
MInt dom = 0; dom < noDomains(); dom++) {
12439 m_wmGlobalNoSrfcProbeIds += m_wmLocalNoSrfcProbeIds[dom];
12442 if(m_wmLocalNoSrfcProbeIds[domainId()] > 0) {
12443 mAlloc(m_wmSrfcProbeSendBuffer, noVars * m_wmLocalNoSrfcProbeIds[domainId()],
"m_wmSrfcProbeSendBuffer", 0.0, AT_);
12445 if(domainId() == 0) {
12446 mAlloc(m_wmSrfcProbeRecvBuffer, noVars * m_wmGlobalNoSrfcProbeIds,
"m_wmSrfcProbeRecvBuffer", 0.0, AT_);
12450template <MInt nDim_,
class SysEqn>
12457 for(
MInt p = 0; p < m_wmLocalNoSrfcProbeIds[domainId()]; p++) {
12458 MInt cellId = m_wmSurfaceProbeIds[p];
12459 MInt srfc = m_wmSurfaceProbeSrfcs[p];
12460 MInt bCellId = a_bndryId(cellId);
12461 MInt ghostCellId = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_ghostCellId;
12463 MFloat pSurface = F1B2 * (a_pvariable(cellId, PV->P) + a_pvariable(ghostCellId, PV->P));
12464 MFloat rhoSurface = F1B2 * (a_pvariable(cellId, PV->RHO) + a_pvariable(ghostCellId, PV->RHO));
12465 MFloat TSurface = sysEqn().temperature_ES(rhoSurface, pSurface);
12466 MFloat mue = SUTHERLANDLAW(TSurface);
12468 m_wmSrfcProbeSendBuffer[noVars * p + 0] = cellId;
12469 m_wmSrfcProbeSendBuffer[noVars * p + 1] = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_coordinates[0];
12470 m_wmSrfcProbeSendBuffer[noVars * p + 2] = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_coordinates[1];
12471 m_wmSrfcProbeSendBuffer[noVars * p + 3] = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_coordinates[2];
12472 m_wmSrfcProbeSendBuffer[noVars * p + 4] = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_normalVector[0];
12473 m_wmSrfcProbeSendBuffer[noVars * p + 5] = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_normalVector[1];
12474 m_wmSrfcProbeSendBuffer[noVars * p + 6] = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_normalVector[2];
12475 m_wmSrfcProbeSendBuffer[noVars * p + 7] = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[0]];
12476 m_wmSrfcProbeSendBuffer[noVars * p + 8] = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[1]];
12477 m_wmSrfcProbeSendBuffer[noVars * p + 9] = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[2]];
12478 m_wmSrfcProbeSendBuffer[noVars * p + 10] = mue;
12479 m_wmSrfcProbeSendBuffer[noVars * p + 11] = m_bndryCells->a[bCellId].m_wmBCVars->m_wmMUEWM;
12480 m_wmSrfcProbeSendBuffer[noVars * p + 12] = m_bndryCells->a[bCellId].m_wmBCVars->m_wmTauW;
12484 MPI_Issend(&m_wmSrfcProbeSendBuffer[0], m_wmLocalNoSrfcProbeIds[domainId()] * noVars, MPI_DOUBLE, 0, 0, mpiComm(),
12485 &m_mpi_wmRequest[0], AT_,
"&m_wmSrfcProbeSendBuffer[0]");
12490 if(domainId() == 0) {
12491 for(
MInt dom = 0; dom < noDomains(); dom++) {
12492 MPI_Recv(&m_wmSrfcProbeRecvBuffer[offset], m_wmLocalNoSrfcProbeIds[dom] * noVars, MPI_DOUBLE, dom, 0, mpiComm(),
12493 &status, AT_,
"&m_wmSrfcProbeRecvBuffer[offset]");
12494 offset += m_wmLocalNoSrfcProbeIds[dom] * noVars;
12498 stringstream filename;
12499 filename << outputDir() <<
"wmSurfaceProbes_" <<
globalTimeStep;
12500 datei = fopen(filename.str().c_str(),
"w+");
12503 fprintf(datei,
"cellId");
12504 fprintf(datei,
" x");
12505 fprintf(datei,
" y");
12506 fprintf(datei,
" z");
12507 fprintf(datei,
" nx");
12508 fprintf(datei,
" ny");
12509 fprintf(datei,
" nz");
12510 fprintf(datei,
" dudn");
12511 fprintf(datei,
" dvdn");
12512 fprintf(datei,
" dwdn");
12513 fprintf(datei,
" mue");
12514 fprintf(datei,
" mue_wm");
12515 fprintf(datei,
" tau_wm");
12516 fprintf(datei,
"\n");
12518 for(
MInt p = 0; p < m_wmGlobalNoSrfcProbeIds; p++) {
12519 for(
MInt v = 0; v < noVars; v++) {
12520 fprintf(datei,
"%f ", m_wmSrfcProbeRecvBuffer[p * noVars + v]);
12522 fprintf(datei,
"\n");
12531template <MInt nDim_,
class SysEqn>
12534 const MInt noFVars = FV->noVariables;
12539 if(m_periodicCells == 1 || m_periodicCells == 2 || m_periodicCells == 3) {
12541#pragma omp parallel for collapse(2)
12543 for(
MInt c = 0; c < m_sortedPeriodicCells->size(); c++) {
12544 for(
MInt v = 0; v < noFVars; v++) {
12545 a_rightHandSide(m_sortedPeriodicCells->a[c], v) = F0;
12552#pragma omp parallel for
12554 for(
MInt bcId = 0; bcId < m_fvBndryCnd->m_noCutOffBndryCndIds; bcId++) {
12555 const MInt noCutOffCells = m_fvBndryCnd->m_sortedCutOffCells[bcId]->size();
12556 for(
MInt scc = 0; scc < noCutOffCells; scc++) {
12557 for(
MInt v = 0; v < noFVars; v++) {
12558 a_rightHandSide(m_fvBndryCnd->m_sortedCutOffCells[bcId]->a[scc], v) = F0;
12576template <MInt nDim_,
class SysEqn>
12578 const MInt noCells = a_noCells();
12579 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
12580 const MInt noSrfcs = a_noSurfaces();
12581 MFloat* area = &a_surfaceArea(0);
12583 MInt cellId0, cellId1;
12585 stringstream filename;
12590 for(
MInt cellId = 0; cellId < noCells; cellId++) {
12591 for(
MInt i = 0; i < nDim; i++) {
12592 cellSurfaceAreas(cellId, i) = F0;
12597 for(
MInt s = 0; s < noSrfcs; s++) {
12598 cellId0 = a_surfaceNghbrCellId(s, 0);
12599 cellId1 = a_surfaceNghbrCellId(s, 1);
12600 if(cellId0 > noCells)
continue;
12601 if(cellId1 > noCells)
continue;
12602 cellSurfaceAreas(cellId0, a_surfaceOrientation(s)) += area[s];
12603 cellSurfaceAreas(cellId1, a_surfaceOrientation(s)) -= area[s];
12607 for(
MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
12608 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == -1)
continue;
12609 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > noCells)
continue;
12610 for(
MInt dir = 0; dir < nDim; dir++) {
12611 cellSurfaceAreas(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId, dir) +=
12612 cellSurfaceAreas(m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId, dir);
12613 cellSurfaceAreas(m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId, dir) = F0;
12617 for(
MInt cellId = 0; cellId < noCells; cellId++) {
12618 for(
MInt dir = 0; dir < nDim; dir++) {
12621 if(abs(cellSurfaceAreas(cellId, dir)) > eps && a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)
12622 && !a_hasProperty(cellId, SolverCell::IsPeriodicWithRot) && (!a_isBndryGhostCell(cellId))
12623 && (!a_hasProperty(cellId, SolverCell::IsNotGradient)) && (!a_isHalo(cellId))) {
12636template <MInt nDim_,
class SysEqn>
12640 m_fvBndryCnd->copyVarsToSmallCells();
12651template <MInt nDim_,
class SysEqn>
12653 const MFloat*
const RESTRICT pvars = &a_pvariable(cellId, 0);
12654 MFloat*
const RESTRICT cvars = &a_variable(cellId, 0);
12655 const MFloat*
const RESTRICT avars = hasAV ? &a_avariable(cellId, 0) :
nullptr;
12657 IF_CONSTEXPR(isDetChem<SysEqn>) setMeanMolarWeight_PV(cellId);
12659 sysEqn().computeConservativeVariables(pvars, cvars, avars);
12662template <MInt nDim,
class SysEqn>
12663template <
class _, std::enable_if_t<isEEGas<SysEqn>, _*>>
12665 if(m_EEGas.depthCorrectionCoefficients.size() != nDim)
12666 mTerm(1, AT_,
"depthCorrectionCoefficients initialized incorrectly!");
12667 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
12668 MFloat depthCorrectionValue = 0.0;
12669 for(
MInt i = 0; i < nDim; i++) {
12670 const MFloat deltaH = a_coordinate(cellId, i) - m_EEGas.gravityRefCoords[i];
12671 depthCorrectionValue += m_EEGas.liquidDensity * m_EEGas.depthCorrectionCoefficients[i] * deltaH;
12673 a_avariable(cellId, AV->DC) = depthCorrectionValue;
12687template <MInt nDim_,
class SysEqn>
12691 if(m_fvBndryCnd->m_cellMerging)
return;
12693 if(noNeighborDomains() == 0 && grid().noAzimuthalNeighborDomains() == 0
12694 && m_azimuthalRemappedNeighborDomains.size() == 0)
12700 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12701 test0 += m_noMaxLevelHaloCells[i];
12702 test1 += m_noMaxLevelWindowCells[i];
12704 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
12705 test0 += m_azimuthalMaxLevelHaloCells[i].size();
12706 test1 += m_azimuthalMaxLevelWindowCells[i].size();
12708 if(test0 == 0 && test1 == 0) {
12709 mTerm(1, AT_,
"Max level exchange has not yet been initialized.");
12714 MIntScratchSpace sendBufferCnts(noNeighborDomains(), AT_,
"sendBufferCnts");
12715 MIntScratchSpace recvBufferCnts(noNeighborDomains(), AT_,
"recvBufferCnts");
12719 sendBufferCnts.
fill(0);
12720 recvBufferCnts.
fill(0);
12721 sendReq.
fill(MPI_REQUEST_NULL);
12722 recvReq.
fill(MPI_REQUEST_NULL);
12723 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12724 m_fvBndryCnd->m_nearBoundaryWindowCells[i].clear();
12725 m_fvBndryCnd->m_nearBoundaryHaloCells[i].clear();
12728 activeFlag.
fill(0);
12730 setActiveFlag(activeFlag, mode, offset);
12732 setAdditionalActiveFlag(activeFlag);
12734 if(grid().azimuthalPeriodicity()) {
12735 initAzimuthalNearBoundaryExchange(activeFlag);
12738 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12739 MInt sendBufferCounter = 0;
12740 for(
MInt j = 0; j < m_noMaxLevelHaloCells[i]; j++) {
12741 MInt cellId = m_maxLevelHaloCells[i][j];
12742 m_receiveBuffers[i][sendBufferCounter] = F0;
12743 if(activeFlag(cellId)) {
12744 m_receiveBuffers[i][sendBufferCounter] = F1;
12745 m_fvBndryCnd->m_nearBoundaryHaloCells[i].push_back(cellId);
12746 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) {
12747 for(
MUint sc = 0; sc < m_splitCells.size(); sc++) {
12748 if(cellId != m_splitCells[sc])
continue;
12749 for(
MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
12750 m_fvBndryCnd->m_nearBoundaryHaloCells[i].push_back(m_splitChilds[sc][ssc]);
12755 sendBufferCounter++;
12757 ASSERT(sendBufferCounter == m_noMaxLevelHaloCells[i],
"");
12758 sendBufferCnts(i) = sendBufferCounter;
12759 recvBufferCnts(i) = m_noMaxLevelWindowCells[i];
12762 if(noNeighborDomains() > 0) {
12763 if(m_nonBlockingComm) {
12764 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12765 ASSERT(recvBufferCnts(i) <= m_noMaxLevelWindowCells[i] * m_dataBlockSize,
"");
12766 MPI_Irecv(m_sendBuffers[i], recvBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 2, mpiComm(), &recvReq[i], AT_,
12767 "m_sendBuffers[i]");
12769 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12770 ASSERT(sendBufferCnts(i) <= m_noMaxLevelHaloCells[i] * m_dataBlockSize,
"");
12771 MPI_Isend(m_receiveBuffers[i], sendBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 2, mpiComm(), &sendReq[i], AT_,
12772 "m_receiveBuffers[i]");
12774 MPI_Waitall(noNeighborDomains(), &recvReq[0], MPI_STATUSES_IGNORE, AT_);
12775 MPI_Waitall(noNeighborDomains(), &sendReq[0], MPI_STATUSES_IGNORE, AT_);
12777 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12778 ASSERT(sendBufferCnts(i) <= m_noMaxLevelHaloCells[i] * m_dataBlockSize,
"");
12779 MPI_Issend(m_receiveBuffers[i], sendBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 2, mpiComm(), &sendReq[i],
12780 AT_,
"m_receiveBuffers[i]");
12782 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12783 ASSERT(recvBufferCnts(i) <= m_noMaxLevelWindowCells[i] * m_dataBlockSize,
"");
12784 MPI_Recv(m_sendBuffers[i], recvBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 2, mpiComm(), MPI_STATUS_IGNORE,
12785 AT_,
"m_sendBuffers[i]");
12787 MPI_Waitall(noNeighborDomains(), &sendReq[0], MPI_STATUSES_IGNORE, AT_);
12790 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12791 MInt recvBufferCounter = 0;
12792 for(
MInt j = 0; j < m_noMaxLevelWindowCells[i]; j++) {
12793 MInt cellId = m_maxLevelWindowCells[i][j];
12794 if((
MInt)m_sendBuffers[i][recvBufferCounter]) {
12795 m_fvBndryCnd->m_nearBoundaryWindowCells[i].push_back(cellId);
12796 ASSERT(c_noChildren(cellId) == 0,
"");
12797 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) {
12798 for(
MUint sc = 0; sc < m_splitCells.size(); sc++) {
12799 if(cellId != m_splitCells[sc])
continue;
12800 for(
MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
12801 m_fvBndryCnd->m_nearBoundaryWindowCells[i].push_back(m_splitChilds[sc][ssc]);
12806 recvBufferCounter++;
12814 MLong totalMaxLevelHaloCells = 0;
12815 MLong totalMaxLevelWindowCells = 0;
12816 MLong totalNearBoundaryHaloCells = 0;
12817 MLong totalNearBoundaryWindowCells = 0;
12818 m_log <<
"Near-boundary exchange size:" << endl;
12819 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12820 m_log <<
"D" << neighborDomain(i) <<
":"
12821 <<
" " << m_fvBndryCnd->m_nearBoundaryWindowCells[i].size() <<
"/" << m_noMaxLevelWindowCells[i] <<
" "
12822 << m_fvBndryCnd->m_nearBoundaryHaloCells[i].size() <<
"/" << m_noMaxLevelHaloCells[i] << endl;
12823 totalMaxLevelHaloCells += m_noMaxLevelHaloCells[i];
12824 totalMaxLevelWindowCells += m_noMaxLevelWindowCells[i];
12825 totalNearBoundaryHaloCells += (signed)m_fvBndryCnd->m_nearBoundaryHaloCells[i].size();
12826 totalNearBoundaryWindowCells += (signed)m_fvBndryCnd->m_nearBoundaryWindowCells[i].size();
12828 MPI_Allreduce(MPI_IN_PLACE, &totalMaxLevelHaloCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
12829 "totalMaxLevelHaloCells");
12830 MPI_Allreduce(MPI_IN_PLACE, &totalMaxLevelWindowCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
12831 "totalMaxLevelWindowCells");
12832 MPI_Allreduce(MPI_IN_PLACE, &totalNearBoundaryHaloCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
12833 "totalNearBoundaryHaloCells");
12834 MPI_Allreduce(MPI_IN_PLACE, &totalNearBoundaryWindowCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
12835 "totalNearBoundaryWindowCells");
12836 m_log <<
"Global near-boundary exchange size: " << totalNearBoundaryWindowCells <<
"/" << totalMaxLevelWindowCells
12837 <<
" (" << 100.0 * ((
MFloat)totalNearBoundaryWindowCells / (
MFloat)totalMaxLevelWindowCells) <<
"%)"
12838 <<
" - " << totalNearBoundaryHaloCells <<
"/" << totalMaxLevelHaloCells <<
" ("
12839 << 100.0 * ((
MFloat)totalNearBoundaryHaloCells / (
MFloat)totalMaxLevelHaloCells) <<
"%)" << endl;
12847template <MInt nDim_,
class SysEqn>
12849 const MInt offset) {
12852 for(
MInt bndryId = 0; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
12853 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
12855 const MFloat vfrac = a_cellVolume(cellId) / grid().cellVolumeAtLevel(maxLevel());
12856 MBool atWall =
false;
12857 for(
MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
12858 if(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId / 1000 == 3) atWall =
true;
12860 const MFloat volumeLimit = atWall ? m_fvBndryCnd->m_volumeLimitWall : m_fvBndryCnd->m_volumeLimitOther;
12861 if(mode == 0 && vfrac > volumeLimit)
continue;
12862 if(mode == 1 && bndryId < offset && vfrac > volumeLimit)
continue;
12863 activeFlag(cellId) = 1;
12864 const MInt noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
12865 const MUint noRecNghbrs = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.
size();
12866 for(
MUint n = noSrfcs; n < noRecNghbrs; n++) {
12867 MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
12868 if(nghbrId < 0)
continue;
12869 activeFlag(nghbrId) = 1;
12870 if(a_hasProperty(nghbrId, SolverCell::IsSplitChild)) {
12871 activeFlag(getAssociatedInternalCell(nghbrId)) = 1;
12874 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && !a_hasProperty(cellId, SolverCell::IsSplitClone)) {
12875 for(
MInt dir = 0; dir < m_noDirs; dir++) {
12876 if(checkNeighborActive(cellId, dir) && a_hasNeighbor(cellId, dir)) {
12877 activeFlag(c_neighborId(cellId, dir)) = 1;
12889template <MInt nDim_,
class SysEqn>
12891 MBool solutionDiverged =
false;
12892 const MInt noCVars = CV->noVariables;
12894 for(
MInt i = 0; i < noNeighborDomains(); i++) {
12895 if(m_fvBndryCnd->m_nearBoundaryHaloCells[i].empty()) {
12898 for(
MUint j = 0; j < m_fvBndryCnd->m_nearBoundaryHaloCells[i].size(); j++) {
12899 MInt cellId = m_fvBndryCnd->m_nearBoundaryHaloCells[i][j];
12900 const MInt rootId =
12901 (a_hasProperty(cellId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(cellId) : cellId;
12902 IF_CONSTEXPR(!isEEGas<SysEqn>) {
12903 for(
MInt v = 0; v < noCVars; v++) {
12904 if(!(a_variable(cellId, v) >= F0 || a_variable(cellId, v) < F0) || std::isnan(a_variable(cellId, v))) {
12905 cerr << domainId() <<
": EXC1 " << i <<
" " << j <<
" " << c_globalId(cellId) <<
" " << a_bndryId(cellId)
12906 <<
" " << a_level(cellId) <<
" /v " << a_cellVolume(cellId) / grid().gridCellVolume(a_level(rootId))
12908 << (a_bndryId(cellId) > -1 ? m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_volume
12909 / grid().gridCellVolume(a_level(rootId))
12911 <<
" " << v <<
" " << a_variable(cellId, v) <<
" " << a_coordinate(cellId, 0) <<
" "
12912 << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, nDim - 1) <<
" "
12913 << a_hasProperty(cellId, SolverCell::IsSplitChild) <<
" "
12914 << a_hasProperty(cellId, SolverCell::IsSplitCell) << endl;
12915 solutionDiverged =
true;
12919 if(a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) > m_fvBndryCnd->m_volumeLimitWall) {
12920 setPrimitiveVariables(cellId);
12921 if(a_pvariable(cellId, PV->RHO) < F0 || a_pvariable(cellId, PV->P) < F0) {
12922 cerr << domainId() <<
": EXC1 " << i <<
" " << j <<
" " << c_globalId(cellId) <<
" " << a_bndryId(cellId)
12923 <<
" " << a_level(cellId) <<
" /r " << a_pvariable(cellId, PV->RHO) <<
" /p "
12924 << a_pvariable(cellId, PV->P) <<
" /v " << a_cellVolume(cellId) / grid().gridCellVolume(a_level(rootId))
12926 << (a_bndryId(cellId) > -1 ? m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_volume
12927 / grid().gridCellVolume(a_level(rootId))
12929 <<
" " << a_coordinate(cellId, 0) <<
" " << a_coordinate(cellId, 1) <<
" "
12930 << a_coordinate(cellId, nDim - 1) <<
" " << a_hasProperty(cellId, SolverCell::IsSplitChild) <<
" "
12931 << a_hasProperty(cellId, SolverCell::IsSplitCell) << endl;
12932 cerr <<
" vel " << a_pvariable(cellId, PV->VV[0]) <<
" " << a_pvariable(cellId, PV->VV[1]) <<
" "
12933 << a_pvariable(cellId, PV->VV[nDim - 1]) << endl;
12934 solutionDiverged =
true;
12940 if(grid().azimuthalPeriodicity()) {
12941 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
12942 if(m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i].empty()) {
12945 for(
MUint j = 0; j < m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i].size(); j++) {
12946 MInt cellId = m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i][j];
12947 const MInt rootId =
12948 (a_hasProperty(cellId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(cellId) : cellId;
12949 for(
MInt v = 0; v < noCVars; v++) {
12950 if(!(a_variable(cellId, v) >= F0 || a_variable(cellId, v) < F0) || std::isnan(a_variable(cellId, v))) {
12951 cerr << domainId() <<
": EXC1 Azi " << i <<
" " << j <<
" " << c_globalId(cellId) <<
" "
12952 << a_bndryId(cellId) <<
" " << a_level(cellId) <<
" /v "
12953 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(rootId)) <<
" "
12954 << (a_bndryId(cellId) > -1 ? m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_volume
12955 / grid().gridCellVolume(a_level(rootId))
12957 <<
" " << v <<
" " << a_variable(cellId, v) <<
" " << a_coordinate(cellId, 0) <<
" "
12958 << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, nDim - 1) <<
" "
12959 << a_hasProperty(cellId, SolverCell::IsSplitChild) <<
" "
12960 << a_hasProperty(cellId, SolverCell::IsSplitCell) << endl;
12961 solutionDiverged =
true;
12964 if(a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) > m_fvBndryCnd->m_volumeLimitWall) {
12965 setPrimitiveVariables(cellId);
12966 if(a_pvariable(cellId, m_sysEqn.PV->RHO) < F0 || a_pvariable(cellId, m_sysEqn.PV->P) < F0) {
12967 cerr << domainId() <<
": EXC1 Azi " << i <<
" " << j <<
" " << c_globalId(cellId) <<
" "
12968 << a_bndryId(cellId) <<
" " << a_level(cellId) <<
" /r " << a_pvariable(cellId, m_sysEqn.PV->RHO)
12969 <<
" /p " << a_pvariable(cellId, m_sysEqn.PV->P) <<
" /v "
12970 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(rootId)) <<
" "
12971 << (a_bndryId(cellId) > -1 ? m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_volume
12972 / grid().gridCellVolume(a_level(rootId))
12974 <<
" " << a_coordinate(cellId, 0) <<
" " << a_coordinate(cellId, 1) <<
" "
12975 << a_coordinate(cellId, nDim - 1) <<
" " << a_hasProperty(cellId, SolverCell::IsSplitChild) <<
" "
12976 << a_hasProperty(cellId, SolverCell::IsSplitCell) << endl;
12977 cerr <<
" vel " << a_pvariable(cellId, m_sysEqn.PV->VV[0]) <<
" " << a_pvariable(cellId, m_sysEqn.PV->VV[1])
12978 <<
" " << a_pvariable(cellId, m_sysEqn.PV->VV[nDim - 1]) << endl;
12979 solutionDiverged =
true;
12985 if(solutionDiverged) {
12986 cerr <<
"Solution diverged (BEXC" << x <<
") at solver " << domainId() <<
" " <<
globalTimeStep <<
" " << m_RKStep
12989 if(noDomains() > 1) {
12991 MInt tmp = solutionDiverged;
12992 MPI_Allreduce(MPI_IN_PLACE, &tmp, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"tmp");
12993 solutionDiverged = tmp;
12995 if(solutionDiverged) {
12996 saveSolverSolution(1);
12998 mTerm(1, AT_,
"Solution diverged after near boundary exchange.");
13013template <MInt nDim_,
class SysEqn>
13017 if(m_fvBndryCnd->m_cellMerging || m_fvBndryCnd->m_smallCellRHSCorrection) {
13021 RECORD_TIMER_START(m_timers[Timers::SCCorrInit]);
13025 const MBool conservation = (m_RKStep == 0);
13028 const MInt noSmallCells = (signed)m_fvBndryCnd->m_smallCutCells.size();
13029 const MInt noCVars = CV->noVariables;
13030 const MInt noPVars = PV->noVariables;
13031 const MInt noAVars = AV->noVariables;
13032 const MInt volFactor = nDim == 3 ? 4 : 2;
13044 redistFac.fill(F0);
13047 RECORD_TIMER_STOP(m_timers[Timers::SCCorrInit]);
13048 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange1]);
13051 if(m_periodicCells == 2 || m_periodicCells == 3) {
13053 exchangePeriodic();
13058 sendReq.fill(MPI_REQUEST_NULL);
13059 recvReq.fill(MPI_REQUEST_NULL);
13060 sendBufferCnts.fill(0);
13061 recvBufferCnts.fill(0);
13062 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13063 sendBufferCnts(i) = noCVars * (signed)m_fvBndryCnd->m_nearBoundaryWindowCells[i].size();
13064 recvBufferCnts(i) = noCVars * (signed)m_fvBndryCnd->m_nearBoundaryHaloCells[i].size();
13065 if(m_fvBndryCnd->m_nearBoundaryWindowCells[i].empty())
continue;
13066 MInt sendBufferCounter = 0;
13067 for(
MUint j = 0; j < m_fvBndryCnd->m_nearBoundaryWindowCells[i].size(); j++) {
13068 MInt cellId = m_fvBndryCnd->m_nearBoundaryWindowCells[i][j];
13069 for(
MInt v = 0; v < noCVars; v++) {
13070 m_sendBuffers[i][sendBufferCounter] = a_variable(cellId, v);
13071 sendBufferCounter++;
13078 if(m_nonBlockingComm) {
13079 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13080 if(sendBufferCnts(i) == 0)
continue;
13081 ASSERT(sendBufferCnts(i) <= m_noMaxLevelWindowCells[i] * m_dataBlockSize,
"");
13082 MPI_Isend(m_sendBuffers[i], sendBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 12, mpiComm(), &sendReq[sendCnt],
13083 AT_,
"m_sendBuffers[i]");
13086 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13087 if(recvBufferCnts(i) == 0)
continue;
13088 ASSERT(recvBufferCnts(i) <= m_noMaxLevelHaloCells[i] * m_dataBlockSize,
"");
13089 MPI_Irecv(m_receiveBuffers[i], recvBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 12, mpiComm(),
13090 &recvReq[recvCnt], AT_,
"m_receiveBuffers[i]");
13093 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange1Wait]);
13094 if(recvCnt > 0)
MPI_Waitall(recvCnt, &recvReq[0], MPI_STATUSES_IGNORE, AT_);
13095 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange1Wait]);
13097 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13098 if(sendBufferCnts(i) == 0)
continue;
13099 ASSERT(sendBufferCnts(i) <= m_noMaxLevelWindowCells[i] * m_dataBlockSize,
"");
13100 MPI_Issend(m_sendBuffers[i], sendBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 12, mpiComm(), &sendReq[sendCnt],
13101 AT_,
"m_sendBuffers[i]");
13104 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13105 if(recvBufferCnts(i) == 0)
continue;
13106 ASSERT(recvBufferCnts(i) <= m_noMaxLevelHaloCells[i] * m_dataBlockSize,
"");
13107 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange1Wait]);
13108 MPI_Recv(m_receiveBuffers[i], recvBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 12, mpiComm(),
13109 MPI_STATUS_IGNORE, AT_,
"m_receiveBuffers[i]");
13110 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange1Wait]);
13114 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13115 if(m_fvBndryCnd->m_nearBoundaryHaloCells[i].empty())
continue;
13116 MInt recvBufferCounter = 0;
13117 for(
MUint j = 0; j < m_fvBndryCnd->m_nearBoundaryHaloCells[i].size(); j++) {
13118 MInt cellId = m_fvBndryCnd->m_nearBoundaryHaloCells[i][j];
13119 for(
MInt v = 0; v < noCVars; v++) {
13120 a_variable(cellId, v) = m_receiveBuffers[i][recvBufferCounter];
13121 recvBufferCounter++;
13125 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange1Wait]);
13126 if(sendCnt > 0)
MPI_Waitall(sendCnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
13127 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange1Wait]);
13129 if(grid().azimuthalPeriodicity()) {
13130 azimuthalNearBoundaryExchange();
13139 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange1]);
13140 RECORD_TIMER_START(m_timers[Timers::SCCorrInterp]);
13143#if !defined NDEBUG || defined _MB_DEBUG_
13149 for(
MInt smallc = 0; smallc < noSmallCells; smallc++) {
13150 const MInt bndryId = m_fvBndryCnd->m_smallCutCells[(unsigned)smallc];
13151 ASSERT(std::count(m_fvBndryCnd->m_smallCutCells.begin(), m_fvBndryCnd->m_smallCutCells.end(), bndryId) == 1,
"");
13152 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
13153 if(a_isPeriodic(cellId)) {
13156 if(a_isHalo(cellId)) {
13159 if(a_hasProperty(cellId, SolverCell::IsPeriodicWithRot)) {
13163 if(a_hasProperty(cellId, SolverCell::IsCutOff) && !m_fvBndryCnd->m_cbcSmallCellCorrection)
continue;
13165 const MInt noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
13166 const MUint noRecNghbrs = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size();
13167 if(noRecNghbrs == 0) {
13168 cerr << domainId() <<
": Warning: no reconstruction posible in small cell " <<
cellId << endl;
13173 for(
MUint n = (
unsigned)noSrfcs + 1; n < noRecNghbrs; n++) {
13174 const MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
13179 if(a_hasProperty(nghbrId, SolverCell::IsCutOff) && !m_fvBndryCnd->m_cbcSmallCellCorrection)
continue;
13188 sum += a_cellVolume(nghbrId);
13193 for(
auto n = (
unsigned)noSrfcs; n < noRecNghbrs; n++) {
13194 setPrimitiveVariables(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n]);
13198 for(
MInt v = 0; v < noPVars; v++) {
13201 for(
MInt srfc = 0; srfc < noSrfcs; srfc++) {
13202 const MInt bc = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v];
13205 stencil +=
IPOW2(srfc);
13210 a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[srfc],
13212 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v];
13215 a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[srfc],
13217 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v];
13221 a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[srfc],
13228 "Invalid BC type in FvCartesianSolverXD::smallCellCorrection(). "
13229 + to_string(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId) +
" "
13230 + to_string(cellId) +
" " + to_string(noSrfcs));
13234 for(
MUint n = 0; n < noRecNghbrs; n++) {
13235 if(fabs(m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n + stencil]) > m_eps) {
13236 pvars[v] += m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n + stencil]
13237 * a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], v);
13240#if !defined NDEBUG || defined _MB_DEBUG_
13242 && (std::isnan(m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n + stencil])
13243 || std::isnan(a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], v)))) {
13244 cerr << domainId() <<
": "
13245 <<
" nan detected in smallCellCorrection " <<
globalTimeStep <<
"/" << m_RKStep <<
" "
13246 <<
" " <<
cellId <<
"(" << c_globalId(cellId) <<
")"
13247 <<
" " << n <<
"/" << noRecNghbrs <<
" " << v <<
" " << stencil <<
" "
13248 << m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n] <<
"("
13249 << c_globalId(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n]) <<
")"
13250 <<
" " << m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n + stencil] <<
" "
13251 << a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], v) <<
" "
13252 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) <<
" "
13253 << a_cellVolume(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n])
13254 / grid().gridCellVolume(a_level(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n]))
13257 if(nanCnt == 100) cerr << domainId() <<
": More than 100 nan's, not reporting any more." << endl;
13267 if(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcs[0]->m_bndryCndId == 3007) {
13269 for(
MInt i = 0; i < nDim; i++) {
13271 for(
MInt srfc = 0; srfc < noSrfcs; srfc++) {
13272 a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[srfc], PV->VV[i]) = F0;
13274 pvars2[PV->VV[i]] = F0;
13275 for(
MUint n = 0; n < noRecNghbrs; n++) {
13276 pvars2[PV->VV[i]] += m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n + stencil]
13277 * a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->VV[i]);
13281 for(
MInt i = 0; i < nDim; i++) {
13282 vel[i] = pvars2[PV->VV[i]];
13283 for(
MInt j = 0; j < nDim; j++) {
13284 vel[i] += m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i] * (pvars[PV->VV[j]] - pvars2[PV->VV[j]])
13285 * m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[j];
13288 for(
MInt i = 0; i < nDim; i++) {
13289 pvars[PV->VV[i]] = vel[i];
13292 if(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_variablesType[PV->RHO] ==
BC_ISOTHERMAL) {
13294 for(
MInt v = 0; v < noPVars; v++) {
13295 for(
MInt srfc = 0; srfc < noSrfcs; srfc++) {
13296 a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[srfc], v) =
13297 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v];
13301 for(
MUint n = 0; n < noRecNghbrs; n++) {
13302 if(fabs(m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n + stencil]) > m_eps) {
13304 IF_CONSTEXPR(isDetChem<SysEqn>) {
13305 Tn = a_avariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], AV->W_MEAN)
13306 * a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->P)
13307 / (a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->RHO) * m_gasConstant);
13310 Tn = sysEqn().temperature_ES(a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->RHO),
13311 a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->P));
13315 Tc += m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n + stencil] * Tn;
13319 IF_CONSTEXPR(isDetChem<SysEqn>) {
13321 avars[AV->W_MEAN] = [&] {
13322 MFloat fRecMeanMolarWeight = F0;
13323 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
13324 fRecMeanMolarWeight += pvars[PV->Y[s]] * sysEqn().m_species->fMolarMass[s];
13326 const MFloat recMeanMolarWeight = F1 / fRecMeanMolarWeight;
13327 return recMeanMolarWeight;
13329 pvars[PV->RHO] = avars[AV->W_MEAN] * pvars[PV->P] / (Tc * m_gasConstant);
13332 pvars[PV->RHO] = sysEqn().density_ES(pvars[PV->P], Tc);
13336 }
else if(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcs[0]->m_bndryCndId == 3067) {
13337 MBool& first = m_static_smallCellCorrection_first;
13338 MInt& slipDirection = m_static_smallCellCorrection_slipDirection;
13339 MFloat& slipCoordinate = m_static_smallCellCorrection_slipCoordinate;
13355 slipDirection = Context::getSolverProperty<MInt>(
"slipDirection", m_solverId, AT_);
13356 slipCoordinate = Context::getSolverProperty<MFloat>(
"slipCoordinate", m_solverId, AT_);
13358 MInt slipDim = slipDirection / 2;
13360 if(slipDirection % 2 == 1) {
13364 if((a_coordinate(cellId, slipDim) - slipCoordinate) * slipSign < F0) {
13366 for(
MInt i = 0; i < nDim; i++) {
13368 for(
MInt srfc = 0; srfc < noSrfcs; srfc++) {
13369 a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[srfc], PV->VV[i]) = F0;
13371 pvars2[PV->VV[i]] = F0;
13372 for(
MUint n = 0; n < noRecNghbrs; n++) {
13373 pvars2[PV->VV[i]] += m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n + stencil]
13374 * a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->VV[i]);
13378 for(
MInt i = 0; i < nDim; i++) {
13379 vel[i] = pvars2[PV->VV[i]];
13380 for(
MInt j = 0; j < nDim; j++) {
13381 vel[i] += m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i] * (pvars[PV->VV[j]] - pvars2[PV->VV[j]])
13382 * m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[j];
13385 for(
MInt i = 0; i < nDim; i++) {
13386 pvars[PV->VV[i]] = vel[i];
13393 IF_CONSTEXPR(isDetChem<SysEqn>) {
13395 avars[AV->W_MEAN] = [&] {
13396 MFloat fRecMeanMolarWeight = F0;
13397 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
13398 fRecMeanMolarWeight += pvars[PV->Y[s]] * sysEqn().m_species->fMolarMass[s];
13400 const MFloat recMeanMolarWeight = F1 / fRecMeanMolarWeight;
13401 return recMeanMolarWeight;
13406 sysEqn().computeConservativeVariables(&pvars[0], &cvars[0], isDetChem<SysEqn> ? &avars[0] :
nullptr);
13408 ASSERT(maxLevel() >= maxUniformRefinementLevel() && maxLevel() <= maxRefinementLevel(),
"");
13413 MFloat vfrac = a_cellVolume(cellId) / grid().gridCellVolume(maxLevel());
13414 MFloat volumeLimit = m_fvBndryCnd->m_volumeLimitWall;
13416 if(a_level(cellId) < maxLevel() && m_bndryLevelJumps) {
13417 volumeLimit = volumeLimit * volFactor * (maxLevel() - a_level(cellId));
13420 vfrac = a_cellVolume(cellId) / c_cellVolumeAtLevel(a_level(cellId));
13425 for(
MInt v = 0; v < noCVars; v++) {
13427 delta(smallc, v) = (F1 - fac) * (cvars[v] - a_variable(cellId, v));
13429 redistFac(smallc) = a_cellVolume(cellId) / sum;
13432 RECORD_TIMER_STOP(m_timers[Timers::SCCorrInterp]);
13433 RECORD_TIMER_START(m_timers[Timers::SCCorrRedist]);
13437 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13438 if(m_fvBndryCnd->m_nearBoundaryHaloCells[i].empty())
continue;
13439 for(
MUint j = 0; j < m_fvBndryCnd->m_nearBoundaryHaloCells[i].size(); j++) {
13440 MInt cellId = m_fvBndryCnd->m_nearBoundaryHaloCells[i][j];
13441 for(
MInt v = 0; v < noCVars; v++) {
13442 a_variable(cellId, v) = F0;
13447 if(grid().azimuthalPeriodicity()) {
13448 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
13449 for(
MUint j = 0; j < m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i].size(); j++) {
13450 MInt cellId = m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i][j];
13451 for(
MInt v = 0; v < noCVars; v++) {
13452 a_variable(cellId, v) = F0;
13456 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
13457 for(
MUint j = 0; j < m_azimuthalRemappedHaloCells[i].size(); j++) {
13458 MInt cellId = m_azimuthalRemappedHaloCells[i][j];
13459 for(
MInt v = 0; v < noCVars; v++) {
13460 a_variable(cellId, v) = F0;
13468 if(conservation && (m_periodicCells == 2 || m_periodicCells == 3)) {
13470 for(
MInt c = 0; c < m_sortedPeriodicCells->size(); c++) {
13471 a_variable(m_sortedPeriodicCells->a[c], CV->RHO) = F0;
13472 IF_CONSTEXPR(hasE<SysEqn>)
13473 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_E) = F0;
13474 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_U) = F0;
13475 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_V) = F0;
13476 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_W) = F0;
13478 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
13479 for(
MInt r = 0; r < m_noRansEquations; r++) {
13480 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_NN[r]) = F0;
13487 for(
MInt smallc = 0; smallc < noSmallCells; smallc++) {
13488 const MInt bndryId = m_fvBndryCnd->m_smallCutCells[(unsigned)smallc];
13489 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
13490 if(a_isPeriodic(cellId))
continue;
13491 if(a_isHalo(cellId))
continue;
13492 if(a_hasProperty(cellId, SolverCell::IsPeriodicWithRot))
continue;
13494 if(a_hasProperty(cellId, SolverCell::IsCutOff) && !m_fvBndryCnd->m_cbcSmallCellCorrection)
continue;
13496 for(
MInt v = 0; v < noCVars; v++) {
13497 a_variable(cellId, v) += delta(smallc, v);
13500#if !defined NDEBUG || defined _MB_DEBUG_
13502 IF_CONSTEXPR(hasE<SysEqn>)
13503 if(std::isnan(a_variable(cellId, v))
13504 || (((v == CV->RHO && a_variable(cellId, CV->RHO) < F0)
13505 || (v == CV->RHO_E && a_variable(cellId, CV->RHO_E) < F0))
13506 && !isDetChem<SysEqn> && !m_isEEGas)) {
13507 cerr << domainId() <<
": small cell correction failed " <<
globalTimeStep <<
" " <<
cellId <<
" "
13508 << c_globalId(cellId) <<
" " << v <<
" " << a_level(cellId) <<
" " << a_variable(cellId, v) <<
" "
13509 << delta(smallc, v) <<
" " << setprecision(12)
13510 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) <<
" "
13511 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) << endl;
13519 for(
MInt smallc = 0; smallc < noSmallCells; smallc++) {
13520 const MInt bndryId = m_fvBndryCnd->m_smallCutCells[(unsigned)smallc];
13521 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
13522 if(a_isPeriodic(cellId))
continue;
13524 if(a_hasProperty(cellId, SolverCell::IsCutOff))
continue;
13525 if(a_isHalo(cellId))
continue;
13526 if(a_hasProperty(cellId, SolverCell::IsPeriodicWithRot))
continue;
13527 if(a_hasProperty(cellId, SolverCell::IsSplitCell))
continue;
13528 if(redistFac(smallc) < 1e-14)
continue;
13529 const MInt noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
13530 const MUint noRecNghbrs = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size();
13531 if(noRecNghbrs == 0)
continue;
13533 for(
MUint n = (
unsigned)noSrfcs + 1; n < noRecNghbrs; n++) {
13534 MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
13535 if(nghbrId < 0)
continue;
13536 ASSERT(a_hasProperty(nghbrId, SolverCell::IsSplitChild) || c_noChildren(nghbrId) == 0,
"");
13538 if(a_hasProperty(nghbrId, SolverCell::IsCutOff))
continue;
13539 for(
MInt v = 0; v < noCVars; v++) {
13540 a_variable(nghbrId, v) -= redistFac(smallc) * delta(smallc, v);
13542#if !defined NDEBUG || defined _MB_DEBUG_
13543 IF_CONSTEXPR(hasE<SysEqn>)
13544 if(!a_isHalo(nghbrId) && !m_isEEGas
13545 && (a_variable(nghbrId, CV->RHO) < F0 || ((a_variable(nghbrId, CV->RHO_E) < F0) && (!isDetChem<SysEqn>)))) {
13546 cerr << domainId() <<
": flux redist failed " <<
globalTimeStep <<
" " <<
cellId <<
" " << c_globalId(cellId)
13547 <<
" " << a_level(cellId) <<
" " << nghbrId <<
" " << c_globalId(nghbrId) <<
" "
13548 << a_variable(nghbrId, CV->RHO) <<
" " << a_variable(nghbrId, CV->RHO_E) <<
" " << noRecNghbrs <<
" "
13549 << redistFac(smallc) <<
" " << delta(smallc, CV->RHO) <<
" " << delta(smallc, CV->RHO_E) <<
" "
13550 << setprecision(12) << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) << endl;
13557 RECORD_TIMER_STOP(m_timers[Timers::SCCorrRedist]);
13558 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange2]);
13563 if(grid().azimuthalPeriodicity()) azimuthalNearBoundaryReverseExchange();
13565 sendReq.fill(MPI_REQUEST_NULL);
13566 recvReq.fill(MPI_REQUEST_NULL);
13567 sendBufferCnts.fill(0);
13568 recvBufferCnts.fill(0);
13569 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13570 sendBufferCnts(i) = noCVars * (signed)m_fvBndryCnd->m_nearBoundaryHaloCells[i].size();
13571 recvBufferCnts(i) = noCVars * (signed)m_fvBndryCnd->m_nearBoundaryWindowCells[i].size();
13572 if(m_fvBndryCnd->m_nearBoundaryHaloCells[i].empty())
continue;
13573 MInt sendBufferCounter = 0;
13574 for(
MUint j = 0; j < m_fvBndryCnd->m_nearBoundaryHaloCells[i].size(); j++) {
13575 MInt cellId = m_fvBndryCnd->m_nearBoundaryHaloCells[i][j];
13576 for(
MInt v = 0; v < noCVars; v++) {
13577 m_receiveBuffers[i][sendBufferCounter] = a_variable(cellId, v);
13578 sendBufferCounter++;
13584 if(m_nonBlockingComm) {
13585 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13586 if(sendBufferCnts(i) == 0)
continue;
13587 ASSERT(sendBufferCnts(i) <= m_noMaxLevelHaloCells[i] * m_dataBlockSize,
"");
13588 MPI_Isend(m_receiveBuffers[i], sendBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 13, mpiComm(),
13589 &sendReq[sendCnt], AT_,
"m_receiveBuffers[i]");
13592 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13593 if(recvBufferCnts(i) == 0)
continue;
13594 ASSERT(recvBufferCnts(i) <= m_noMaxLevelWindowCells[i] * m_dataBlockSize,
"");
13595 MPI_Irecv(m_sendBuffers[i], recvBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 13, mpiComm(), &recvReq[recvCnt],
13596 AT_,
"m_sendBuffers[i]");
13599 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange2Wait]);
13600 if(recvCnt > 0)
MPI_Waitall(recvCnt, &recvReq[0], MPI_STATUSES_IGNORE, AT_);
13601 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange2Wait]);
13603 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13604 if(sendBufferCnts(i) == 0)
continue;
13605 ASSERT(sendBufferCnts(i) <= m_noMaxLevelHaloCells[i] * m_dataBlockSize,
"");
13606 MPI_Issend(m_receiveBuffers[i], sendBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 13, mpiComm(),
13607 &sendReq[sendCnt], AT_,
"m_receiveBuffers[i]");
13610 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13611 if(recvBufferCnts(i) == 0)
continue;
13612 ASSERT(recvBufferCnts(i) <= m_noMaxLevelWindowCells[i] * m_dataBlockSize,
"");
13613 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange2Wait]);
13614 MPI_Recv(m_sendBuffers[i], recvBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 13, mpiComm(), MPI_STATUS_IGNORE,
13615 AT_,
"m_sendBuffers[i]");
13616 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange2Wait]);
13620 for(
MInt i = 0; i < noNeighborDomains(); i++) {
13621 if(m_fvBndryCnd->m_nearBoundaryWindowCells[i].empty())
continue;
13622 MInt recvBufferCounter = 0;
13623 for(
MUint j = 0; j < m_fvBndryCnd->m_nearBoundaryWindowCells[i].size(); j++) {
13624 MInt cellId = m_fvBndryCnd->m_nearBoundaryWindowCells[i][j];
13625 for(
MInt v = 0; v < noCVars; v++) {
13627 a_variable(cellId, v) += m_sendBuffers[i][recvBufferCounter];
13631 recvBufferCounter++;
13635 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange2Wait]);
13636 if(sendCnt > 0)
MPI_Waitall(sendCnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
13638 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange2Wait]);
13642 if(conservation && (m_periodicCells == 2 || m_periodicCells == 3)) {
13644 for(
MInt c = 0; c < m_sortedPeriodicCells->size(); c++) {
13645 if(a_isHalo(m_sortedPeriodicCells->a[c])) {
13646 a_variable(m_sortedPeriodicCells->a[c], CV->RHO) = F0;
13647 IF_CONSTEXPR(hasE<SysEqn>)
13648 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_E) = F0;
13649 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_U) = F0;
13650 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_V) = F0;
13651 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_W) = F0;
13653 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
13654 for(
MInt r = 0; r < m_noRansEquations; ++r) {
13655 a_variable(m_sortedPeriodicCells->a[c], CV->RHO_NN[r]) = F0;
13661 for(
MInt d = 0; d < noDomains(); d++) {
13662 for(
MInt c = 0; c < m_noPerCellsToReceive[d]; c++) {
13663 const auto sortedId =
static_cast<MInt>(m_periodicDataToReceive[d][5 + c * m_noPeriodicData]);
13664 const MInt cell_Id = m_sortedPeriodicCells->a[sortedId];
13666 m_periodicDataToReceive[d][0 + c * m_noPeriodicData] = a_variable(cell_Id, CV->RHO);
13667 m_periodicDataToReceive[d][1 + c * m_noPeriodicData] = a_variable(cell_Id, CV->RHO_U);
13668 m_periodicDataToReceive[d][2 + c * m_noPeriodicData] = a_variable(cell_Id, CV->RHO_V);
13669 m_periodicDataToReceive[d][3 + c * m_noPeriodicData] = a_variable(cell_Id, CV->RHO_W);
13670 IF_CONSTEXPR(hasE<SysEqn>)
13671 m_periodicDataToReceive[d][4 + c * m_noPeriodicData] = a_variable(cell_Id, CV->RHO_E);
13676 for(
MInt c = 0; c < m_noPerCellsToReceive[domainId()]; c++) {
13677 for(
MInt v = 0; v < m_noPeriodicData; v++) {
13678 m_periodicDataToSend[domainId()][v + c * m_noPeriodicData] =
13679 m_periodicDataToReceive[domainId()][v + c * m_noPeriodicData];
13687 send_Req.fill(MPI_REQUEST_NULL);
13688 recv_Req.fill(MPI_REQUEST_NULL);
13690 for(
MInt snd = 0; snd < domainId(); snd++) {
13691 if(m_noPerCellsToSend[snd] > 0) {
13692 MInt bufSize = m_noPerCellsToSend[snd] * m_noPeriodicData;
13693 MPI_Irecv(m_periodicDataToSend[snd], bufSize, MPI_DOUBLE, snd, 0, mpiComm(), &recv_Req[snd], AT_,
13694 "m_periodicDataToSend[snd]");
13697 for(
MInt rcv = 0; rcv < noDomains(); rcv++) {
13698 if(m_noPerCellsToReceive[rcv] > 0 && rcv != domainId()) {
13699 MInt bufSize = m_noPerCellsToReceive[rcv] * m_noPeriodicData;
13700 MPI_Isend(m_periodicDataToReceive[rcv], bufSize, MPI_DOUBLE, rcv, 0, mpiComm(), &send_Req[rcv], AT_,
13701 "m_periodicDataToReceive[rcv]");
13705 if(domainId() < noDomains() - 1) {
13706 for(
MInt snd = domainId() + 1; snd < noDomains(); snd++) {
13707 if(m_noPerCellsToSend[snd] > 0) {
13708 MInt bufSize = m_noPerCellsToSend[snd] * m_noPeriodicData;
13709 MPI_Irecv(m_periodicDataToSend[snd], bufSize, MPI_DOUBLE, snd, 0, mpiComm(), &recv_Req[snd], AT_,
13710 "m_periodicDataToSend[snd]");
13715 RECORD_TIMER_START(m_timers[Timers::SCCorrExchange2Wait]);
13716 MPI_Waitall(noDomains(), &recv_Req[0], MPI_STATUSES_IGNORE, AT_);
13717 MPI_Waitall(noDomains(), &send_Req[0], MPI_STATUSES_IGNORE, AT_);
13718 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange2Wait]);
13722 for(
MInt d = 0; d < noDomains(); d++) {
13723 for(
MInt c = 0; c < m_noPerCellsToSend[d]; c++) {
13724 const auto cell_Id =
static_cast<MInt>(m_periodicDataToSend[d][6 + c * m_noPeriodicData]);
13726 a_variable(cell_Id, CV->RHO) += m_periodicDataToSend[d][0 + c * m_noPeriodicData];
13727 a_variable(cell_Id, CV->RHO_U) += m_periodicDataToSend[d][1 + c * m_noPeriodicData];
13728 a_variable(cell_Id, CV->RHO_V) += m_periodicDataToSend[d][2 + c * m_noPeriodicData];
13729 a_variable(cell_Id, CV->RHO_W) += m_periodicDataToSend[d][3 + c * m_noPeriodicData];
13730 IF_CONSTEXPR(hasE<SysEqn>)
13731 a_variable(cell_Id, CV->RHO_E) += m_periodicDataToSend[d][4 + c * m_noPeriodicData];
13736 RECORD_TIMER_STOP(m_timers[Timers::SCCorrExchange2]);
13759template <MInt nDim_,
class SysEqn>
13760template <MInt diag, MBool recorrectBndryCellCoords>
13764 if(recorrectBndryCellCoords != m_fvBndryCnd->m_cellCoordinatesCorrected) {
13765 return getAdjacentLeafCells<diag, !recorrectBndryCellCoords>(cellId, noLayers, adjacentCells, layerId);
13768 if(recorrectBndryCellCoords && !m_fvBndryCnd->m_cellCoordinatesCorrected)
13769 mTerm(1, AT_,
"Corrected cell coordinates are expected.");
13770 if(!recorrectBndryCellCoords && m_fvBndryCnd->m_cellCoordinatesCorrected)
13771 mTerm(1, AT_,
"Uncorrected cell coordinates are expected.");
13773 std::array<std::array<MInt, 4>, nDim> tmpNghbrs;
13775 MInt gridcell = cellId;
13776 if(a_hasProperty(cellId, SolverCell::IsSplitClone)) {
13777 gridcell = m_splitChildToSplitCell.find(cellId)->second;
13779 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && c_noChildren(gridcell) > 0)
return 0;
13780 map<MInt, MInt> nghbrs;
13781 nghbrs.insert(pair<MInt, MInt>(cellId, 0));
13782 for(
MInt layer = 1; layer <= noLayers; layer++) {
13783 set<MInt> nextLayer;
13784 for(
auto& nghbr : nghbrs) {
13785 MInt nghbrId = nghbr.first;
13786 for(
MInt dir0 = 0; dir0 < 2 * nDim; dir0++) {
13787 const MInt cnt0 = getNghbrLeafCells<recorrectBndryCellCoords>(nghbrId, cellId, layer, &tmpNghbrs[0][0], dir0);
13788 for(
MInt c0 = 0; c0 < cnt0; c0++) {
13789 nextLayer.insert(tmpNghbrs[0][c0]);
13791 for(
MInt dir1 = 0; dir1 < 2 * nDim; dir1++) {
13792 if((dir1 / 2) == (dir0 / 2)) {
13795 const MInt cnt1 = getNghbrLeafCells<recorrectBndryCellCoords>(tmpNghbrs[0][c0], cellId, layer,
13796 &tmpNghbrs[1][0], dir1, dir0);
13797 for(
MInt c1 = 0; c1 < cnt1; c1++) {
13798 nextLayer.insert(tmpNghbrs[1][c1]);
13799 IF_CONSTEXPR(nDim == 3 && diag == 2) {
13800 for(
MInt dir2 = 0; dir2 < 2 * nDim; dir2++) {
13801 if(((dir2 / 2) == (dir0 / 2)) || ((dir2 / 2) == (dir1 / 2)))
continue;
13802 const MInt cnt2 = getNghbrLeafCells<recorrectBndryCellCoords>(tmpNghbrs[1][c1], cellId, layer,
13803 &tmpNghbrs[2][0], dir2, dir1, dir0);
13804 for(
MInt c2 = 0; c2 < cnt2; c2++) {
13805 nextLayer.insert(tmpNghbrs[2][c2]);
13815 for(
MInt it : nextLayer) {
13816 nghbrs.insert(pair<MInt, MInt>(it, layer));
13819 nghbrs.erase(cellId);
13821 for(
auto it = nghbrs.begin(); it != nghbrs.end(); it++) {
13822 ASSERT(cnt < (
signed)adjacentCells.
size(),
13823 to_string(cellId) +
" " + to_string(nghbrs.size()) +
" " + to_string(a_isHalo(cellId)) +
" "
13824 + to_string(a_isWindow(cellId)) +
" " + to_string(adjacentCells.
size()));
13825 if(a_hasProperty(it->first, SolverCell::IsSplitCell)) {
13826 auto it2 = find(m_splitCells.begin(), m_splitCells.end(), it->first);
13827 if(it2 == m_splitCells.end())
mTerm(1, AT_,
"split cells inconsistency.");
13828 const MInt pos = distance(m_splitCells.begin(), it2);
13829 ASSERT(m_splitCells[pos] == it->first,
"");
13830 for(
MUlong c = 0; c < m_splitChilds[pos].size(); c++) {
13831 adjacentCells[cnt] = m_splitChilds[pos][c];
13832 layerId[cnt] = it->second;
13833 ASSERT(adjacentCells[cnt] > -1,
"");
13834 ASSERT(a_hasProperty(adjacentCells[cnt], SolverCell::IsSplitChild) || c_noChildren(adjacentCells[cnt]) == 0,
13839 adjacentCells[cnt] = it->first;
13840 layerId[cnt] = it->second;
13841 ASSERT(adjacentCells[cnt] > -1,
"");
13842 ASSERT(c_noChildren(adjacentCells[cnt]) == 0,
"");
13857template <MInt nDim_,
class SysEqn>
13858template <MBool recorrectBndryCellCoords>
13863 const MInt gridcellId =
13864 a_hasProperty(cellId, SolverCell::IsSplitClone) ? m_splitChildToSplitCell.find(cellId)->second : cellId;
13866 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
13870 if(checkNeighborActive(gridcellId, dir) && a_hasNeighbor(gridcellId, dir) > 0) {
13871 const MInt nextId = c_neighborId(gridcellId, dir);
13872 if(nextId < 0)
return 0;
13874 if(c_noChildren(nextId) > 0) {
13875 for(
MInt child = 0; child <
IPOW2(nDim); child++) {
13876 if(!childCode[dir][child])
continue;
13877 if(dir1 > -1 && !childCode[dir1][child])
continue;
13878 if(dir2 > -1 && !childCode[dir2][child])
continue;
13879 const MInt childId = c_childId(nextId, child);
13880 if(childId < 0)
continue;
13881 if(c_noChildren(childId) > 0)
continue;
13882 if(a_hasProperty(childId, SolverCell::IsOnCurrentMGLevel)) {
13883 nghbrs[count] = childId;
13887 }
else if(a_hasProperty(nextId, SolverCell::IsOnCurrentMGLevel)) {
13888 nghbrs[0] = nextId;
13891 }
else if(c_parentId(gridcellId) > -1) {
13892 if(a_hasNeighbor(c_parentId(gridcellId), dir) > 0) {
13893 const MInt nextId = c_neighborId(c_parentId(gridcellId), dir);
13894 if(nextId < 0 || c_noChildren(nextId) > 0) {
13897 if(a_hasProperty(nextId, SolverCell::IsOnCurrentMGLevel)) {
13898 nghbrs[0] = nextId;
13904 std::array<MFloat, nDim> coord0{};
13905 for(
MInt i = 0; i < nDim; i++) {
13906 coord0[i] = a_coordinate(refCell, i)
13907 - ((recorrectBndryCellCoords && a_bndryId(refCell) > -1)
13908 ? m_fvBndryCnd->m_bndryCells->a[a_bndryId(refCell)].m_coordinates[i]
13912 for(
MInt c = 0; c < count; c++) {
13913 const MFloat delta = ((
MFloat)layer) * 0.5005 * (c_cellLengthAtCell(nghbrs[c]) + c_cellLengthAtCell(refCell));
13915 for(
MInt i = 0; i < nDim; i++) {
13916 const MFloat correctedCoord = a_coordinate(nghbrs[c], i)
13917 - ((recorrectBndryCellCoords && a_bndryId(nghbrs[c]) > -1)
13918 ? m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrs[c])].m_coordinates[i]
13920 if(std::abs(correctedCoord - coord0[i]) > delta) {
13921 nghbrs[c] = nghbrs[count - 1];
13934template <MInt nDim_,
class SysEqn>
13938 return getAdjacentLeafCells<0>(cellId, noLayers, nghbrList, layerId);
13940template <MInt nDim_,
class SysEqn>
13944 return getAdjacentLeafCells<1>(cellId, noLayers, nghbrList, layerId);
13946template <MInt nDim_,
class SysEqn>
13950 return getAdjacentLeafCells<2>(cellId, noLayers, nghbrList, layerId);
13952template <MInt nDim_,
class SysEqn>
13956 return getAdjacentLeafCells<0, true>(cellId, noLayers, nghbrList, layerId);
13958template <MInt nDim_,
class SysEqn>
13962 return getAdjacentLeafCells<1, true>(cellId, noLayers, nghbrList, layerId);
13964template <MInt nDim_,
class SysEqn>
13968 return getAdjacentLeafCells<2, true>(cellId, noLayers, nghbrList, layerId);
13983template <MInt nDim_,
class SysEqn>
13988 if(m_levelSet && m_combustion && abs(m_flameSpeed) <= 0) {
13989 m_log <<
"WARNING: applyBoundaryCondition() " << endl;
13997 if(m_fvBndryCnd->m_multipleGhostCells) {
13999 m_fvBndryCnd->updateImagePointVariables(0);
14002 if(m_fvBndryCnd->m_multipleGhostCells && m_fvBndryCnd->m_ipVariableIterative) {
14004 while(iter < m_fvBndryCnd->m_noImagePointIterations) {
14006 m_fvBndryCnd->updateGhostCellVariables();
14008 m_fvBndryCnd->applyNeumannBoundaryCondition();
14010 LSReconstructCellCenter_Boundary();
14012 m_fvBndryCnd->updateImagePointVariables(1);
14019 m_fvBndryCnd->updateGhostCellVariables();
14022 m_fvBndryCnd->applyNeumannBoundaryCondition();
14032template <MInt nDim_,
class SysEqn>
14036 const MBool diagonalCellAddition = m_fvBndryCnd->m_cellMerging && (nDim == 3);
14037 const MInt maxNoNghbrs = 100;
14041 m_fvBndryCnd->recorrectCellCoordinates();
14043 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
14044 const MInt bndryId = a_bndryId(cellId);
14045 MInt gridcell = cellId;
14046 if(a_hasProperty(cellId, SolverCell::IsSplitClone)) {
14047 gridcell = m_splitChildToSplitCell.find(cellId)->second;
14050 a_noReconstructionNeighbors(cellId) = 0;
14052 if(a_isBndryGhostCell(cellId))
continue;
14053 if(c_noChildren(gridcell) > 0)
continue;
14054 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
14056 if(a_hasProperty(cellId, SolverCell::IsNotGradient))
continue;
14057 if(a_hasProperty(cellId, SolverCell::IsInvalid))
continue;
14064 const MInt counter = getAdjacentLeafCells<0>(cellId, 1, nghbrList, layerId);
14065 if(counter > maxNoNghbrs)
mTerm(1, AT_,
"too many nghbrs " + to_string(counter));
14067 for(
MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
14068 a_reconstructionNeighborId(cellId, a_noReconstructionNeighbors(cellId)) =
14069 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
14070 a_noReconstructionNeighbors(cellId)++;
14073 MBool atInterface =
false;
14074 for(
MInt k = 0; k < counter; k++) {
14075 MInt nghbrId = nghbrList[k];
14076 if(nghbrId < 0)
continue;
14077 if(a_hasProperty(nghbrId, SolverCell::IsInvalid))
continue;
14079 a_reconstructionNeighborId(cellId, a_noReconstructionNeighbors(cellId)) = nghbrId;
14080 a_noReconstructionNeighbors(cellId)++;
14081 if(a_noReconstructionNeighbors(cellId) > m_cells.noRecNghbrs()) {
14082 mTerm(1, AT_,
"too many rec nghbrs " + to_string(cellId) +
" " + to_string(counter));
14084 if(a_level(nghbrId) < a_level(cellId)) atInterface =
true;
14086 if(diagonalCellAddition && atInterface) {
14087 const MInt counter2 = getAdjacentLeafCells<2>(cellId, 1, nghbrList, layerId);
14088 for(
MInt k = 0; k < counter2; k++) {
14089 MInt nghbrId = nghbrList[k];
14090 if(nghbrId < 0)
continue;
14091 if(a_hasProperty(nghbrId, SolverCell::IsInvalid))
continue;
14092 if(a_level(nghbrId) >= a_level(cellId))
continue;
14093 MBool exist =
false;
14094 for(
MInt i = 0; i < a_noReconstructionNeighbors(cellId); i++) {
14095 if(a_reconstructionNeighborId(cellId, i) == nghbrId) {
14101 a_reconstructionNeighborId(cellId, a_noReconstructionNeighbors(cellId)) = nghbrId;
14102 a_noReconstructionNeighbors(cellId)++;
14104 if(a_noReconstructionNeighbors(cellId) > m_cells.noRecNghbrs()) {
14105 mTerm(1, AT_,
"too many rec nghbrs " + to_string(cellId) +
" " + to_string(counter));
14111 if(m_fvBndryCnd->m_cellMerging) {
14114 MInt noSmallCells = m_fvBndryCnd->m_smallBndryCells->size();
14115 for(
MInt smallId = 0; smallId < noSmallCells; smallId++) {
14116 MInt smallCell = m_fvBndryCnd->m_smallBndryCells->a[smallId];
14117 MInt smallCellId = m_fvBndryCnd->m_bndryCells->a[smallCell].m_cellId;
14118 MInt masterCellId = m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId;
14119 if(a_bndryId(masterCellId) == -1) {
14120 for(
MInt i = 0; i < a_noReconstructionNeighbors(smallCellId); i++) {
14121 MInt nghbrId = a_reconstructionNeighborId(smallCellId, i);
14122 if(a_bndryId(nghbrId) > -1)
14123 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId > -1)
14124 nghbrId = m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId;
14125 MBool found =
false;
14126 for(
MInt j = 0; j < a_noReconstructionNeighbors(masterCellId); j++) {
14127 if(nghbrId == a_reconstructionNeighborId(masterCellId, j)) {
14132 if(!found && nghbrId != masterCellId) {
14133 a_reconstructionNeighborId(masterCellId, a_noReconstructionNeighbors(masterCellId)) = nghbrId;
14134 a_noReconstructionNeighbors(masterCellId)++;
14141 m_fvBndryCnd->rerecorrectCellCoordinates();
14151template <MInt nDim_,
class SysEqn>
14155 if(m_orderOfReconstruction > 1)
mTerm(1, AT_,
"Check code here.");
14157 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
14158 const MInt recDim = (m_orderOfReconstruction == 2) ? (
IPOW2(nDim) + 1) : nDim;
14169 m_reconstructionConstants.clear();
14170 m_reconstructionCellIds.clear();
14171 m_reconstructionNghbrIds.clear();
14174 m_reconstructionDataSize = 0;
14177 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
14178 a_hasProperty(cellId, SolverCell::IsFlux) =
false;
14181 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
14182 a_reconstructionData(cellId) = m_reconstructionDataSize;
14184 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
14186 if(a_isBndryGhostCell(cellId))
continue;
14187 if(a_hasProperty(cellId, SolverCell::IsNotGradient))
continue;
14191 if(a_bndryId(cellId) > -1) {
14192 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId > -1) {
14197 a_hasProperty(cellId, SolverCell::IsFlux) =
true;
14200 const MInt noNghbrIds = a_noReconstructionNeighbors(cellId);
14201 if(noNghbrIds == 0)
continue;
14203 for(
MInt n = 0; n < noNghbrIds; n++) {
14204 const MInt nghbrId = a_reconstructionNeighborId(cellId, n);
14205 a_hasProperty(nghbrId, SolverCell::IsFlux) =
true;
14209 computeRecConstSVD(cellId, m_reconstructionDataSize, tmpA, tmpC, weights, recDim, m_reConstSVDWeightMode, -1);
14211 m_reconstructionDataSize += noNghbrIds;
14215 maxc =
mMax(maxc, condNum);
14218 std::ignore = condNum;
14223 a_reconstructionData(a_noCells()) = m_reconstructionDataSize;
14226 for(
MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
14227 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
14228 if(a_hasProperty(cellId, SolverCell::IsNotGradient))
continue;
14229 for(
MInt nghbr = 0; nghbr < a_noReconstructionNeighbors(cellId); nghbr++) {
14230 for(
MInt i = 0; i < nDim; i++) {
14231 m_fvBndryCnd->m_reconstructionConstants[bndryId][nghbr * nDim + i] =
14232 m_reconstructionConstants[nDim * (a_reconstructionData(cellId) + nghbr) + i];
14235 const MUint noRecNghbrs = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size();
14236 const MInt noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
14238 for(
MUint n = noSrfcs; n < noRecNghbrs; n++) {
14239 a_hasProperty(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], SolverCell::IsFlux) =
true;
14243 m_log <<
"ok" << endl;
14247 MPI_Allreduce(MPI_IN_PLACE, &maxc, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"maxc");
14248 MPI_Allreduce(MPI_IN_PLACE, &avg, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"avg");
14249 MPI_Allreduce(MPI_IN_PLACE, &counter, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"counter");
14251 m_log <<
" -> Singular value decomposition: maximum/average condition number: " << maxc <<
"/" << avg / counter
14261template <MInt nDim_,
class SysEqn>
14265 m_fvBndryCnd->updateCutOffCellVariables();
14269template <MInt nDim_,
class SysEqn>
14273 m_fvBndryCnd->initCutOffBndryCnds();
14278template <MInt nDim_,
class SysEqn>
14282 m_fvBndryCnd->applyNonReflectingBCCutOff();
14289template <MInt nDim_,
class SysEqn>
14293 m_fvBndryCnd->applyNonReflectingBCAfterTreatmentCutOff();
14300template <MInt nDim_,
class SysEqn>
14304 const MInt noSrfcs = a_noSurfaces();
14307 for(
MInt s = 0; s < noSrfcs; s++) {
14308 for(
MInt i = 0; i < nDim; i++) {
14309 a_surfaceDeltaX(s, i) = a_surfaceCoordinate(s, i) - a_coordinate(a_surfaceNghbrCellId(s, 0), i);
14310 a_surfaceDeltaX(s, nDim + i) = a_surfaceCoordinate(s, i) - a_coordinate(a_surfaceNghbrCellId(s, 1), i);
14340template <MInt nDim_,
class SysEqn>
14344 MInt noCellIds = a_noCells();
14351 for(
MInt cellId = 0; cellId < noCellIds; cellId++) {
14352 if(!a_isBndryGhostCell(cellId)) {
14353 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
14355 gccCoordinates[cellId * nDim + spaceId] = a_coordinate(cellId, spaceId);
14358 if(a_bndryId(cellId) > -1) {
14359 bndryId = a_bndryId(cellId);
14361 gccCoordinates[cellId * nDim + spaceId] -= m_fvBndryCnd->m_bndryCells->a[bndryId].m_coordinates[spaceId];
14368 for(
MInt smallId = 0; smallId < m_fvBndryCnd->m_smallBndryCells->size(); smallId++) {
14369 smallCell = m_fvBndryCnd->m_smallBndryCells->a[smallId];
14370 if(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId > -1) {
14371 if(a_bndryId(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId) == -1) {
14372 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
14373 gccCoordinates[(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId) * nDim + spaceId] =
14374 m_fvBndryCnd->m_bndryCells->a[smallCell].m_masterCoordinates[spaceId];
14385template <MInt nDim_,
class SysEqn>
14391 const MInt noCells = a_noCells();
14392 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
14395 for(
MInt cellId = 0; cellId < noCells; cellId++) {
14396 a_cellVolume(cellId) = c_cellLengthAtCell(cellId);
14397 for(
MInt spaceId = 1; spaceId < nDim; spaceId++) {
14398 a_cellVolume(cellId) *= c_cellLengthAtCell(cellId);
14402 for(
MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
14403 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
14404 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
14408 for(
MInt smallId = 0; smallId < m_fvBndryCnd->m_smallBndryCells->size(); smallId++) {
14409 smallCell = m_fvBndryCnd->m_smallBndryCells->a[smallId];
14410 masterId = m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId;
14411 if(a_bndryId(masterId) == -1) {
14412 a_cellVolume(masterId) += m_fvBndryCnd->m_bndryCells->a[smallCell].m_volume;
14418 for(
MInt cellId = 0; cellId < noCells; cellId++) {
14419 if(a_cellVolume(cellId) < 0.0
14422 cerr <<
"!!!Volume is " << a_cellVolume(cellId) << endl;
14423 cerr <<
"cell Id " << c_globalId(cellId) <<
" level " << a_level(cellId) << endl;
14424 if(a_bndryId(cellId) > -1) {
14425 cerr <<
"... is a boundary cell" << endl << endl;
14427 cerr <<
"Coordinates: " << a_coordinate(cellId, 0) <<
" " << a_coordinate(cellId, 1);
14428 IF_CONSTEXPR(nDim == 3) cerr <<
" " << a_coordinate(cellId, 2);
14434 for(
MInt cellId = 0; cellId < noCells; cellId++) {
14435 a_FcellVolume(cellId) = F1 / a_cellVolume(cellId);
14448template <MInt nDim_,
class SysEqn>
14452 if(m_spongeLayerThickness > F0) {
14453 std::array<MFloat, 6> values{};
14454 values = computeTargetValues();
14456 for(
MInt c = 0; c < m_noCellsInsideSpongeLayer; c++) {
14457 const MInt cellId = m_cellsInsideSpongeLayer[c];
14459 updateSpongeLayerRhs(cellId, computeSpongeDeltas(cellId, values));
14464template <MInt nDim_,
class SysEqn>
14466 using valueA = std::array<MFloat, 6>;
14468 values[0] = m_rhoInfinity;
14469 values[1] = m_PInfinity;
14470 values[2] = m_rhoInfinity;
14471 values[3] = m_PInfinity;
14472 values[4] = m_rhoInfinity;
14473 values[5] = m_PInfinity;
14475 switch(m_spongeLayerType) {
14477 values[0] = m_rhoHg;
14480 values[3] = m_rhoCg;
14486 values[0] = m_rhoInfinity;
14487 values[1] = m_PInfinity;
14488 values[2] = m_UInfinity;
14489 values[3] = m_VInfinity;
14490 values[4] = m_WInfinity;
14491 values[5] = m_UInfinity;
14495 values[0] = m_rhoInfinity;
14496 values[1] = m_PInfinity;
14497 values[2] = m_UInfinity;
14498 values[3] = m_VInfinity;
14499 values[4] = m_WInfinity;
14500 values[5] = m_UInfinity;
14504 values[0] = m_rhoInfinity;
14505 values[1] = m_PInfinity;
14506 values[2] = m_UInfinity;
14507 values[3] = m_VInfinity;
14508 values[4] = m_WInfinity;
14509 values[5] = m_UInfinity;
14515 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "Info: untested in 2D.");
14517 m_deltaP = 1.002083018;
14518 values[1] = m_PInfinity * m_deltaP;
14525 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "Info: This sponge layer type only works in 3D.");
14527 static constexpr
MInt noRSteps = 20;
14529 if(m_firstUseUpdateSpongeLayerCase51) {
14530 m_hasCellsInSpongeLayer = m_noCellsInsideSpongeLayer;
14532 m_noSpongeZonesIn = 0;
14545 m_noSpongeZonesOut = 0;
14546 m_noSpongeZonesIn = Context::getSolverProperty<MInt>(
"noSpongeZonesIn", m_solverId, AT_, &m_noSpongeZonesIn);
14547 m_noSpongeZonesOut = Context::getSolverProperty<MInt>(
"noSpongeZonesOut", m_solverId, AT_, &m_noSpongeZonesOut);
14548 if(m_noSpongeZonesIn > 0) {
14549 for(
MInt i = 0; i < m_noSpongeZonesIn; i++) {
14550 m_spongeDirectionsIn[i] = Context::getSolverProperty<MInt>(
"spongeDirectionsIn", m_solverId, AT_, i);
14559 m_secondSpongeDirectionsIn[i] =
14560 Context::getSolverProperty<MInt>(
"secondSpongeDirectionsIn", m_solverId, AT_, i);
14561 m_spongeAveragingIn[i] = Context::getSolverProperty<MInt>(
"spongeAveragingIn", m_solverId, AT_, i);
14564 if(m_noSpongeZonesOut > 0) {
14565 for(
MInt i = 0; i < m_noSpongeZonesOut; i++) {
14575 m_spongeDirectionsOut[i] = Context::getSolverProperty<MInt>(
"spongeDirectionsOut", m_solverId, AT_, i);
14584 m_secondSpongeDirectionsOut[i] =
14585 Context::getSolverProperty<MInt>(
"secondSpongeDirectionsOut", m_solverId, AT_, i);
14594 m_spongeAveragingOut[i] = Context::getSolverProperty<MInt>(
"spongeAveragingOut", m_solverId, AT_, i);
14597 MIntScratchSpace comm_buff_scratch_processes(1, AT_,
"comm_buff_scratch_processes");
14598 MIntScratchSpace comm_buff_result_scratch_processes(noDomains(), AT_,
"comm_buff_result_scratch_processes");
14599 MInt* comm_buff_processes = comm_buff_scratch_processes.getPointer();
14600 MInt* comm_buff_result_processes = comm_buff_result_scratch_processes.getPointer();
14601 comm_buff_processes[0] = m_hasCellsInSpongeLayer;
14603 MPI_Allgather(comm_buff_processes, 1, MPI_INT, comm_buff_result_processes, 1, MPI_INT, mpiComm(), AT_,
14604 "comm_buff_processes",
"comm_buff_result_processes");
14606 MPI_Group world_group;
14607 MPI_Group group_sponge;
14608 MInt noProcs_sponge = 0;
14609 for(
MInt i = 0; i < noDomains(); i++) {
14610 if(comm_buff_result_processes[i] > 0) {
14616 for(
MInt i = 0; i < noDomains(); i++) {
14617 if(comm_buff_result_processes[i] > 0) {
14618 procs_sponge[count++] = i;
14623 MPI_Group_incl(world_group, noProcs_sponge, procs_sponge.getPointer(), &group_sponge, AT_);
14625 MPI_Comm_create(mpiComm(), group_sponge, &comm_sponge, AT_,
"comm_sponge");
14638 m_timeOfMaxPdiff = 0.0;
14639 m_timeOfMaxPdiff = Context::getSolverProperty<MFloat>(
"timeOfMaxPdiff", m_solverId, AT_, &m_timeOfMaxPdiff);
14641 m_timeOfMaxPdiff = m_timeOfMaxPdiff / m_timeRef;
14643 m_firstUseUpdateSpongeLayerCase51 =
false;
14646 mAlloc(m_coordSpongeIn, m_noSpongeZonesIn,
"m_coordSpongeIn", AT_);
14647 mAlloc(m_secondCoordSpongeIn, m_noSpongeZonesIn,
"m_secondCoordSpongeIn", AT_);
14648 mAlloc(m_coordSpongeOut, m_noSpongeZonesOut,
"m_coordSpongeOut", AT_);
14649 mAlloc(m_secondCoordSpongeOut, m_noSpongeZonesOut,
"m_secondCoordSpongeOut", AT_);
14650 mAlloc(m_uNormal_r, noRSteps,
"m_uNormal_r", AT_);
14652 if(!m_hasCellsInSpongeLayer) {
14663 MFloatScratchSpace comm_buff_scratch(2 * m_noSpongeZonesIn + 2 * m_noSpongeZonesOut + 40, AT_,
14664 "comm_buff_scratch");
14665 MFloatScratchSpace comm_buff_result_scratch(2 * m_noSpongeZonesIn + 2 * m_noSpongeZonesOut + 40, AT_,
14666 "comm_buff_result_scratch");
14667 MFloat* comm_buff = comm_buff_scratch.getPointer();
14668 MFloat* comm_buff_result = comm_buff_result_scratch.getPointer();
14670 auto* tmp =
new MFloat[6];
14671 m_geometry->getBoundingBox(tmp);
14678 constexpr MFloat directionSign[6] = {1.0, -1.0, 1.0, -1.0, 1.0, -1.0};
14679 constexpr MInt directionDim[6] = {0, 0, 1, 1, 2, 2};
14680 constexpr MInt otherDirection[6] = {1, 0, 3, 2, 5, 4};
14681 const MFloat cellLength = c_cellLengthAtLevel(maxRefinementLevel());
14683 MInt counter_r[noRSteps];
14684 for(
MInt i = 0; i < noRSteps; i++) {
14685 m_uNormal_r[i] = F0;
14688 const MFloat rDiff = R / noRSteps;
14692 for(
MInt i = 0; i < m_noSpongeZonesIn; i++) {
14694 pressureIn[i] = F0;
14695 spongeVolumeIn[i] = F0;
14696 coordAverageIn[i] = bBox[m_spongeDirectionsIn[i]]
14697 + directionSign[m_spongeDirectionsIn[i]] * m_spongeAveragingIn[i] * cellLength;
14698 m_coordSpongeIn[i] = m_spongeCoord[m_spongeDirectionsIn[i]];
14699 if(m_secondSpongeDirectionsIn[i] > -1) {
14700 m_secondCoordSpongeIn[i] =
14701 F1B2 * (bBox[m_secondSpongeDirectionsIn[i]] + bBox[otherDirection[m_secondSpongeDirectionsIn[i]]]);
14703 m_secondSpongeDirectionsIn[i] = m_spongeDirectionsIn[i];
14704 m_secondCoordSpongeIn[i] = bBox[otherDirection[m_secondSpongeDirectionsIn[i]]];
14707 for(
MInt i = 0; i < m_noSpongeZonesOut; i++) {
14708 densityOut[i] = F0;
14709 pressureOut[i] = F0;
14710 spongeVolumeOut[i] = F0;
14711 coordAverageOut[i] = bBox[m_spongeDirectionsOut[i]]
14712 + directionSign[m_spongeDirectionsOut[i]] * m_spongeAveragingOut[i] * cellLength;
14713 m_coordSpongeOut[i] = m_spongeCoord[m_spongeDirectionsOut[i]];
14714 if(m_secondSpongeDirectionsOut[i] > -1) {
14715 m_secondCoordSpongeOut[i] =
14716 F1B2 * (bBox[m_secondSpongeDirectionsOut[i]] + bBox[otherDirection[m_secondSpongeDirectionsOut[i]]]);
14718 m_secondSpongeDirectionsOut[i] = m_spongeDirectionsOut[i];
14719 m_secondCoordSpongeOut[i] = bBox[otherDirection[m_secondSpongeDirectionsOut[i]]];
14724 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
14727 if(a_hasProperty(cellId, SolverCell::IsInvalid)) {
14730 if(!a_hasProperty(cellId, SolverCell::IsActive)) {
14734 for(
MInt i = 0; i < m_noSpongeZonesIn; i++) {
14735 if(!a_isBndryGhostCell(cellId)
14736 && (a_coordinate(cellId, directionDim[m_spongeDirectionsIn[i]]) - coordAverageIn[i])
14737 * directionSign[m_spongeDirectionsIn[i]]
14739 && (a_coordinate(cellId, directionDim[m_secondSpongeDirectionsIn[i]]) - m_secondCoordSpongeIn[i])
14740 * directionSign[m_secondSpongeDirectionsIn[i]]
14742 pressureIn[i] += a_pvariable(cellId, PV->P) * a_cellVolume(cellId);
14743 spongeVolumeIn[i] += a_cellVolume(cellId);
14744 if(a_bndryId(cellId) > -1) {
14745 for(
MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs; srfc++) {
14746 const MInt ghostCellId =
14747 m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcVariables[srfc]->m_ghostCellId;
14748 pressureIn[i] += a_pvariable(ghostCellId, PV->P) * a_cellVolume(ghostCellId);
14749 spongeVolumeIn[i] += a_cellVolume(ghostCellId);
14754 for(
MInt i = 0; i < m_noSpongeZonesOut; i++) {
14755 if(!a_isBndryGhostCell(cellId)
14756 && (a_coordinate(cellId, directionDim[m_spongeDirectionsOut[i]]) - coordAverageOut[i])
14757 * directionSign[m_spongeDirectionsOut[i]]
14759 && (a_coordinate(cellId, directionDim[m_secondSpongeDirectionsOut[i]]) - m_secondCoordSpongeOut[i])
14760 * directionSign[m_secondSpongeDirectionsOut[i]]
14762 densityOut[i] += a_pvariable(cellId, PV->RHO) * a_cellVolume(cellId);
14763 spongeVolumeOut[i] += a_cellVolume(cellId);
14765 const MFloat r = sqrt(
POW2(a_coordinate(cellId, 1)) +
POW2(a_coordinate(cellId, 2)));
14766 const auto rIndex = (
MInt)((R - r) / rDiff);
14767 m_uNormal_r[rIndex] += a_pvariable(cellId, PV->U);
14768 counter_r[rIndex]++;
14774 for(
MInt i = 0; i < m_noSpongeZonesIn; i++) {
14775 comm_buff[2 * i] = pressureIn[i];
14776 comm_buff[2 * i + 1] = spongeVolumeIn[i];
14779 for(
MInt i = 0; i < m_noSpongeZonesOut; i++) {
14780 comm_buff[2 * m_noSpongeZonesIn + 2 * i] = densityOut[i];
14781 comm_buff[2 * m_noSpongeZonesIn + 2 * i + 1] = spongeVolumeOut[i];
14783 for(
MInt i = 0; i < 20; i++) {
14784 comm_buff[2 * m_noSpongeZonesIn + 2 * m_noSpongeZonesOut + i] = m_uNormal_r[i];
14785 comm_buff[2 * m_noSpongeZonesIn + 2 * m_noSpongeZonesOut + 20 + i] = counter_r[i];
14788 MPI_Allreduce(comm_buff, comm_buff_result, 2 * (m_noSpongeZonesIn + m_noSpongeZonesOut) + 40, MPI_DOUBLE, MPI_SUM,
14789 comm_sponge, AT_,
"comm_buff",
"comm_buff_result");
14791 for(
MInt i = 0; i < m_noSpongeZonesIn; i++) {
14792 pressureIn[i] = comm_buff_result[2 * i] / comm_buff_result[2 * i + 1];
14793 densityIn[i] = sysEqn().density_IR_P(pressureIn[i]);
14795 for(
MInt i = 0; i < noRSteps; i++) {
14796 m_uNormal_r[i] = comm_buff_result[i + 2 * (m_noSpongeZonesIn + m_noSpongeZonesOut)]
14797 / comm_buff_result[i + 2 * (m_noSpongeZonesIn + m_noSpongeZonesOut) + 20];
14798 if(m_uNormal_r[i] < F0) {
14799 m_uNormal_r[i] = F0;
14804 if(m_noSpongeZonesIn > 6)
14806 "FvCartesianSolverXD::computeTargetValues(): For noSpongeZonesIn>6 the code needs to be "
14809 for(
MInt i = 0; i < m_noSpongeZonesIn; i++)
14810 values[i] = pressureIn[i];
14817 const MFloat pressureAmbient = m_PInfinity;
14818 const MFloat densityAmbient = m_rhoInfinity;
14820 const MFloat pressure_i = m_nozzleInletP;
14821 const MFloat density_i = m_nozzleInletRho;
14823 values[0] = density_i;
14824 values[1] = pressure_i;
14826 values[2] = densityAmbient;
14827 values[3] = pressureAmbient;
14836 MFloat* comm_buff = comm_buff_scratch.getPointer();
14837 MFloat* comm_buff_result = comm_buff_result_scratch.getPointer();
14839 MFloat spongeVolume = F0;
14840 MFloat pressureIn1 = F0;
14841 MFloat spongeVolumeIn1 = F0;
14842 MFloat pressureIn2 = F0;
14843 MFloat spongeVolumeIn2 = F0;
14851 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
14854 if(a_hasProperty(cellId, SolverCell::IsInvalid)) {
14857 if(!a_hasProperty(cellId, SolverCell::IsActive)) {
14860 if(a_hasProperty(cellId, SolverCell::IsHalo))
continue;
14861 if(!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 2) < -67.0) {
14862 density += a_pvariable(cellId, PV->RHO) * a_cellVolume(cellId);
14863 spongeVolume += a_cellVolume(cellId);
14865 if(!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 0) > 82.0 && a_coordinate(cellId, 1) > 0.0) {
14866 pressureIn1 += a_pvariable(cellId, PV->P) * a_cellVolume(cellId);
14867 u_in1 += a_pvariable(cellId, PV->U) * a_cellVolume(cellId);
14868 v_in1 += a_pvariable(cellId, PV->V) * a_cellVolume(cellId);
14869 w_in1 += a_pvariable(cellId, PV->W) * a_cellVolume(cellId);
14870 spongeVolumeIn1 += a_cellVolume(cellId);
14871 if(a_bndryId(cellId) > -1) {
14872 for(
MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs; srfc++) {
14873 ghostCellId = m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcVariables[srfc]->m_ghostCellId;
14874 pressureIn1 += a_pvariable(ghostCellId, PV->P) * a_cellVolume(ghostCellId);
14875 spongeVolumeIn1 += a_cellVolume(ghostCellId);
14879 if(!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 0) > 82.0 && a_coordinate(cellId, 1) < 0.0) {
14880 pressureIn2 += a_pvariable(cellId, PV->P) * a_cellVolume(cellId);
14881 u_in2 += a_pvariable(cellId, PV->U) * a_cellVolume(cellId);
14882 v_in2 += a_pvariable(cellId, PV->V) * a_cellVolume(cellId);
14883 w_in2 += a_pvariable(cellId, PV->W) * a_cellVolume(cellId);
14884 spongeVolumeIn2 += a_cellVolume(cellId);
14885 if(a_bndryId(cellId) > -1) {
14886 for(
MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs; srfc++) {
14887 ghostCellId = m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcVariables[srfc]->m_ghostCellId;
14888 pressureIn2 += a_pvariable(ghostCellId, PV->P) * a_cellVolume(ghostCellId);
14889 u_in2 += a_pvariable(ghostCellId, PV->U) * a_cellVolume(ghostCellId);
14890 v_in2 += a_pvariable(ghostCellId, PV->V) * a_cellVolume(ghostCellId);
14891 w_in2 += a_pvariable(ghostCellId, PV->W) * a_cellVolume(ghostCellId);
14892 spongeVolumeIn2 += a_cellVolume(ghostCellId);
14897 comm_buff[0] = density;
14898 comm_buff[1] = pressureIn1;
14899 comm_buff[2] = pressureIn2;
14900 comm_buff[3] = spongeVolume;
14901 comm_buff[4] = spongeVolumeIn1;
14902 comm_buff[5] = spongeVolumeIn2;
14903 MPI_Allreduce(comm_buff, comm_buff_result, 6, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"comm_buff",
14904 "comm_buff_result");
14905 density = comm_buff_result[0] / comm_buff_result[3];
14906 MFloat pressure = m_PInfinity - m_deltaPL;
14907 pressureIn1 = comm_buff_result[1] / comm_buff_result[4];
14908 MFloat densityIn1 = sysEqn().density_IR_P(pressureIn1);
14909 pressureIn2 = comm_buff_result[2] / comm_buff_result[5];
14910 MFloat densityIn2 = sysEqn().density_IR_P(pressureIn2);
14912 pressureIn1 = sysEqn().p_Ref();
14914 pressureIn2 = pressureIn1;
14915 densityIn2 = densityIn1;
14917 values[0] = density;
14918 values[1] = pressure;
14919 values[2] = densityIn1;
14920 values[3] = pressureIn1;
14921 values[4] = densityIn2;
14922 values[5] = pressureIn2;
14928 values[0] = m_rhoInfinity;
14929 values[1] = m_PInfinity;
14930 values[2] = m_rhoInfinity;
14931 values[3] = m_PInfinity;
14932 values[4] = m_rhoInfinity;
14933 values[5] = m_PInfinity;
14940 IF_CONSTEXPR(nDim == 3)
mTerm(-1, "Info: This sponge layer type only works in 2D.");
14943 MFloat maxSpongeFactor1 = -999999, minSpongeFactor1 = 999999;
14944 MFloat maxSpongeFactor2 = -999999, minSpongeFactor2 = 999999;
14945 MFloat maxSpongeFactor3 = -999999, minSpongeFactor3 = 999999;
14946 MFloat spongeEndFactor = -99999;
14949 const
MFloat backupMeanPressure = m_meanPressure;
14951 m_meanPressure = F0;
14954 for(
MInt c = 0; c < m_noCellsInsideSpongeLayer; c++) {
14955 const MInt cellId = m_cellsInsideSpongeLayer[c];
14956 if(a_spongeBndryId(cellId, 0) == 176191 || a_spongeBndryId(cellId, 1) == 176191
14957 || a_spongeBndryId(cellId, 0) == 209104 || a_spongeBndryId(cellId, 1) == 209104
14958 || a_spongeBndryId(cellId, 0) == 209101 || a_spongeBndryId(cellId, 1) == 209101
14959 || a_spongeBndryId(cellId, 0) == 17616 || a_spongeBndryId(cellId, 1) == 17616
14960 || a_spongeBndryId(cellId, 0) == 3906 || a_spongeBndryId(cellId, 1) == 3906
14961 || a_spongeBndryId(cellId, 0) == 39060 || a_spongeBndryId(cellId, 1) == 39060
14962 || a_spongeBndryId(cellId, 0) == 209102 || a_spongeBndryId(cellId, 1) == 209102) {
14964 m_meanPressure += a_pvariable(cellId, PV->P);
14968 MPI_Allreduce(MPI_IN_PLACE, &m_meanPressure, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
14970 MPI_Allreduce(MPI_IN_PLACE, &counter, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"counter");
14972 m_meanPressure /= (
MFloat)counter;
14975 for(
MInt c = 0; c < m_noCellsInsideSpongeLayer; c++) {
14976 const MInt cellId = m_cellsInsideSpongeLayer[c];
14978 if(m_spongeTimeDep) {
14979 for(
MInt bcId = 0; bcId < m_noSpongeBndryCndIds; bcId++) {
14980 const MInt bcSpId = m_spongeBndryCndIds[bcId];
14982 if(a_spongeBndryId(cellId, 0) != bcSpId && a_spongeBndryId(cellId, 1) != bcSpId)
continue;
14987 if(a_spongeBndryId(cellId, 1) != -1) {
14988 if(a_spongeBndryId(cellId, 1) == bcSpId) {
14989 bcSpId2 = a_spongeBndryId(cellId, 0);
14991 bcSpId2 = a_spongeBndryId(cellId, 1);
14994 for(
MInt k = 0; k < m_noSpongeBndryCndIds; ++k) {
14995 if(m_spongeBndryCndIds[k] == bcSpId2) {
15006 if(m_spongeTimeDependent[bcId] < 1 && m_spongeTimeDependent[bcId2] < 1)
continue;
15009 if(m_spongeTimeDependent[bcId] < 1)
continue;
15018 if(m_spongeTimeDependent[bcId] == 1 || m_spongeTimeDependent[bcId2] == 1) {
15019 if(a_spongeBndryId(cellId, 0) == bcSpId && a_spongeBndryId(cellId, 1) == -1) {
15022 const MFloat spongeDiff = m_spongeEndIteration[bcId] - m_spongeStartIteration[bcId];
15023 a_spongeFactor(cellId) =
15028 a_spongeFactor(cellId) *= a_spongeFactorStart(cellId);
15030 maxSpongeFactor1 =
mMax(a_spongeFactor(cellId), maxSpongeFactor1);
15031 minSpongeFactor1 =
mMin(a_spongeFactor(cellId), minSpongeFactor1);
15033 if(
approx(a_spongeFactorStart(cellId), -1.0, MFloatEps)) {
15034 cerr <<
"sponge time dependent error, see code in fvbndrycnd2d.cpp or fvsolver2d.cpp" << endl;
15038 a_spongeFactor(cellId) = a_spongeFactorStart(cellId);
15040 maxSpongeFactor1 =
mMax(a_spongeFactor(cellId), maxSpongeFactor1);
15041 minSpongeFactor1 =
mMin(a_spongeFactor(cellId), minSpongeFactor1);
15044 a_spongeFactor(cellId) = F0;
15045 maxSpongeFactor1 = F0;
15046 minSpongeFactor1 = F0;
15053 if(m_spongeTimeDependent[bcId] == 1) {
15056 }
else if(m_spongeTimeDependent[bcId2] == 1) {
15061 stringstream errorMessage;
15062 errorMessage <<
"ERROR: sponge time dependent";
15063 mTerm(1, AT_, errorMessage.str());
15065 switch(m_spongeDirections[bcIdS]) {
15085 mTerm(1, AT_,
"wrong sponge direction selected during solver run, how can this happen?!");
15089 MFloat spongeEpsilon = c_cellLengthAtLevel(maxLevel()) / 1000.0;
15090 MFloat spongeFactorBcId = m_spongeLayerThickness * abs(m_spongeFactor[bcIdS]);
15091 MFloat spongeDistanceFactor = F1 / (
mMax(spongeEpsilon, spongeFactorBcId));
15092 MFloat spongeDistance = abs(a_coordinate(cellId, s2) - m_spongeCoord[bcIdS]) * spongeDistanceFactor;
15093 spongeEndFactor = pow(spongeDistance, m_spongeBeta);
15094 spongeEndFactor *= m_sigmaSpongeBndryId[bcIdS];
15096 m_log <<
"spongeEnd " << spongeEndFactor << endl;
15100 const MFloat spongeDiff = m_spongeEndIteration[bcIdT] - m_spongeStartIteration[bcIdT];
15107 const MFloat spongeFactorDiff = spongeEndFactor - a_spongeFactorStart(cellId);
15108 a_spongeFactor(cellId) =
15109 a_spongeFactorStart(cellId) + (spongeFactorDiff / spongeDiff) *
globalTimeStep;
15113 maxSpongeFactor1 =
mMax(a_spongeFactor(cellId), maxSpongeFactor1);
15114 minSpongeFactor1 =
mMin(a_spongeFactor(cellId), minSpongeFactor1);
15116 if(
approx(a_spongeFactorStart(cellId), -1.0, MFloatEps)) {
15117 cerr <<
"sponge time dependent error, see code in fvbndrycnd2d.cpp or fvsolver2d.cpp" << endl;
15122 a_spongeFactor(cellId) = a_spongeFactorStart(cellId);
15124 maxSpongeFactor1 =
mMax(a_spongeFactor(cellId), maxSpongeFactor1);
15125 minSpongeFactor1 =
mMin(a_spongeFactor(cellId), minSpongeFactor1);
15128 a_spongeFactor(cellId) = spongeEndFactor;
15129 maxSpongeFactor1 = F0;
15130 minSpongeFactor1 = F0;
15136 }
else if(m_spongeTimeDependent[bcId] == 2) {
15139 const MFloat spongeDiff = m_spongeEndIteration[bcId] - m_spongeStartIteration[bcId];
15140 a_spongeFactor(cellId) =
15141 F1 - F1B2 * tanh(5.0)
15145 a_spongeFactor(cellId) *= a_spongeFactorStart(cellId);
15147 maxSpongeFactor2 =
mMax(a_spongeFactor(cellId), maxSpongeFactor2);
15148 minSpongeFactor2 =
mMin(a_spongeFactor(cellId), minSpongeFactor2);
15150 if(
approx(a_spongeFactorStart(cellId), -1.0, MFloatEps)) {
15151 cerr <<
"sponge time dependent error, see code in fvbndrycnd2d.cpp or fvsolver2d.cpp" << endl;
15155 a_spongeFactor(cellId) = F0;
15156 maxSpongeFactor2 = F0;
15157 minSpongeFactor2 = F0;
15160 a_spongeFactor(cellId) = a_spongeFactorStart(cellId);
15161 maxSpongeFactor2 =
mMax(a_spongeFactor(cellId), maxSpongeFactor2);
15162 minSpongeFactor2 =
mMin(a_spongeFactor(cellId), minSpongeFactor2);
15167 }
else if(m_spongeTimeDependent[bcId] == 3) {
15170 const MFloat spongeDiff = m_spongeEndIteration[bcId] - m_spongeStartIteration[bcId];
15173 spongeEndFactor = a_spongeFactorStart(cellId) / m_sigmaSpongeBndryId[bcId];
15174 spongeEndFactor *= m_sigmaEndSpongeBndryId[bcId];
15176 const MFloat spongeFactorDiff = a_spongeFactorStart(cellId) - spongeEndFactor;
15178 a_spongeFactor(cellId) =
15180 * (F1 + F1B2 * tanh(5.0)
15185 maxSpongeFactor3 =
mMax(a_spongeFactor(cellId), maxSpongeFactor3);
15186 minSpongeFactor3 =
mMin(a_spongeFactor(cellId), minSpongeFactor3);
15188 if(
approx(a_spongeFactorStart(cellId), -1.0, MFloatEps)) {
15189 cerr <<
"sponge time dependent error, see code in fvbndrycnd2d.cpp or fvsolver2d.cpp" << endl;
15194 a_spongeFactor(cellId) = a_spongeFactorStart(cellId);
15195 maxSpongeFactor3 =
mMax(a_spongeFactor(cellId), maxSpongeFactor3);
15196 minSpongeFactor3 =
mMin(a_spongeFactor(cellId), minSpongeFactor3);
15201 spongeEndFactor = a_spongeFactorStart(cellId) / m_sigmaSpongeBndryId[bcId];
15202 spongeEndFactor *= m_sigmaEndSpongeBndryId[bcId];
15203 a_spongeFactor(cellId) = spongeEndFactor;
15204 maxSpongeFactor3 =
mMax(spongeEndFactor, maxSpongeFactor3);
15205 minSpongeFactor3 =
mMin(spongeEndFactor, minSpongeFactor3);
15210 }
else if(m_spongeTimeDependent[bcId] == 4) {
15213 const MFloat spongeDiff = m_spongeEndIteration[bcId] - m_spongeStartIteration[bcId];
15216 spongeEndFactor = a_spongeFactorStart(cellId) / m_sigmaSpongeBndryId[bcId];
15217 spongeEndFactor *= m_sigmaEndSpongeBndryId[bcId];
15219 const MFloat spongeFactorDiff = spongeEndFactor - a_spongeFactorStart(cellId);
15221 a_spongeFactor(cellId) =
15222 a_spongeFactorStart(cellId)
15224 * (F1 - F1B2 * tanh(5.0)
15227 * 5.0 / spongeDiff));
15229 maxSpongeFactor2 =
mMax(a_spongeFactor(cellId), maxSpongeFactor2);
15230 minSpongeFactor2 =
mMin(a_spongeFactor(cellId), minSpongeFactor2);
15232 if(
approx(a_spongeFactorStart(cellId), -1.0, MFloatEps)) {
15233 cerr <<
"sponge time dependent error, see code in fvbndrycnd2d.cpp or fvsolver2d.cpp" << endl;
15237 a_spongeFactor(cellId) = F0;
15238 maxSpongeFactor2 = F0;
15239 minSpongeFactor2 = F0;
15242 a_spongeFactor(cellId) = a_spongeFactorStart(cellId);
15243 maxSpongeFactor2 =
mMax(a_spongeFactor(cellId), maxSpongeFactor2);
15244 minSpongeFactor2 =
mMin(a_spongeFactor(cellId), minSpongeFactor2);
15252 if(m_spongeTimeDep) {
15254 if(noDomains() > 1) {
15255 MPI_Allreduce(MPI_IN_PLACE, &maxSpongeFactor1, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
15256 "maxSpongeFactor1");
15257 MPI_Allreduce(MPI_IN_PLACE, &maxSpongeFactor2, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
15258 "maxSpongeFactor2");
15259 MPI_Allreduce(MPI_IN_PLACE, &maxSpongeFactor3, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
15260 "maxSpongeFactor3");
15261 MPI_Allreduce(MPI_IN_PLACE, &minSpongeFactor1, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
15262 "minSpongeFactor1");
15263 MPI_Allreduce(MPI_IN_PLACE, &minSpongeFactor2, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
15264 "minSpongeFactor2");
15265 MPI_Allreduce(MPI_IN_PLACE, &minSpongeFactor3, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
15266 "minSpongeFactor3");
15268 if(domainId() == 0) {
15270 datei = fopen(
"spongeFactor",
"a+");
15272 fprintf(datei,
" %f", m_time);
15273 fprintf(datei,
" %-10.8f", maxSpongeFactor1);
15274 fprintf(datei,
" %-10.8f", minSpongeFactor1);
15275 fprintf(datei,
" %-10.8f", maxSpongeFactor2);
15276 fprintf(datei,
" %-10.8f", minSpongeFactor2);
15277 fprintf(datei,
" %-10.8f", maxSpongeFactor3);
15278 fprintf(datei,
" %-10.8f", minSpongeFactor3);
15279 fprintf(datei,
"\n");
15288 MFloat pressureLoss = F0;
15290 pressureLoss = m_rhoInfinity *
POW2(m_VInfinity) * (m_inletTubeAreaRatio - F1);
15294 pressureLoss += m_rhoFlameTube * m_targetDensityFactor
15295 * (
POW2(m_velocityOutlet) -
POW2(m_flameSpeed) * m_flameOutletAreaRatio);
15300 m_PInfinity + m_rhoInfinity *
POW2(m_VInfinity) * (m_burntUnburntTemperatureRatio - F1) + pressureLoss;
15303 m_PInfinity + m_rhoInfinity *
POW2(m_flameSpeed) * (m_burntUnburntTemperatureRatio - F1) + pressureLoss;
15306 if(m_confinedFlame) {
15307 pressure = backupMeanPressure * (m_spongeWeight - 1) / m_spongeWeight;
15308 pressure += m_meanPressure / m_spongeWeight;
15320 MFloat outflowPressure = m_pressureFlameTube;
15321 MFloat outflowDensity = m_rhoFlameTube * m_targetDensityFactor;
15322 if(m_confinedFlame) {
15323 outflowPressure = m_jetPressure;
15328 values[0] = m_rhoInfinity;
15329 values[1] = pressure;
15330 values[2] = outflowDensity;
15331 values[3] = outflowPressure;
15338 MFloat pressureLoss = F0;
15340 pressureLoss = m_rhoInfinity *
POW2(m_VInfinity) * (m_inletTubeAreaRatio - F1);
15344 pressureLoss += m_rhoFlameTube * m_targetDensityFactor
15345 * (
POW2(m_velocityOutlet) -
POW2(m_flameSpeed) * m_flameOutletAreaRatio);
15350 m_PInfinity + m_rhoInfinity *
POW2(m_VInfinity) * (m_burntUnburntTemperatureRatio - F1) + pressureLoss;
15353 m_PInfinity + m_rhoInfinity *
POW2(m_flameSpeed) * (m_burntUnburntTemperatureRatio - F1) + pressureLoss;
15356 if(m_confinedFlame) {
15357 pressure = m_PInfinity + m_deltaPL;
15368 values[0] = m_rhoInfinity;
15369 values[1] = pressure;
15373 values[2] = m_rhoFlameTube * m_targetDensityFactor;
15374 values[3] = m_pressureFlameTube;
15403template <MInt nDim_,
class SysEqn>
15404std::array<MFloat, nDim_ + 2>
15407 using PVars = std::array<MFloat, nDim + 2>;
15408 using VelA = std::array<MFloat, nDim>;
15411 VelA noVelocitySponge;
15412 MFloat noDensitySponge = a_pvariable(cellId, PV->RHO);
15413 MFloat noPressureSponge = a_pvariable(cellId, PV->P);
15416 for(
MInt d = 0; d < nDim; ++d) {
15417 VVInfinity[d] = m_VVInfinity[d];
15419 for(
MInt d = 0; d < nDim; ++d) {
15420 noVelocitySponge[d] = a_pvariable(cellId, PV->VV[d]);
15422 auto pJet = [&] {
return m_jet ? m_jetPressure : m_PInfinity; };
15423 auto rhoJet = [&] {
return m_jet ? m_jetDensity : m_rhoInfinity; };
15424 auto from_target = [&](
MFloat targetRho, VelA targetU,
MFloat targetP) {
15426 dPV[PV->RHO] = a_pvariable(cellId, PV->RHO) - targetRho;
15427 for(
MInt d = 0; d < nDim; ++d) {
15428 dPV[PV->VV[d]] = (a_pvariable(cellId, PV->VV[d]) - targetU[d]) * targetRho;
15430 IF_CONSTEXPR(isDetChem<SysEqn>) {
15431 const MFloat*
const pvarsCell = &a_pvariable(cellId, 0);
15432 std::vector<MFloat> targetPV;
15433 targetPV.resize(nDim + 2 + PV->m_noSpecies);
15434 targetPV[PV->RHO] = targetRho;
15435 targetPV[PV->P] = targetP;
15436 for(
MInt d = 0; d < nDim; ++d) {
15437 targetPV[PV->VV[d]] = targetU[d];
15439 for(
MInt s = 0; s < m_noSpecies; ++s) {
15440 targetPV[PV->Y[s]] = pvarsCell[PV->Y[s]];
15442 MFloat sensibleEnergy = F0;
15443 sysEqn().evaluateSensibleEnergy(sensibleEnergy, pvarsCell, a_avariable(cellId, AV->W_MEAN));
15445 MFloat targetSensibleEnergy = F0;
15446 sysEqn().evaluateSensibleEnergy(targetSensibleEnergy, &targetPV[0], a_avariable(cellId, AV->W_MEAN));
15448 dPV[PV->P] = (sensibleEnergy - targetSensibleEnergy) * targetRho;
15451 dPV[PV->P] = sysEqn().pressureEnergy(a_pvariable(cellId, PV->P) - targetP);
15455 auto targetVelocityU = [&]() {
15456 MFloat velocityU = a_oldVariable(cellId, CV->RHO_VV[0]) * (m_spongeWeight - 1) / m_spongeWeight;
15457 velocityU /= a_oldVariable(cellId, CV->RHO);
15458 velocityU += a_variable(cellId, CV->RHO_VV[0]) / (a_variable(cellId, CV->RHO) * m_spongeWeight);
15461 auto targetVelocityV = [&]() {
15462 MFloat velocityV = a_oldVariable(cellId, CV->RHO_VV[1]) * (m_spongeWeight - 1) / m_spongeWeight;
15463 velocityV /= a_oldVariable(cellId, CV->RHO);
15469 auto targetVelocityW = [&]() {
15470 MFloat velocityW = a_oldVariable(cellId, CV->RHO_VV[2]) * (m_spongeWeight - 1) / m_spongeWeight;
15471 velocityW /= a_oldVariable(cellId, CV->RHO);
15472 velocityW += a_variable(cellId, CV->RHO_VV[2]) / (a_variable(cellId, CV->RHO) * m_spongeWeight);
15484 switch(m_spongeLayerType) {
15490 return from_target(m_rhoInfinity, noVelocitySponge, m_PInfinity);
15498 dPVtmp = from_target(noDensitySponge, noVelocitySponge, m_PInfinity);
15499 dPVtmp[PV->RHO] = a_pvariable(cellId, PV->RHO)
15500 * ((a_pvariable(cellId, PV->P) + dPVtmp[PV->P]) / a_pvariable(cellId, PV->P) - 1);
15509 dPVtmp = from_target(m_rhoInfinity * m_targetDensityFactor, noVelocitySponge, m_PInfinity);
15510 for(
MInt d = 0; d < nDim; ++d) {
15511 dPVtmp[PV->VV[d]] = a_pvariable(cellId, PV->VV[d]);
15520 dPVtmp = from_target(noDensitySponge, noVelocitySponge, value[1]);
15534 dPVtmp = from_target(value[0], noVelocitySponge, value[1]);
15541 dPVtmp = from_target(noDensitySponge, noVelocitySponge, value[1]);
15549 dPVtmp = from_target(noDensitySponge, noVelocitySponge, noPressureSponge);
15552 MFloat halfCellLength = grid().halfCellLength(cellId);
15553 MBool apply =
false;
15555 for(
MInt b = 0;
b < m_noStgSpongePositions;
b++) {
15556 if(abs(a_coordinate(cellId, 0) - m_stgSpongePositions[
b]) < 4 * halfCellLength) {
15564 if(a_pvariable(cellId, sysEqn().PV->U) > F0) {
15566 MFloat rho = a_pvariable(cellId, sysEqn().PV->RHO);
15568 dPVtmp[sysEqn().PV->U] = r * u_delta * rho;
15580 const MFloat phi_mid = 74.9355804414;
15582 PVars dPVtmp = from_target(m_rhoInfinity, noVelocitySponge,
15583 a_coordinate(cellId, 0) > c_cellLengthAtLevel(2) ? value[1] : m_PInfinity);
15584 if(a_coordinate(cellId, 0) > c_cellLengthAtLevel(2))
15585 dPVtmp[PV->U] = a_pvariable(cellId, PV->RHO) * a_pvariable(cellId, PV->U)
15586 -
cos(phi_mid / 180.0 * PI) * m_UInfinity * m_rhoInfinity * 1.2539184953;
15597 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
15600 if(a_hasProperty(cellId, SolverCell::IsInvalid)) {
15603 if(!a_hasProperty(cellId, SolverCell::IsActive)) {
15606 updateSpongeLayerRhs(
15608 from_target((!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 2) < -50.0) ? value[0] : noDensitySponge,
15610 (!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 2) < -50.0) ? value[1] : noPressureSponge));
15611 updateSpongeLayerRhs(
15613 from_target((!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 0) > 60.0 && a_coordinate(cellId, 1) > 0.0)
15617 (!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 0) > 60.0 && a_coordinate(cellId, 1) > 0.0)
15619 : noPressureSponge));
15620 return from_target(
15621 (!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 0) > 60.0 && a_coordinate(cellId, 1) < 0.0)
15625 (!a_isBndryGhostCell(cellId) && a_coordinate(cellId, 0) > 60.0 && a_coordinate(cellId, 1) < 0.0)
15627 : noPressureSponge);
15635 IF_CONSTEXPR(!hasE<SysEqn>)
15636 mTerm(1, AT_,
"Not compatible with SysEqn without RHO_E!");
15640 for(
MInt d = 0; d < nDim; ++d) {
15641 U2 +=
POW2(a_pvariable(cellId, PV->VV[d]));
15643 dPVtmp = from_target(noDensitySponge, noVelocitySponge, noPressureSponge);
15645 a_variable(cellId, CV->RHO_E) - sysEqn().internalEnergy(m_PInfinity, a_variable(cellId, CV->RHO), U2);
15655 return from_target(noDensitySponge, noVelocitySponge, m_PInfinity);
15661 const MInt oneDGridSize = m_oneDimFlame->m_grid.size();
15662 VelA forcedVelocity;
15664 for(
MInt dim = 0; dim < nDim; dim++)
15665 forcedVelocity[dim] = (dim == mainAxis) ? m_oneDimFlame->m_profile.velocity[oneDGridSize - 1] : F0;
15667 return from_target(noDensitySponge, forcedVelocity, m_PInfinity);
15673 const MInt oneDGridSize = m_oneDimFlame->m_grid.size();
15675 MFloat FmeanMolarMassBurnt = F0;
15676 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
15677 FmeanMolarMassBurnt +=
15678 m_oneDimFlame->m_profile.massFractions[m_noSpecies * (oneDGridSize - 1) + s] * m_fMolarMass[s];
15681 const MFloat temperatureInfinityBurnt = m_oneDimFlame->m_profile.temperature[oneDGridSize - 1];
15682 const MFloat meanMolarMassBurnt = F1 / FmeanMolarMassBurnt;
15684 const MFloat rhoInfinityBurnt = m_PInfinity * meanMolarMassBurnt / (temperatureInfinityBurnt * m_gasConstant);
15686 const MFloat spongeRho = a_coordinate(cellId, 1) < 0 ? m_rhoInfinity : rhoInfinityBurnt;
15690 targetV[1] = m_VInfinity;
15691 IF_CONSTEXPR(nDim == 3) targetV[1] = F0;
15692 if(a_coordinate(cellId, 1) < 0) {
15693 return from_target(spongeRho, targetV, noPressureSponge);
15695 return from_target(noDensitySponge, noVelocitySponge, m_PInfinity);
15703 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "Info: This sponge layer type only works in 3D.");
15706 if(a_hasProperty(cellId, SolverCell::
IsInvalid)) break;
15707 if(!a_hasProperty(cellId, SolverCell::
IsActive)) break;
15708 if(a_isBndryGhostCell(cellId)) break;
15710 constexpr
MFloat directionSign[6] = {1.0, -1.0, 1.0, -1.0, 1.0, -1.0};
15711 constexpr MInt directionDim[6] = {0, 0, 1, 1, 2, 2};
15712 const MFloat Pdiff = m_deltaPL;
15714 if(m_time < m_timeOfMaxPdiff) fac = (m_time / m_timeOfMaxPdiff);
15715 const MFloat finalPressure = m_PInfinity - Pdiff;
15716 const MFloat initialPressure = sysEqn().p_Ref() - Pdiff;
15717 const MFloat deltaPressure = finalPressure - initialPressure;
15718 static constexpr MInt noRSteps = 20;
15720 const MFloat rDiff = R / noRSteps;
15722 dPVtmp[PV->P] = noPressureSponge;
15723 dPVtmp[PV->RHO] = noDensitySponge;
15724 std::copy_n(&dPVtmp[0], nDim, &noVelocitySponge[0]);
15726 for(
MInt i = 0; i < m_noSpongeZonesIn; i++) {
15727 if((a_coordinate(cellId, directionDim[m_spongeDirectionsIn[i]]) - m_coordSpongeIn[i])
15728 * directionSign[m_spongeDirectionsIn[i]]
15730 && (a_coordinate(cellId, directionDim[m_secondSpongeDirectionsIn[i]]) - m_secondCoordSpongeIn[i])
15731 * directionSign[m_secondSpongeDirectionsIn[i]]
15734 const MFloat pressureIn = value[i];
15735 const MFloat densityIn = sysEqn().density_IR_P(pressureIn);
15736 dPVtmp[PV->P] += sysEqn().pressureEnergy(a_pvariable(cellId, PV->P) - pressureIn);
15737 dPVtmp[PV->RHO] += a_pvariable(cellId, PV->RHO) - densityIn;
15740 for(
MInt i = 0; i < m_noSpongeZonesOut; i++) {
15741 if((a_coordinate(cellId, directionDim[m_spongeDirectionsOut[i]]) - m_coordSpongeOut[i])
15742 * directionSign[m_spongeDirectionsOut[i]]
15744 && (a_coordinate(cellId, directionDim[m_secondSpongeDirectionsOut[i]]) - m_secondCoordSpongeOut[i])
15745 * directionSign[m_secondSpongeDirectionsOut[i]]
15748 const MFloat pressureOut = (initialPressure + fac * deltaPressure);
15749 const MFloat densityOut = sysEqn().density_IR_P(pressureOut);
15751 dPVtmp[PV->P] += sysEqn().pressureEnergy(a_pvariable(cellId, PV->P) - pressureOut);
15752 dPVtmp[PV->RHO] += a_pvariable(cellId, PV->RHO) - densityOut;
15754 for(
MInt dimId = 0; dimId < nDim; dimId++)
15755 dPVtmp[PV->VV[dimId]] += a_pvariable(cellId, PV->VV[dimId]);
15757 const MFloat r = sqrt(
POW2(a_coordinate(cellId, 1)) +
POW2(a_coordinate(cellId, 2)));
15758 const MInt rIndex = (
MInt)((R - r) / rDiff);
15759 dPVtmp[PV->VV[0]] -= m_uNormal_r[rIndex];
15768 MFloat spongeDistanceFactor = F1;
15770 if(m_velocitySponge) {
15771 VV[0] = targetVelocityU();
15772 VV[1] = targetVelocityV();
15773 VV[2] = targetVelocityW();
15774 if(a_variable(cellId, CV->RHO_VV[1]) < 0) {
15775 spongeDistanceFactor = F2;
15776 VV[1] += m_VInfinity / m_spongeWeight;
15778 VV[1] += a_variable(cellId, CV->RHO_VV[1]) / (a_variable(cellId, CV->RHO) * m_spongeWeight);
15781 VV = noVelocitySponge;
15783 tmpVars = from_target(rhoJet(),
15785 (a_coordinate(cellId, 1) < m_yOffsetFlameTube - 0.5) ? rhoJet()
15786 : rhoJet() * m_targetDensityFactor);
15787 tmpVars[PV->VV[0]] *= spongeDistanceFactor;
15796 return from_target(noDensitySponge, VVInfinity, noPressureSponge);
15803 return from_target(m_rhoInfinity, VVInfinity, m_PInfinity);
15808 if(m_velocitySponge) {
15809 VV[0] = targetVelocityU();
15810 VV[1] = targetVelocityV();
15811 VV[2] = targetVelocityW();
15813 VV = noVelocitySponge;
15815 return from_target(
15816 (a_coordinate(cellId, 1) < m_yOffsetFlameTube - 0.5 && abs(a_coordinate(cellId, 2)) < m_jetHalfLength + 0.1)
15818 : rhoJet() * m_targetDensityFactor,
15827 if(m_velocitySponge) {
15828 VV[0] = targetVelocityU();
15829 VV[1] = targetVelocityV();
15830 VV[2] = targetVelocityW();
15832 VV = noVelocitySponge;
15834 return from_target(
15835 (a_coordinate(cellId, 1) < m_yOffsetFlameTube - 0.5 && abs(a_coordinate(cellId, 2)) < m_jetHalfLength + 0.1)
15837 : rhoJet() * m_targetDensityFactor,
15847 if(m_velocitySponge) {
15848 VV[0] = targetVelocityU();
15849 VV[1] = targetVelocityV();
15850 VV[2] = targetVelocityW();
15852 VV = noVelocitySponge;
15854 tmpVars = from_target(
15855 (a_coordinate(cellId, 1) < m_yOffsetFlameTube - 0.5 && abs(a_coordinate(cellId, 2)) < m_jetHalfLength + 0.1)
15857 : rhoJet() * m_targetDensityFactor,
15860 if(a_coordinate(cellId, 1) < m_yOffsetFlameTube - 0.5 && abs(a_coordinate(cellId, 2)) < m_jetHalfLength + 0.1) {
15861 tmpVars[PV->RHO] *= m_sigmaSpongeInflow / m_sigmaSponge;
15862 tmpVars[PV->P] *= m_sigmaSpongeInflow / m_sigmaSponge;
15872 return from_target(m_rhoInfinity * m_targetDensityFactor,
15874 m_PInfinity + m_deltaP * (m_domainBoundaries[3] - a_coordinate(cellId, 1)));
15880 ASSERT(!a_hasProperty(cellId, SolverCell::IsInvalid),
"sponge cell invalid");
15881 ASSERT(!a_isBndryGhostCell(cellId),
"sponge cell is bndry ghost cell");
15884 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
break;
15885 if(!a_hasProperty(cellId, SolverCell::IsActive))
break;
15887 VelA velSponge(noVelocitySponge);
15888 MFloat targetRho, targetP;
15891 const MFloat centerY = 0.0;
15892 const MFloat centerZ = 0.0;
15893 const MFloat radius = sqrt(
POW2(a_coordinate(cellId, 1) - centerY) +
POW2(a_coordinate(cellId, 2) - centerZ));
15894 const MFloat xpos = a_coordinate(cellId, 0);
15895 const MFloat maxInletPosX = 3.0;
15896 const MFloat minOutletPosX = 50.0;
15898 if(xpos <= maxInletPosX && radius <= m_inletRadius) {
15899 const MFloat deltaMomentum = m_momentumThickness * m_inletRadius;
15900 const MFloat jet = tanh((m_inletRadius - radius) / (2.0 * deltaMomentum));
15902 const MFloat density_i = value[0];
15903 targetRho = density_i / sysEqn().CroccoBusemann(m_maNozzleInlet, jet);
15904 targetP = value[1];
15907 targetRho = value[2];
15908 targetP = value[3];
15911 if(xpos >= minOutletPosX && a_pvariable(cellId, PV->U) < 0) {
15912 velSponge[0] = 0.0;
15916 return from_target(targetRho, velSponge, targetP);
15928 dPVtmp = from_target(noDensitySponge, noVelocitySponge, m_PInfinity);
15929 dPVtmp[PV->RHO] = a_pvariable(cellId, PV->RHO)
15930 * ((a_pvariable(cellId, PV->P) + dPVtmp[PV->P]) / a_pvariable(cellId, PV->P) - 1);
15931 for(
MInt d = 0; d < nDim; ++d) {
15932 dPVtmp[PV->VV[d]] = dPVtmp[PV->RHO] * a_pvariable(cellId, PV->VV[d]);
15943 dPVtmp = from_target(noDensitySponge, noVelocitySponge, noPressureSponge);
15944 dPVtmp[PV->P] = sysEqn().pressureEnergy(a_pvariable(cellId, PV->P) - sysEqn().p_Ref());
15945 dPVtmp[PV->RHO] = a_pvariable(cellId, PV->RHO) - 1.0;
15952 const MFloat T2 = sysEqn().temperature_ES(m_postShockPV[PV->RHO], m_postShockPV[PV->P]);
15954 for(
MInt d = 0; d < nDim; ++d) {
15955 velSq +=
POW2(m_postShockPV[PV->VV[d]]);
15959 dPVtmp = from_target(noDensitySponge, noVelocitySponge, m_postShockPV[PV->P]);
15960 dPVtmp[PV->RHO] = (a_pvariable(cellId, PV->P) - m_postShockPV[PV->P]) / T2;
15961 dPVtmp[PV->P] = (dPVtmp[PV->P] + dPVtmp[PV->RHO] * velSq);
15967 return from_target((a_coordinate(cellId, 0) < 0) ? m_rhoInfinity : m_rhoInfinity * m_targetDensityFactor,
15981 pressure = m_PInfinity + m_rhoInfinity *
POW2(m_flameSpeed) * (m_burntUnburntTemperatureRatio - F1);
15982 return from_target((a_coordinate(cellId, 1) < 0.0) ? m_rhoInfinity : m_rhoInfinity * m_targetDensityFactor,
15984 (a_coordinate(cellId, 1) < 0.0) ? pressure : m_PInfinity);
15991 return from_target((a_coordinate(cellId, 1) < 0.0) ? m_rhoInfinity : m_rhoInfinity * m_targetDensityFactor,
15993 (a_coordinate(cellId, 1) < 0.0) ? value[1] : m_PInfinity);
16000 MFloat ampl = m_forcingAmplitude;
16001 MFloat xPlus, xNegative;
16002 MFloat St = m_flameStrouhal;
16014 if(a_spongeBndryId(cellId, 0) == 176191 || a_spongeBndryId(cellId, 1) == 176191
16015 || a_spongeBndryId(cellId, 0) == 209104 || a_spongeBndryId(cellId, 1) == 209104
16016 || a_spongeBndryId(cellId, 0) == 209101 || a_spongeBndryId(cellId, 1) == 209101
16017 || a_spongeBndryId(cellId, 0) == 17616 || a_spongeBndryId(cellId, 1) == 17616
16018 || a_spongeBndryId(cellId, 0) == 3906 || a_spongeBndryId(cellId, 1) == 3906
16019 || a_spongeBndryId(cellId, 0) == 39060 || a_spongeBndryId(cellId, 1) == 39060
16020 || a_spongeBndryId(cellId, 0) == 209102
16021 || a_spongeBndryId(cellId, 1) == 209102) {
16023 const MFloat density = value[0];
16024 const MFloat pressure = value[1];
16026 dPVtmp[PV->RHO] = a_pvariable(cellId, PV->RHO) - density;
16027 dPVtmp[PV->P] = sysEqn().pressureEnergy(a_pvariable(cellId, PV->P) - pressure);
16029 xPlus = a_coordinate(cellId, 0) + m_radiusVelFlameTube;
16030 xNegative = a_coordinate(cellId, 0) - m_radiusVelFlameTube;
16034 * (F1B2 * (F1 + tanh(xPlus * m_shearLayerStrength)) * (F1 - tanh(xNegative * m_shearLayerStrength)) - F1);
16040 if(!m_specialSpongeTreatment) {
16041 deltaV = (a_pvariable(cellId, PV->VV[1]) - velocity) * m_rhoInfinity;
16042 deltaU = (a_pvariable(cellId, PV->VV[0]) - velocityU) * m_rhoInfinity;
16044 a_variable(cellId, CV->RHO_V) = velocity * m_rhoInfinity;
16045 a_variable(cellId, CV->RHO_U) = F0;
16050 const MFloat outflowDensity = value[2];
16051 const MFloat outflowPressure = value[3];
16053 dPVtmp[PV->RHO] = a_pvariable(cellId, PV->RHO) - outflowDensity;
16054 dPVtmp[PV->P] = sysEqn().pressureEnergy(a_pvariable(cellId, PV->P) - outflowPressure);
16058 if(m_velocitySponge && (a_spongeBndryId(cellId, 0) == 1763 || a_spongeBndryId(cellId, 1) == 1763)) {
16059 velocity = a_oldVariable(cellId, CV->RHO_VV[1]) * (m_spongeWeight - 1) / m_spongeWeight;
16060 velocity /= a_oldVariable(cellId, CV->RHO);
16061 velocity += a_variable(cellId, CV->RHO_VV[1]) / (a_variable(cellId, CV->RHO) * m_spongeWeight);
16063 velocityU = a_oldVariable(cellId, CV->RHO_VV[0]) * (m_spongeWeight - 1) / m_spongeWeight;
16064 velocityU /= a_oldVariable(cellId, CV->RHO);
16065 velocityU += a_variable(cellId, CV->RHO_VV[0]) / (a_variable(cellId, CV->RHO) * m_spongeWeight);
16067 deltaV = (a_pvariable(cellId, PV->VV[1]) - velocity) * m_rhoInfinity;
16068 deltaU = (a_pvariable(cellId, PV->VV[0]) - velocityU) * m_rhoInfinity;
16072 dPVtmp[PV->U] = deltaU * (m_velocitySponge + (!m_specialSpongeTreatment) * m_spongeReductionFactor);
16073 dPVtmp[PV->V] = deltaV * (m_velocitySponge + (!m_specialSpongeTreatment) * m_spongeReductionFactor);
16084 if((a_spongeBndryId(cellId, 0) == 17616 || a_spongeBndryId(cellId, 1) == 17616)
16085 || (a_spongeBndryId(cellId, 0) == 176191 || a_spongeBndryId(cellId, 1) == 176191)
16086 || (a_spongeBndryId(cellId, 0) == 209102 || a_spongeBndryId(cellId, 1) == 209102)
16087 || (a_spongeBndryId(cellId, 0) == 209101 || a_spongeBndryId(cellId, 1) == 209101)
16088 || (a_spongeBndryId(cellId, 0) == 209104
16089 || a_spongeBndryId(cellId, 1) == 209104)) {
16091 const MFloat density = value[0];
16092 const MFloat pressure = value[1];
16094 dPVtmp[PV->RHO] = a_pvariable(cellId, PV->RHO) - density;
16095 dPVtmp[PV->P] = sysEqn().pressureEnergy(a_pvariable(cellId, PV->P) - pressure);
16097 xPlus = a_coordinate(cellId, 0) + m_radiusVelFlameTube;
16098 xNegative = a_coordinate(cellId, 0) - m_radiusVelFlameTube;
16102 * (F1B2 * (F1 + tanh(xPlus * m_shearLayerStrength)) * (F1 - tanh(xNegative * m_shearLayerStrength)) - F1);
16104 velocity *= (F1 + ampl * sin(St * m_time));
16112 if(!m_specialSpongeTreatment) {
16113 deltaV = (a_pvariable(cellId, PV->VV[1]) - velocity) * m_rhoInfinity;
16114 deltaU = (a_pvariable(cellId, PV->VV[0]) - velocityU) * m_rhoInfinity;
16116 a_variable(cellId, CV->RHO_V) = velocity * m_rhoInfinity;
16117 a_variable(cellId, CV->RHO_U) = F0;
16122 const MFloat outflowDensity = value[2];
16123 const MFloat outflowPressure = value[3];
16125 dPVtmp[PV->RHO] = a_pvariable(cellId, PV->RHO) - outflowDensity;
16126 dPVtmp[PV->P] = sysEqn().pressureEnergy(a_pvariable(cellId, PV->P) - outflowPressure);
16129 if(m_velocitySponge && (a_spongeBndryId(cellId, 0) == 1763 || a_spongeBndryId(cellId, 1) == 1763)) {
16130 velocity = a_oldVariable(cellId, CV->RHO_VV[1]) * (m_spongeWeight - 1) / m_spongeWeight;
16131 velocity /= a_oldVariable(cellId, CV->RHO);
16132 velocity += a_variable(cellId, CV->RHO_VV[1]) / (a_variable(cellId, CV->RHO) * m_spongeWeight);
16134 velocityU = a_oldVariable(cellId, CV->RHO_VV[0]) * (m_spongeWeight - 1) / m_spongeWeight;
16135 velocityU /= a_oldVariable(cellId, CV->RHO);
16136 velocityU += a_variable(cellId, CV->RHO_VV[0]) / (a_variable(cellId, CV->RHO) * m_spongeWeight);
16138 deltaV = (a_pvariable(cellId, PV->VV[1]) - velocity) * m_rhoInfinity;
16139 deltaU = (a_pvariable(cellId, PV->VV[0]) - velocityU) * m_rhoInfinity;
16143 dPVtmp[PV->U] = deltaU * (m_velocitySponge + (!m_specialSpongeTreatment) * m_spongeReductionFactor);
16144 dPVtmp[PV->V] = deltaV * (m_velocitySponge + (!m_specialSpongeTreatment) * m_spongeReductionFactor);
16153 "FvCartesianSolverXD::computeSpongeDeltas() switch variable 'm_spongeLayerType' not matching any "
16157 return from_target(noDensitySponge, noVelocitySponge, noPressureSponge);
16161template <MInt nDim_,
class SysEqn>
16166 IF_CONSTEXPR(hasE<SysEqn>)
16167 a_rightHandSide(cellId, CV->RHO_E) += a_spongeFactor(cellId) * dPV[PV->P] * a_cellVolume(cellId);
16168 a_rightHandSide(cellId, CV->RHO) += a_spongeFactor(cellId) * dPV[PV->RHO] * a_cellVolume(cellId);
16169 for(
MInt d = 0; d < nDim; ++d) {
16170 a_rightHandSide(cellId, CV->RHO_VV[d]) += a_spongeFactor(cellId) * dPV[PV->VV[d]] * a_cellVolume(cellId);
16181 for(
MInt s = 0; s < m_noSpecies; s++) {
16182 a_rightHandSide(cellId, CV->RHO_Y[s]) +=
16183 a_spongeFactor(cellId) * dPV[PV->RHO] * a_cellVolume(cellId) * a_pvariable(cellId, PV->Y[s]);
16193template <MInt nDim_,
class SysEqn>
16197 MInt noDirs = 2 * nDim;
16199 MFloat epsilon = c_cellLengthAtLevel(maxRefinementLevel()) / 1000.0;
16205 halfCellWidth = F1B2 * c_cellLengthAtCell(0);
16206 for(
MInt i = 0; i < nDim; i++) {
16207 m_domainBoundaries[2 * i] = a_coordinate(0, i) - halfCellWidth;
16208 m_domainBoundaries[2 * i + 1] = a_coordinate(0, i) + halfCellWidth;
16210 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
16211 if(c_noChildren(cellId) > 0)
continue;
16212 halfCellWidth = F1B2 * c_cellLengthAtCell(cellId);
16213 for(
MInt i = 0; i < nDim; i++) {
16214 m_domainBoundaries[2 * i] =
mMin(m_domainBoundaries[2 * i], a_coordinate(cellId, i) - halfCellWidth);
16215 m_domainBoundaries[2 * i + 1] =
mMax(m_domainBoundaries[2 * i + 1], a_coordinate(cellId, i) + halfCellWidth);
16220 for(
MInt i = 0; i < nDim; i++)
16221 tmp.
p[i] = m_domainBoundaries[2 * i + 1];
16223 "tmp2.getPointer()");
16225 for(
MInt i = 0; i < nDim; i++)
16226 m_domainBoundaries[2 * i + 1] = tmp2.
p[i];
16228 for(
MInt i = 0; i < nDim; i++)
16229 tmp.
p[i] = m_domainBoundaries[2 * i];
16231 "tmp2.getPointer()");
16233 for(
MInt i = 0; i < nDim; i++)
16234 m_domainBoundaries[2 * i] = tmp2.
p[i];
16237 m_meanCoord[2] = F0;
16238 m_fvBndryCnd->m_meanCoord[2] = m_meanCoord[2];
16239 for(
MInt i = 0; i < nDim; i++) {
16240 m_meanCoord[i] = F1B2 * (m_domainBoundaries[2 * i] + m_domainBoundaries[2 * i + 1]);
16241 m_fvBndryCnd->m_meanCoord[i] = m_meanCoord[i];
16244 if(m_spongeLayerThickness > F0) {
16245 if(!m_createSpongeBoundary) {
16247 for(
MInt i = 0; i < nDim; i++) {
16248 m_spongeCoord[2 * i] = m_domainBoundaries[2 * i] + m_spongeLayerThickness * m_spongeFactor[2 * i];
16249 m_spongeCoord[noDirs + 2 * i] = F1 /
mMax(epsilon, m_spongeLayerThickness * m_spongeFactor[2 * i]);
16250 m_spongeCoord[2 * i + 1] = m_domainBoundaries[2 * i + 1] - m_spongeLayerThickness * m_spongeFactor[2 * i + 1];
16251 m_spongeCoord[noDirs + 2 * i + 1] = F1 / (
mMax(epsilon, m_spongeLayerThickness * m_spongeFactor[2 * i + 1]));
16256 m_log <<
"*** boundaries of the computational domain " << endl;
16257 m_log <<
" direction " << endl;
16258 for(
MInt i = 0; i < nDim; i++) {
16259 m_log <<
"min " << i <<
" " << m_domainBoundaries[2 * i] << endl;
16260 m_log <<
"max " << i <<
" " << m_domainBoundaries[2 * i + 1] << endl;
16261 m_log <<
"mean " << i <<
" " << m_meanCoord[i] << endl;
16280template <MInt nDim_,
class SysEqn>
16284 const MInt noSmallCells = m_fvBndryCnd->m_smallBndryCells->size();
16285 const MInt noVarIds = FV->noVariables;
16289#pragma omp parallel for collapse(2)
16291 for(
MInt s = 0; s < noSmallCells; s++) {
16292 for(
MInt varId = 0; varId < noVarIds; varId++) {
16293 a_rightHandSide(m_masterCellIds[s], varId) += a_rightHandSide(m_smallCellIds[s], varId);
16294 a_rightHandSide(m_smallCellIds[s], varId) = F0;
16316template <MInt nDim_,
class SysEqn>
16319 std::ignore = finalTimeStep;
16325 if(isMultilevel() && !isMultilevelPrimary()) {
16329 MInt offset = m_solutionOffset;
16330 MInt rank = domainId();
16331 stringstream gridFileName;
16333 MIntScratchSpace MS_Ids(m_fvBndryCnd->m_bndryCells->size(), AT_,
"MS_Ids");
16334 cerr <<
"detailed Output!" << endl;
16343 if(m_recordWallVorticity) {
16347 MFloat minimumWallVorticity = 10000.;
16348 MFloat maximumWallVorticity = -10000.;
16350 datei = fopen(
"wallVorticity",
"a+");
16352 fprintf(datei,
" %f", m_physicalTime);
16353 fprintf(datei,
" %f", m_time);
16355 for(
MInt bcId = 0; bcId < m_fvBndryCnd->m_noBndryCndIds; bcId++) {
16356 if(m_fvBndryCnd->m_bndryCndIds[bcId] != 3006)
continue;
16357 for(
MInt id = m_fvBndryCnd->m_bndryCndCells[bcId]; id < m_fvBndryCnd->m_bndryCndCells[bcId + 1];
id++) {
16358 bndryId = m_fvBndryCnd->m_sortedBndryCells->a[
id];
16359 cellId = m_bndryCells->a[bndryId].m_cellId;
16360 if(m_bndryCells->a[bndryId].m_linkedCellId > -1)
16361 if(a_bndryId(m_bndryCells->a[bndryId].m_linkedCellId) == -1)
cellId = m_bndryCells->a[bndryId].m_linkedCellId;
16362 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
16363 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
16366 * (a_slope(cellId, PV->V, 0) + a_slope(ghostCellId, PV->V, 0) - a_slope(cellId, PV->U, 1)
16367 - a_slope(ghostCellId, PV->U, 1));
16368 vorticity /= m_UInfinity;
16369 minimumWallVorticity =
mMin(minimumWallVorticity, vorticity);
16370 maximumWallVorticity =
mMax(maximumWallVorticity, vorticity);
16373 fprintf(datei,
" %f", minimumWallVorticity);
16374 fprintf(datei,
" %f", maximumWallVorticity);
16376 fprintf(datei,
"\n");
16383 if(m_recordLandA) {
16384 TERMM_IF_COND(m_reConstSVDWeightMode == 3 || m_reConstSVDWeightMode == 4,
"Not yet implemented!");
16388 MInt noSrfcs = a_noSurfaces();
16390 MFloat totalVorticity = F0;
16391 MFloat totalVorticityPrimary = F0;
16392 MFloat totalVorticitySecondary = F0;
16393 MFloat totalSecondaryVorticity = F0;
16394 MFloat kineticEnergy = F0;
16411 MFloat LXsecondary = F0;
16417 MFloat gridVelocity[3] = {F0, F0, F0};
16418 MFloat gridVelocityDt1[3] = {F0, F0, F0};
16419 MFloat gridCenter[3] = {F0, F0, F0};
16432 MInt refinementPatches = 0;
16433 refinementPatches = Context::getSolverProperty<MInt>(
"refinementPatches", m_solverId, AT_, &refinementPatches);
16434 switch(refinementPatches) {
16453 for(
MInt cell = m_noActiveCells - 1; cell >= 0; --cell) {
16455 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
16456 if(a_isBndryGhostCell(cellId))
continue;
16457 if(a_coordinate(cellId, 0) > xmax)
continue;
16458 if(a_coordinate(cellId, 0) < xmin)
continue;
16459 if(
ABS(a_coordinate(cellId, 1)) > ymax)
continue;
16460 vorticity = F1B2 * (a_slope(cellId, PV->V, 0) - a_slope(cellId, PV->U, 1));
16462 F1B2 * a_cellVolume(cellId) * (
POW2(a_pvariable(cellId, PV->U)) +
POW2(a_pvariable(cellId, PV->V)));
16463 enstrophy += F1B2 * a_cellVolume(cellId) *
POW2(vorticity);
16464 totalVorticity +=
ABS(vorticity) * a_cellVolume(cellId);
16465 if(vorticity * a_coordinate(cellId, 1) > F0) totalSecondaryVorticity +=
ABS(vorticity) * a_cellVolume(cellId);
16466 L2X += a_cellVolume(cellId) * vorticity * (a_coordinate(cellId, 1));
16467 L2Y -= a_cellVolume(cellId) * vorticity * (a_coordinate(cellId, 0));
16468 AZ1 -= a_cellVolume(cellId) * vorticity * F1B2
16469 * (
POW2(a_coordinate(cellId, 0)) +
16470 POW2(a_coordinate(cellId, 1)));
16471 AZ3 -= a_cellVolume(cellId) * vorticity
16472 * ((a_coordinate(cellId, 0)) * gridCenter[0] + (a_coordinate(cellId, 1)) * gridCenter[1]);
16474 if(a_coordinate(cellId, 1) > F0) {
16475 tvtop += vorticity * a_cellVolume(cellId);
16476 LtopX += a_cellVolume(cellId) * vorticity * (a_coordinate(cellId, 1));
16477 LtopY -= a_cellVolume(cellId) * vorticity * (a_coordinate(cellId, 0));
16478 AZtop -= a_cellVolume(cellId) * vorticity
16479 * ((a_coordinate(cellId, 0)) * gridCenter[0] + (a_coordinate(cellId, 1)) * gridCenter[1]);
16480 LtopXrect += a_cellVolume(cellId) * vorticity * (a_coordinate(cellId, 1));
16481 LtopYrect -= a_cellVolume(cellId) * vorticity * (a_coordinate(cellId, 0));
16482 tvtoprect += vorticity * a_cellVolume(cellId);
16485 if(vorticity * (a_coordinate(cellId, 1)) > F0) {
16486 LXprimary += a_cellVolume(cellId) * vorticity * (a_coordinate(cellId, 1));
16487 totalVorticityPrimary +=
ABS(vorticity) * a_cellVolume(cellId);
16489 LXsecondary += a_cellVolume(cellId) * vorticity * (a_coordinate(cellId, 1));
16490 totalVorticitySecondary +=
ABS(vorticity) * a_cellVolume(cellId);
16493 L1X = totalVorticity * gridCenter[1];
16494 L1Y = -totalVorticity * gridCenter[0];
16495 AZ2 = -m_angularBodyVelocity;
16496 LtopX += tvtop * gridCenter[1];
16497 LtopY -= tvtop * gridCenter[0];
16498 AZtop -= F1B2 * tvtop * (
POW2(gridCenter[0]) +
POW2(gridCenter[1]));
16499 LtopXrect += tvtoprect * gridCenter[1];
16500 LtopYrect -= tvtoprect * gridCenter[0];
16505 L1X /= m_UInfinity;
16506 L1Y /= m_UInfinity;
16507 L2X /= m_UInfinity;
16508 L2Y /= m_UInfinity;
16509 AZ1 /= m_UInfinity;
16510 AZ2 /= m_UInfinity;
16511 AZ3 /= m_UInfinity;
16512 LtopX /= m_UInfinity;
16513 LtopY /= m_UInfinity;
16514 AZtop /= m_UInfinity;
16515 LtopXrect /= m_UInfinity;
16516 LtopYrect /= m_UInfinity;
16517 LXprimary /= m_UInfinity;
16518 LXsecondary /= m_UInfinity;
16524 for(
MInt i = 0; i < a_noCells(); i++)
16525 for(
MInt d = 0; d < nDim; d++)
16526 a_rightHandSide(i, d) = F0;
16528 for(
MUint k = 0; k < m_reconstructionDataSize; k++) {
16529 MFloat vorticityDifference =
16531 * ((a_slope(m_reconstructionNghbrIds[k], 1, 0) - a_slope(m_reconstructionNghbrIds[k], 0, 1))
16532 - (a_slope(m_reconstructionCellIds[k], 1, 0) - a_slope(m_reconstructionCellIds[k], 0, 1))));
16533 a_rightHandSide(m_reconstructionCellIds[k], 0) += m_reconstructionConstants[nDim * k] * vorticityDifference;
16534 a_rightHandSide(m_reconstructionCellIds[k], 1) += m_reconstructionConstants[nDim * k + 1] * vorticityDifference;
16537 copyRHSIntoGhostCells();
16540 MFloat laplaceVorticityIntegral = F0;
16541 MFloat* area = &a_surfaceArea(0);
16542 for(
MInt srfcId = 0; srfcId < noSrfcs; srfcId++) {
16544 a_surfaceFlux(srfcId, 0) =
16546 * (a_surfaceFactor(srfcId, 0) * a_rightHandSide(a_surfaceNghbrCellId(srfcId, 0), a_surfaceOrientation(srfcId))
16547 + (a_surfaceFactor(srfcId, 1)
16548 * a_rightHandSide(a_surfaceNghbrCellId(srfcId, 1), a_surfaceOrientation(srfcId))));
16550 for(
MInt cell = m_noActiveCells - 1; cell >= 0; --cell) {
16552 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
16553 a_rightHandSide(cellId, 0) = F0;
16555 for(
MInt srfcId = 0; srfcId < noSrfcs; srfcId++) {
16556 a_rightHandSide(a_surfaceNghbrCellId(srfcId, 0), 0) += a_surfaceFlux(srfcId, 0);
16557 a_rightHandSide(a_surfaceNghbrCellId(srfcId, 1), 0) -= a_surfaceFlux(srfcId, 0);
16559 for(
MInt cell = m_noActiveCells - 1; cell >= 0; --cell) {
16561 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
16562 if(a_isBndryGhostCell(cellId))
continue;
16563 if(a_coordinate(cellId, 0) > xmax)
continue;
16564 if(a_coordinate(cellId, 0) < xmin)
continue;
16565 if(
ABS(a_coordinate(cellId, 1)) > ymax)
continue;
16566 laplaceVorticityIntegral += a_rightHandSide(cellId, 0) * (a_coordinate(cellId, 1) - gridCenter[1]);
16569 datei = fopen(
"conservedQuantities",
"a+");
16571 fprintf(datei,
" %f", m_physicalTime);
16572 fprintf(datei,
" %f", m_time);
16573 fprintf(datei,
" %f", L1X);
16574 fprintf(datei,
" %f", L1Y);
16575 fprintf(datei,
" %f", L2X);
16576 fprintf(datei,
" %f", L2Y);
16577 fprintf(datei,
" %f", AZ1);
16578 fprintf(datei,
" %f", AZ2);
16579 fprintf(datei,
" %f", AZ3);
16580 fprintf(datei,
" %f", LtopX);
16581 fprintf(datei,
" %f", LtopY);
16582 fprintf(datei,
" %f", AZtop);
16583 fprintf(datei,
" %f", LtopXrect);
16584 fprintf(datei,
" %f", LtopYrect);
16585 fprintf(datei,
" %f", LXprimary);
16586 fprintf(datei,
" %f", LXsecondary);
16587 fprintf(datei,
"\n");
16590 datei = fopen(
"flowFieldQuantities",
"a+");
16592 fprintf(datei,
" %f", m_physicalTime);
16593 fprintf(datei,
" %f", m_time);
16594 fprintf(datei,
" %f", totalVorticity);
16595 fprintf(datei,
" %f", kineticEnergy);
16596 fprintf(datei,
" %f", enstrophy);
16597 fprintf(datei,
" %f", totalSecondaryVorticity);
16598 fprintf(datei,
" %f", laplaceVorticityIntegral);
16599 fprintf(datei,
"\n");
16604 MFloat momentOfVorticity = F0;
16605 MFloat positiveMomentOfVorticity = F0;
16606 MFloat negativeMomentOfVorticity = F0;
16607 for(
MInt cell = m_noActiveCells - 1; cell >= 0; --cell) {
16609 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
16610 if(a_isBndryGhostCell(cellId))
continue;
16611 if(a_coordinate(cellId, 0) > xmax)
continue;
16612 if(a_coordinate(cellId, 0) < xmin)
continue;
16613 if(
ABS(a_coordinate(cellId, 1)) > ymax)
continue;
16614 vorticity = F1B2 * (a_slope(cellId, PV->V, 0) - a_slope(cellId, PV->U, 1));
16615 momentOfVorticity += a_cellVolume(cellId) * vorticity * a_coordinate(cellId, 1);
16616 if(vorticity * a_coordinate(cellId, 1) > F0)
16617 positiveMomentOfVorticity += a_cellVolume(cellId) * vorticity * a_coordinate(cellId, 1);
16619 negativeMomentOfVorticity += a_cellVolume(cellId) * vorticity * a_coordinate(cellId, 1);
16622 MFloat timeDerivativeMOV = (momentOfVorticity - m_oldMomentOfVorticity) / timeStep();
16623 MFloat timeDerivativeNMOV = (negativeMomentOfVorticity - m_oldNegativeMomentOfVorticity) / timeStep();
16624 MFloat timeDerivativePMOV = (positiveMomentOfVorticity - m_oldPositiveMomentOfVorticity) / timeStep();
16626 timeDerivativeMOV = F0;
16627 timeDerivativeNMOV = F0;
16628 timeDerivativePMOV = F0;
16630 MFloat dUxdt = (gridVelocityDt1[0] - gridVelocity[0]) / timeStep();
16631 MFloat Ustar = m_Re / m_UInfinity * gridVelocity[0];
16633 m_oldMomentOfVorticity = momentOfVorticity;
16634 m_oldNegativeMomentOfVorticity = negativeMomentOfVorticity;
16635 m_oldPositiveMomentOfVorticity = positiveMomentOfVorticity;
16637 datei = fopen(
"bodyForceBalance",
"a+");
16639 fprintf(datei,
" %f", m_physicalTime);
16640 fprintf(datei,
" %f", m_time);
16641 fprintf(datei,
" %f", momentOfVorticity);
16642 fprintf(datei,
" %f", timeDerivativeMOV);
16643 fprintf(datei,
" %f", negativeMomentOfVorticity);
16644 fprintf(datei,
" %f", timeDerivativeNMOV);
16645 fprintf(datei,
" %f", positiveMomentOfVorticity);
16646 fprintf(datei,
" %f", timeDerivativePMOV);
16647 fprintf(datei,
" %f", Ustar);
16648 fprintf(datei,
" %f", dUxdt);
16649 fprintf(datei,
"\n");
16653 if(m_integratedHeatReleaseOutput) {
16654 if(m_integratedHeatReleaseOutputInterval != 0
16655 && (((
globalTimeStep - offset) % m_integratedHeatReleaseOutputInterval) == 0)) {
16656 calculateHeatRelease();
16658 MFloat accumulatedHeatRelease = F0;
16660 accumulatedHeatRelease += m_heatRelease[
cellId] * a_cellVolume(cellId);
16663 MPI_Allreduce(MPI_IN_PLACE, &accumulatedHeatRelease, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
16664 "accumulatedHeatRelease");
16668 datei = fopen(
"integratedHeatRelease",
"a+");
16670 fprintf(datei,
" %-10.10f", m_physicalTime);
16671 fprintf(datei,
" %-10.10f", m_time);
16672 fprintf(datei,
" %-10.10f", accumulatedHeatRelease);
16673 fprintf(datei,
"\n");
16679 if(!m_combustion) {
16681 if(m_dragOutputInterval != 0
16684 computeForceCoefficients(&forceCoefficientVector.p[0]);
16686 MFloat m_ub_utau = 1.0 / sqrt(forceCoefficientVector.p[0] / 2.0);
16687 MFloat Re_tau = m_Re / m_ub_utau;
16691 datei = fopen(
"forceCoef",
"a+");
16693 fprintf(datei,
" %f", m_physicalTime);
16694 fprintf(datei,
" %f", m_time);
16695 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
16696 fprintf(datei,
" %f", forceCoefficientVector.p[spaceId]);
16698 IF_CONSTEXPR(nDim == 2) {
16699 fprintf(datei,
" %f",
16700 forceCoefficientVector.p[0] *
cos(m_angle[0]) + forceCoefficientVector.p[1] * sin(m_angle[0]));
16701 fprintf(datei,
" %f",
16702 -forceCoefficientVector.p[0] * sin(m_angle[0]) + forceCoefficientVector.p[1] *
cos(m_angle[0]));
16704 if(m_periodicCells == 3) {
16705 fprintf(datei,
" %f", m_ub_utau);
16706 fprintf(datei,
" %f", Re_tau);
16708 fprintf(datei,
"\n");
16714 if(m_wmSurfaceProbeInterval > 0) {
16716 writeWMSurfaceProbes();
16720 if(m_wallNormalOutput && m_normalOutputInterval > 0) {
16722 getWallNormalPointVars();
16726 if(m_saSrfcProbeInterval > 0) {
16729 writeSpanAvgSrfcProbes();
16739 if(m_outputPhysicalTime) {
16740 if(domainId() == 0)
16741 cerr <<
"solverId: " << m_solverId <<
", Writing " << m_outputFormat <<
" output at time step "
16742 <<
globalTimeStep <<
", physical time " << m_physicalTime <<
" ... ";
16743 m_log <<
"Writing " << m_outputFormat <<
" output at time step " <<
globalTimeStep <<
", physical time "
16744 << m_physicalTime <<
" ... ";
16746 if(domainId() == 0)
16747 cerr <<
"solverId: " << m_solverId <<
", Writing " << m_outputFormat <<
" output at time step "
16749 m_log <<
"Writing " << m_outputFormat <<
" output at time step " <<
globalTimeStep <<
", time " << m_time
16754 MInt noLevelSetFieldData = 0;
16758 noLevelSetFieldData = 0;
16760 }
else if(m_levelSetMb) {
16761 noLevelSetFieldData = 0;
16763 noLevelSetFieldData = a_noLevelSetFieldData();
16767 MBool writeSpongeInfo =
false;
16768 writeSpongeInfo = Context::getSolverProperty<MBool>(
"writeSpongeInfo", solverId(), AT_, &writeSpongeInfo);
16770 if(m_spongeTimeDep) writeSpongeInfo =
true;
16772 MBool writeLimInfo =
false;
16776 * (PV->noVariables + (
MInt)m_levelSet * noLevelSetFieldData
16777 + m_vorticitySize + (
MInt)m_qCriterionOutput + (
MInt)writeSpongeInfo
16778 + (
MInt)writeLimInfo + (5 + PV->noVariables) * (
MInt)m_wmOutput
16779 + (
MInt)m_useSandpaperTrip)
16780 + (
MInt)isDetChem<SysEqn>,
16781 AT_,
"dbVariables");
16786 vector<MString> dbVariablesName;
16787 vector<MString> idVariablesName;
16788 vector<MString> dbParametersName;
16789 vector<MString> idParametersName;
16790 vector<MString> name;
16792 stringstream fileName;
16793 if(m_multipleFvSolver) {
16794 fileName << m_solutionOutput <<
"QOUT" << getIdentifier(
true,
"_") <<
globalTimeStep;
16799 for(
MInt v = 0; v < PV->noVariables; v++) {
16800 name.push_back(m_variablesName[v]);
16803 this->collectVariables(&a_pvariable(0, 0), dbVariables, name, dbVariablesName, PV->noVariables, a_noCells());
16806 name.push_back(
"limPhi");
16807 this->collectVariables(m_limPhi, dbVariables, name, dbVariablesName, 1, a_noCells());
16810 if(m_vorticityOutput) {
16812 getVorticity(&vorticity[0]);
16814 for(
MInt i = 0; i < m_vorticitySize; i++) {
16815 name.push_back(m_vorticityName[i]);
16817 this->collectVariables(vorticity.begin(), dbVariables, name, dbVariablesName, m_vorticitySize, a_noCells(),
16821 if(m_qCriterionOutput) {
16823 computeQCriterion(qCriterion);
16825 name.push_back(
"qCriterion");
16826 this->collectVariables(qCriterion.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16833 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16836 for(
MUint wmSrfcId = 0; wmSrfcId < m_wmSurfaces.size(); wmSrfcId++) {
16837 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
16838 const MInt cell = m_bndryCells->a[bndryCellId].m_cellId;
16839 tmp[cell] = (
MFloat)m_wmSurfaces[wmSrfcId].m_wmHasImgCell;
16842 name.push_back(
"hasImgCell");
16843 this->collectVariables(tmp.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16845 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16848 for(
MUint wmSrfcId = 0; wmSrfcId < m_wmSurfaces.size(); wmSrfcId++) {
16849 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
16850 const MInt cell = m_bndryCells->a[bndryCellId].m_cellId;
16851 tmp[cell] = (
MFloat)m_wmSurfaces[wmSrfcId].m_wmUII;
16854 name.push_back(
"u_II");
16855 this->collectVariables(tmp.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16857 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16860 for(
MUint wmSrfcId = 0; wmSrfcId < m_wmSurfaces.size(); wmSrfcId++) {
16861 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
16862 const MInt cell = m_bndryCells->a[bndryCellId].m_cellId;
16863 tmp[cell] = (
MFloat)m_wmSurfaces[wmSrfcId].m_wmTauW;
16866 name.push_back(
"tau_w_spalding");
16867 this->collectVariables(tmp.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16869 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16872 for(
MUint wmSrfcId = 0; wmSrfcId < m_wmSurfaces.size(); wmSrfcId++) {
16873 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
16874 const MInt cell = m_bndryCells->a[bndryCellId].m_cellId;
16875 tmp[cell] = (
MFloat)m_wmSurfaces[wmSrfcId].m_wmMUEWM;
16878 name.push_back(
"mue_wm");
16879 this->collectVariables(tmp.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16881 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16882 tmp[cell] = (
MFloat)a_isWMImgCell(cell);
16885 name.push_back(
"isWMImgCell");
16886 this->collectVariables(tmp.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16888 const MChar* imgVarNames[5] = {
"UImg",
"VImg",
"WImg",
"RHOImg",
"PImg"};
16889 for(
MInt v = 0; v < PV->noVariables; v++) {
16890 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16893 for(
MUint wmSrfcId = 0; wmSrfcId < m_wmSurfaces.size(); wmSrfcId++) {
16894 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
16895 const MInt cell = m_bndryCells->a[bndryCellId].m_cellId;
16896 tmp[cell] = (
MFloat)m_wmSurfaces[wmSrfcId].m_wmImgVars[v];
16899 name.push_back(v <= 4 ? imgVarNames[v] :
"YImg" + std::to_string(v));
16900 this->collectVariables(tmp.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16904 if(m_useSandpaperTrip) {
16906 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16907 tmp[cell] = (
MFloat)a_isSandpaperTripCell(cell);
16910 name.push_back(
"isSandpaperTripCell");
16911 this->collectVariables(tmp.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16917 noSets = a_noSets();
16918 }
else if(!m_levelSetMb) {
16919 noSets = a_noSets();
16921 for(
MInt set = 0; set < noSets; set++) {
16925 for(
MInt cell = 0; cell < c_noCells(); cell++) {
16927 levelSetFunction[cell] = a_levelSetFunction(cell, 0);
16928 curvature[cell] = a_curvatureG(cell, 0);
16929 }
else if(m_levelSetMb) {
16932 levelSetFunction[cell] = a_levelSetFunction(cell, 0);
16933 curvature[cell] = a_curvatureG(cell, 0);
16936 stringstream gName;
16937 stringstream gCurv;
16938 gName <<
"G_" << set << endl;
16939 gCurv <<
"curvature_" << set << endl;
16941 name.push_back(gName.str());
16942 this->collectVariables(levelSetFunction.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16944 name.push_back(gCurv.str());
16945 this->collectVariables(curvature.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16949 this->collectParameters(m_noSamples, idParameters,
"noSamples", idParametersName);
16950 this->collectParameters(
globalTimeStep, idParameters,
"globalTimeStep", idParametersName);
16951 if(m_outputPhysicalTime) {
16952 this->collectParameters(m_physicalTime, dbParameters,
"time", dbParametersName);
16953 this->collectParameters(m_time, dbParameters,
"internalTime", dbParametersName);
16955 this->collectParameters(m_time, dbParameters,
"time", dbParametersName);
16956 this->collectParameters(m_physicalTime, dbParameters,
"physicalTime", dbParametersName);
16961 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16962 domainIdCheck.p[cell] = domainId();
16963 if(a_isBndryGhostCell(cell))
continue;
16964 if(a_isWindow(cell)) {
16965 windowCheck.p[cell] = domainId();
16967 windowCheck.p[cell] = -1;
16971 if(writeSpongeInfo) {
16973 for(
MInt cell = 0; cell < a_noCells(); cell++) {
16974 spongeFactor[cell] = a_spongeFactor(cell);
16977 name.push_back(
"sigmaSponge");
16978 this->collectVariables(spongeFactor.begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
16985 fileName << ParallelIo::fileExt();
16989 saveGridFlowVarsPar((fileName.str()).c_str(), a_noCells(), noInternalCells(), dbVariables, dbVariablesName, 0,
16990 idVariables, idVariablesName, 0, dbParameters, dbParametersName, idParameters,
16991 idParametersName, m_recalcIds);
16997 m_fvBndryCnd->recorrectCellCoordinates();
16999 extractPointIdsFromGrid(m_extractedCells, m_gridPoints,
false, m_splitChildToSplitCell, m_vtuLevelThreshold,
17000 m_vtuCoordinatesThreshold);
17002 fileName <<
"_D" << domainId() <<
".vtu";
17007 if(m_extractedCells) {
17008 delete m_extractedCells;
17009 m_extractedCells =
nullptr;
17012 delete m_gridPoints;
17013 m_gridPoints =
nullptr;
17015 m_fvBndryCnd->rerecorrectCellCoordinates();
17019 stringstream errorMessage;
17020 errorMessage <<
"FvCartesianSolverXD::saveOutputFv(): switch variable 'm_outputFormat' with value "
17021 << m_outputFormat <<
" not matching any case." << endl;
17022 mTerm(1, AT_, errorMessage.str());
17026 if(domainId() == 0) cerr <<
"ok" << endl;
17034template <MInt nDim_,
class SysEqn>
17036 const MString gridFileName,
MInt* recalcIdTree) {
17039 m_currentGridFileName = gridFileName;
17041 if(m_recalcIds !=
nullptr) {
17042 for(
MInt cellId = 0; cellId < maxNoGridCells(); cellId++) {
17043 m_recalcIds[cellId] = recalcIdTree[cellId];
17048 saveRestartFile(writeBackup);
17051 if(m_useSandpaperTrip) {
17052 saveSandpaperTripVars();
17056 writeWMTimersASCII();
17064template <MInt nDim_,
class SysEqn>
17068 writeGridRestart =
false;
17071 if(m_restartInterval == -1 && !writeRestart) {
17072 writeRestart =
false;
17076 MInt relativeRestartTimeStep = m_restartTimeStep - m_restartOffset;
17078 if(((relativeTimeStep % m_restartInterval) == 0 && relativeTimeStep > relativeRestartTimeStep) || writeRestart) {
17079 writeRestart =
true;
17081 if(m_forceRestartGrid) {
17082 m_adaptationSinceLastRestart =
true;
17083 writeGridRestart =
true;
17084 if(m_recalcIds ==
nullptr && isActive())
mAlloc(m_recalcIds, maxNoGridCells(),
"m_recalcIds", -1, AT_);
17087 if(m_adaptationSinceLastRestartBackup || m_adaptationSinceLastRestart) {
17088 writeGridRestart =
true;
17092 if(isActive() && m_levelSetMb && writeRestart) {
17093 if(maxLevel() > minLevel()) {
17094 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
17095 if(a_isBndryGhostCell(cellId))
continue;
17096 if(a_isHalo(cellId))
continue;
17097 if(a_level(cellId) != minLevel())
continue;
17098 reduceData(cellId, &a_pvariable(0, 0), PV->noVariables);
17103 return writeRestart;
17106template <MInt nDim_,
class SysEqn>
17111 m_adaptationSinceLastRestart =
false;
17112 m_adaptationSinceLastRestartBackup =
false;
17119template <MInt nDim_,
class SysEqn>
17123 if(m_time < m_samplingTimeBegin) {
17126 if(m_time > m_samplingTimeEnd) {
17133 const MInt oldSize = a_noCells();
17134 m_cells.size(m_bndryGhostCellsOffset);
17136 MInt ghostcellbackup = m_totalnoghostcells;
17137 MInt splitchildbackup = m_totalnosplitchilds;
17138 m_totalnoghostcells = 0;
17139 m_totalnosplitchilds = 0;
17141 stringstream varFileName;
17144 varFileName << outputDir() <<
"Q_" << m_noSamples << ParallelIo::fileExt();
17147 a_noCells() * (PV->noVariables + (
MInt)m_levelSet + m_vorticitySize + (
MInt)m_qCriterionOutput), AT_,
17152 vector<MString> dbVariablesName;
17153 vector<MString> idVariablesName;
17154 vector<MString> dbParametersName;
17155 vector<MString> idParametersName;
17156 vector<MString> name;
17158 for(
MInt v = 0; v < PV->noVariables; v++) {
17159 name.push_back(m_variablesName[v]);
17162 this->collectVariables(&a_pvariable(0, 0), dbVariables, name, dbVariablesName, PV->noVariables, a_noCells());
17164 if(m_vorticityOutput) {
17166 getVorticity(&vorticity[0]);
17168 for(
MInt i = 0; i < m_vorticitySize; i++) {
17169 name.push_back(m_vorticityName[i]);
17171 this->collectVariables(vorticity.
begin(), dbVariables, name, dbVariablesName, m_vorticitySize, a_noCells(),
true);
17174 if(m_qCriterionOutput) {
17176 computeQCriterion(qCriterion);
17178 name.push_back(
"qCriterion");
17179 this->collectVariables(qCriterion.
begin(), dbVariables, name, dbVariablesName, 1, a_noCells());
17181 setRestartFileOutputTimeStep();
17182 this->collectParameters(m_noSamples, idParameters,
"noSamples", idParametersName);
17183 this->collectParameters(
globalTimeStep, idParameters,
"globalTimeStep", idParametersName);
17184 if(m_outputPhysicalTime) {
17185 this->collectParameters(m_physicalTime, dbParameters,
"time", dbParametersName);
17187 this->collectParameters(m_time, dbParameters,
"time", dbParametersName);
17189 this->collectParameters(m_restartFileOutputTimeStep, dbParameters,
"timeStep", dbParametersName);
17190 this->collectParameters(m_noTimeStepsBetweenSamples, idParameters,
"noTimeStepsBetweenSamples", idParametersName);
17191 this->collectParameters(m_physicalTime, dbParameters,
"physicalTime", dbParametersName);
17192 this->collectParameters((
MInt)m_forcing, idParameters,
"forcing", idParametersName);
17193 this->collectParameters(m_meanPressure, dbParameters,
"meanPressure", dbParametersName);
17198 saveGridFlowVarsPar((varFileName.str()).c_str(), a_noCells(), noInternalCells(), dbVariables, dbVariablesName, 0,
17199 idVariables, idVariablesName, 0, dbParameters, dbParametersName, idParameters, idParametersName,
17206 m_cells.size(oldSize);
17207 m_totalnoghostcells = ghostcellbackup;
17208 m_totalnosplitchilds = splitchildbackup;
17212template <MInt nDim_,
class SysEqn>
17217 MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
17218 MInt cellId, ghostCellId;
17219 MFloat rhoSurface, pSurface;
17220 MFloat T, mue, dAoverRe, rhoU2;
17222 const MFloat eps = c_cellLengthAtLevel(maxRefinementLevel()) * 0.0001;
17227 MFloat globalForceCoefficients[nDim];
17228 MInt localNoSurfacePoints = 0;
17229 MFloat ypmin = 999999.99;
17235 for(
MInt i = 0; i < nDim; i++) {
17236 tau[i] = numeric_limits<MFloat>::max();
17240 if(m_surfDistParallel) {
17241 for(
MInt bndryCellId = 0; bndryCellId < noBndryCells; bndryCellId++) {
17242 cellId = m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_cellId;
17245 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
17246 if(a_isHalo(cellId))
continue;
17247 if(a_isPeriodic(cellId))
continue;
17248 for(
MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_noSrfcs; srfc++) {
17249 if(m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_bndryCndId < 3000
17250 || m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_bndryCndId >= 4000)
17252 localNoSurfacePoints++;
17256 const MInt surfaceValuesSize = 4 + nDim;
17257 MFloatScratchSpace surfaceValues(localNoSurfacePoints * surfaceValuesSize, AT_,
"surfaceValues");
17262 for(
MInt i = 0; i < nDim; i++) {
17268 for(
MInt i = 0; i < nDim; i++) {
17269 rhoU2 +=
POW2(m_VVInfinity[i]);
17271 rhoU2 *= m_rhoInfinity;
17273 MBool found_ =
false;
17276 localRetau[0] = 0.0;
17277 globalRetau[0] = 0.0;
17281 localArea1[0] = 0.0;
17282 globalArea1[0] = 0.0;
17286 for(
MInt bndryCellId = 0; bndryCellId < noBndryCells; bndryCellId++) {
17288 cellId = m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_cellId;
17289 if(cellId >= noInternalCells() && (!m_surfDistParallel))
continue;
17290 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
17291 if(a_isHalo(cellId))
continue;
17292 if(a_isPeriodic(cellId))
continue;
17294 MFloatScratchSpace dummyPvariables(m_bndryCells->a[bndryCellId].m_noSrfcs, PV->noVariables, AT_,
"dummyPvariables");
17296 if(!m_surfDistParallel)
17297 if(m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_linkedCellId > -1)
17298 if(a_bndryId(m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_linkedCellId) > -1)
continue;
17299 if(!m_fvBndryCnd->m_cellMerging) {
17300 for(
MInt s = 0; s <
mMin((
signed)m_fvBndryCnd->m_bndryCell[bndryCellId].m_recNghbrIds.size(),
17301 m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_noSrfcs);
17303 dummyPvariables(s, PV->P) = m_fvBndryCnd->m_bndryCell[bndryCellId].m_srfcVariables[s]->m_primVars[PV->P];
17304 dummyPvariables(s, PV->RHO) = m_fvBndryCnd->m_bndryCell[bndryCellId].m_srfcVariables[s]->m_primVars[PV->RHO];
17307 for(
MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_noSrfcs; srfc++) {
17308 if(m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_bndryCndId < 3000
17309 || m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_bndryCndId >= 4000)
17312 ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcVariables[srfc]->m_ghostCellId;
17315 rhoSurface = F1B2 * (a_pvariable(cellId, PV->RHO) + a_pvariable(ghostCellId, PV->RHO));
17316 pSurface = F1B2 * (a_pvariable(cellId, PV->P) + a_pvariable(ghostCellId, PV->P));
17319 T = sysEqn().temperature_ES(rhoSurface, pSurface);
17322 mue = SUTHERLANDLAW(T);
17326 m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_area / (m_referenceLength * sysEqn().m_Re0);
17330 for(
MInt i = 0; i < nDim; i++) {
17332 fabs((a_coordinate(cellId, i) - m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_coordinates[i])
17333 * m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_normalVector[i]);
17337 if(m_fvBndryCnd->m_cellMerging) {
17338 for(
MInt orientation = 0; orientation < nDim; orientation++) {
17339 if(fabs(
dist) > eps)
17341 mue * F1B2 * (a_pvariable(cellId, PV->VV[orientation]) - a_pvariable(ghostCellId, PV->VV[orientation]))
17344 tau[orientation] = F0;
17349 for(
MInt n = 0; n < (signed)m_fvBndryCnd->m_bndryCell[bndryCellId].m_recNghbrIds.size(); n++) {
17350 const MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryCellId].m_recNghbrIds[n];
17351 const MFloat nghbrPvariableP = (n < m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_noSrfcs)
17352 ? dummyPvariables(n, PV->P)
17353 : a_pvariable(nghbrId, PV->P);
17354 const MFloat nghbrPvariableRho = (n < m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_noSrfcs)
17355 ? dummyPvariables(n, PV->RHO)
17356 : a_pvariable(nghbrId, PV->RHO);
17358 m_fvBndryCnd->m_bndryCell[bndryCellId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariableRho;
17360 m_fvBndryCnd->m_bndryCell[bndryCellId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariableP;
17362 T = sysEqn().temperature_ES(rhoSurface, pSurface);
17363 mue = SUTHERLANDLAW(T);
17364 for(
MInt k = 0; k < nDim; k++) {
17365 tau[k] = mue * m_fvBndryCnd->m_bndryCell[bndryCellId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[k]];
17370 for(
MInt orientation = 0; orientation < nDim; orientation++) {
17371 pressure[orientation] +=
17372 (-F1) * pSurface * m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_area
17373 * m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_normalVector[orientation];
17374 shear[orientation] += tau[orientation] * dAoverRe;
17378 if(m_periodicCells == 3) {
17381 MFloat Length_2 = c_cellLengthAtCell(cellId);
17382 if(a_coordinate(cellId, 2) < 200.0 && a_coordinate(cellId, 1) > 200.0
17383 && a_coordinate(cellId, 1) < (200.0 + Length_2) && a_coordinate(cellId, 0) >= 2.5
17384 && a_coordinate(cellId, 0) < 2.5 + Length_2) {
17386 Re_tau_ = sqrt(tau[0] / sysEqn().m_Re0 / rhoSurface / (m_Ma * sqrt(m_TInfinity)) / (m_Ma * sqrt(m_TInfinity)))
17390 if(a_coordinate(cellId, 0) >= 2.5 && a_coordinate(cellId, 0) < 2.5 + Length_2) {
17393 localArea1[0] += m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[0]->m_area;
17395 sqrt(fabs(tau[0]) / sysEqn().m_Re0 / rhoSurface / (m_Ma * sqrt(m_TInfinity)) / (m_Ma * sqrt(m_TInfinity)))
17396 * m_Re * m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[0]->m_area;
17403 for(
MInt dim = 0; dim < nDim; dim++) {
17404 magTau +=
POW2(tau[dim]);
17406 yplus = sqrt(sysEqn().m_Re0 * sqrt(magTau) * rhoSurface) * c_cellLengthAtCell(cellId) / mue;
17408 ypmin =
mMin(ypmin, yplus);
17409 ypmax =
mMax(ypmax, yplus);
17411 yprms +=
POW2(yplus);
17415 if(m_surfDistParallel) {
17416 MFloat radToDeg = 360.0 / (2.0 * PI);
17420 MInt body = m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_bodyId[0];
17421 ASSERT(body > -1,
"wrong body Id for boundary surface...");
17422 xOffset = m_bodyCenter[body * nDim + 0];
17423 yOffset = m_bodyCenter[body * nDim + 1];
17425 MFloat dx = m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_coordinates[0] - xOffset;
17426 MFloat dy = m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_coordinates[1] - yOffset;
17427 angle = 180.0 - (radToDeg * atan2(dy, dx));
17429 for(
MInt i = 0; i < nDim; i++)
17430 ma +=
POW2(m_fvBndryCnd->m_bndryCell[bndryCellId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]]);
17432 ma /= sysEqn().speedOfSound(rhoSurface, pSurface);
17433 cp = (pSurface - m_PInfinity) / (F1B2 * rhoU2);
17434 MFloat cf = (m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_normalVector[1] * tau[0]
17435 - m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_normalVector[0] * tau[1])
17436 / (F1B2 * rhoU2 * sysEqn().m_Re0);
17437 MInt idcnt = counter * surfaceValuesSize;
17438 surfaceValues(idcnt++) = angle;
17439 for(
MInt i = 0; i < nDim; i++) {
17440 surfaceValues(idcnt++) = m_fvBndryCnd->m_bndryCells->a[bndryCellId].m_srfcs[srfc]->m_coordinates[i];
17442 surfaceValues(idcnt++) = cp;
17443 surfaceValues(idcnt++) = cf;
17444 surfaceValues(idcnt) = ma;
17452 if(m_surfDistParallel) {
17453 const MString fileName =
"surfaceDistribution";
17454 const MInt dataSolver = surfaceValuesSize;
17455 const MInt floatWidth = 9;
17456 const MInt noChars = floatWidth + 2;
17457 MInt dataSize = dataSolver * noChars * counter;
17460 for(
MInt c = 0; c < counter; c++) {
17461 for(
MInt i = 0; i < dataSolver; i++) {
17464 s << fixed << setprecision(floatWidth) << surfaceValues[c * dataSolver + i];
17465 s.str().copy(&data[cnt], floatWidth);
17467 if(i < (dataSolver - 1))
17468 sprintf(&data[cnt],
", ");
17470 sprintf(&data[cnt],
" \n");
17474 ASSERT(dataSize == cnt,
"");
17476 MPI_Allgather(&dataSize, 1, MPI_INT, &dataPerDomain[0], 1, MPI_INT, mpiComm(), AT_,
"dataSize",
"dataPerDomain[0]");
17477 MInt globalDataOffset = 0;
17478 for(
MInt d = 0; d < domainId(); d++)
17479 globalDataOffset += dataPerDomain[d];
17480 MPI_File file =
nullptr;
17481 MInt rcode =
MPI_File_open(mpiComm(),
const_cast<MChar*
>(fileName.c_str()), MPI_MODE_CREATE | MPI_MODE_WRONLY,
17482 MPI_INFO_NULL, &file, AT_);
17483 if(rcode != MPI_SUCCESS)
mTerm(1, AT_,
"Error opening file " + fileName);
17487 rcode = (counter > 0) ? MPI_File_write(file, &data[0], dataSize, MPI_CHAR, &status) : MPI_SUCCESS;
17488 if(rcode != MPI_SUCCESS)
mTerm(1, AT_,
"Error (1) writing to file " + fileName);
17493 for(
MInt i = 0; i < nDim; i++)
17494 forceCoefficients[i] = (pressure[i]) / (F1B2 * rhoU2);
17496 for(
MInt i = 0; i < nDim; i++) {
17497 forceCoefficients[i] = (shear[i] + pressure[i]) / (F1B2 * rhoU2);
17499 if(m_periodicCells == 3) {
17500 for(
MInt i = 0; i < nDim; i++)
17501 forceCoefficients[i] = (shear[i]) / (F1B2 * rhoU2) / (5.0) / (2.0 * PI * 0.5);
17506 if(m_periodicCells == 3) {
17507 MPI_Allreduce(localRetau, globalRetau, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localRetau",
"globalRetau");
17508 MPI_Allreduce(localArea1, globalArea1, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"localArea1",
"globalArea1");
17511 globalRetau[0] / globalArea1[0];
17514 MPI_Reduce(forceCoefficients, globalForceCoefficients, nDim, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_,
17515 "forceCoefficients",
"globalForceCoefficients");
17516 MPI_Bcast(globalForceCoefficients, nDim, MPI_DOUBLE, 0, mpiComm(), AT_,
"globalForceCoefficients");
17518 for(
MInt i = 0; i < nDim; i++) {
17519 forceCoefficients[i] = globalForceCoefficients[i];
17522 MPI_Allreduce(MPI_IN_PLACE, &ypmin, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
"ypmin");
17523 MPI_Allreduce(MPI_IN_PLACE, &ypmax, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"ypmax");
17524 MPI_Allreduce(MPI_IN_PLACE, &ypavg, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"ypavg");
17525 MPI_Allreduce(MPI_IN_PLACE, &yprms, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"yprms");
17526 MPI_Allreduce(MPI_IN_PLACE, &ypcnt, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"ypcnt");
17529 if(found_ && m_periodicCells == 3)
17532 datei = fopen(
"reTau_loc",
"a+");
17534 fprintf(datei,
" %f", Re_tau_);
17535 fprintf(datei,
"\n");
17539 if(domainId() == 0 && m_periodicCells == 3) {
17541 datei = fopen(
"reTau",
"a+");
17543 fprintf(datei,
" %f", globalRetau[0]);
17544 fprintf(datei,
"\n");
17549 m_log <<
"yplus: min=" << ypmin <<
", avg=" << ypavg / ypcnt <<
", rms=" << sqrt(yprms / ypcnt) <<
", max=" << ypmax
17561template <MInt nDim_,
class SysEqn>
17563 const MInt noPVars = PV->noVariables;
17564 if(m_extractedCells ==
nullptr) {
17565 cerr <<
"Extracted cells not allocated." << endl;
17568 for(
MInt c = 0; c < m_extractedCells->size(); c++) {
17569 MInt cellId = m_extractedCells->a[c].m_cellId;
17570 for(
MInt dir = 0; dir < nDim; dir++) {
17571 MInt n0 = (a_hasNeighbor(cellId, 2 * dir) > 0) ? c_neighborId(cellId, 2 * dir) : cellId;
17572 MInt n1 = (a_hasNeighbor(cellId, 2 * dir + 1) > 0) ? c_neighborId(cellId, 2 * dir + 1) : cellId;
17573 for(
MInt var = 0; var < noPVars; var++) {
17574 a_slope(cellId, var, dir) =
17575 (a_pvariable(n1, var) - a_pvariable(n0, var)) /
mMax(1e-10, a_coordinate(n1, dir) - a_coordinate(n0, dir));
17589template <MInt nDim_,
class SysEqn>
17593 const MInt noPVars = PV->noVariables;
17594 const MBool needSlopes =
17595 (m_vtuQCriterionOutput || m_vtuVorticityOutput || m_vtuVelocityGradientOutput || m_vtuLambda2Output);
17596 if(m_extractedCells ==
nullptr) {
17597 cerr <<
"Extracted cells not allocated." << endl;
17601 if(m_vtuLevelThreshold < maxRefinementLevel()) {
17602 if(needSlopes && m_vtuLevelThreshold > maxUniformRefinementLevel()) {
17603 LSReconstructCellCenter();
17605 for(
MInt c = 0; c < m_extractedCells->size(); c++) {
17606 MInt cellId = m_extractedCells->a[c].m_cellId;
17607 if(c_noChildren(cellId) > 0 && a_level(cellId) == m_vtuLevelThreshold) {
17608 reduceData(cellId, &a_pvariable(0, 0), noPVars);
17611 if(needSlopes && m_vtuLevelThreshold <= maxUniformRefinementLevel()) {
17612 exchangeDataFV(&a_pvariable(0, 0), noPVars,
false, m_rotIndVarsPV);
17613 computeSlopesByCentralDifferences();
17614 }
else if(m_vtuWritePointData) {
17615 exchangeDataFV(&a_pvariable(0, 0), noPVars,
false, m_rotIndVarsPV);
17618 for(
MInt c = 0; c < m_extractedCells->size(); c++) {
17619 MInt cellId = m_extractedCells->a[c].m_cellId;
17620 if(c_noChildren(cellId) > 0 && a_level(cellId) == m_vtuLevelThreshold) {
17621 reduceData(cellId, &a_slope(0, 0, 0), noPVars * nDim);
17626 if(m_vtuWritePointData) {
17629 exchangeDataFV(&a_slope(0, 0, 0), noPVars * nDim,
false);
17644template <MInt nDim_,
class SysEqn>
17648 MBool debugOutput = m_domainIdOutput;
17650 debugOutput =
true;
17654 if(m_jet || m_confinedFlame) jet =
true;
17655 m_levelSetOutput = m_levelSetOutput || (m_levelSet && !m_combustion && !m_levelSetMb);
17658 MInt noInternalCellIds;
17659 std::vector<MInt> recalcIdsSolver(0);
17660 std::vector<MInt> reOrderedCells(0);
17663 if(grid().newMinLevel() > 0) {
17664 m_recalcIds =
nullptr;
17667 this->calcRecalcCellIdsSolver(m_recalcIds, noCells, noInternalCellIds, recalcIdsSolver, reOrderedCells);
17669 noCells = (grid().newMinLevel() < 0) ? a_noCells() : reOrderedCells.size();
17671 stringstream varFileName;
17672 stringstream backupFileName;
17673 const MInt noDbVariables =
17676 + (
MInt)debugOutput * 2
17677 + (
MInt)m_levelSetRans + ((
MInt)m_acousticAnalysis) * 3
17678 + ((m_averageVorticity && m_movingAvgInterval == 0) || m_saveVorticityToRestart)
17680 + (
MInt)m_restartOldVariables * CV->noVariables
17681 + (
MInt)m_localTS + (
MInt)m_bodyIdOutput + (
MInt)m_levelSetOutput
17682 + ((
MInt)(isDetChem<SysEqn> && m_detChemExtendedOutput)) * 3
17683 + ((
MInt)(isDetChem<SysEqn> && m_detChemExtendedOutput && m_acousticAnalysis)) * 4 + (
MInt)m_wmLES * 2);
17685 MBool addVarOut = m_localTS || m_bodyIdOutput || m_levelSetOutput;
17691 const MInt noIdVariables = (
MInt)m_isActiveOutput;
17695 MInt writeRestartTimeBc2800 = 0;
17699 vector<MString> dbVariablesName;
17700 vector<MString> idVariablesName;
17701 vector<MString> dbParametersName;
17702 vector<MString> idParametersName;
17703 vector<MString> name;
17705 for(
MInt v = 0; v < PV->noVariables; v++) {
17706 name.push_back(m_variablesName[v]);
17709 if(grid().newMinLevel() < 0) {
17710 this->collectVariables(&a_pvariable(0, 0), dbVariables, name, dbVariablesName, PV->noVariables, a_noCells());
17712 MFloat** variables =
nullptr;
17713 const MInt noPVars = PV->noVariables;
17714 mAlloc(variables, noCells, noPVars,
"variables", 0.0, AT_);
17716 for(
MInt cell = 0; cell < noCells; cell++) {
17717 for(
MInt var = 0; var < noPVars; var++)
17718 variables[cell][var] = a_pvariable(reOrderedCells[cell], var);
17721 this->collectVariables(variables, dbVariables, name, dbVariablesName, noPVars, noCells);
17722 variables =
nullptr;
17726 IF_CONSTEXPR(isDetChem<SysEqn>) {
17727 if(m_detChemExtendedOutput) {
17729 name.push_back(
"RHO_E");
17730 if(grid().newMinLevel() < 0) {
17731 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17732 tmpDetChem[cellId] = a_variable(cellId, CV->RHO_E);
17735 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17736 tmpDetChem[cellId] = a_variable(reOrderedCells[cellId], CV->RHO_E);
17739 this->collectVariables(tmpDetChem.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17742 name.push_back(
"T");
17743 if(grid().newMinLevel() < 0) {
17744 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17745 tmpDetChem[cellId] = a_pvariable(cellId, PV->P) / m_gasConstant * a_avariable(cellId, AV->W_MEAN)
17746 / a_pvariable(cellId, PV->RHO);
17749 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17750 tmpDetChem[cellId] = a_pvariable(reOrderedCells[cellId], PV->P) / m_gasConstant
17751 * a_avariable(reOrderedCells[cellId], AV->W_MEAN)
17752 / a_pvariable(reOrderedCells[cellId], PV->RHO);
17755 this->collectVariables(tmpDetChem.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17758 name.push_back(
"HeatRelease");
17759 if(grid().newMinLevel() < 0) {
17760 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17761 if(a_isBndryGhostCell(cellId))
continue;
17762 const MFloat dampeningFactor = m_heatReleaseDamp ? m_dampFactor[cellId] : F1;
17763 tmpDetChem[cellId] = 0;
17764 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
17765 tmpDetChem[cellId] -= dampeningFactor * a_speciesReactionRate(cellId, s) * m_standardHeatFormation[s];
17769 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17770 if(a_isBndryGhostCell(cellId))
continue;
17771 const MFloat dampeningFactor = m_heatReleaseDamp ? m_dampFactor[cellId] : F1;
17772 tmpDetChem[cellId] = 0;
17773 for(
MUint s = 0; s < PV->m_noSpecies; ++s) {
17774 tmpDetChem[cellId] -=
17775 dampeningFactor * a_speciesReactionRate(reOrderedCells[cellId], s) * m_standardHeatFormation[s];
17779 this->collectVariables(tmpDetChem.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17781 if(m_acousticAnalysis) {
17787 computeAcousticSourceTermQe(QeI, QeIII, cSquared, drhodt);
17790 name.push_back(
"QeI");
17791 this->collectVariables(QeI.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17794 name.push_back(
"QeIII");
17795 this->collectVariables(QeIII.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17798 name.push_back(
"cSquared");
17799 this->collectVariables(cSquared.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17802 name.push_back(
"drhodt");
17803 this->collectVariables(drhodt.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17809 MFloat** wmVariables =
nullptr;
17810 const MInt noWMVars = 2;
17811 mAlloc(wmVariables, noCells, noWMVars,
"wmVariables", 0.0, AT_);
17813 name.emplace_back(
"utau");
17814 name.emplace_back(
"u_II");
17815 for(
MUint wmSrfcId = 0; wmSrfcId < m_wmSurfaces.size(); wmSrfcId++) {
17816 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
17817 const MInt cell = m_bndryCells->a[bndryCellId].m_cellId;
17818 wmVariables[cell][0] = m_wmSurfaces[wmSrfcId].m_wmUTAU;
17819 wmVariables[cell][1] = m_wmSurfaces[wmSrfcId].m_wmUII;
17821 this->collectVariables(wmVariables, dbVariables, name, dbVariablesName, noWMVars, noCells);
17822 wmVariables =
nullptr;
17828 name.push_back(
"domainId");
17829 for(
MInt i = 0; i < c_noCells(); i++) {
17830 if(a_isWindow(i)) {
17831 tmpW[i] = -domainId();
17833 tmpW[i] = domainId();
17836 this->collectVariables(tmpW.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17839 name.push_back(
"globalId");
17840 for(
MInt i = 0; i < c_noCells(); i++) {
17841 assertValidGridCellId(i);
17842 tmpW[i] = c_globalId(i);
17844 for(
MInt i = c_noCells(); i < noCells; i++) {
17847 this->collectVariables(tmpW.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17850 if(m_levelSetOutput) {
17852 name.push_back(
"G");
17854 if(grid().newMinLevel() < 0) {
17855 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17856 tmp[cellId] = a_levelSetValuesMb(cellId, 0);
17859 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17860 tmp[cellId] = a_levelSetValuesMb(reOrderedCells[cellId], 0);
17864 for(
MInt i = 0; i < noCells; i++) {
17865 tmp[i] = a_levelSetFunction(i, 0);
17868 this->collectVariables(tmp.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17873 name.push_back(
"localTS");
17874 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17875 tmp[cellId] = a_localTimeStep(cellId);
17877 this->collectVariables(tmp.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17880 if(m_levelSetRans) {
17882 name.push_back(
"d");
17883 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17884 tmp[cellId] = a_levelSetFunction(cellId, 0);
17886 this->collectVariables(tmp.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17889 if(m_bodyIdOutput) {
17890 ASSERT(m_levelSetMb,
"");
17891 if(grid().newMinLevel() < 0) {
17892 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17893 tmp[cellId] = a_associatedBodyIds(cellId, 0);
17896 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17897 tmp[cellId] = a_associatedBodyIds(reOrderedCells[cellId], 0);
17901 name.push_back(
"BodyId");
17902 this->collectVariables(tmp.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17905 if(m_isActiveOutput) {
17906 if(grid().newMinLevel() < 0) {
17907 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17908 tmpId[cellId] = (
MInt)(!a_hasProperty(cellId, SolverCell::IsInactive));
17911 for(
MInt cellId = 0; cellId < noCells; cellId++) {
17912 tmpId[cellId] = (
MInt)(!a_hasProperty(reOrderedCells[cellId], SolverCell::IsInactive));
17916 name.push_back(
"IsActive");
17917 this->collectVariables(tmpId.
begin(), idVariables, name, idVariablesName, 1, noCells);
17920 if(m_combustion && m_acousticAnalysis) {
17921 IF_CONSTEXPR(!hasE<SysEqn>)
17922 mTerm(1, AT_,
"Not compatible with SysEqn without RHO_E!");
17923 const MFloat gammaMinusOne = m_gamma - F1;
17924 const MFloat FgammaMinusOne = F1 / gammaMinusOne;
17925 MFloat reactionEnthalpy = (m_burntUnburntTemperatureRatio - F1) * FgammaMinusOne;
17926 MFloat FtimeStep = 1 / timeStep();
17932 for(
MInt cell = 0; cell < noCells; cell++) {
17937 if(!a_hasProperty(cell, SolverCell::IsOnCurrentMGLevel))
continue;
17941 for(
MInt i = 0; i < nDim; i++) {
17942 velPOW2 +=
POW2(a_oldVariable(cell, CV->RHO_VV[i]));
17945 dPdT[cell] = a_pvariable(cell, 3);
17947 const MFloat pold = sysEqn().pressure(a_oldVariable(cell, CV->RHO), velPOW2, a_oldVariable(cell, CV->RHO_E));
17949 dPdT[cell] -= pold;
17950 dPdT[cell] *= FtimeStep;
17952 h[cell] = a_reactionRate(cell, 0);
17953 h[cell] *= a_cellVolume(cell) * reactionEnthalpy;
17954 dHdT[cell] = a_reactionRate(cell, 0);
17955 dHdT[cell] -= a_reactionRateBackup(cell, 0);
17956 dHdT[cell] *= a_cellVolume(cell) * reactionEnthalpy;
17957 dHdT[cell] *= FtimeStep;
17960 stringstream dPdTname;
17961 stringstream dHdTname;
17962 stringstream hName;
17963 dPdTname <<
"dPdT";
17964 dHdTname <<
"dHdT";
17967 name.push_back(dPdTname.str());
17968 this->collectVariables(dPdT.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17970 name.push_back(dHdTname.str());
17971 this->collectVariables(dHdT.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17973 name.push_back(hName.str());
17974 this->collectVariables(h.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
17977 setRestartFileOutputTimeStep();
17979 this->collectParameters(m_noSamples, idParameters,
"noSamples", idParametersName);
17980 this->collectParameters(
globalTimeStep, idParameters,
"globalTimeStep", idParametersName);
17981 if(m_outputPhysicalTime) {
17982 this->collectParameters(m_physicalTime, dbParameters,
"time", dbParametersName);
17984 this->collectParameters(m_time, dbParameters,
"time", dbParametersName);
17986 this->collectParameters(m_restartFileOutputTimeStep, dbParameters,
"timeStep", dbParametersName);
17987 this->collectParameters(m_noTimeStepsBetweenSamples, idParameters,
"noTimeStepsBetweenSamples", idParametersName);
17988 this->collectParameters(m_physicalTime, dbParameters,
"physicalTime", dbParametersName);
17989 this->collectParameters((
MInt)m_forcing, idParameters,
"forcing", idParametersName);
17990 if(writeRestartTimeBc2800 != 0) {
17991 this->collectParameters(m_restartTimeBc2800, dbParameters,
"restartTimeBc2800", dbParametersName);
17994 if(m_jet || m_confinedFlame) {
17995 this->collectParameters(m_jetDensity, dbParameters,
"jetDensity", dbParametersName);
17996 this->collectParameters(m_jetPressure, dbParameters,
"jetPressure", dbParametersName);
17997 this->collectParameters(m_jetTemperature, dbParameters,
"jetTemperature", dbParametersName);
18001 if((m_averageVorticity && m_movingAvgInterval == 0) || m_saveVorticityToRestart) {
18003 getVorticity(&vorticity[0]);
18005 for(
MInt i = 0; i < m_vorticitySize; i++) {
18006 name.push_back(m_vorticityName[i]);
18008 this->collectVariables(vorticity.
begin(), dbVariables, name, dbVariablesName, m_vorticitySize, noCells,
true);
18012 if(m_restartOldVariables) {
18021 IF_CONSTEXPR(nDim == 3) {
18023 for(
MInt c = 0; c < noCells; c++) {
18024 IF_CONSTEXPR(hasE<SysEqn>)
18025 oldRhoE[c] = a_oldVariable(c, CV->RHO_E);
18026 oldRhoU[c] = a_oldVariable(c, CV->RHO_VV[0]);
18027 oldRhoV[c] = a_oldVariable(c, CV->RHO_VV[1]);
18028 oldRhoW[c] = a_oldVariable(c, CV->RHO_VV[2]);
18029 oldRho[c] = a_oldVariable(c, CV->RHO);
18034 for(
MInt c = 0; c < noCells; c++) {
18035 IF_CONSTEXPR(hasE<SysEqn>)
18036 oldRhoE[c] = a_oldVariable(c, CV->RHO_E);
18037 oldRhoU[c] = a_oldVariable(c, CV->RHO_VV[0]);
18038 oldRhoV[c] = a_oldVariable(c, CV->RHO_VV[1]);
18039 oldRho[c] = a_oldVariable(c, CV->RHO);
18045 name.push_back(
"oldRhoE");
18046 this->collectVariables(oldRhoE.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
18048 name.push_back(
"oldRhoU");
18049 this->collectVariables(oldRhoU.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
18051 name.push_back(
"oldRhoV");
18052 this->collectVariables(oldRhoV.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
18053 IF_CONSTEXPR(nDim == 3) {
18055 name.push_back(
"oldRhoW");
18056 this->collectVariables(oldRhoW.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
18059 name.push_back(
"oldRho");
18060 this->collectVariables(oldRho.
begin(), dbVariables, name, dbVariablesName, 1, noCells);
18063 MInt* pointerRecalcIds = (m_recalcIds ==
nullptr) ?
nullptr : recalcIdsSolver.data();
18065 if(m_useNonSpecifiedRestartFile) {
18068 backupFileName << outputDir() <<
"restartVariablesBackup_" <<
globalTimeStep << ParallelIo::fileExt();
18070 cerr0 <<
"writing flow variables (backup) for the fv-solver... ";
18072 saveGridFlowVarsPar((backupFileName.str()).c_str(), noCells, noInternalCellIds, dbVariables, dbVariablesName, 0,
18073 idVariables, idVariablesName, 0, dbParameters, dbParametersName, idParameters,
18074 idParametersName, pointerRecalcIds);
18076 cerr0 <<
"ok" << endl;
18078 varFileName << outputDir() <<
"restartVariables" << ParallelIo::fileExt();
18079 struct stat buffer {};
18080 if(stat((varFileName.str()).c_str(), &buffer) == 0) {
18082 std::rename(varFileName.str().c_str(), (varFileName.str() + to_string(
globalTimeStep) +
"backup").c_str());
18085 if(!isMultilevel()) {
18086 varFileName << outputDir() <<
"restartVariables" << getIdentifier(m_multipleFvSolver,
"",
"") <<
"_"
18090 const MInt maxLength = 256;
18091 array<MChar, maxLength> buffer{};
18092 snprintf(buffer.data(), maxLength,
"restart_b%02d_t%08d", solverId(),
globalTimeStep);
18093 varFileName << outputDir() <<
MString(buffer.data()) << ParallelIo::fileExt();
18097 saveGridFlowVarsPar((varFileName.str()).c_str(), noCells, noInternalCellIds, dbVariables, dbVariablesName, 0,
18098 idVariables, idVariablesName, 0, dbParameters, dbParametersName, idParameters, idParametersName,
18101 if(domainId() == 0) cerr <<
"ok" << endl;
18112template <MInt nDim_,
class SysEqn>
18114 stringstream gridFile;
18115 stringstream gridFilePath;
18117 gridFilePath << outputDir() <<
"grid_" <<
globalTimeStep <<
".Netcdf";
18118 MIntScratchSpace recalcIds(grid().raw().treeb().size(), AT_,
"recalcIds");
18120 grid().raw().saveGrid((gridFilePath.str()).c_str(), recalcIds.
begin());
18122 writeRestartFile(
true,
false, (gridFile.str()).c_str(), recalcIds.
begin());
18131template <MInt nDim_,
class SysEqn>
18136 stringstream varFileName;
18139 if(m_useNonSpecifiedRestartFile) {
18141 if(m_multipleFvSolver) {
18142 varFileName << restartDir() <<
"restartVariables" << m_solverId << ParallelIo::fileExt();
18144 varFileName << restartDir() <<
"restartVariables" << ParallelIo::fileExt();
18152 if(!isMultilevel()) {
18153 if(m_multipleFvSolver) {
18154 varFileName << restartDir() <<
"restartVariables" << m_solverId <<
"_" <<
globalTimeStep
18155 << ParallelIo::fileExt();
18157 varFileName << restartDir() <<
"restartVariables_" <<
globalTimeStep << ParallelIo::fileExt();
18161 const MInt maxLength = 256;
18162 array<MChar, maxLength> buffer{};
18163 snprintf(buffer.data(), maxLength,
"restart_b%02d_t%08d", solverId(),
globalTimeStep);
18164 varFileName << restartDir() <<
MString(buffer.data()) << ParallelIo::fileExt();
18168 m_log <<
"loading primitive variables ... ";
18169 loadGridFlowVarsPar((varFileName.str()).c_str());
18172 if(m_restartOldVariables && !m_restartOldVariablesReset) {
18173 m_log <<
"loading old variables..." << endl;
18174 loadOldVariables(varFileName.str());
18177 if(!m_resetInitialCondition) {
18178 if(!m_useNonSpecifiedRestartFile) {
18180 stringstream errorMessage;
18181 m_log <<
"globalTimeStep unequal m_restartTimeStep!" << endl;
18182 m_log <<
"globalTimeStep = " <<
globalTimeStep <<
" and m_restartTimeStep = " << m_restartTimeStep << endl;
18183 m_log <<
"abort!" << endl;
18184 errorMessage <<
"globalTimeStep unequal m_restartTimeStep!" << endl;
18185 errorMessage <<
"globalTimeStep = " <<
globalTimeStep <<
" and m_restartTimeStep = " << m_restartTimeStep
18187 errorMessage <<
"abort!" << endl;
18197 m_log <<
"ok" << endl;
18202 m_log <<
"convert primitive restart variables ( " << m_previousMa <<
" ) to the Mach number " << m_Ma <<
"..."
18204 convertPrimitiveRestartVariables();
18205 m_log <<
"ok" << endl;
18208 computePrimitiveVariablesCoarseGrid(noInternalCells());
18211 computePrimitiveVariablesCoarseGrid();
18214 m_log <<
"computing conservative variables (only on internal cells)... ";
18217 computeConservativeVariables();
18218 m_log <<
"ok" << endl;
18220 if(m_restartOldVariables && m_restartOldVariablesReset) {
18221 m_log <<
"Resetting old variables..." << endl;
18222 if(domainId() == 0) std::cout <<
"FVSolver: Resetting old variables..." << endl;
18224 std::copy_n(&a_variable(0, 0), a_noCells() * CV->noVariables, &a_oldVariable(0, 0));
18227 if(m_outputPhysicalTime) {
18228 m_log <<
"restart at time step: " <<
globalTimeStep <<
" - solution physical time: " << m_physicalTime << endl;
18230 m_log <<
"restart at time step: " <<
globalTimeStep <<
" - solution time: " << m_time << endl;
18232 m_log << m_noSamples <<
" samples read" << endl;
18245template <MInt nDim_,
class SysEqn>
18249 IF_CONSTEXPR(nDim != 2 && nDim != 3) {
18250 cerr <<
" In global function loadGridFlowVarsPar: wrong number of "
18258 stringstream variables;
18260 using namespace maia;
18261 using namespace parallel_io;
18265 ParallelIo::size_type dimLen = noInternalCells();
18266 ParallelIo::size_type start = domainOffset(domainId()) - grid().bitOffset();
18269 parallelIo.setOffset(dimLen, start);
18272 static constexpr MInt maxVariables = 128;
18273 array<MString, maxVariables> varNames;
18275 for(
MInt vId = 0; vId < maxVariables; vId++) {
18276 MString varName =
"variables" + to_string(vId);
18278 if(!parallelIo.hasDataset(varName)) {
18283 parallelIo.getAttribute(&tmp,
"name", varName);
18284 varNames[vId] = tmp;
18287 auto varPosition = [&](
const MString& _varName) {
18288 auto it = find(varNames.begin(), varNames.end(), _varName);
18289 if(it == varNames.end()) {
18290 mTerm(-1,
"Couldn't find variable with name " + _varName +
" for solver " + to_string(m_solverId));
18292 return "variables" + to_string(distance(varNames.begin(), it));
18295 auto hasVar = [&](
const MString& _varName) {
18296 auto it = find(varNames.begin(), varNames.end(), _varName);
18297 return !(it == varNames.end());
18304 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"u"));
18305 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18306 a_pvariable(i, PV->U) = tmpVar.
p[i];
18310 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"v"));
18311 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18312 a_pvariable(i, PV->V) = tmpVar.
p[i];
18316 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"rho"));
18317 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18318 a_pvariable(i, PV->RHO) = tmpVar.
p[i];
18322 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"p"));
18323 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18324 a_pvariable(i, PV->P) = tmpVar.
p[i];
18328 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
18329 for(
MInt r = 0; r < m_noRansEquations; r++) {
18330 parallelIo.readArray(tmpVar.
getPointer(), varPosition(m_variablesName[nDim + 2 + r]));
18331 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18332 a_pvariable(i, PV->NN[r]) = tmpVar.
p[i];
18338 if(m_noSpecies > 1) {
18339 mTerm(-1,
"code is incorrect!");
18344 if(m_noSpecies == 1) {
18345 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"c"));
18346 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18347 a_pvariable(i, PV->C) = tmpVar.
p[i];
18350 if(m_statisticCombustionAnalysis) {
18352 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"h"));
18353 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18354 m_heatRelease[i] = tmpVar.
p[i];
18358 if(m_localTS && hasVar(
"localTS")) {
18359 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"localTS"));
18360 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18361 a_localTimeStep(i) = tmpVar.
p[i];
18364 if(m_noSpecies == 1 && hasVar(
"Y")) {
18365 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"Y"));
18366 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18367 a_pvariable(i, PV->Y[0]) = tmpVar.
p[i];
18370 for(
MInt s = 0; s < m_noSpecies; s++) {
18371 MString tmpString =
"Y" + m_speciesName[s];
18372 if(hasVar(tmpString)) {
18373 parallelIo.readArray(tmpVar.
getPointer(), varPosition(tmpString));
18374 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18375 a_pvariable(i, PV->Y[s]) = tmpVar.
p[i];
18382 IF_CONSTEXPR(nDim == 3) {
18384 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"w"));
18385 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
18386 a_pvariable(i, PV->W) = tmpVar.
p[i];
18390 if(m_loadSampleVariables && m_averageVorticity && m_movingAvgInterval == 0) {
18391 mTerm(-666,
"fix calls see above");
18393 parallelIo.readArray(&m_vorticity[0][0],
"variables5", 3);
18394 parallelIo.readArray(&m_vorticity[0][1],
"variables6", 3);
18395 parallelIo.readArray(&m_vorticity[0][2],
"variables7", 3);
18400 if(m_loadSampleVariables && m_averageVorticity && m_movingAvgInterval == 0) {
18401 mTerm(-666,
"fix calls see above");
18402 parallelIo.readArray(&m_vorticity[0][0],
"variables4");
18407 parallelIo.getAttribute(&m_noSamples,
"noSamples");
18409 if(!m_resetInitialCondition) {
18411 if(m_outputPhysicalTime) {
18412 parallelIo.getAttribute(&m_physicalTime,
"time");
18414 parallelIo.getAttribute(&m_time,
"time");
18416 parallelIo.getAttribute(&m_timeStep,
"timeStep");
18417 parallelIo.getAttribute(&m_physicalTime,
"physicalTime");
18420 if(useTimeStepFromRestartFile() &&
approx(timeStep(), -1., m_eps)) {
18422 "the time-step from the restart file will be used but its equal to -1. That might not do what you think "
18427 if(m_restartBc2800) {
18428 parallelIo.getAttribute(&m_restartTimeBc2800,
"restartTimeBc2800");
18431 parallelIo.getAttribute(&m_noTimeStepsBetweenSamples,
"noTimeStepsBetweenSamples");
18436 if(parallelIo.hasAttribute(
"meanPressure")) {
18437 parallelIo.getAttribute(&m_meanPressure,
"meanPressure");
18438 m_log <<
"meanPressure is" << m_meanPressure << endl;
18441 if(m_jet || m_confinedFlame) {
18442 parallelIo.getAttribute(&m_jetDensity,
"jetDensity");
18443 m_log <<
"jetDensity is" << m_jetDensity << endl;
18445 parallelIo.getAttribute(&m_jetPressure,
"jetPressure");
18446 m_log <<
"jetPressure is" << m_jetPressure << endl;
18448 parallelIo.getAttribute(&m_jetTemperature,
"jetTemperature");
18449 m_log <<
"jetTemperature is" << m_jetTemperature << endl;
18452 if(parallelIo.hasAttribute(
"Re",
"")) {
18453 parallelIo.getAttribute(&m_Re,
"Re");
18454 parallelIo.getAttribute(&sysEqn().m_Re0,
"Re0");
18455 parallelIo.getAttribute(&m_randomDeviceSeed,
"randomDeviceSeed");
18456 if(domainId() == 0)
m_log <<
"Read Reynolds number: " << m_Re <<
" (" << sysEqn().m_Re0 <<
")." << endl;
18465template <MInt nDim_,
class SysEqn>
18468 IF_CONSTEXPR(!hasE<SysEqn>)
18469 mTerm(1, AT_,
"Not compatible with SysEqn without RHO_E!");
18472 parallelIo.setOffset(noInternalCells(), domainOffset(domainId()));
18475 IF_CONSTEXPR(nDim == 2) {
18477 parallelIo.readArray(&buffer[0],
"variables7");
18478 for(
MInt i = 0; i < noInternalCells(); i++) {
18479 a_oldVariable(i, CV->RHO_E) = buffer[i];
18482 parallelIo.readArray(&buffer[0],
"variables8");
18483 for(
MInt i = 0; i < noInternalCells(); i++) {
18484 a_oldVariable(i, CV->RHO_VV[0]) = buffer[i];
18487 parallelIo.readArray(&buffer[0],
"variables9");
18488 for(
MInt i = 0; i < noInternalCells(); i++) {
18489 a_oldVariable(i, CV->RHO_VV[1]) = buffer[i];
18492 parallelIo.readArray(&buffer[0],
"variables10");
18493 for(
MInt i = 0; i < noInternalCells(); i++) {
18494 a_oldVariable(i, CV->RHO) = buffer[i];
18497 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
18498 for(
MInt rans = 1; rans < (m_noRansEquations + 1); rans++) {
18499 MString varname =
"variables" + to_string(10 + rans);
18500 parallelIo.readArray(&buffer[0], varname);
18501 for(
MInt i = 0; i < noInternalCells(); i++) {
18502 a_oldVariable(i, CV->RHO_NN[rans]) = buffer[i];
18507 else IF_CONSTEXPR(nDim == 3) {
18509 parallelIo.readArray(&buffer[0],
"variables8");
18510 for(
MInt i = 0; i < noInternalCells(); i++) {
18511 a_oldVariable(i, CV->RHO_E) = buffer[i];
18514 parallelIo.readArray(&buffer[0],
"variables9");
18515 for(
MInt i = 0; i < noInternalCells(); i++) {
18516 a_oldVariable(i, CV->RHO_VV[0]) = buffer[i];
18519 parallelIo.readArray(&buffer[0],
"variables10");
18520 for(
MInt i = 0; i < noInternalCells(); i++) {
18521 a_oldVariable(i, CV->RHO_VV[1]) = buffer[i];
18524 parallelIo.readArray(&buffer[0],
"variables11");
18525 for(
MInt i = 0; i < noInternalCells(); i++) {
18526 a_oldVariable(i, CV->RHO_VV[2]) = buffer[i];
18529 parallelIo.readArray(&buffer[0],
"variables12");
18530 for(
MInt i = 0; i < noInternalCells(); i++) {
18531 a_oldVariable(i, CV->RHO) = buffer[i];
18533 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
18534 for(
MInt rans = 1; rans < (m_noRansEquations + 1); rans++) {
18535 MString varname =
"variables" + to_string(12 + rans);
18536 parallelIo.readArray(&buffer[0], varname);
18537 for(
MInt i = 0; i < noInternalCells(); i++) {
18538 a_oldVariable(i, CV->RHO_NN[rans]) = buffer[i];
18544 mTerm(1,
"bad number of dimensions");
18548template <MInt nDim_,
class SysEqn>
18552 m_log <<
"Reading WM Surface data from restart file ...";
18554 using namespace maia;
18555 using namespace parallel_io;
18558 ParallelIo::size_type dimLen = noInternalCells();
18559 ParallelIo::size_type start = domainOffset(domainId()) - grid().bitOffset();
18562 stringstream varFileName;
18564 if(m_useNonSpecifiedRestartFile) {
18566 if(m_multipleFvSolver) {
18567 varFileName << restartDir() <<
"restartVariables" << m_solverId << ParallelIo::fileExt();
18569 varFileName << restartDir() <<
"restartVariables" << ParallelIo::fileExt();
18572 if(!isMultilevel()) {
18573 if(m_multipleFvSolver) {
18574 varFileName << restartDir() <<
"restartVariables" << m_solverId <<
"_" << m_restartTimeStep
18575 << ParallelIo::fileExt();
18577 varFileName << restartDir() <<
"restartVariables_" << m_restartTimeStep << ParallelIo::fileExt();
18581 const MInt maxLength = 256;
18582 array<MChar, maxLength> buffer{};
18583 snprintf(buffer.data(), maxLength,
"restart_b%02d_t%08d", solverId(), m_restartTimeStep);
18584 varFileName << restartDir() <<
MString(buffer.data()) << ParallelIo::fileExt();
18591 parallelIo.setOffset(dimLen, start);
18594 static constexpr MInt maxVariables(128);
18595 array<MString, maxVariables> varNames;
18597 for(
MInt vId = 0; vId < maxVariables; vId++) {
18598 MString varName =
"variables" + to_string(vId);
18600 if(!parallelIo.hasDataset(varName)) {
18604 parallelIo.getAttribute(&tmp,
"name", varName);
18605 varNames[vId] = tmp;
18608 auto varPosition = [&](
const MString& _varName) {
18609 auto it = find(varNames.begin(), varNames.end(), _varName);
18610 if(it == varNames.end()) {
18611 mTerm(-1,
"Couldn't find variable with name " + _varName +
" for solver " + to_string(m_solverId));
18613 return "variables" + to_string(distance(varNames.begin(), it));
18627 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"utau"));
18628 for(
MUint wmSrfcId = 0; wmSrfcId < m_wmSurfaces.size(); wmSrfcId++) {
18629 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
18630 const MInt cellId = m_bndryCells->a[bndryCellId].m_cellId;
18631 m_wmSurfaces[wmSrfcId].m_wmUTAU = tmpVar.
p[cellId];
18635 parallelIo.readArray(tmpVar.
getPointer(), varPosition(
"u_II"));
18636 for(
MUint wmSrfcId = 0; wmSrfcId < m_wmSurfaces.size(); wmSrfcId++) {
18637 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
18638 const MInt cellId = m_bndryCells->a[bndryCellId].m_cellId;
18639 m_wmSurfaces[wmSrfcId].m_wmUII = tmpVar.
p[cellId];
18642 m_log <<
" done." << endl;
18654template <MInt nDim_,
class SysEqn>
18658 const MUint totalNoSlopes = nDim * noPVars * a_noCells();
18659 MFloat*
const RESTRICT slopes = ALIGNED_MF(&a_slope(0, 0, 0));
18660 const MInt*
const RESTRICT recCellIds = ALIGNED_I(m_reconstructionCellIds.data());
18661 const MInt*
const RESTRICT recNghbrIds = ALIGNED_I(m_reconstructionNghbrIds.data());
18662 const MFloat*
const RESTRICT cellCoord = ALIGNED_F(&a_coordinate(0, 0));
18667#pragma omp parallel for
18669 for(
MUint slopeId = 0; slopeId < totalNoSlopes; ++slopeId) {
18670 slopes[slopeId] = F0;
18674 for(
MUint k = 0; k < m_reconstructionDataSize; ++k) {
18675 const MFloat*
const RESTRICT recNghbrVars = ALIGNED_F(&a_pvariable(recNghbrIds[k], 0));
18676 const MFloat*
const RESTRICT recCellVars = ALIGNED_F(&a_pvariable(recCellIds[k], 0));
18677 const MUint slopeId = nDim * noPVars * recCellIds[k];
18678 for(
MUint v = 0; v < noPVars; ++v) {
18679 const MFloat tmp = recNghbrVars[v] - recCellVars[v];
18680 slopes[slopeId + v * nDim] += m_reconstructionConstants[nDim * k] * tmp;
18681 slopes[slopeId + v * nDim + 1] += m_reconstructionConstants[nDim * k + 1] * tmp;
18682 IF_CONSTEXPR(nDim == 3) slopes[slopeId + v * nDim + 2] += m_reconstructionConstants[nDim * k + 2] * tmp;
18686 if(m_reConstSVDWeightMode == 3) {
18688 if(!a_hasProperty(cellId, SolverCell::HasCoarseNghbr)) {
18691 const MFloat*
const RESTRICT recCellVars = ALIGNED_F(&a_pvariable(0, 0) + noPVars * cellId);
18693 std::array<MBool, nDim> dirsJmp = {};
18694 for(
MInt d = 0; d < nDim; ++d) {
18695 if(m_cells.nghbrInterface(cellId, 2 * d) == 3 || m_cells.nghbrInterface(cellId, 2 * d + 1) == 3) {
18698 dirsJmp[d] =
false;
18703 const MFloat*
const RESTRICT cellIdCoord = ALIGNED_F(cellCoord + cc1);
18704 for(
MUint v = 0; v < noPVars; ++v) {
18705 for(
MInt d = 0; d < nDim; ++d) {
18707 slopes[slopeId + v * nDim + d] = 0.0;
18712 for(
MInt k = a_reconstructionData(cellId); k < a_reconstructionData(cellId + 1); ++k) {
18713 const MFloat*
const RESTRICT recNghbrVars = ALIGNED_F(&a_pvariable(0, 0) + noPVars * recNghbrIds[k]);
18714 const MUint cc = recNghbrIds[k] * nDim;
18716 const MFloat*
const RESTRICT nghbrCoord = ALIGNED_F(cellCoord + cc);
18718 for(
MUint v = 0; v < noPVars; ++v) {
18719 MFloat tmp = recNghbrVars[v] - recCellVars[v];
18720 for(
MInt d = 0; d < nDim; ++d) {
18722 const MFloat dx = nghbrCoord[d] - cellIdCoord[d];
18723 tmp -= slopes[slopeId2 + v * nDim + d] * dx;
18726 for(
MInt d = 0; d < nDim; ++d) {
18728 slopes[slopeId + v * nDim + d] += m_reconstructionConstants[nDim * k + d] * tmp;
18742template <MInt nDim_,
class SysEqn>
18745 const MInt noSpecies = m_noSpecies;
18746 if(noSpecies == 0) {
18747 LSReconstructCellCenter_(0);
18748 }
else if(noSpecies == 1) {
18749 LSReconstructCellCenter_(1);
18751 LSReconstructCellCenter_(noSpecies);
18762template <MInt nDim_,
class SysEqn>
18765 const MUint noCVars = CV->noVariables;
18766 const MUint noSlopes = nDim * noCVars;
18767 const MUint totalNoSlopes = noSlopes * a_noCells();
18768 const MUint recDataSize = m_reconstructionDataSize;
18769 MFloat*
const RESTRICT slopes = ALIGNED_MF(&a_storedSlope(0, 0, 0));
18770 const MInt*
const RESTRICT recCellIds = ALIGNED_I(m_reconstructionCellIds.data());
18771 const MInt*
const RESTRICT recNghbrIds = ALIGNED_I(m_reconstructionNghbrIds.data());
18772 const MFloat*
const RESTRICT vars = ALIGNED_F(&a_variable(0, 0));
18773 const MFloat*
const RESTRICT cellCoord = ALIGNED_F(&a_coordinate(0, 0));
18777#pragma omp parallel for
18779 for(
MUint slopeId = 0; slopeId < totalNoSlopes; ++slopeId) {
18780 slopes[slopeId] = F0;
18784 for(
MUint k = 0; k < recDataSize; ++k) {
18785 const MFloat*
const RESTRICT recNghbrVars = ALIGNED_F(vars + noCVars * recNghbrIds[k]);
18786 const MFloat*
const RESTRICT recCellVars = ALIGNED_F(vars + noCVars * recCellIds[k]);
18787 const MUint slopeId = noSlopes * recCellIds[k];
18788 for(
MUint v = 0; v < noCVars; ++v) {
18789 const MFloat tmp = recNghbrVars[v] - recCellVars[v];
18790 slopes[slopeId + v * nDim] += m_reconstructionConstants[nDim * k] * tmp;
18791 slopes[slopeId + v * nDim + 1] += m_reconstructionConstants[nDim * k + 1] * tmp;
18792 IF_CONSTEXPR(nDim == 3) slopes[slopeId + v * nDim + 2] += m_reconstructionConstants[nDim * k + 2] * tmp;
18796 if(m_reConstSVDWeightMode == 3) {
18797 for(
MInt cellId = 0; cellId < a_noCells(); ++cellId) {
18798 if(!a_hasProperty(cellId, SolverCell::HasCoarseNghbr)) {
18801 const MFloat*
const RESTRICT recCellVars = ALIGNED_F(vars + noCVars * cellId);
18802 const MUint slopeId = nDim * noCVars * cellId;
18803 std::array<MBool, nDim> dirsJmp = {};
18804 for(
MInt d = 0; d < nDim; ++d) {
18805 if(m_cells.nghbrInterface(cellId, 2 * d) == 3 || m_cells.nghbrInterface(cellId, 2 * d + 1) == 3) {
18808 dirsJmp[d] =
false;
18812 const MUint cc1 = cellId * nDim;
18813 const MFloat*
const RESTRICT cellIdCoord = ALIGNED_F(cellCoord + cc1);
18814 for(
MUint v = 0; v < noCVars; ++v) {
18815 for(
MInt d = 0; d < nDim; ++d) {
18817 slopes[slopeId + v * nDim + d] = 0.0;
18822 for(
MInt k = a_reconstructionData(cellId); k < a_reconstructionData(cellId + 1); ++k) {
18823 const MFloat*
const RESTRICT recNghbrVars = ALIGNED_F(vars + noCVars * recNghbrIds[k]);
18824 const MUint cc = recNghbrIds[k] * nDim;
18825 const MUint slopeId2 = nDim * noCVars * cellId;
18826 const MFloat*
const RESTRICT nghbrCoord = ALIGNED_F(cellCoord + cc);
18828 for(
MUint v = 0; v < noCVars; ++v) {
18829 MFloat tmp = recNghbrVars[v] - recCellVars[v];
18830 for(
MInt d = 0; d < nDim; ++d) {
18832 const MFloat dx = nghbrCoord[d] - cellIdCoord[d];
18833 tmp -= slopes[slopeId2 + v * nDim + d] * dx;
18836 for(
MInt d = 0; d < nDim; ++d) {
18838 slopes[slopeId + v * nDim + d] += m_reconstructionConstants[nDim * k + d] * tmp;
18853template <MInt nDim_,
class SysEqn>
18856 const MUint noSrfcs = a_noSurfaces();
18857 const MUint noPVars = PV->noVariables;
18858 const MUint noSlopes = nDim * noPVars;
18859 const MUint surfaceVarMemory = 2 * noPVars;
18860 const MInt*
const RESTRICT nghbrCellIds = ALIGNED_I(&a_surfaceNghbrCellId(0, 0));
18861 const MFloat*
const RESTRICT cellCoord = ALIGNED_F(&a_coordinate(0, 0));
18862 const MFloat*
const RESTRICT surfaceCoord = ALIGNED_F(&a_surfaceCoordinate(0, 0));
18863 MFloat*
const RESTRICT surfaceVar = ALIGNED_MF(&a_surfaceVariable(0, 0, 0));
18864 const MFloat*
const RESTRICT cellSlopes = ALIGNED_F(&a_slope(0, 0, 0));
18865 const MFloat*
const RESTRICT vars = ALIGNED_F(&a_pvariable(0, 0));
18868#pragma omp parallel for
18870 for(
MUint srfcId = 0; srfcId < noSrfcs; ++srfcId) {
18871 const MUint sc = srfcId * nDim;
18872 const MInt*
const RESTRICT nghbrIds = ALIGNED_I(nghbrCellIds + srfcId * 2);
18873 const MFloat*
const RESTRICT srfcCoord = ALIGNED_F(surfaceCoord + sc);
18874 for(
MUint side = 0; side < 2; ++side) {
18875 const MUint nghbr = nghbrIds[side];
18876 const MUint cc = nghbr * nDim;
18877 const MFloat*
const RESTRICT nghbrCoord = ALIGNED_F(cellCoord + cc);
18879 for(
MInt d = 0; d < nDim; ++d) {
18880 dx[d] = srfcCoord[d] - nghbrCoord[d];
18882 const MUint srfcVarOffset = srfcId * surfaceVarMemory + side * noPVars;
18883 MFloat*
const RESTRICT currentSrfcVars = ALIGNED_MF(surfaceVar + srfcVarOffset);
18884 const MFloat*
const RESTRICT nghbrVars = ALIGNED_F(vars + nghbr * noPVars);
18885 for(
MUint v = 0; v < noPVars; ++v) {
18886 const MUint sl = nghbr * noSlopes + v * nDim;
18887 const MFloat*
const RESTRICT nghbrSlopes = ALIGNED_F(cellSlopes + sl);
18888 currentSrfcVars[v] = nghbrVars[v];
18889 for(
MInt d = 0; d < nDim; ++d) {
18890 currentSrfcVars[v] += nghbrSlopes[d] * dx[d];
18901template <MInt nDim_,
class SysEqn>
18906 RECORD_TIMER_START(m_timers[Timers::ReconstSrfcCompValues]);
18908 const MUint noSpecies = m_noSpecies;
18909 if(noSpecies == 0) {
18910 computeSurfaceValues_(0);
18911 }
else if(noSpecies == 1) {
18912 computeSurfaceValues_(1);
18914 computeSurfaceValues_(noSpecies);
18916 RECORD_TIMER_STOP(m_timers[Timers::ReconstSrfcCompValues]);
18918 RECORD_TIMER_START(m_timers[Timers::ReconstSrfcCorrVars]);
18920 IF_CONSTEXPR(nDim == 2) m_fvBndryCnd->correctBoundarySurfaceVariables();
18921 IF_CONSTEXPR(nDim == 3) {
18922 if(m_fvBndryCnd->m_multipleGhostCells) {
18923 if(m_fvBndryCnd->m_surfaceGhostCell) {
18924 m_fvBndryCnd->correctBoundarySurfaceVariablesMGCSurface();
18926 m_fvBndryCnd->correctBoundarySurfaceVariablesMGC();
18929 m_fvBndryCnd->correctBoundarySurfaceVariables();
18932 RECORD_TIMER_STOP(m_timers[Timers::ReconstSrfcCorrVars]);
18934 RECORD_TIMER_START(m_timers[Timers::ReconstSrfcUpdateGhost]);
18936 m_fvBndryCnd->updateGhostCellSlopesViscous();
18937 RECORD_TIMER_STOP(m_timers[Timers::ReconstSrfcUpdateGhost]);
18939 RECORD_TIMER_START(m_timers[Timers::ReconstSrfcUpdateCutOff]);
18940 m_fvBndryCnd->updateCutOffSlopesViscous();
18941 RECORD_TIMER_STOP(m_timers[Timers::ReconstSrfcUpdateCutOff]);
18947template <MInt nDim_,
class SysEqn>
18949#define VENKATAKRISHNAN
18952 const MInt noCells = a_noCells();
18953 MFloat*
const RESTRICT cellSlopes = ALIGNED_MF(&a_slope(0, 0, 0));
18954 const MInt slopeMemory = m_slopeMemory;
18956 for(
MInt cellId = 0; cellId < noCells; cellId++) {
18957 if(a_isBndryGhostCell(cellId))
continue;
18958 if(a_hasProperty(cellId, SolverCell::IsCutOff))
continue;
18959 for(
MInt it = 0; it < m_noLimitedSlopesVar; it++) {
18960 MInt varId = m_limitedSlopesVar[it];
18962 MFloat minNghbrDelta = F0;
18963 MFloat maxNghbrDelta = F0;
18964 MFloat effNghbrDelta = F0;
18965 const MFloat cellValue = a_pvariable(cellId, varId);
18967 for(
MInt rcnstructnNghbr = 0; rcnstructnNghbr < a_noReconstructionNeighbors(cellId); rcnstructnNghbr++) {
18968 const MInt rcnstrctnNghbrId = a_reconstructionNeighborId(cellId, rcnstructnNghbr);
18969 const MFloat rcnstrctnNghbrValue = a_pvariable(rcnstrctnNghbrId, varId);
18970 const MFloat tmpDelta = rcnstrctnNghbrValue - cellValue;
18971 if(tmpDelta > maxNghbrDelta) {
18972 maxNghbrDelta = tmpDelta;
18973 }
else if(tmpDelta < minNghbrDelta) {
18974 minNghbrDelta = tmpDelta;
18977 effNghbrDelta =
mMin(maxNghbrDelta, abs(minNghbrDelta));
18979 const MFloat dx = F1B2 * c_cellLengthAtCell(cellId);
18981 for(
MInt dim = 0; dim < nDim; dim++)
18982 srfcDelta += abs(cellSlopes[cellId * slopeMemory + varId * nDim + dim]) * dx;
18983#ifdef BART_AND_JESPERSON
18984 const MFloat eps = 1e-12;
18985 const MFloat phi_max = effNghbrDelta / (srfcDelta + eps);
18988#ifdef VENKATAKRISHNAN
18989 const MFloat eps = 1e-12;
18990 const MFloat y = effNghbrDelta / (srfcDelta + eps);
18993#ifdef VENKATAKRISHNAN_MOD
18995 const MFloat epsSqr = pow(K * dx, F3);
18996 const MFloat minPhi = (pow(effNghbrDelta, F2) + epsSqr + F2 * effNghbrDelta * srfcDelta)
18997 / (pow(effNghbrDelta, F2) + F2 * pow(srfcDelta, F2) + effNghbrDelta * srfcDelta + epsSqr);
19000 for(
MInt dim = 0; dim < nDim; dim++)
19001 cellSlopes[cellId * slopeMemory + varId * nDim + dim] *= minPhi;
19006 if(m_noSpecies == 0) {
19007 computeSurfaceValues_(0);
19008 }
else if(m_noSpecies == 1) {
19009 computeSurfaceValues_(1);
19011 computeSurfaceValues_(m_noSpecies);
19015 IF_CONSTEXPR(nDim == 2) m_fvBndryCnd->correctBoundarySurfaceVariables();
19016 IF_CONSTEXPR(nDim == 3) {
19017 if(m_fvBndryCnd->m_multipleGhostCells) {
19018 if(m_fvBndryCnd->m_surfaceGhostCell) {
19019 m_fvBndryCnd->correctBoundarySurfaceVariablesMGCSurface();
19021 m_fvBndryCnd->correctBoundarySurfaceVariablesMGC();
19024 m_fvBndryCnd->correctBoundarySurfaceVariables();
19029 m_fvBndryCnd->updateGhostCellSlopesViscous();
19030 m_fvBndryCnd->updateCutOffSlopesViscous();
19042template <MInt nDim_,
class SysEqn>
19046 m_log <<
" first step of initialization of computeSurfaceValuesLimitedSlopesMan" << endl;
19058 MInt limDist = Context::getSolverProperty<MInt>(
"slopeLimiterDistance1", m_solverId, AT_, &limDist);
19069 MString filename = Context::getSolverProperty<MString>(
"slopeLimiterFilename", m_solverId, AT_, &filename);
19071 mAlloc(m_limPhi, a_noCells(),
"m_limPhi", F1, AT_);
19073 vector<MInt> markedCells;
19075 propDist.fill(numeric_limits<MInt>::max());
19077 IF_CONSTEXPR(nDim == 2) {
19079 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
19080 const MFloat cellHalfLength = c_cellLengthAtLevel(a_level(cellId) + 1);
19081 if(!c_noChildren(cellId) && auxGeom->
isOnGeometry(cellHalfLength, &a_coordinate(cellId, 0),
"SAT")
19082 && a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
19083 if(grid().tree().solver2grid(cellId) > -1) markedCells.push_back(grid().tree().solver2grid(cellId));
19086 IF_CONSTEXPR(nDim == 3) {
19089 const MFloat cellHalfLength = c_cellLengthAtLevel(a_level(cellId) + 1);
19090 if(!c_noChildren(cellId) && auxGeom->
isOnGeometry(cellHalfLength, &a_coordinate(cellId, 0),
"SAT")
19091 && a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
19092 if(grid().tree().solver2grid(cellId) > -1) markedCells.push_back(grid().tree().solver2grid(cellId));
19100 MLong tmp = markedCells.size();
19101 MPI_Allreduce(MPI_IN_PLACE, &tmp, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"tmp");
19102 m_log <<
" overall cells on shock: " << tmp << endl;
19105 grid().raw().propagateDistance(markedCells, propDist, limDist);
19108 const MInt gridCellId = grid().tree().solver2grid(cellId);
19109 if(gridCellId < 0)
continue;
19110 if(propDist[gridCellId] != numeric_limits<MInt>::max()) {
19116 MPI_Allreduce(MPI_IN_PLACE, &tmp, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"tmp");
19117 m_log <<
" overall limited cells: " << tmp << endl;
19129template <MInt nDim_,
class SysEqn>
19133 m_log <<
" second step of initialization of computeSurfaceValuesLimitedSlopesMan" << endl;
19146 limDistF = Context::getSolverProperty<MFloat>(
"slopeLimiterDistance2", m_solverId, AT_, &limDistF);
19148 vector<MInt> markedCells;
19150 propDist.fill(numeric_limits<MInt>::max());
19153 if(limDistF > F0) {
19154 for(
MInt bc = 0; bc < m_fvBndryCnd->m_noCutOffBndryCndIds; bc++) {
19155 if(m_fvBndryCnd->m_cutOffBndryCndIds[bc] / 10 == 272 || m_fvBndryCnd->m_cutOffBndryCndIds[bc] / 10 == 271) {
19156 for(
MInt lvl = maxUniformRefinementLevel(); lvl <= maxRefinementLevel(); lvl++) {
19157 for(
MInt i = 0; i < m_fvBndryCnd->m_sortedCutOffCells[bc]->size(); i++) {
19158 if(a_level(m_fvBndryCnd->m_sortedCutOffCells[bc]->a[i]) == lvl)
19159 if(grid().tree().solver2grid(m_fvBndryCnd->m_sortedCutOffCells[bc]->a[i]) > -1)
19160 markedCells.push_back(grid().tree().solver2grid(m_fvBndryCnd->m_sortedCutOffCells[bc]->a[i]));
19162 auto limDist = (
MInt)(limDistF / c_cellLengthAtLevel(lvl) + F1B2);
19163 grid().raw().propagateDistance(markedCells, propDist, limDist);
19164 markedCells.clear();
19170 const MInt gridCellId = grid().tree().solver2grid(cellId);
19171 if(gridCellId < 0)
continue;
19172 if(propDist[gridCellId] != numeric_limits<MInt>::max()) {
19174 MInt lvl = a_level(cellId);
19175 MFloat dist = (propDist[gridCellId] + F1B2) * c_cellLengthAtLevel(lvl);
19176 m_limPhi[
cellId] = F1B2 - F1B2 *
cos(PI *
dist / limDistF);
19182 MPI_Allreduce(MPI_IN_PLACE, &tmp, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"tmp");
19183 m_log <<
" added overall limited cells: " << tmp << endl;
19193template <MInt nDim_,
class SysEqn>
19197 const MInt noCells = a_noCells();
19198 MFloat*
const RESTRICT cellSlopes = ALIGNED_MF(&a_slope(0, 0, 0));
19199 const MInt slopeMemory = m_slopeMemory;
19201 for(
MInt cellId = 0; cellId < noCells; cellId++) {
19204 for(
MInt it = 0; it < m_noLimitedSlopesVar; it++) {
19205 MInt varId = m_limitedSlopesVar[it];
19208 for(
MInt dim = 0; dim < nDim; dim++)
19209 cellSlopes[cellId * slopeMemory + varId * nDim + dim] *= m_limPhi[cellId];
19214 if(m_noSpecies == 0) {
19215 computeSurfaceValues_(0);
19216 }
else if(m_noSpecies == 1) {
19217 computeSurfaceValues_(1);
19219 computeSurfaceValues_(m_noSpecies);
19223 if(m_fvBndryCnd->m_multipleGhostCells) {
19224 if(m_fvBndryCnd->m_surfaceGhostCell) {
19225 m_fvBndryCnd->correctBoundarySurfaceVariablesMGCSurface();
19227 m_fvBndryCnd->correctBoundarySurfaceVariablesMGC();
19230 m_fvBndryCnd->correctBoundarySurfaceVariables();
19234 m_fvBndryCnd->updateGhostCellSlopesViscous();
19235 m_fvBndryCnd->updateCutOffSlopesViscous();
19243template <MInt nDim_,
class SysEqn>
19248 Ausm_<AUSM>(sysEqn());
19250 Ausm_<AUSMPLUS>(sysEqn());
19252 Ausm_<SLAU>(sysEqn());
19256template <MInt nDim_,
class SysEqn>
19257template <MInt stencil,
class F>
19259 const MUint noPVars = PV->noVariables;
19260 const MUint noFluxVars = FV->noVariables;
19261 const MUint noSurfaceCoefficients = hasSC ? SC->m_noSurfaceCoefficients : 0;
19262 const MUint surfaceVarMemory = 2 * noPVars;
19263 const MUint noSurfaces = a_noSurfaces();
19264 const MUint noInternalSurfaces = m_bndrySurfacesOffset;
19266 MFloat*
const RESTRICT fluxes = ALIGNED_MF(&a_surfaceFlux(0, 0));
19267 const MFloat*
const RESTRICT surfaceVars = ALIGNED_F(&a_surfaceVariable(0, 0, 0));
19268 const MFloat*
const RESTRICT surfaceCoefficients = hasSC ? ALIGNED_F(&a_surfaceCoefficient(0, 0)) :
nullptr;
19269 const MFloat*
const RESTRICT upwindCoefficients = ALIGNED_F(&a_surfaceUpwindCoefficient(0));
19270 const MFloat*
const RESTRICT area = ALIGNED_F(&a_surfaceArea(0));
19271 const MInt*
const RESTRICT orientations = ALIGNED_I(&a_surfaceOrientation(0));
19272 const MInt*
const RESTRICT bndryCndIds = ALIGNED_I(&a_surfaceBndryCndId(0));
19276#pragma omp parallel for
19278 for(
MUint srfcId = 0; srfcId < noSurfaces; ++srfcId) {
19279 const MUint orientation = orientations[srfcId];
19281 const MUint offset = srfcId * surfaceVarMemory;
19282 const MFloat*
const RESTRICT leftVars = ALIGNED_F(surfaceVars + offset);
19283 const MFloat*
const RESTRICT rightVars = ALIGNED_F(leftVars + noPVars);
19285 const MUint coefficientOffset = srfcId * noSurfaceCoefficients;
19286 const MFloat*
const RESTRICT srfcCoeff = hasSC ? ALIGNED_F(surfaceCoefficients + coefficientOffset) :
nullptr;
19288 const MFloat A = area[srfcId];
19290 const MUint fluxOffset = srfcId * noFluxVars;
19291 MFloat*
const RESTRICT flux = ALIGNED_MF(fluxes + fluxOffset);
19293 const MFloat upwindCoefficient = upwindCoefficients[srfcId];
19295 fluxFct.template Ausm<stencil>(orientation, upwindCoefficient, A, leftVars, rightVars, srfcCoeff, flux);
19300 MBool& checkedBndryCndIds = m_static_computeSurfaceValuesLimitedSlopesMan_checkedBndryCndIds;
19301 MBool& correctWallBndryFluxes = m_static_computeSurfaceValuesLimitedSlopesMan_correctWallBndryFluxes;
19302 if(!checkedBndryCndIds) {
19303 for(
MUint srfcId = noInternalSurfaces; srfcId < noSurfaces; ++srfcId) {
19304 if((bndryCndIds[srfcId] > 1999 && bndryCndIds[srfcId] < 4000)) {
19305 correctWallBndryFluxes =
true;
19308 checkedBndryCndIds =
true;
19311 if(correctWallBndryFluxes) {
19313 for(
MUint srfcId = noInternalSurfaces; srfcId < noSurfaces; ++srfcId) {
19314 if(!(bndryCndIds[srfcId] > 1999 && bndryCndIds[srfcId] < 4000)) {
19318 const MUint orientation = orientations[srfcId];
19320 const MUint offset = srfcId * surfaceVarMemory;
19321 const MFloat* leftVars = surfaceVars + offset;
19322 const MFloat* rightVars = leftVars + noPVars;
19324 const MFloat A = area[srfcId];
19325 const MUint fluxOffset = srfcId * noFluxVars;
19326 MFloat*
const RESTRICT flux = fluxes + fluxOffset;
19328 fluxFct.AusmBndryCorrection(orientation, A, leftVars, rightVars, flux);
19333template <MInt nDim_,
class SysEqn>
19337 viscousFlux_<FIVE_POINT>(sysEqn());
19339 viscousFluxCompact_<THREE_POINT>(sysEqn());
19341 viscousFluxCompact_<FIVE_POINT_STABILIZED>(sysEqn());
19343 IF_CONSTEXPR(isEEGas<SysEqn>) {
19344 if(m_EEGas.bubblePathDispersion) bubblePathDispersion();
19360template <MInt nDim_,
class SysEqn>
19361template <MInt stencil,
class F>
19364 const MUint noPVars = PV->noVariables;
19365 const MUint noFluxVars = FV->noVariables;
19366 const MUint noSurfaceCoefficients = hasSC ? SC->m_noSurfaceCoefficients : 0;
19367 const MUint surfaceVarMemory = 2 * noPVars;
19368 const MUint noSlopes = nDim * noPVars;
19369 const MUint noSurfaces = a_noSurfaces();
19371#ifdef FV_FREE_SURFACE_BC
19372 const MInt*
const bndryCndIds RESTRICT = ALIGNED_I(&a_surfaceBndryCndId(0));
19374 const MInt*
const RESTRICT orientations = ALIGNED_I(&a_surfaceOrientation(0));
19375 const MInt*
const RESTRICT nghbrCellIds = ALIGNED_I(&a_surfaceNghbrCellId(0, 0));
19376 const MFloat*
const RESTRICT surfaceVars = ALIGNED_F(&a_surfaceVariable(0, 0, 0));
19377 const MFloat*
const RESTRICT surfaceCoefficients = hasSC ? ALIGNED_F(&a_surfaceCoefficient(0, 0)) :
nullptr;
19378 const MFloat*
const RESTRICT factor = ALIGNED_F(&a_surfaceFactor(0, 0));
19379 const MFloat*
const RESTRICT slope = ALIGNED_F(&a_slope(0, 0, 0));
19380 const MFloat*
const RESTRICT area = ALIGNED_F(&a_surfaceArea(0));
19381 MFloat*
const RESTRICT fluxes = ALIGNED_MF(&a_surfaceFlux(0, 0));
19384#pragma omp parallel for
19386 for(
MUint srfcId = 0; srfcId < noSurfaces; srfcId++) {
19388#ifdef FV_FREE_SURFACE_BC
19390 if((
MInt)srfcId > m_bndrySurfacesOffset) {
19391 if(bndryCndId[srfcId] == 5000) {
19397 const MUint offset = srfcId * surfaceVarMemory;
19398 const MFloat*
const RESTRICT vars0 = ALIGNED_F(surfaceVars + offset);
19399 const MFloat*
const RESTRICT vars1 = ALIGNED_F(vars0 + noPVars);
19401 const MUint orientation = orientations[srfcId];
19402 const MFloat A = area[srfcId];
19404 const MFloat f0 = factor[srfcId * 2];
19405 const MFloat f1 = factor[srfcId * 2 + 1];
19406 const MUint offset0 = nghbrCellIds[2 * srfcId] * noSlopes;
19407 const MUint offset1 = nghbrCellIds[2 * srfcId + 1] * noSlopes;
19408 const MFloat*
const RESTRICT slope0 = ALIGNED_F(slope + offset0);
19409 const MFloat*
const RESTRICT slope1 = ALIGNED_F(slope + offset1);
19411 const MUint coefficientOffset = srfcId * noSurfaceCoefficients;
19412 const MFloat*
const RESTRICT srfcCoeff = hasSC ? ALIGNED_F(surfaceCoefficients + coefficientOffset) :
nullptr;
19414 const MUint fluxOffset = srfcId * noFluxVars;
19415 MFloat*
const RESTRICT flux = ALIGNED_MF(fluxes + fluxOffset);
19417 viscousFluxFct.template viscousFlux<stencil>(orientation, A, vars0, vars1, slope0, slope1, srfcCoeff, f0, f1, flux);
19424 RECORD_TIMER_START(m_timers[Timers::WMSurfaceLoop]);
19425 const MInt noWMSurfaces = m_wmSurfaces.size();
19427#pragma omp parallel for
19429 for(
MInt wmSrfcId = 0; wmSrfcId < noWMSurfaces; wmSrfcId++) {
19430 const MFloat mue_wm = computeWMViscositySpalding(wmSrfcId);
19431 const MInt bndryCellId = m_wmSurfaces[wmSrfcId].m_bndryCellId;
19432 const MInt bndrySrfcId = m_wmSurfaces[wmSrfcId].m_bndrySrfcId;
19434 for(
MInt dim = 0; dim < nDim; dim++) {
19435 const MInt srfcId = m_bndryCells->a[bndryCellId].m_srfcVariables[bndrySrfcId]->m_srfcId[dim];
19437 if(srfcId < 0)
continue;
19439 const MUint offset = srfcId * surfaceVarMemory;
19440 const MFloat*
const RESTRICT vars0 = ALIGNED_F(surfaceVars + offset);
19441 const MFloat*
const RESTRICT vars1 = ALIGNED_F(vars0 + noPVars);
19443 const MUint orientation = orientations[srfcId];
19444 const MFloat A = area[srfcId];
19446 const MFloat f0 = factor[srfcId * 2];
19447 const MFloat f1 = factor[srfcId * 2 + 1];
19448 const MUint offset0 = nghbrCellIds[2 * srfcId] * noSlopes;
19449 const MUint offset1 = nghbrCellIds[2 * srfcId + 1] * noSlopes;
19450 const MFloat*
const RESTRICT slope0 = ALIGNED_F(slope + offset0);
19451 const MFloat*
const RESTRICT slope1 = ALIGNED_F(slope + offset1);
19453 const MUint fluxOffset = srfcId * noPVars;
19454 MFloat*
const RESTRICT flux = ALIGNED_MF(fluxes + fluxOffset);
19456 RECORD_TIMER_START(m_timers[Timers::WMFluxCorrection]);
19457 viscousFluxFct.template wmViscousFluxCorrection<stencil>(orientation, A, vars0, vars1, slope0, slope1, f0, f1,
19459 RECORD_TIMER_STOP(m_timers[Timers::WMFluxCorrection]);
19462 RECORD_TIMER_STOP(m_timers[Timers::WMSurfaceLoop]);
19474template <MInt nDim_,
class SysEqn>
19475template <MInt stencil,
class F>
19477 const MUint noPVars = PV->noVariables;
19478 const MUint noFluxVars = FV->noVariables;
19479 const MUint surfaceVarMemory = 2 * noPVars;
19480 const MUint noSlopes = nDim * noPVars;
19481 const MUint noSurfaces = a_noSurfaces();
19483 const MInt*
const RESTRICT orientations = ALIGNED_I(&a_surfaceOrientation(0));
19484 const MInt*
const RESTRICT nghbrCellIds = ALIGNED_I(&a_surfaceNghbrCellId(0, 0));
19485 const MFloat*
const RESTRICT surfaceVars = ALIGNED_F(&a_surfaceVariable(0, 0, 0));
19486 const MFloat*
const RESTRICT scoords = ALIGNED_F(&a_surfaceCoordinate(0, 0));
19487 const MFloat*
const RESTRICT factor = ALIGNED_F(&a_surfaceFactor(0, 0));
19488 const MFloat*
const RESTRICT slope = ALIGNED_F(&a_slope(0, 0, 0));
19489 const MFloat*
const RESTRICT ccoords = ALIGNED_F(&a_coordinate(0, 0));
19490 const MFloat*
const RESTRICT area = ALIGNED_F(&a_surfaceArea(0));
19491 const MFloat*
const RESTRICT cellvars = ALIGNED_F(&a_pvariable(0, 0));
19492 MFloat*
const RESTRICT fluxes = ALIGNED_MF(&a_surfaceFlux(0, 0));
19495#pragma omp parallel for
19497 for(
MUint srfcId = 0; srfcId < noSurfaces; srfcId++) {
19498 const MUint offset = srfcId * surfaceVarMemory;
19499 const MFloat*
const RESTRICT vars0 = ALIGNED_F(surfaceVars + offset);
19500 const MFloat*
const RESTRICT vars1 = ALIGNED_F(vars0 + noPVars);
19502 const MFloat f0 = factor[srfcId * 2];
19503 const MFloat f1 = factor[srfcId * 2 + 1];
19505 const MUint orientation = orientations[srfcId];
19506 const MFloat A = area[srfcId];
19508 const MBool isBndry = a_surfaceBndryCndId(srfcId) > -1;
19510 const MUint offsetSurfaceCoord = nDim * srfcId;
19511 const MFloat*
const RESTRICT surfaceCoord = ALIGNED_F(scoords + offsetSurfaceCoord);
19513 const MUint off0 = nghbrCellIds[2 * srfcId] * nDim;
19514 const MUint off1 = nghbrCellIds[2 * srfcId + 1] * nDim;
19515 const MFloat*
const RESTRICT coord0 = ALIGNED_F(ccoords + off0);
19516 const MFloat*
const RESTRICT coord1 = ALIGNED_F(ccoords + off1);
19518 const MUint voff0 = nghbrCellIds[2 * srfcId] * noPVars;
19519 const MUint voff1 = nghbrCellIds[2 * srfcId + 1] * noPVars;
19520 const MFloat*
const RESTRICT cellVars0 = ALIGNED_F(cellvars + voff0);
19521 const MFloat*
const RESTRICT cellVars1 = ALIGNED_F(cellvars + voff1);
19523 const MUint offset0 = nghbrCellIds[2 * srfcId] * noSlopes;
19524 const MUint offset1 = nghbrCellIds[2 * srfcId + 1] * noSlopes;
19525 const MFloat*
const RESTRICT slope0 = ALIGNED_F(slope + offset0);
19526 const MFloat*
const RESTRICT slope1 = ALIGNED_F(slope + offset1);
19528 const MUint fluxOffset = srfcId * noFluxVars;
19529 MFloat*
const RESTRICT flux = ALIGNED_MF(fluxes + fluxOffset);
19531 viscousFluxFct.template viscousFlux<stencil>(orientation, A, isBndry, surfaceCoord, coord0, coord1, cellVars0,
19532 cellVars1, vars0, vars1, slope0, slope1, f0, f1, flux);
19536template <MInt nDim,
class SysEqn>
19537template <
class _, std::enable_if_t<isEEGas<SysEqn>, _*>>
19540 const MUint noPVars = PV->noVariables;
19541 const MUint noFluxVars = FV->noVariables;
19542 const MUint surfaceVarMemory = 2 * noPVars;
19544 const MUint noSurfaces = a_noSurfaces();
19546 const MInt*
const RESTRICT orientations = ALIGNED_I(&a_surfaceOrientation(0));
19547 const MInt*
const RESTRICT nghbrCellIds = ALIGNED_I(&a_surfaceNghbrCellId(0, 0));
19548 const MFloat*
const RESTRICT surfaceVars = ALIGNED_F(&a_surfaceVariable(0, 0, 0));
19549 const MFloat*
const RESTRICT factor = ALIGNED_F(&a_surfaceFactor(0, 0));
19551 const MFloat*
const RESTRICT area = ALIGNED_F(&a_surfaceArea(0));
19552 MFloat*
const RESTRICT fluxes = ALIGNED_MF(&a_surfaceFlux(0, 0));
19555 const MFloat fScRe0 = F1 / (m_EEGas.schmidtNumber * sysEqn().m_Re0);
19557#pragma omp parallel for
19559 for(
MUint srfcId = 0; srfcId < noSurfaces; ++srfcId) {
19560 const MInt leftCellId = nghbrCellIds[2 * srfcId];
19561 const MInt rightCellId = nghbrCellIds[2 * srfcId + 1];
19563 const MUint orientation = orientations[srfcId];
19564 const MUint offset = srfcId * surfaceVarMemory;
19565 const MFloat*
const RESTRICT leftVars = ALIGNED_F(surfaceVars + offset);
19566 const MFloat*
const RESTRICT rightVars = ALIGNED_F(leftVars + noPVars);
19567 const MFloat A = area[srfcId];
19568 const MFloat f0 = factor[srfcId * 2];
19569 const MFloat f1 = factor[srfcId * 2 + 1];
19571 const MFloat alphaSlopeL = m_cells.slope(leftCellId, PV->A, orientation);
19572 const MFloat RHOL = leftVars[PV->RHO];
19573 const MFloat nutL = a_nuEffOtherPhase(leftCellId);
19575 const MFloat alphaSlopeR = m_cells.slope(rightCellId, PV->A, orientation);
19576 const MFloat RHOR = rightVars[PV->RHO];
19577 const MFloat nutR = a_nuEffOtherPhase(rightCellId);
19579 const MFloat alphaSlopeLR = f0 * alphaSlopeL + f1 * alphaSlopeR;
19580 const MFloat RHOLR = 0.5 * (RHOL + RHOR);
19581 const MFloat nutLR = f0 * nutL + f1 * nutR;
19583 if(fabs(alphaSlopeLR) < 1e-10)
continue;
19585 const MUint fluxOffset = srfcId * noFluxVars;
19586 MFloat*
const RESTRICT flux = ALIGNED_MF(fluxes + fluxOffset);
19587 flux[FV->A_RHO] -= fScRe0 * alphaSlopeLR * RHOLR * nutLR * A;
19592template <MInt nDim_,
class SysEqn>
19597#pragma omp parallel for
19599 for(
MInt ac = 0; ac < m_noActiveCells; ac++) {
19600 const MInt cellId = m_activeCellIds[ac];
19602 if(a_isBndryGhostCell(cellId))
continue;
19603 if(a_isInactive(cellId))
continue;
19605 MFloat* vars = &a_pvariable(0, 0);
19606 MFloat* rhs = &a_rightHandSide(cellId, 0);
19607 const MFloat cellVol = a_cellVolume(cellId);
19608 const MFloat*
const slopes = &a_slope(0, 0, 0);
19609 const MInt*
const recNghbr = &a_reconstructionNeighborId(cellId, 0);
19610 const MInt noRecNghbr = a_noReconstructionNeighbors(cellId);
19611 const MInt recData = a_reconstructionData(cellId);
19612 const MFloat*
const recConst = &m_reconstructionConstants[0];
19615 if(m_levelSetRans) {
19616 dist = a_levelSetFunction(cellId, 0);
19619 dist = a_coordinate(cellId, 1);
19622 sysEqn().computeVolumeForces(cellId, vars, rhs, cellVol, slopes, recData, recNghbr, recConst, noRecNghbr,
dist);
19643template <MInt nDim,
class SysEqn>
19644template <
class _, std::enable_if_t<!isEEGas<SysEqn>, _*>>
19648 const MUint noCVars = CV->noVariables;
19649 const MUint noFVars = FV->noVariables;
19652 const MFloat rkAlpha = m_RKalpha[m_RKStep];
19653 const MFloat dt = timeStep(
true);
19654 const MFloat rkFactor = m_dualTimeStepping ? rkAlpha : rkAlpha * dt;
19656 const MUint last = m_noActiveHaloCellOffset > 0 ? m_activeCellIds[m_noActiveHaloCellOffset - 1] + 1
19657 : std::numeric_limits<MUint>::min();
19658 MFloat*
const RESTRICT oldVars = &a_oldVariable(0, 0);
19659 MFloat*
const RESTRICT vars = &a_variable(0, 0);
19660 const MFloat*
const RESTRICT fCellVol = &a_FcellVolume(0);
19661 const MFloat*
const RESTRICT localTimeStep = m_dualTimeStepping ? &a_localTimeStep(0) : nullptr;
19662 const MFloat*
const RESTRICT rhs = &a_rightHandSide(0, 0);
19664 if(m_RKStep == 0) {
19666#pragma omp parallel for
19668 for(
MUint cellId = m_activeCellIds[0]; cellId < last; ++cellId) {
19669#if !defined(DISABLE_FV_MG)
19670 IF_CONSTEXPR(nDim == 2) {
19671 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
19677 MFloat*
const RESTRICT oldCellVars = oldVars + cellOffset;
19678 const MFloat*
const RESTRICT cellVars = vars + cellOffset;
19679 for(
MUint varId = 0; varId < noCVars; ++varId) {
19680 oldCellVars[varId] = cellVars[varId];
19686 switch(m_rungeKuttaOrder) {
19689 if(!m_dualTimeStepping) {
19691#pragma omp parallel for
19694#if !defined(DISABLE_FV_MG)
19695 IF_CONSTEXPR(nDim == 2) {
19696 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
19703 const MFloat*
const RESTRICT oldCellVars = oldVars + cellOffset;
19704 const MFloat*
const RESTRICT cellRhs = rhs + cellOffset;
19705 MFloat*
const RESTRICT cellVars = vars + cellOffset;
19707 for(
MUint varId = 0; varId < noCVars; ++varId) {
19708 cellVars[varId] = oldCellVars[varId] - factor * cellRhs[varId];
19713#pragma omp parallel for
19716#if !defined(DISABLE_FV_MG)
19717 IF_CONSTEXPR(nDim == 2) {
19718 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
19726 const MFloat*
const RESTRICT oldCellVars = oldVars + cellOffset;
19727 const MFloat*
const RESTRICT cellRhs = rhs + cellRhsOffset;
19728 MFloat*
const RESTRICT cellVars = vars + cellOffset;
19729 for(
MUint varId = 0; varId < noCVars; ++varId) {
19730 cellVars[varId] = oldCellVars[varId] - factor * cellRhs[varId];
19738 if(!m_dualTimeStepping) {
19740#pragma omp parallel for
19743#if !defined(DISABLE_FV_MG)
19744 IF_CONSTEXPR(nDim == 2) {
19745 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
19753 const MFloat*
const RESTRICT oldCellVars = oldVars + cellOffset;
19754 const MFloat*
const RESTRICT cellRhs = rhs + cellRhsOffset;
19755 MFloat*
const RESTRICT cellVars = vars + cellOffset;
19756 for(
MUint varId = 0; varId < noCVars; ++varId) {
19757 cellVars[varId] = rkAlpha * cellVars[varId] + (F1 - rkAlpha) * oldCellVars[varId] - factor * cellRhs[varId];
19762#pragma omp parallel for
19765#if !defined(DISABLE_FV_MG)
19766 IF_CONSTEXPR(nDim == 2) {
19767 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
19775 const MFloat*
const RESTRICT oldCellVars = oldVars + cellOffset;
19776 const MFloat*
const RESTRICT cellRhs = rhs + cellRhsOffset;
19777 MFloat*
const RESTRICT cellVars = vars + cellOffset;
19778 for(
MUint varId = 0; varId < noCVars; ++varId) {
19779 cellVars[varId] = rkAlpha * cellVars[varId] + (F1 - rkAlpha) * oldCellVars[varId] - factor * cellRhs[varId];
19786 stringstream errorMessage;
19787 errorMessage <<
"Runge-Kutta Order (property 'rungeKuttaOrder) " << m_rungeKuttaOrder <<
" is not implemented.";
19788 mTerm(1, AT_, errorMessage.str());
19793 if(m_RKStep == m_noRKSteps) {
19794 if(!m_dualTimeStepping) {
19795 m_physicalTime += dt * m_timeRef;
19812template <MInt nDim_,
class SysEqn>
19814 const MUint noSpecies = m_noSpecies;
19816 IF_CONSTEXPR(isEEGas<SysEqn>) {
return rungeKuttaStepEEGas(); }
19818 if(noSpecies == 0) {
19819 return rungeKuttaStep_(0);
19820 }
else if(noSpecies == 1) {
19821 return rungeKuttaStep_(1);
19823 return rungeKuttaStep_(noSpecies);
19841template <MInt nDim_,
class SysEqn>
19842template <
class _, std::enable_if_t<isEEGas<SysEqn>, _*>>
19846 const MUint noCVars = CV->noVariables;
19847 const MUint noFVars = FV->noVariables;
19850 const MFloat rkAlpha = m_RKalpha[m_RKStep];
19851 const MFloat dt = timeStep(
true);
19852 const MFloat rkFactor = rkAlpha * dt;
19854 const MUint noActiveCells = m_noActiveCells;
19855 const MUint last = m_activeCellIds[noActiveCells - 1] + 1;
19856 MFloat*
const RESTRICT oldVars = &a_oldVariable(0, 0);
19857 MFloat*
const RESTRICT vars = &a_variable(0, 0);
19858 const MFloat*
const RESTRICT fCellVol = &a_FcellVolume(0);
19859 const MFloat*
const RESTRICT rhs = &a_rightHandSide(0, 0);
19862 if(m_RKStep == 0) {
19864#pragma omp parallel for
19866 for(
MUint cellId = m_activeCellIds[0]; cellId < last; ++cellId) {
19867 const MUint cellOffset = cellId * noCVars;
19868 MFloat*
const RESTRICT oldCellVars = oldVars + cellOffset;
19869 const MFloat*
const RESTRICT cellVars = vars + cellOffset;
19870 for(
MUint varId = 0; varId < noCVars; ++varId) {
19871 oldCellVars[varId] = cellVars[varId];
19877 switch(m_rungeKuttaOrder) {
19880 if(!m_dualTimeStepping) {
19882#pragma omp parallel for
19888 const MFloat*
const RESTRICT oldCellVars = oldVars + cellOffset;
19889 const MFloat*
const RESTRICT cellRhs = rhs + cellRhsOffset;
19890 MFloat*
const RESTRICT cellVars = vars + cellOffset;
19892 cellVars[CV->RHO] = oldCellVars[CV->RHO] - factor * cellRhs[CV->RHO];
19893 for(
MUint dir = 0; dir < nDim; dir++) {
19894 const MFloat C_1 = a_implicitCoefficient(cellId, dir * 2);
19895 const MFloat C_2 = a_implicitCoefficient(cellId, dir * 2 + 1);
19897 if(cellVars[CV->RHO] > -m_EEGas.eps) {
19898 rhoAlpha =
mMax(cellVars[CV->RHO], m_EEGas.eps);
19900 rhoAlpha = cellVars[CV->RHO];
19902 cellVars[CV->RHO_VV[dir]] = (-cellRhs[CV->RHO_VV[dir]] + C_1 + oldCellVars[CV->RHO_VV[dir]] / factor)
19903 / (F1 / factor - C_2 / rhoAlpha);
19907 mTerm(1, AT_,
"Dual timestepping not implemented for semi implicit EEGas!");
19912 stringstream errorMessage;
19913 errorMessage <<
"Runge-Kutta Order (property 'rungeKuttaOrder) " << m_rungeKuttaOrder <<
" is not implemented.";
19914 mTerm(1, AT_, errorMessage.str());
19919 if(m_RKStep == m_noRKSteps) {
19920 if(!m_dualTimeStepping) {
19921 m_physicalTime += dt * m_timeRef;
19937template <MInt nDim_,
class SysEqn>
19939 const MUint noFVars = FV->noVariables;
19940 const MInt*
const RESTRICT nghbrCellIds = ALIGNED_I(&a_surfaceNghbrCellId(0, 0));
19941 const MFloat*
const RESTRICT fluxes = ALIGNED_F(&a_surfaceFlux(0, 0));
19942 MFloat*
const RESTRICT rhs = ALIGNED_MF(&a_rightHandSide(0, 0));
19945 for(
MUint srfcId = 0; srfcId < static_cast<MUint>(a_noSurfaces()); ++srfcId) {
19946 const MUint offset0 = nghbrCellIds[srfcId * 2] * noFVars;
19947 const MUint offset1 = nghbrCellIds[srfcId * 2 + 1] * noFVars;
19948 const MUint fluxOffset = srfcId * noFVars;
19949 const MFloat*
const RESTRICT flux = ALIGNED_F(fluxes + fluxOffset);
19950 for(
MUint var = 0; var < noFVars; ++var) {
19951 rhs[offset0 + var] += flux[var];
19952 rhs[offset1 + var] -= flux[var];
19956 IF_CONSTEXPR(isEEGas<SysEqn>) {
19957 const MUint noCells = a_noCells();
19959#pragma omp parallel for
19961 for(
MUint cellId = 0; cellId < noCells; ++cellId) {
19962 const MFloat alpha = a_alphaGas(cellId);
19963 for(
MUint i = 0; i < nDim; i++) {
19964 rhs[cellId * noFVars + CV->A_RHO_VV[i]] += rhs[cellId * noFVars + FV->P_RHO_VV[i]] * alpha;
19975template <MInt nDim_,
class SysEqn>
19979 IF_CONSTEXPR(isDetChem<SysEqn>) { computeMeanMolarWeights_CV(); }
19981 computePrimitiveVariables_();
19983 computePrimitiveVariablesCoarseGrid(noInternalCells());
19992template <MInt nDim,
class SysEqn>
19994 const MUint noCells = a_noCells();
19995 const MUint noPVars = PV->noVariables;
19996 const MUint noCVars = CV->noVariables;
19997 const MUint noAVars = hasAV ? AV->noVariables : 0;
19999 MFloat*
const RESTRICT cvars = &a_variable(0, 0);
20000 MFloat*
const RESTRICT pvars = &a_pvariable(0, 0);
20001 MFloat*
const RESTRICT avars = hasAV ? &a_avariable(0, 0) : nullptr;
20002 const MFloat*
const RESTRICT uOtherPhase = isEEGas<SysEqn> ? &a_uOtherPhase(0, 0) : nullptr;
20005#pragma omp parallel for
20007 for(
MUint cellId = 0; cellId < noCells; ++cellId) {
20008 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
20009 const MUint cellPVarOffset = cellId * noPVars;
20010 const MUint cellCVarOffset = cellId * noCVars;
20011 const MUint cellAVarOffset = hasAV ? cellId * noAVars : 0;
20012 const MFloat*
const RESTRICT cvarsCell = cvars + cellCVarOffset;
20013 MFloat*
const RESTRICT pvarsCell = pvars + cellPVarOffset;
20014 const MFloat*
const RESTRICT avarsCell = hasAV ? avars + cellAVarOffset :
nullptr;
20015 sysEqn().computePrimitiveVariables(cvarsCell, pvarsCell, avarsCell);
20017 IF_CONSTEXPR(isEEGas<SysEqn>)
20018 if(m_EEGas.uDLimiter) {
20020#pragma omp parallel for
20023 const MInt cellPVarOffset =
cellId * noPVars;
20024 const MInt cellCVarOffset =
cellId * noCVars;
20025 const MUint cellAVarOffset = hasAV ?
cellId * noAVars : 0;
20027 MFloat*
const RESTRICT pvarsCell = pvars + cellPVarOffset;
20028 MFloat*
const RESTRICT cvarsCell = cvars + cellCVarOffset;
20029 const MFloat*
const RESTRICT avarsCell = hasAV ? avars + cellAVarOffset :
nullptr;
20030 const MFloat*
const RESTRICT uOtherPhaseCell = uOtherPhase + uOthOffset;
20031 const MBool change = uDLimiter(uOtherPhaseCell, pvarsCell);
20032 if(change) sysEqn().computeConservativeVariables(pvarsCell, cvarsCell, avarsCell);
20042template <MInt nDim_,
class SysEqn>
20044 const MFloat*
const cvarsCell = &a_variable(cellId, 0);
20045 MFloat*
const pvarsCell = &a_pvariable(cellId, 0);
20046 const MFloat*
const avarsCell = hasAV ? &a_avariable(cellId, 0) :
nullptr;
20048 IF_CONSTEXPR(isDetChem<SysEqn>) setMeanMolarWeight_CV(cellId);
20050 sysEqn().computePrimitiveVariables(cvarsCell, pvarsCell, avarsCell);
20052 IF_CONSTEXPR(isEEGas<SysEqn>) {
20053 MBool change =
false;
20054 if(m_EEGas.uDLimiter) {
20055 change = uDLimiter(&a_uOtherPhase(cellId, 0), &a_pvariable(cellId, 0));
20057 if(change) setConservativeVariables(cellId);
20067template <MInt nDim_,
class SysEqn>
20069 const MUint noCells = a_noCells();
20070 const MUint noPVars = PV->noVariables;
20071 const MUint noCVars = CV->noVariables;
20072 const MUint noAVars = hasAV ? AV->noVariables : 0;
20074 const MFloat*
const RESTRICT pvars = &a_pvariable(0, 0);
20075 MFloat*
const RESTRICT cvars = &a_variable(0, 0);
20076 MFloat*
const RESTRICT avars = hasAV ? &a_avariable(0, 0) : nullptr;
20079#pragma omp parallel for
20081 for(
MUint cellId = 0; cellId < noCells; ++cellId) {
20082 const MUint cellPVarOffset = cellId * noPVars;
20083 const MUint cellCVarOffset = cellId * noCVars;
20084 const MUint cellAVarOffset = hasAV ? (cellId * noAVars) : 0;
20085 const MFloat*
const RESTRICT pvarsCell = pvars + cellPVarOffset;
20086 MFloat*
const RESTRICT cvarsCell = cvars + cellCVarOffset;
20087 const MFloat*
const RESTRICT avarsCell = hasAV ? avars + cellAVarOffset :
nullptr;
20089 sysEqn().computeConservativeVariables(pvarsCell, cvarsCell, avarsCell);
20099template <MInt nDim_,
class SysEqn>
20103 if(!m_combustion) {
20108 for(
MInt level_ = maxLevel() - 1; level_ >= minLevel(); --level_) {
20110#pragma omp parallel for
20112 for(
MInt cellId = 0; cellId < noCells; cellId++) {
20113 if(a_isBndryGhostCell(cellId))
continue;
20115 if(level_ != a_level(cellId)) {
20119 if(c_isLeafCell(cellId)) {
20123 MInt noChildren = 0;
20124 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
20125 if(c_childId(cellId, childId) > -1) {
20129 if(noChildren == 0) {
20135 for(
MInt i = 0; i < PV->noVariables; i++) {
20136 a_pvariable(cellId, i) = F0;
20139 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
20140 if(c_childId(cellId, childId) < 0) {
20144 for(
MInt i = 0; i < PV->noVariables; i++) {
20145 a_pvariable(cellId, i) += FnoChildren * a_pvariable(c_childId(cellId, childId), i);
20151 ASSERT(m_combustion,
"someone changed the code -> this code is only needed for combustion computations");
20161template <MInt nDim_,
class SysEqn>
20167 MInt noCells = a_noCells();
20169 computePrimitiveVariablesCoarseGrid(noCells);
20170 ASSERT(m_combustion,
"someone changed the code -> this code is only needed for combustion computations");
20179template <MInt nDim_,
class SysEqn>
20186 const MUint noCells = a_noCells();
20189 for(
MInt level_ = maxLevel() - 1; level_ >= minLevel(); --level_) {
20190 for(
MUint cellId = 0; cellId < noCells; cellId++) {
20191 if(a_isBndryGhostCell(cellId))
continue;
20192 if(level_ != a_level(cellId))
continue;
20194 if(c_isLeafCell(cellId))
continue;
20196 MInt noChildren = 0;
20197 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
20198 if(c_childId(cellId, childId) > -1) {
20203 if(noChildren == 0)
continue;
20205 MFloat FnoChildren = 1.0 / noChildren;
20207 for(
MInt i = 0; i < CV->noVariables; i++) {
20208 a_variable(cellId, i) = F0;
20211 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
20212 if(c_childId(cellId, childId) < 0)
continue;
20214 for(
MInt i = 0; i < CV->noVariables; i++) {
20215 a_variable(cellId, i) +=
20217 * a_variable(c_childId(cellId, childId), i);
20223 ASSERT(m_combustion,
"someone changed the code -> this code is only needed for combustion computations");
20231template <MInt nDim_,
class SysEqn>
20235 IF_CONSTEXPR(isDetChem<SysEqn>) { computeMeanMolarWeights_PV(); }
20237 computeConservativeVariables_();
20238 computeConservativeVariablesCoarseGrid();
20251template <MInt nDim_,
class SysEqn>
20257 return static_cast<MFloat>(a_pvariable(cellId_, varId_));
20259 interpolateVariablesInCell<0, nDim + 2>(cellId, position, varPtr, vars);
20260 ASSERT(noVariables() == nDim + 2,
"ERROR: Number of variables not correct.");
20274template <MInt nDim_,
class SysEqn>
20279 interpolateVariables<0, nDim + 2>(cellId, position, vars);
20281 ASSERT(noVariables() == nDim + 2,
"ERROR: Number of variables not correct.");
20295template <MInt nDim_,
class SysEqn>
20296template <MInt noSpecies>
20301 interpolateVariables<0, nDim + 2 + noSpecies>(cellId, position, vars);
20303 ASSERT(noVariables() == nDim + 2 + noSpecies,
"ERROR: Number of variables not correct.");
20317template <MInt nDim_,
class SysEqn>
20318template <MInt a, MInt b, MBool old>
20320 MFloat* interpolatedVar) {
20322 ASSERT((
b -
a) > 0,
"ERROR: Difference between b and a needs to be positive!");
20323 ASSERT(cellId >= 0,
"ERROR: Invalid cellId!");
20325 const MFloat originX = a_coordinate(cellId, 0);
20326 const MFloat originY = a_coordinate(cellId, 1);
20327 const MFloat originZ = a_coordinate(cellId, 2);
20332 vector<MInt> nghbrList;
20334#pragma omp critical
20337 if(m_cellToNghbrHood.count(cellId) > 0) {
20338 nghbrList = m_cellToNghbrHood[cellId];
20341 findDirectNghbrs(cellId, nghbrList);
20343 if(nghbrList.size() < 12) {
20344 findNeighborHood(cellId, 2, nghbrList);
20347 if(nghbrList.size() < 14) {
20348 cout <<
"WARNING: Only found " << nghbrList.size() <<
" neighbors during interpolation!" << endl;
20352 m_cellToNghbrHood.emplace(make_pair(cellId, nghbrList));
20361 vector<array<
MFloat,
b -
a>> pseudoCellVar(nghbrList.size());
20362 vector<array<MFloat, nDim>> pseudoCellPos(nghbrList.size());
20364 for(
MUint nId = 0; nId < nghbrList.size(); nId++) {
20365 const MInt nghbrId = nghbrList[nId];
20366 if(nghbrId >= 0 && a_bndryId(nghbrId) > -1) {
20368 nghbrList[nId] = -1;
20369 for(
MInt i = 0; i < nDim; i++) {
20370 pseudoCellPos[nId][i] = m_bndryCells->a[a_bndryId(nghbrId)].m_srfcs[0]->m_coordinates[i];
20375 for(
MInt i =
a; i <
b; i++) {
20378 pseudoCellVar[nId][i -
a] = a_oldVariable(cellId, i);
20380 pseudoCellVar[nId][i -
a] = a_variable(cellId, i);
20393 for(
MUint nId = 0; nId < nghbrList.size(); nId++) {
20394 const MInt nghbrId = nghbrList[nId];
20396 if(a_bndryId(nghbrId) > -1) {
20407 if(nghbrList.size() < 10) {
20408 vector<MFloat>
dist(nghbrList.size(), 0);
20409 for(
MUint nId = 0; nId < nghbrList.size(); nId++) {
20410 const MInt nghbrId = nghbrList[nId];
20413 IF_CONSTEXPR(nDim == 2) {
20414 dist[nId] =
POW2(pseudoCellPos[nId][0] - position[0]) +
POW2(pseudoCellPos[nId][1] - position[1]);
20417 dist[nId] =
POW2(pseudoCellPos[nId][0] - position[0]) +
POW2(pseudoCellPos[nId][1] - position[1])
20418 +
POW2(pseudoCellPos[nId][2] - position[2]);
20421 IF_CONSTEXPR(nDim == 2) {
20422 dist[nId] =
POW2(a_coordinate(nghbrId, 0) - position[0]) +
POW2(a_coordinate(nghbrId, 1) - position[1]);
20425 dist[nId] =
POW2(a_coordinate(nghbrId, 0) - position[0]) +
POW2(a_coordinate(nghbrId, 1) - position[1])
20426 +
POW2(a_coordinate(nghbrId, 2) - position[2]);
20433 for(
MInt k =
a; k <
b; k++) {
20435 interpolatedVar[k] = 0.0;
20437 for(
MUint nId = 1; nId < nghbrList.size(); nId++) {
20438 const MInt nghbrId = nghbrList[nId];
20440 var = pseudoCellVar[nId][k -
a];
20443 var = a_oldVariable(nghbrId, k);
20445 var = a_variable(nghbrId, k);
20448 interpolatedVar[k] +=
dist[nId] / sum * var;
20454 m_log <<
"WARNING: Not enough neighbors found to use LS using weighted averaging instead!" << endl;
20460 MFloatTensor LSMatrix(2 * nDim + pow(2, nDim - 1), 2 * nDim + pow(2, nDim - 1));
20463 MFloatTensor matInv(2 * nDim + pow(2, nDim - 1), 2 * nDim + pow(2, nDim - 1));
20506 for(
MUint nId = 1; nId < nghbrList.size(); nId++) {
20510 const MInt nghbrId = nghbrList[nId];
20512 x = pseudoCellPos[nId][0] - originX;
20513 y = pseudoCellPos[nId][1] - originY;
20514 IF_CONSTEXPR(nDim == 3) { z = pseudoCellPos[nId][2] - originZ; }
20516 x = a_coordinate(nghbrId, 0) - originX;
20517 y = a_coordinate(nghbrId, 1) - originY;
20518 IF_CONSTEXPR(nDim == 3) { z = a_coordinate(nghbrId, 2) - originZ; }
20530 sumXYZ += x *
y * z;
20531 sumX2Y += x * x *
y;
20532 sumX2Z += x * x * z;
20533 sumXY2 += x *
y *
y;
20534 sumY2Z +=
y *
y * z;
20535 sumXZ2 += z * z * x;
20536 sumYZ2 += z * z *
y;
20537 sumX3 += x * x * x;
20538 sumY3 +=
y *
y *
y;
20539 sumZ3 += z * z * z;
20540 sumX3Y += x * x * x *
y;
20541 sumX3Z += x * x * x * z;
20542 sumXY3 +=
y *
y *
y * x;
20543 sumY3Z +=
y *
y *
y * z;
20544 sumXZ3 += z * z * z * x;
20545 sumYZ3 += z * z * z *
y;
20546 sumX2Y2 += x * x *
y *
y;
20547 sumX2Z2 += x * x * z * z;
20548 sumX2YZ += x * x *
y * z;
20549 sumY2Z2 +=
y *
y * z * z;
20550 sumXY2Z += x *
y *
y * z;
20551 sumXYZ2 += x *
y * z * z;
20552 sumX4 += x * x * x * x;
20553 sumY4 +=
y *
y *
y *
y;
20554 sumZ4 += z * z * z * z;
20558 IF_CONSTEXPR(nDim == 2) {
20560 LSMatrix(0, 0) = sumX4;
20561 LSMatrix(1, 1) = sumY4;
20562 LSMatrix(2, 2) = sumX2Y2;
20563 LSMatrix(3, 3) = sumX2;
20564 LSMatrix(4, 4) = sumY2;
20565 LSMatrix(5, 5) = nghbrList.
size();
20568 LSMatrix(0, 1) = LSMatrix(1, 0) = sumX2Y2;
20569 LSMatrix(0, 2) = LSMatrix(2, 0) = sumX3Y;
20570 LSMatrix(0, 3) = LSMatrix(3, 0) = sumX3;
20571 LSMatrix(0, 4) = LSMatrix(4, 0) = sumX2Y;
20572 LSMatrix(0, 5) = LSMatrix(5, 0) = sumX2;
20575 LSMatrix(1, 2) = LSMatrix(2, 1) = sumXY3;
20576 LSMatrix(1, 3) = LSMatrix(3, 1) = sumXY2;
20577 LSMatrix(1, 4) = LSMatrix(4, 1) = sumY3;
20578 LSMatrix(1, 5) = LSMatrix(5, 1) = sumY2;
20581 LSMatrix(2, 3) = LSMatrix(3, 2) = sumX2Y;
20582 LSMatrix(2, 4) = LSMatrix(4, 2) = sumXY2;
20583 LSMatrix(2, 5) = LSMatrix(5, 2) = sumXY;
20586 LSMatrix(3, 4) = LSMatrix(4, 3) = sumXY;
20587 LSMatrix(3, 5) = LSMatrix(5, 3) = sumX;
20590 LSMatrix(4, 5) = LSMatrix(5, 4) = sumY;
20594 LSMatrix(0, 0) = sumX4;
20595 LSMatrix(1, 1) = sumY4;
20596 LSMatrix(2, 2) = sumZ4;
20597 LSMatrix(3, 3) = sumX2Y2;
20598 LSMatrix(4, 4) = sumX2Z2;
20599 LSMatrix(5, 5) = sumY2Z2;
20600 LSMatrix(6, 6) = sumX2;
20601 LSMatrix(7, 7) = sumY2;
20602 LSMatrix(8, 8) = sumZ2;
20603 LSMatrix(9, 9) = nghbrList.
size();
20606 LSMatrix(0, 1) = LSMatrix(1, 0) = sumX2Y2;
20607 LSMatrix(0, 2) = LSMatrix(2, 0) = sumX2Z2;
20608 LSMatrix(0, 3) = LSMatrix(3, 0) = sumX3Y;
20609 LSMatrix(0, 4) = LSMatrix(4, 0) = sumX3Z;
20610 LSMatrix(0, 5) = LSMatrix(5, 0) = sumX2YZ;
20611 LSMatrix(0, 6) = LSMatrix(6, 0) = sumX3;
20612 LSMatrix(0, 7) = LSMatrix(7, 0) = sumX2Y;
20613 LSMatrix(0, 8) = LSMatrix(8, 0) = sumX2Z;
20614 LSMatrix(0, 9) = LSMatrix(9, 0) = sumX2;
20617 LSMatrix(1, 2) = LSMatrix(2, 1) = sumY2Z2;
20618 LSMatrix(1, 3) = LSMatrix(3, 1) = sumXY3;
20619 LSMatrix(1, 4) = LSMatrix(4, 1) = sumXY2Z;
20620 LSMatrix(1, 5) = LSMatrix(5, 1) = sumY3Z;
20621 LSMatrix(1, 6) = LSMatrix(6, 1) = sumXY2;
20622 LSMatrix(1, 7) = LSMatrix(7, 1) = sumY3;
20623 LSMatrix(1, 8) = LSMatrix(8, 1) = sumY2Z;
20624 LSMatrix(1, 9) = LSMatrix(9, 1) = sumY2;
20627 LSMatrix(2, 3) = LSMatrix(3, 2) = sumXYZ2;
20628 LSMatrix(2, 4) = LSMatrix(4, 2) = sumXZ3;
20629 LSMatrix(2, 5) = LSMatrix(5, 2) = sumYZ3;
20630 LSMatrix(2, 6) = LSMatrix(6, 2) = sumXZ2;
20631 LSMatrix(2, 7) = LSMatrix(7, 2) = sumYZ2;
20632 LSMatrix(2, 8) = LSMatrix(8, 2) = sumZ3;
20633 LSMatrix(2, 9) = LSMatrix(9, 2) = sumZ2;
20636 LSMatrix(3, 4) = LSMatrix(4, 3) = sumX2YZ;
20637 LSMatrix(3, 5) = LSMatrix(5, 3) = sumXY2Z;
20638 LSMatrix(3, 6) = LSMatrix(6, 3) = sumX2Y;
20639 LSMatrix(3, 7) = LSMatrix(7, 3) = sumXY2;
20640 LSMatrix(3, 8) = LSMatrix(8, 3) = sumXYZ;
20641 LSMatrix(3, 9) = LSMatrix(9, 3) = sumXY;
20644 LSMatrix(4, 5) = LSMatrix(5, 4) = sumXYZ2;
20645 LSMatrix(4, 6) = LSMatrix(6, 4) = sumX2Z;
20646 LSMatrix(4, 7) = LSMatrix(7, 4) = sumXYZ;
20647 LSMatrix(4, 8) = LSMatrix(8, 4) = sumXZ2;
20648 LSMatrix(4, 9) = LSMatrix(9, 4) = sumXZ;
20651 LSMatrix(5, 6) = LSMatrix(6, 5) = sumXYZ;
20652 LSMatrix(5, 7) = LSMatrix(7, 5) = sumY2Z;
20653 LSMatrix(5, 8) = LSMatrix(8, 5) = sumYZ2;
20654 LSMatrix(5, 9) = LSMatrix(9, 5) = sumYZ;
20657 LSMatrix(6, 7) = LSMatrix(7, 6) = sumXY;
20658 LSMatrix(6, 8) = LSMatrix(8, 6) = sumXZ;
20659 LSMatrix(6, 9) = LSMatrix(9, 6) = sumX;
20662 LSMatrix(7, 8) = LSMatrix(8, 7) = sumYZ;
20663 LSMatrix(7, 9) = LSMatrix(9, 7) = sumY;
20666 LSMatrix(8, 9) = LSMatrix(9, 8) = sumZ;
20670 const MFloat normalizationFactor =
FPOW2(2 * a_level(cellId)) / c_cellLengthAtLevel(0);
20671 for(
MInt i = 0; i < 2 * nDim + pow(2, nDim - 1); i++) {
20672 for(
MInt j = 0; j < 2 * nDim + pow(2, nDim - 1); j++) {
20673 LSMatrix(i, j) *= normalizationFactor;
20678 maia::math::invert(LSMatrix, matInv, 2 * nDim + pow(2, nDim - 1), 2 * nDim + pow(2, nDim - 1));
20683 for(
MInt k =
a; k <
b; k++) {
20686 sumVar = a_oldVariable(cellId, k);
20688 sumVar = a_variable(cellId, k);
20703 for(
MUint nId = 1; nId < nghbrList.size(); nId++) {
20708 const MInt nghbrId = nghbrList[nId];
20710 x = pseudoCellPos[nId][0] - originX;
20711 y = pseudoCellPos[nId][1] - originY;
20712 var = pseudoCellVar[nId][k -
a];
20714 IF_CONSTEXPR(nDim == 3) { z = pseudoCellPos[nId][2] - originZ; }
20716 x = a_coordinate(nghbrId, 0) - originX;
20717 y = a_coordinate(nghbrId, 1) - originY;
20719 var = a_oldVariable(nghbrId, k);
20721 var = a_variable(nghbrId, k);
20723 IF_CONSTEXPR(nDim == 3) { z = a_coordinate(nghbrId, 2) - originZ; }
20727 sumVarX += var * x;
20728 sumVarY += var *
y;
20729 sumVarZ += var * z;
20730 sumVarXY += var * x *
y;
20731 sumVarXZ += var * x * z;
20732 sumVarYZ += var *
y * z;
20733 sumVarX2 += var * x * x;
20734 sumVarY2 += var *
y *
y;
20735 sumVarZ2 += var * z * z;
20739 IF_CONSTEXPR(nDim == 2) {
20761 for(
MInt i = 0; i < 2 * nDim + pow(2, nDim - 1); i++) {
20762 rhs(i) *= normalizationFactor;
20769 for(
MInt i = 0; i < 2 * nDim + pow(2, nDim - 1); i++) {
20770 for(
MInt j = 0; j < 2 * nDim + pow(2, nDim - 1); j++) {
20771 coeff(i) += matInv(i, j) * rhs(j);
20778 MFloat positionX = position[0] - originX;
20779 MFloat positionY = position[1] - originY;
20781 IF_CONSTEXPR(nDim == 3) { positionZ = position[2] - originZ; }
20782 MFloat result = coeff((
MInt)(2 * nDim + pow(2, nDim - 1) - 1));
20783 IF_CONSTEXPR(nDim == 2) {
20784 result += coeff(0) * positionX * positionX;
20785 result += coeff(1) * positionY * positionY;
20786 result += coeff(2) * positionX * positionY;
20787 result += coeff(3) * positionX;
20788 result += coeff(4) * positionY;
20791 result += coeff(0) * positionX * positionX;
20792 result += coeff(1) * positionY * positionY;
20793 result += coeff(2) * positionZ * positionZ;
20794 result += coeff(3) * positionX * positionY;
20795 result += coeff(4) * positionX * positionZ;
20796 result += coeff(5) * positionY * positionZ;
20797 result += coeff(6) * positionX;
20798 result += coeff(7) * positionY;
20799 result += coeff(8) * positionZ;
20802 interpolatedVar[k -
a] = result;
20811template <MInt nDim_,
class SysEqn>
20813 ASSERT(cellId >= 0,
"ERROR: Invalid cellId!");
20815 if(m_cellInterpolationIndex[cellId] != -1) {
20820 const MFloat*
const origin = &a_coordinate(cellId, 0);
20825 vector<MInt> nghbrList;
20827#pragma omp critical
20830 findDirectNghbrs(cellId, nghbrList);
20831 if(nghbrList.size() < 12) {
20832 findNeighborHood(cellId, 2, nghbrList);
20834 if(nghbrList.size() < 14) {
20835 cout <<
"WARNING: Only found " << nghbrList.size() <<
" neighbors during interpolation!" << endl;
20847 for(
MUint nId = 0; nId < nghbrList.size(); nId++) {
20848 const MInt nghbrId = nghbrList[nId];
20849 if(nghbrId >= 0 && a_bndryId(nghbrId) > -1) {
20850 mTerm(1,
"boundary cells not handled");
20867 if(nghbrList.size() < 10) {
20868 mTerm(1,
"too few neighbors");
20874 MFloatTensor LSMatrix(2 * nDim + pow(2, nDim - 1), 2 * nDim + pow(2, nDim - 1));
20877 MFloatTensor matInv(2 * nDim + pow(2, nDim - 1), 2 * nDim + pow(2, nDim - 1));
20920 for(
MUint nId = 1; nId < nghbrList.size(); nId++) {
20924 const MInt nghbrId = nghbrList[nId];
20926 mTerm(1,
"not supported");
20934 x = a_coordinate(nghbrId, 0) - origin[0];
20935 y = a_coordinate(nghbrId, 1) - origin[1];
20936 IF_CONSTEXPR(nDim == 3) { z = a_coordinate(nghbrId, 2) - origin[2]; }
20948 sumXYZ += x *
y * z;
20949 sumX2Y += x * x *
y;
20950 sumX2Z += x * x * z;
20951 sumXY2 += x *
y *
y;
20952 sumY2Z +=
y *
y * z;
20953 sumXZ2 += z * z * x;
20954 sumYZ2 += z * z *
y;
20955 sumX3 += x * x * x;
20956 sumY3 +=
y *
y *
y;
20957 sumZ3 += z * z * z;
20958 sumX3Y += x * x * x *
y;
20959 sumX3Z += x * x * x * z;
20960 sumXY3 +=
y *
y *
y * x;
20961 sumY3Z +=
y *
y *
y * z;
20962 sumXZ3 += z * z * z * x;
20963 sumYZ3 += z * z * z *
y;
20964 sumX2Y2 += x * x *
y *
y;
20965 sumX2Z2 += x * x * z * z;
20966 sumX2YZ += x * x *
y * z;
20967 sumY2Z2 +=
y *
y * z * z;
20968 sumXY2Z += x *
y *
y * z;
20969 sumXYZ2 += x *
y * z * z;
20970 sumX4 += x * x * x * x;
20971 sumY4 +=
y *
y *
y *
y;
20972 sumZ4 += z * z * z * z;
20976 IF_CONSTEXPR(nDim == 2) {
20978 LSMatrix(0, 0) = sumX4;
20979 LSMatrix(1, 1) = sumY4;
20980 LSMatrix(2, 2) = sumX2Y2;
20981 LSMatrix(3, 3) = sumX2;
20982 LSMatrix(4, 4) = sumY2;
20983 LSMatrix(5, 5) = nghbrList.
size();
20986 LSMatrix(0, 1) = LSMatrix(1, 0) = sumX2Y2;
20987 LSMatrix(0, 2) = LSMatrix(2, 0) = sumX3Y;
20988 LSMatrix(0, 3) = LSMatrix(3, 0) = sumX3;
20989 LSMatrix(0, 4) = LSMatrix(4, 0) = sumX2Y;
20990 LSMatrix(0, 5) = LSMatrix(5, 0) = sumX2;
20993 LSMatrix(1, 2) = LSMatrix(2, 1) = sumXY3;
20994 LSMatrix(1, 3) = LSMatrix(3, 1) = sumXY2;
20995 LSMatrix(1, 4) = LSMatrix(4, 1) = sumY3;
20996 LSMatrix(1, 5) = LSMatrix(5, 1) = sumY2;
20999 LSMatrix(2, 3) = LSMatrix(3, 2) = sumX2Y;
21000 LSMatrix(2, 4) = LSMatrix(4, 2) = sumXY2;
21001 LSMatrix(2, 5) = LSMatrix(5, 2) = sumXY;
21004 LSMatrix(3, 4) = LSMatrix(4, 3) = sumXY;
21005 LSMatrix(3, 5) = LSMatrix(5, 3) = sumX;
21008 LSMatrix(4, 5) = LSMatrix(5, 4) = sumY;
21012 LSMatrix(0, 0) = sumX4;
21013 LSMatrix(1, 1) = sumY4;
21014 LSMatrix(2, 2) = sumZ4;
21015 LSMatrix(3, 3) = sumX2Y2;
21016 LSMatrix(4, 4) = sumX2Z2;
21017 LSMatrix(5, 5) = sumY2Z2;
21018 LSMatrix(6, 6) = sumX2;
21019 LSMatrix(7, 7) = sumY2;
21020 LSMatrix(8, 8) = sumZ2;
21021 LSMatrix(9, 9) = nghbrList.
size();
21024 LSMatrix(0, 1) = LSMatrix(1, 0) = sumX2Y2;
21025 LSMatrix(0, 2) = LSMatrix(2, 0) = sumX2Z2;
21026 LSMatrix(0, 3) = LSMatrix(3, 0) = sumX3Y;
21027 LSMatrix(0, 4) = LSMatrix(4, 0) = sumX3Z;
21028 LSMatrix(0, 5) = LSMatrix(5, 0) = sumX2YZ;
21029 LSMatrix(0, 6) = LSMatrix(6, 0) = sumX3;
21030 LSMatrix(0, 7) = LSMatrix(7, 0) = sumX2Y;
21031 LSMatrix(0, 8) = LSMatrix(8, 0) = sumX2Z;
21032 LSMatrix(0, 9) = LSMatrix(9, 0) = sumX2;
21035 LSMatrix(1, 2) = LSMatrix(2, 1) = sumY2Z2;
21036 LSMatrix(1, 3) = LSMatrix(3, 1) = sumXY3;
21037 LSMatrix(1, 4) = LSMatrix(4, 1) = sumXY2Z;
21038 LSMatrix(1, 5) = LSMatrix(5, 1) = sumY3Z;
21039 LSMatrix(1, 6) = LSMatrix(6, 1) = sumXY2;
21040 LSMatrix(1, 7) = LSMatrix(7, 1) = sumY3;
21041 LSMatrix(1, 8) = LSMatrix(8, 1) = sumY2Z;
21042 LSMatrix(1, 9) = LSMatrix(9, 1) = sumY2;
21045 LSMatrix(2, 3) = LSMatrix(3, 2) = sumXYZ2;
21046 LSMatrix(2, 4) = LSMatrix(4, 2) = sumXZ3;
21047 LSMatrix(2, 5) = LSMatrix(5, 2) = sumYZ3;
21048 LSMatrix(2, 6) = LSMatrix(6, 2) = sumXZ2;
21049 LSMatrix(2, 7) = LSMatrix(7, 2) = sumYZ2;
21050 LSMatrix(2, 8) = LSMatrix(8, 2) = sumZ3;
21051 LSMatrix(2, 9) = LSMatrix(9, 2) = sumZ2;
21054 LSMatrix(3, 4) = LSMatrix(4, 3) = sumX2YZ;
21055 LSMatrix(3, 5) = LSMatrix(5, 3) = sumXY2Z;
21056 LSMatrix(3, 6) = LSMatrix(6, 3) = sumX2Y;
21057 LSMatrix(3, 7) = LSMatrix(7, 3) = sumXY2;
21058 LSMatrix(3, 8) = LSMatrix(8, 3) = sumXYZ;
21059 LSMatrix(3, 9) = LSMatrix(9, 3) = sumXY;
21062 LSMatrix(4, 5) = LSMatrix(5, 4) = sumXYZ2;
21063 LSMatrix(4, 6) = LSMatrix(6, 4) = sumX2Z;
21064 LSMatrix(4, 7) = LSMatrix(7, 4) = sumXYZ;
21065 LSMatrix(4, 8) = LSMatrix(8, 4) = sumXZ2;
21066 LSMatrix(4, 9) = LSMatrix(9, 4) = sumXZ;
21069 LSMatrix(5, 6) = LSMatrix(6, 5) = sumXYZ;
21070 LSMatrix(5, 7) = LSMatrix(7, 5) = sumY2Z;
21071 LSMatrix(5, 8) = LSMatrix(8, 5) = sumYZ2;
21072 LSMatrix(5, 9) = LSMatrix(9, 5) = sumYZ;
21075 LSMatrix(6, 7) = LSMatrix(7, 6) = sumXY;
21076 LSMatrix(6, 8) = LSMatrix(8, 6) = sumXZ;
21077 LSMatrix(6, 9) = LSMatrix(9, 6) = sumX;
21080 LSMatrix(7, 8) = LSMatrix(8, 7) = sumYZ;
21081 LSMatrix(7, 9) = LSMatrix(9, 7) = sumY;
21084 LSMatrix(8, 9) = LSMatrix(9, 8) = sumZ;
21089 const MFloat normalizationFactor =
FPOW2(2 * a_level(cellId)) / grid().cellLengthAtLevel(0);
21090 for(
MInt i = 0; i < 2 * nDim + pow(2, nDim - 1); i++) {
21091 for(
MInt j = 0; j < 2 * nDim + pow(2, nDim - 1); j++) {
21092 LSMatrix(i, j) *= normalizationFactor;
21097 maia::math::invert(LSMatrix, matInv, 2 * nDim + pow(2, nDim - 1), 2 * nDim + pow(2, nDim - 1));
21099 const MInt matSize = 2 * nDim + pow(2, nDim - 1);
21100 std::vector<MFloat> matInvVector(matSize * matSize);
21103 for(
MInt i = 0; i < 2 * nDim + pow(2, nDim - 1); i++) {
21104 for(
MInt j = 0; j < 2 * nDim + pow(2, nDim - 1); j++) {
21105 matInvVector[k] = matInv(i, j);
21110 const MInt interpIndex = m_cellInterpolationIds.size();
21112 m_cellInterpolationIndex[cellId] = interpIndex;
21113 m_cellInterpolationIds.push_back(nghbrList);
21114 m_cellInterpolationMatrix.push_back(matInvVector);
21120template <MInt nDim_,
class SysEqn>
21121template <MInt a, MInt b>
21124 MFloat* interpolatedVar) {
21125 ASSERT((
b -
a) > 0,
"ERROR: Difference between b and a needs to be positive!");
21126 ASSERT(cellId >= 0,
"ERROR: Invalid cellId!");
21128 const MInt interpIndex = m_cellInterpolationIndex[cellId];
21129 if(interpIndex < 0) {
21130 mTerm(1,
"Interpolation for cell not initialized");
21136 const MFloat originX = a_coordinate(cellId, 0);
21137 const MFloat originY = a_coordinate(cellId, 1);
21139 IF_CONSTEXPR(nDim == 3) { originZ = a_coordinate(cellId, 2); }
21141 const MFloat normalizationFactor =
FPOW2(2 * a_level(cellId)) / grid().cellLengthAtLevel(0);
21143 const MInt noNghbrs = m_cellInterpolationIds[interpIndex].size();
21144 const MInt*
const nghbrList = &m_cellInterpolationIds[interpIndex][0];
21146 const MInt matSize = 2 * nDim + pow(2, nDim - 1);
21147 MFloatTensor interpMatInv(&m_cellInterpolationMatrix[interpIndex][0], matSize, matSize);
21155 for(
MInt k =
a; k <
b; k++) {
21156 MFloat sumVar = variables(cellId, k);
21167 std::fill_n(&rhs[0], matSize, 0.0);
21170 for(
MInt nId = 1; nId < noNghbrs; nId++) {
21171 const MInt nghbrId = nghbrList[nId];
21172 const MFloat x = a_coordinate(nghbrId, 0) - originX;
21173 const MFloat y = a_coordinate(nghbrId, 1) - originY;
21174 const MFloat var = variables(nghbrId, k);
21176 IF_CONSTEXPR(nDim == 3) { z = a_coordinate(nghbrId, 2) - originZ; }
21178 const MFloat varX = var * x;
21180 const MFloat varZ = var * z;
21187 sumVarXY += varX *
y;
21188 sumVarXZ += varX * z;
21189 sumVarYZ += varY * z;
21191 sumVarX2 += varX * x;
21192 sumVarY2 += varY *
y;
21193 sumVarZ2 += varZ * z;
21197 IF_CONSTEXPR(nDim == 2) {
21221 for(
MInt i = 0; i < matSize; i++) {
21222 rhs[i] *= normalizationFactor;
21225 std::fill_n(&coeff[0], matSize, 0.0);
21228 for(
MInt i = 0; i < matSize; i++) {
21229 for(
MInt j = 0; j < matSize; j++) {
21230 coeff[i] += interpMatInv(i, j) * rhs[j];
21237 const MFloat positionX = position[0] - originX;
21238 const MFloat positionY = position[1] - originY;
21240 IF_CONSTEXPR(nDim == 3) { positionZ = position[2] - originZ; }
21242 MFloat result = coeff[matSize - 1];
21243 IF_CONSTEXPR(nDim == 2) {
21244 result += coeff[0] * positionX * positionX;
21245 result += coeff[1] * positionY * positionY;
21246 result += coeff[2] * positionX * positionY;
21247 result += coeff[3] * positionX;
21248 result += coeff[4] * positionY;
21251 result += coeff[0] * positionX * positionX;
21252 result += coeff[1] * positionY * positionY;
21253 result += coeff[2] * positionZ * positionZ;
21254 result += coeff[3] * positionX * positionY;
21255 result += coeff[4] * positionX * positionZ;
21256 result += coeff[5] * positionY * positionZ;
21257 result += coeff[6] * positionX;
21258 result += coeff[7] * positionY;
21259 result += coeff[8] * positionZ;
21262 interpolatedVar[k -
a] = result;
21268template <MInt nDim_,
class SysEqn>
21271 const MBool interpolate) {
21273 switch(sampleVarId) {
21276 const MInt noSpecies = PV->m_noSpecies;
21277 constexpr MInt noVarsNoSpecies = (nDim == 2) ? 4 : 5;
21280 return static_cast<MFloat>(a_pvariable(cellId_, varId_));
21282 if(noSpecies == 0) {
21283 ASSERT(noVarsNoSpecies == PV->noVariables,
"wrong number of variables");
21284 interpolateVariablesInCell<0, noVarsNoSpecies>(
id, point, varPtr, state);
21285 }
else if(noSpecies == 1) {
21286 interpolateVariablesInCell<0, noVarsNoSpecies + 1>(
id, point, varPtr, state);
21288 mTerm(1,
"Fixme: noSpecies > 1");
21291 const MInt noVars = PV->noVariables;
21292 std::copy_n(&a_pvariable(
id, 0), noVars, state);
21297 const MInt noVort = (nDim == 2) ? 1 : 3;
21299 std::function<
MFloat(
const MInt,
const MInt)> vortPointer = [&](
const MInt cellId_,
const MInt varId_) {
21300 return m_samplingVariables[sampleVarId][cellId_][varId_];
21302 interpolateVariablesInCell<0, noVort>(
id, point, vortPointer, state);
21304 const MFloat** vortPointer =
const_cast<const MFloat**
>(m_samplingVariables[sampleVarId]);
21305 std::copy_n(vortPointer[
id], noVort, state);
21311 mTerm(1,
"Fixme: interpolation of heat release");
21313 state[0] = m_heatRelease[
id];
21317 mTerm(1,
"Invalid variable id");
21328template <MInt nDim_,
class SysEqn>
21332 m_physicalTime += m_physicalTimeStep;
21334 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
21335 for(
MInt varId = 0; varId < CV->noVariables; varId++) {
21336 a_dt2Variable(cellId, varId) = a_dt1Variable(cellId, varId);
21337 a_dt1Variable(cellId, varId) = a_variable(cellId, varId);
21347template <MInt nDim_,
class SysEqn>
21353 const MFloat F4B2 = 2.0;
21356 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
21358 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
21359 if(!a_isBndryGhostCell(cellId)) {
21361 if(a_bndryId(cellId) > -1) {
21362 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId != -1) {
21367 dt = a_cellVolume(cellId) / m_physicalTimeStep;
21369 for(
MInt varId = 0; varId < CV->noVariables; varId++) {
21370 a_rightHandSide(cellId, varId) += (F3B2 * a_variable(cellId, varId) - F4B2 * a_dt1Variable(cellId, varId)
21371 + F1B2 * a_dt2Variable(cellId, varId))
21381template <MInt nDim_,
class SysEqn>
21383 IF_CONSTEXPR(!hasE<SysEqn>)
21384 mTerm(1, AT_,
"Not compatible with SysEqn without RHO_E!");
21385 MFloat momentumDensitySquare = F0;
21386 for(
MInt d = 0; d < nDim; ++d) {
21387 momentumDensitySquare +=
POW2((a_variable(cellId, CV->RHO_VV[d])));
21389 return sysEqn().pressure(a_variable(cellId, CV->RHO), momentumDensitySquare, a_variable(cellId, CV->RHO_E));
21393template <MInt nDim_,
class SysEqn>
21395 return sysEqn().temperature_ES(a_variable(cellId, CV->RHO), cv_p(cellId));
21399template <MInt nDim_,
class SysEqn>
21401 return sysEqn().speedOfSound(a_variable(cellId, CV->RHO), cv_p(cellId));
21410template <MInt nDim_,
class SysEqn>
21413 IF_CONSTEXPR(!hasE<SysEqn>)
21414 mTerm(1, AT_,
"Not compatible with SysEqn without RHO_E!");
21416 IF_CONSTEXPR(isDetChem<SysEqn>) {
21417 MFloat gamma = a_avariable(cellId, AV->GAMMA);
21418 MFloat p = a_pvariable(cellId, PV->P);
21419 MFloat rho = a_pvariable(cellId, PV->RHO);
21420 a = sqrt(gamma *
mMax(MFloatEps, p /
mMax(MFloatEps, rho)));
21426 MFloat dt = std::numeric_limits<MFloat>::max();
21427 const MFloat Frho = 1. / a_variable(cellId, CV->RHO);
21428 const MFloat dx = c_cellLengthAtCell(cellId);
21429 for(
MInt d = 0; d < nDim; ++d) {
21430 MFloat abs_u_d = fabs(a_variable(cellId, CV->RHO_VV[d]) * Frho);
21431 MFloat dt_dir = m_cfl * dx / (abs_u_d +
a);
21432 dt =
mMin(dt, dt_dir);
21440template <MInt nDim_,
class SysEqn>
21443 "FV_APE solver not selected");
21445 const MFloat dx = c_cellLengthAtCell(cellId);
21447 MFloat lambdaMaxSum = (m_initialCondition == 1184) ? 0.0 : nDim;
21448 MFloat advectionVelocity[nDim];
21449 for(
MInt d = 0; d < nDim; ++d) {
21450 advectionVelocity[d] =
21451 Context::getSolverProperty<MFloat>(
"advectionVelocity", m_solverId, AT_, &advectionVelocity[d], d);
21452 lambdaMaxSum += fabs(advectionVelocity[d]);
21454 return m_cfl * dx / (lambdaMaxSum);
21460template <MInt nDim_,
class SysEqn>
21463 return sysEqn().computeTimeStepDiffusion(SUTHERLANDLAW(temperature) / (density * Re), C, dx);
21476template <MInt nDim_,
class SysEqn>
21478 switch(m_timeStepMethod) {
21480 if(m_timeStepFixedValue > 0.) {
21481 return m_timeStepFixedValue;
21483 mTerm(1, AT_,
"unknown time-step method: " + to_string(m_timeStepMethod));
21488 return computeTimeStepEulerDirectional(cellId);
21491 return computeTimeStepApeDirectional(cellId);
21494 return m_cfl * c_cellLengthAtLevel(maxRefinementLevel());
21499 const MFloat dx = c_cellLengthAtLevel(maxRefinementLevel());
21500 std::array<MFloat, nDim> u = {};
21501 u[0] = m_UInfinity;
21502 u[1] = m_VInfinity;
21503 IF_CONSTEXPR(nDim == 3) u[2] = m_WInfinity;
21504 const MFloat dt_inv = sysEqn().computeTimeStepEulerMagnitude(m_rhoInfinity, u, m_PInfinity, m_cfl, dx);
21505 const MFloat dt_visc = computeTimeStepDiffusionNS(m_rhoInfinity, m_TInfinity, sysEqn().m_Re0, m_cflViscous, dx);
21506 return mMin(dt_inv, dt_visc);
21511template <MInt nDim_,
class SysEqn>
21513 MFloat dtCell = computeTimeStepMethod(cellId);
21516 if(m_timeStepVolumeWeighted && a_bndryId(cellId) != -1) {
21517 dtCell *= a_cellVolume(cellId) / grid().cellVolumeAtLevel(a_level(cellId));
21523template <MInt nDim_,
class SysEqn>
21526 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
21530 if(a_bndryId(cellId) < -1) {
21542 if(a_bndryId(cellId) > -1 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId != -1) {
21547 if(a_isHalo(cellId)) {
21552 if(a_hasProperty(cellId, SolverCell::IsInactive)) {
21557 if(a_hasProperty(cellId, SolverCell::IsTempLinked)) {
21560 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
21563 if(!m_fvBndryCnd->m_cellMerging && a_isBndryCell(cellId)
21564 && a_cellVolume(cellId) / grid().cellVolumeAtLevel(maxLevel()) <= m_fvBndryCnd->m_volumeLimitWall) {
21577template <MInt nDim_,
class SysEqn>
21581 const MFloat invalidTimeStep = std::numeric_limits<MFloat>::max();
21583 MFloat newTimeStep = invalidTimeStep;
21584 const MInt noCells = a_noCells();
21587 if(m_dualTimeStepping || m_localTS) {
21588 for(
MInt cellId = 0; cellId < noCells; cellId++) {
21589 a_localTimeStep(cellId) = invalidTimeStep;
21594 MInt noCellsOnWhichTheTimeStepIsComputed = 0;
21595 for(
MInt cellId = 0; cellId < noCells; ++cellId) {
21596 if(!cellParticipatesInTimeStep(cellId)) {
21597 if(m_dualTimeStepping) {
21598 a_localTimeStep(cellId) = F0;
21603 MFloat dtCell = computeTimeStep(cellId);
21604 newTimeStep =
mMin(newTimeStep, dtCell);
21605 if(m_dualTimeStepping) {
21606 a_localTimeStep(cellId) = dtCell;
21609 ++noCellsOnWhichTheTimeStepIsComputed;
21615 if(noCellsOnWhichTheTimeStepIsComputed != 0 &&
approx(newTimeStep, invalidTimeStep, m_eps)) {
21616 mTerm(1, AT_,
"failed to compute the time-step " + std::to_string(m_solverId));
21620 if(m_timeStepFixedValue > 0.) {
21621 MPI_Allreduce(MPI_IN_PLACE, &newTimeStep, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
"m_timeStep");
21622 if(m_timeStepFixedValue > newTimeStep && domainId() == 0) {
21625 <<
"WARNING: timeStepFixedvalue = " << m_timeStepFixedValue
21626 <<
" > computedGlobalTimeStep = " << newTimeStep << endl
21631 +
", using fixed time step: " + std::to_string(m_timeStepFixedValue)
21632 +
" (computeGlobalTimeStep = " + std::to_string(newTimeStep) +
")";
21633 m_log << msg << std::endl;
21634 if(domainId() == 0) {
21635 std::cerr << msg << std::endl;
21638 newTimeStep = m_timeStepFixedValue;
21640 if(m_dualTimeStepping) {
21641 for(
MInt cellId = 0; cellId < noCells; ++cellId) {
21642 if(m_timeStepFixedValue < a_localTimeStep(cellId)) {
21643 m_log <<
"Warning: cell " << cellId <<
"timeStepFixedvalue = " << m_timeStepFixedValue
21644 <<
" < computedLocalTimeStep = " << a_localTimeStep(cellId) << endl;
21646 a_localTimeStep(cellId) = m_timeStepFixedValue;
21649 forceTimeStep(newTimeStep);
21652 RECORD_TIMER_START(m_tcomm);
21653 RECORD_TIMER_START(m_texchangeDt);
21655 forceTimeStep(newTimeStep);
21656 ASSERT(m_timeStepAvailable,
"overlapping time-step computations?!");
21657#ifndef MAIA_MS_COMPILER
21658 MPI_Iallreduce(MPI_IN_PLACE, &m_timeStep, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), &m_timeStepReq, AT_,
"MPI_IN_PLACE",
21661 MPI_Allreduce(MPI_IN_PLACE, &m_timeStep, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
"m_timeStep");
21664 m_timeStepAvailable =
false;
21665 if(!m_timeStepNonBlocking) {
21668 RECORD_TIMER_STOP(m_texchangeDt);
21669 RECORD_TIMER_STOP(m_tcomm);
21676template <MInt nDim_,
class SysEqn>
21680 if(!useTimeStepFromRestartFile()) {
21681 computeAndSetTimeStep();
21684 m_timeStepUpdated =
true;
21687 IF_CONSTEXPR(nDim == 2) {
21696 m_restartFileOutputTimeStep =
21697 (m_timeStepMethod == 17511 || m_timeStepMethod == 6) ? timeStep(
true) : m_restartFileOutputTimeStep;
21698 if(m_timeStepMethod == 17511) {
21699 computeSamplingTimeStep();
21718template <MInt nDim_,
class SysEqn>
21727 if(isMultilevel() && !isMultilevelPrimary()) {
21731 RECORD_TIMER_START(m_timers[Timers::TimeInt]);
21732 RECORD_TIMER_START(m_timers[Timers::Residual]);
21734 const MInt noCells = a_noCells();
21735 const MInt noCVars = CV->noVariables;
21739 rmsResidual.
fill(F0);
21745 for(
MInt cellId = 0; cellId < noCells; cellId++) {
21746 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
21747 if(a_isHalo(cellId))
continue;
21748 if(a_isBndryGhostCell(cellId))
continue;
21749 if(a_isPeriodic(cellId))
continue;
21750 if(a_hasProperty(cellId, SolverCell::IsPeriodicWithRot))
continue;
21751 if(a_hasProperty(cellId, SolverCell::IsCutOff))
continue;
21752 if(a_hasProperty(cellId, SolverCell::IsInvalid))
continue;
21753 MInt gridcellId = cellId;
21754 if(a_hasProperty(cellId, SolverCell::IsSplitClone) || a_hasProperty(cellId, SolverCell::IsSplitChild)) {
21755 gridcellId = m_splitChildToSplitCell.find(cellId)->second;
21757 if(c_noChildren(gridcellId) > 0)
continue;
21758 if(a_bndryId(cellId) > -1 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId > -1)
continue;
21759 if(a_isInactive(cellId))
continue;
21761 rmsResidual(0) += a_cellVolume(cellId);
21763 for(
MInt var = 0; var < noCVars; var++) {
21765 MBool useOldResidual =
true;
21766 if(useOldResidual) {
21767 rmsResidual(1 + var) += a_cellVolume(cellId) *
POW2(a_FcellVolume(cellId) * a_rightHandSide(cellId, var));
21769 rmsResidual(1 + var) += a_cellVolume(cellId) *
POW2(a_variable(cellId, var) - a_oldVariable(cellId, var));
21771 avgResidual(1 + var) +=
POW2(a_variable(cellId, var) - a_oldVariable(cellId, var));
21772 maxResidual(var) =
mMax(maxResidual(var),
POW2(a_variable(cellId, var) - a_oldVariable(cellId, var)));
21774 rmsResidual(1 + var) +=
21775 a_cellVolume(cellId) *
POW2(a_variable(cellId, var) - a_oldVariable(cellId, var)) / a_localTimeStep(cellId);
21776 avgResidual(1 + var) +=
POW2(a_variable(cellId, var) - a_oldVariable(cellId, var)) / a_localTimeStep(cellId);
21777 maxResidual(var) =
mMax(maxResidual(var),
21778 POW2(a_variable(cellId, var) - a_oldVariable(cellId, var)) / a_localTimeStep(cellId));
21783 RECORD_TIMER_START(m_timers[Timers::ResidualMpi]);
21784 MPI_Allreduce(MPI_IN_PLACE, &rmsResidual(0), rmsResidual.
size(), MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
21786 MPI_Allreduce(MPI_IN_PLACE, &maxResidual(0), maxResidual.
size(), MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
21788 MPI_Allreduce(MPI_IN_PLACE, &avgResidual(0), avgResidual.
size(), MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
21790 RECORD_TIMER_STOP(m_timers[Timers::ResidualMpi]);
21793 for(
MInt var = 0; var < noCVars; var++) {
21795 rmsResidual(1 + var) = sqrt(rmsResidual(1 + var) / rmsResidual(0));
21796 avgResidual(1 + var) = sqrt(avgResidual(1 + var) / avgResidual(0));
21797 maxResidual(var) = sqrt(maxResidual(var));
21799 rmsResidual(1 + var) = sqrt(rmsResidual(1 + var) / rmsResidual(0)) / timeStep();
21800 avgResidual(1 + var) = sqrt(avgResidual(1 + var) / avgResidual(0)) / timeStep();
21801 maxResidual(var) = sqrt(maxResidual(var)) / timeStep();
21805 if(mode == 0 && this->m_adaptation && this->m_resTriggeredAdapt && maxResidual(1 + PV->RHO) < 0.00001) {
21806 MInt limit = m_localTS ? 10 : 350;
21808 if(domainId() == 0) {
21809 cerr <<
"Residual threshold reached within 100 TS after last adaptation at " <<
globalTimeStep << endl;
21810 cerr <<
" -> Deactivating residual triggered Adaptation" << endl;
21812 this->m_resTriggeredAdapt =
false;
21814 if(domainId() == 0) {
21815 cerr <<
"Forcing residual-based adaptation at time-step " <<
globalTimeStep <<
" with rms-density Residual of "
21816 << rmsResidual(1 + PV->RHO) << endl;
21818 m_forceAdaptation =
true;
21822 MBool abort =
false;
21824 for(
MInt var = 0; var < noCVars; var++) {
21826 if(!(rmsResidual(1 + var) >= F0 || rmsResidual(1 + var) < F0)) {
21827 if(domainId() == 0) {
21828 cerr <<
"Solution diverged, average residual is nan " << endl;
21830 m_log <<
"Solution diverged, average residual is nan " << endl;
21833 maxRes =
mMax(maxRes, rmsResidual(1 + var));
21838 disableDlbTimers();
21839 m_vtuWritePointData =
false;
21840 m_vtuLevelThreshold = maxRefinementLevel();
21841 saveSolverSolution(1);
21842 if(!m_levelSetMb) {
21843 mTerm(1, AT_,
"Solution diverged, average residual is NaN!");
21847 if(mode == 1)
return false;
21849 if(domainId() == 0) {
21851 if(!m_multipleFvSolver || (isMultilevel() && isMultilevelPrimary())) {
21852 surname =
"Residual";
21854 surname =
"Residual_s" + to_string(solverId());
21856 MString surnameBAK = surname +
"_BAK";
21862 struct stat buffer;
21863 if(stat(surname.c_str(), &buffer) == 0) {
21864 rename(surname.c_str(),
"Residual_BAK");
21866 datei = fopen(surname.c_str(),
"w");
21867 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
21868 IF_CONSTEXPR(nDim == 3) {
21869 fprintf(datei,
"%s",
21870 "# 1:time_step 2:hydrodynamic_time 3:acoustic_time 4:res_rhoU 5:res_rhoV 6:res_rhoW 7:res_rhoE "
21872 "9:res_rhon 10:maxRes_rhoU 11:maxRes_rhoV 12:maxRes_rhoW 13:maxRes_rhoE 14:maxRes_rho "
21873 "15:avgRes_rhoU 16:avgRes_rhoV 17:avgRes_rhoW 18:avgRes_rhoE 19:avgRes_rho\n");
21876 fprintf(datei,
"%s",
21877 "# 1:time_step 2:hydrodynamic_time 3:acoustic_time 4:res_rhoU 5:res_rhoV 6:res_rhoE 7:res_rho "
21878 "8:res_rhon 9:maxRes_rhoU 10:maxRes_rhoV 11:maxRes_rhoE 12:maxRes_rho "
21879 "13:avgRes_rhoU 14:avgRes_rhoV 15:avgRes_rhoE 16:avgRes_rho\n");
21883 IF_CONSTEXPR(nDim == 3) {
21884 fprintf(datei,
"%s",
21885 "# 1:time_step 2:hydrodynamic_time 3:acoustic_time 4:res_rhoU 5:res_rhoV 6:res_rhoW 7:res_rhoE "
21887 "9:maxRes_rhoU 10:maxRes_rhoV 11:maxRes_rhoW 12:maxRes_rhoE 13:maxRes_rho "
21888 "14:avgRes_rhoU 15:avgRes_rhoV 16:avgRes_rhoW 17:avgRes_rhoE 18:avgRes_rho\n");
21891 fprintf(datei,
"%s",
21892 "# 1:time_step 2:hydrodynamic_time 3:acoustic_time 4:res_rhoU 5:res_rhoV 6:res_rhoE 7:res_rho "
21893 "8:maxRes_rhoU 9:maxRes_rhoV 10:maxRes_rhoE 11:maxRes_rho "
21894 "12:avgRes_rhoU 13:avgRes_rhoV 14:avgRes_rhoE 15:avgRes_rho\n");
21898 datei = fopen(surname.c_str(),
"a");
21901 fprintf(datei,
" %f", m_physicalTime);
21902 fprintf(datei,
" %f", m_time);
21903 for(
MInt var = 0; var < noCVars; var++) {
21904 fprintf(datei,
" %.8g", rmsResidual(1 + var));
21906 for(
MInt var = 0; var < noCVars; var++) {
21907 fprintf(datei,
" %.8g", maxResidual(var));
21909 for(
MInt var = 0; var < noCVars; var++) {
21910 fprintf(datei,
" %.8g", avgResidual(1 + var));
21912 fprintf(datei,
"\n");
21916 RECORD_TIMER_STOP(m_timers[Timers::Residual]);
21917 RECORD_TIMER_STOP(m_timers[Timers::TimeInt]);
21919 if(maxRefinementLevel() == maxLevel() && maxRes < m_timeStepConvergenceCriterion) {
21939template <MInt nDim_,
class SysEqn>
21943 if(!calcSlopesAfterStep()) {
21944 RECORD_TIMER_START(m_timers[Timers::MusclReconst]);
21945 LSReconstructCellCenter();
21946 RECORD_TIMER_STOP(m_timers[Timers::MusclReconst]);
21949 RECORD_TIMER_START(m_timers[Timers::MusclCopy]);
21950 m_fvBndryCnd->copySlopesToSmallCells();
21951 RECORD_TIMER_STOP(m_timers[Timers::MusclCopy]);
21955 RECORD_TIMER_START(m_timers[Timers::MusclGhostSlopes]);
21956 m_fvBndryCnd->updateGhostCellSlopesInviscid();
21957 RECORD_TIMER_STOP(m_timers[Timers::MusclGhostSlopes]);
21959 RECORD_TIMER_START(m_timers[Timers::MusclCutSlopes]);
21960 m_fvBndryCnd->updateCutOffSlopesInviscid();
21961 RECORD_TIMER_STOP(m_timers[Timers::MusclCutSlopes]);
21966 RECORD_TIMER_START(m_timers[Timers::MusclReconstSrfc]);
21967 (this->*m_reconstructSurfaceData)(-1);
21968 RECORD_TIMER_STOP(m_timers[Timers::MusclReconstSrfc]);
21970 if(m_useSandpaperTrip) {
21971 RECORD_TIMER_START(m_timers[Timers::SandpaperTrip]);
21972 applySandpaperTrip();
21973 RECORD_TIMER_STOP(m_timers[Timers::SandpaperTrip]);
21976 if(m_useChannelForce) {
21977 applyChannelForce();
21988template <MInt nDim_,
class SysEqn>
21992 MInt noCVars = CV->noVariables;
21994 MFloat childDistance, cellDistance, nghbrDistance;
21995 MFloat factor, cellFactor, nghbrFactor;
22001 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
22002 childDistance += (a_coordinate(child, spaceId)
22003 - m_fvBndryCnd->m_bndryCells->a[a_bndryId(child)].m_srfcs[0]->m_coordinates[spaceId])
22004 * m_fvBndryCnd->m_bndryCells->a[a_bndryId(child)].m_srfcs[0]->m_normalVector[spaceId];
22006 childDistance = fabs(childDistance);
22009 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
22010 cellDistance += (a_coordinate(cellId, spaceId)
22011 - m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcs[0]->m_coordinates[spaceId])
22012 * m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcs[0]->m_normalVector[spaceId];
22014 cellDistance = fabs(cellDistance);
22017 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
22018 nghbrDistance += (a_coordinate(stencilCellIds[1], spaceId)
22019 - m_fvBndryCnd->m_bndryCells->a[a_bndryId(stencilCellIds[1])].m_srfcs[0]->m_coordinates[spaceId])
22020 * m_fvBndryCnd->m_bndryCells->a[a_bndryId(stencilCellIds[1])].m_srfcs[0]->m_normalVector[spaceId];
22022 nghbrDistance = fabs(nghbrDistance);
22026 cellFactor = (cellDistance - childDistance) / (2.0 * cellDistance);
22028 nghbrFactor = (nghbrDistance - childDistance) / (2.0 * nghbrDistance);
22033 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
22034 delta = a_coordinate(cellId, spaceId) - a_coordinate(child, spaceId);
22035 cellDistance += delta * delta;
22039 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
22040 delta = a_coordinate(stencilCellIds[1], spaceId) - a_coordinate(child, spaceId);
22041 nghbrDistance += delta * delta;
22045 factor = nghbrDistance / (nghbrDistance + cellDistance);
22049 for(
MInt varId = 0; varId < noCVars; varId++) {
22050 a_variable(child, varId) =
22051 factor * (cellFactor * a_variable(stencilCellIds[0], varId) + (1.0 - cellFactor) * a_variable(cellId, varId))
22053 * (nghbrFactor * a_variable(stencilCellIds[2], varId)
22054 + (1.0 - cellFactor) * a_variable(stencilCellIds[1], varId));
22058template <MInt nDim_,
class SysEqn>
22065 if(!a_hasProperty(cellId, SolverCell::IsSplitCell)) {
22067 interpolationCells[count++] = cellId;
22068 if(a_isBndryCell(cellId)) {
22069 interpolationCells[count++] = a_bndryGhostCellId(a_bndryId(cellId), 0);
22074 for(
MInt sc = 0; sc < a_noSplitCells(); sc++) {
22075 const MInt splitCell = m_splitCells[sc];
22076 if(splitCell == cellId) {
22083 for(
MInt ssc = 0; ssc < a_noSplitChilds(scId); ssc++) {
22084 const MInt splitChild = a_splitChildId(scId, ssc);
22085 IF_CONSTEXPR(nDim == 2) {
22086 dist(ssc) = sqrt(
POW2(point[0] - a_coordinate(splitChild, 0)) +
POW2(point[1] - a_coordinate(splitChild, 1)));
22089 dist(ssc) = sqrt(
POW2(point[0] - a_coordinate(splitChild, 0)) +
POW2(point[1] - a_coordinate(splitChild, 1))
22090 +
POW2(point[2] - a_coordinate(splitChild, 2)));
22096 for(
MInt ssc = 0; ssc < a_noSplitChilds(scId); ssc++) {
22097 if(
dist(ssc) < minDist) {
22098 minDist =
dist(ssc);
22102 const MInt splitChildId = a_splitChildId(scId, sscId);
22103 interpolationCells[count++] = splitChildId;
22104 interpolationCells[count++] = a_bndryGhostCellId(a_bndryId(splitChildId), 0);
22109 MInt debugDomainId = -1;
22111 if(cellId == debugId && domainId() == debugDomainId) {
22113 cerr <<
"Cell has only " << interpolationCells[0] <<
" s" << count << endl;
22115 cerr <<
"Cell has " << interpolationCells[0] <<
" and bndry-ghost-cell " << interpolationCells[1] <<
" s" << count
22118 cerr <<
"Cell is " << cellId <<
" " << c_noCells() << a_hasProperty(cellId, SolverCell::IsSplitCell) << endl;
22124 for(
MInt dir = 0; dir < m_noDirs; dir++) {
22125 if(!checkNeighborActive(cellId, dir) || !a_hasNeighbor(cellId, dir)) {
22126 neighborDistance[dir] = 99.9;
22128 IF_CONSTEXPR(nDim == 2) {
22129 neighborDistance[dir] = sqrt(
POW2(point[0] - a_coordinate(c_neighborId(cellId, dir), 0))
22130 +
POW2(point[1] - a_coordinate(c_neighborId(cellId, dir), 1)));
22133 neighborDistance[dir] = sqrt(
POW2(point[0] - a_coordinate(c_neighborId(cellId, dir), 0))
22134 +
POW2(point[1] - a_coordinate(c_neighborId(cellId, dir), 1))
22135 +
POW2(point[2] - a_coordinate(c_neighborId(cellId, dir), 2)));
22141 if(cellId == debugId && domainId() == debugDomainId) {
22142 for(
MInt i = 0; i < m_noDirs; i++) {
22143 const MInt nghbrId = c_neighborId(cellId, i);
22144 MInt ghostCell = -1;
22145 if(nghbrId > -1 && a_isBndryCell(nghbrId)) {
22146 ghostCell = a_bndryGhostCellId(a_bndryId(nghbrId), 0);
22148 cerr <<
"distance " << i <<
" " << neighborDistance[i] <<
" neighbor " << nghbrId <<
" neighbor-ghost "
22149 << ghostCell <<
" " << a_hasProperty(nghbrId, SolverCell::IsSplitCell) << endl;
22155 for(
MInt i = 0; i < m_noDirs; i++) {
22157 MFloat minDistance = 99;
22158 for(
MInt dir = 0; dir < m_noDirs; dir++) {
22159 if(neighborDistance[dir] < minDistance) {
22160 minDistance = neighborDistance[dir];
22165 const MInt nghbrId = c_neighborId(cellId, minId);
22166 interpolationCells[count++] = nghbrId;
22169 if(cellId == debugId && domainId() == debugDomainId) {
22170 cerr <<
"Adding " << interpolationCells[count - 1] <<
" in dir " << minId <<
" s" << count << endl;
22174 if(count < stencilSize && a_isBndryCell(nghbrId) && a_bndryGhostCellId(a_bndryId(nghbrId), 0) > -1) {
22176 interpolationCells[count++] = a_bndryGhostCellId(a_bndryId(nghbrId), 0);
22179 if(cellId == debugId && domainId() == debugDomainId) {
22180 cerr <<
"Adding ghost-cell" << interpolationCells[count - 1] <<
" from dir " << minId <<
" s" << count
22185 neighborDistance[minId] = 99;
22187 if(count == stencilSize) {
22201template <MInt nDim_,
class SysEqn>
22205 MBool a0Computed, a1Computed;
22206 MInt noCVars = CV->noVariables;
22207 MFloat rightHandSide1, rightHandSide2;
22208 MFloat xy, xy0, xy1, xy2, y2y1, xy1xy0, xy2xy0;
22210 MFloat rhs1, rhs2, lhs2;
22211 MFloat x1term, x2term, y1term, y2term;
22213 MFloat coordinates[4 * nDim];
22214 MFloat epsilon = c_cellLengthAtLevel(maxRefinementLevel()) / 100.0;
22215 MFloat parameter[4] = {0, 0, 0, 0};
22220 a0Computed =
false;
22221 a1Computed =
false;
22224 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
22225 coordinates[spaceId] = a_coordinate(child, spaceId) - a_coordinate(cellId, spaceId);
22226 coordinates[nDim + spaceId] = a_coordinate(stencilCellIds[0], spaceId) - a_coordinate(cellId, spaceId);
22227 coordinates[2 * nDim + spaceId] = a_coordinate(stencilCellIds[1], spaceId) - a_coordinate(cellId, spaceId);
22228 coordinates[3 * nDim + spaceId] = a_coordinate(stencilCellIds[2], spaceId) - a_coordinate(cellId, spaceId);
22232 xy = coordinates[0] * coordinates[1];
22233 xy0 = coordinates[nDim] * coordinates[nDim + 1];
22234 xy1 = coordinates[2 * nDim] * coordinates[2 * nDim + 1];
22235 xy2 = coordinates[3 * nDim] * coordinates[3 * nDim + 1];
22237 for(
MInt varId = 0; varId < noCVars; varId++) {
22239 if(fabs(coordinates[nDim + 1]) < epsilon) {
22240 parameter[0] = (a_variable(stencilCellIds[0], varId) - a_variable(cellId, varId)) / coordinates[nDim];
22243 if(fabs(coordinates[2 * nDim + 1] - coordinates[3 * nDim + 1]) < epsilon) {
22244 parameter[0] = (a_variable(stencilCellIds[2], varId) - a_variable(stencilCellIds[1], varId))
22245 / (coordinates[3 * nDim] - coordinates[2 * nDim]);
22251 if(fabs(coordinates[2 * nDim]) < epsilon) {
22252 parameter[1] = (a_variable(stencilCellIds[1], varId) - a_variable(cellId, varId)) / coordinates[2 * nDim + 1];
22255 if(fabs(coordinates[nDim] - coordinates[3 * nDim]) < epsilon) {
22256 parameter[1] = (a_variable(stencilCellIds[2], varId) - a_variable(stencilCellIds[0], varId))
22257 / (coordinates[3 * nDim + 1] - coordinates[nDim + 1]);
22263 parameter[3] = a_variable(cellId, varId);
22266 if(a0Computed && a1Computed) {
22267 parameter[2] = (a_variable(stencilCellIds[2], varId) - parameter[3] - parameter[0] * coordinates[3 * nDim]
22268 - parameter[1] * coordinates[3 * nDim + 1])
22273 rightHandSide1 = a_variable(stencilCellIds[1], varId) - parameter[3] - parameter[0] * coordinates[2 * nDim];
22274 rightHandSide2 = a_variable(stencilCellIds[2], varId) - parameter[3] - parameter[0] * coordinates[3 * nDim];
22275 ratio = coordinates[3 * nDim + 1] / coordinates[2 * nDim + 1];
22277 parameter[2] = (rightHandSide2 - ratio * rightHandSide1) / (xy2 - ratio * xy1);
22278 parameter[1] = (rightHandSide1 - xy1 * parameter[2]) / coordinates[2 * nDim + 1];
22282 rightHandSide1 = a_variable(stencilCellIds[0], varId) - parameter[3] - parameter[1] * coordinates[nDim + 1];
22284 a_variable(stencilCellIds[2], varId) - parameter[3] - parameter[1] * coordinates[3 * nDim + 1];
22285 ratio = coordinates[3 * nDim] / coordinates[nDim];
22287 parameter[2] = (rightHandSide2 - ratio * rightHandSide1) / (xy2 - ratio * xy0);
22288 parameter[0] = (rightHandSide1 - xy0 * parameter[2]) / coordinates[nDim];
22295 xy1xy0 = xy1 / xy0;
22296 xy2xy0 = xy2 / xy0;
22297 x1term = coordinates[2 * nDim] - xy1xy0 * coordinates[nDim];
22298 x2term = coordinates[3 * nDim] - xy2xy0 * coordinates[nDim];
22299 y1term = coordinates[2 * nDim + 1] - xy1xy0 * coordinates[nDim + 1];
22300 y2term = coordinates[3 * nDim + 1] - xy2xy0 * coordinates[nDim + 1];
22301 y2y1 = y2term / y1term;
22303 parameter[3] = a_variable(cellId, varId);
22304 r0 = a_variable(stencilCellIds[0], varId) - parameter[3];
22305 r1 = a_variable(stencilCellIds[1], varId) - parameter[3];
22306 r2 = a_variable(stencilCellIds[2], varId) - parameter[3];
22309 rhs2 = r2 - xy2xy0 * r0 - y2y1 * (r1 - xy1xy0 * r0);
22310 rhs1 = r1 - xy1xy0 * r0;
22311 lhs2 = x2term - y2y1 * (x1term);
22314 parameter[0] = rhs2 / lhs2;
22315 parameter[1] = (rhs1 - x1term * parameter[0]) / y1term;
22316 parameter[2] = (r0 - coordinates[nDim] * parameter[0] - coordinates[nDim + 1] * parameter[1]) / xy0;
22323 a_variable(child, varId) =
22324 parameter[0] * coordinates[0] + parameter[1] * coordinates[1] + parameter[2] * xy + parameter[3];
22335template <MInt nDim_,
class SysEqn>
22339 MInt noCVars = CV->noVariables;
22340 MFloat coordinates[3 * nDim];
22345 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
22346 coordinates[spaceId] = a_coordinate(child, spaceId) - a_coordinate(cellId, spaceId);
22347 coordinates[nDim + spaceId] = a_coordinate(stencilCellIds[0], spaceId) - a_coordinate(cellId, spaceId);
22348 coordinates[2 * nDim + spaceId] = a_coordinate(stencilCellIds[1], spaceId) - a_coordinate(cellId, spaceId);
22352 for(
MInt varId = 0; varId < noCVars; varId++) {
22353 parameter[2] = a_variable(cellId, varId);
22355 if(
approx(coordinates[2 * nDim], 0.0, MFloatEps)) {
22356 parameter[1] = (a_variable(stencilCellIds[1], varId) - a_variable(cellId, varId)) / coordinates[2 * nDim + 1];
22358 ratio = coordinates[2 * nDim] / coordinates[nDim];
22359 parameter[1] = (parameter[2] * (ratio - 1.) + a_variable(stencilCellIds[1], varId)
22360 - a_variable(stencilCellIds[0], varId) * ratio)
22361 / (coordinates[2 * nDim + 1] - coordinates[nDim + 1] * ratio);
22364 if(
approx(coordinates[nDim + 1], 0.0, MFloatEps)) {
22365 parameter[0] = (a_variable(stencilCellIds[0], varId) - a_variable(cellId, varId)) / coordinates[nDim];
22367 parameter[0] = (a_variable(stencilCellIds[0], varId) - parameter[2] - parameter[1] * coordinates[nDim + 1])
22368 / coordinates[nDim];
22371 a_variable(child, varId) = parameter[0] * coordinates[0] + parameter[1] * coordinates[1] + parameter[2];
22386template <MInt nDim_,
class SysEqn>
22390 const MInt noCellIds = a_noCells();
22391 const MInt noCVars = CV->noVariables;
22392 mTerm(1,
"code does not work, see comment below");
22394 for(
MInt cellId = 0; cellId < noCellIds; cellId++) {
22395 for(
MInt varId = 0; varId < noCVars; varId++) {
22396 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22397 a_variable(cellId, varId) -=
22398 a_restrictedVar(cellId, varId);
22400 a_tau(cellId, varId) = 0;
22405template <MInt nDim_,
class SysEqn>
22409 m_fvBndryCnd->copyRHSIntoGhostCells();
22422template <MInt nDim_,
class SysEqn>
22426 this->identifyBoundaryCells();
22428 ASSERT(c_noCells() == a_noCells() && a_noCells() == grid().tree().size(),
22429 to_string(c_noCells()) +
" " + to_string(a_noCells()) +
" " + to_string(grid().tree().size()) +
" "
22430 + to_string(m_cells.size()));
22435 if(m_levelSetMb && !m_constructGField) {
22436 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
22437 assertValidGridCellId(cellId);
22438 if(a_isInterface(cellId)) {
22439 if(c_isLeafCell(cellId) && a_hasProperty(cellId, SolverCell::IsInactive)) {
22440 a_isInterface(cellId) =
false;
22441 }
else if(!c_isLeafCell(cellId)) {
22442 a_isInterface(cellId) =
false;
22454template <MInt nDim_,
class SysEqn>
22458 const MInt noSrfcs = a_noSurfaces();
22459 MInt nghbrCells[2];
22460 MFloat eps = F1 / FPOW10[10];
22461 MFloat totalDistance, distance;
22462 MFloat factor0, factor1;
22467 for(
MInt srfcId = 0; srfcId < noSrfcs; srfcId++) {
22468 nghbrCells[0] = a_surfaceNghbrCellId(srfcId, 0);
22469 nghbrCells[1] = a_surfaceNghbrCellId(srfcId, 1);
22471 totalDistance = F0;
22472 for(
MInt i = 0; i < nDim; i++) {
22473 distance +=
POW2(a_surfaceCoordinate(srfcId, i) - a_coordinate(nghbrCells[0], i));
22474 totalDistance +=
POW2(a_surfaceCoordinate(srfcId, i) - a_coordinate(nghbrCells[1], i));
22476 distance = sqrt(distance);
22477 totalDistance = sqrt(totalDistance) + distance;
22478 factor1 = distance /
mMax(eps, totalDistance);
22479 factor0 = F1 - factor1;
22480 a_surfaceFactor(srfcId, 0) = factor0;
22481 a_surfaceFactor(srfcId, 1) = factor1;
22484 if(!m_fvBndryCnd->m_cellMerging) {
22486#pragma omp parallel for
22488 for(
MInt bs = 0; bs < m_fvBndryCnd->m_noBoundarySurfaces; bs++) {
22489 MInt srfcId = m_fvBndryCnd->m_boundarySurfaces[bs];
22490 a_surfaceFactor(srfcId, 0) = F1B2;
22491 a_surfaceFactor(srfcId, 1) = F1B2;
22501template <MInt nDim_,
class SysEqn>
22503 static constexpr MFloat signStencil[8][3] = {{-F1, -F1, -F1}, {F1, -F1, -F1}, {-F1, F1, -F1}, {F1, F1, -F1},
22504 {-F1, -F1, F1}, {F1, -F1, F1}, {-F1, F1, F1}, {F1, F1, F1}};
22506 if(!
g_multiSolverGrid) ASSERT(grid().raw().a_hasProperty(gridCellId, Cell::WasRefined),
"");
22508 const MInt noCVars = CV->noVariables;
22509 const MInt noFVars = FV->noVariables;
22510 const MInt noPVars = PV->noVariables;
22511 const MInt childLevel = grid().raw().a_level(gridCellId) + 1;
22512 const MFloat childCellLength = c_cellLengthAtLevel(childLevel);
22513 const MFloat childVolume = grid().cellVolumeAtLevel(childLevel);
22515 const MInt solverCellId = grid().tree().grid2solver(gridCellId);
22517 const MFloat*
const pvarsCell = ALIGNED_F(&a_pvariable(solverCellId, 0));
22518 const MFloat*
const cvarsCell = ALIGNED_F(&a_variable(solverCellId, 0));
22519 const MFloat*
const avarsCell = ALIGNED_F(&a_avariable(solverCellId, 0));
22520 const MFloat*
const slopesCell = ALIGNED_F(&a_slope(solverCellId, 0, 0));
22523 if(solverCellId < 0)
return;
22525 MInt noAddedChilds = 0;
22527 for(
MInt c = 0; c < grid().m_maxNoChilds; c++) {
22528 const MInt gridChildId = grid().raw().a_childId(gridCellId, c);
22530 if(gridChildId < 0)
continue;
22533 if(grid().azimuthalPeriodicity()) {
22537 if(grid().checkOutsideGeometry(gridChildId) == 1) {
22538 grid().raw().setSolver(gridChildId, solverId(),
false);
22545 if(!grid().solverFlag(gridChildId, solverId()))
continue;
22548 if(!grid().raw().a_hasProperty(gridChildId, Cell::WasNewlyCreated)
22549 && grid().raw().a_hasProperty(gridCellId, Cell::IsPartLvlAncestor)) {
22553 MInt solverChildId = this->createCellId(gridChildId);
22556 ASSERT(grid().tree().solver2grid(solverChildId) == gridChildId,
" ");
22559 std::vector<std::vector<MFloat>> dQ(PV->noVariables, std::vector<MFloat>(nDim));
22561 for(
MInt i = 0; i < nDim; i++) {
22562 U2 +=
POW2(a_pvariable(solverCellId, PV->VV[i]));
22565 dQ = sysEqn().conservativeSlopes(pvarsCell, cvarsCell, avarsCell, slopesCell);
22567 for(
MInt v = 0; v < noCVars; v++) {
22568 for(
MInt i = 0; i < nDim; i++) {
22569 dQ[v][i] *= F1B2 * childCellLength;
22570 if(std::isnan(dQ[v][i])) {
22575 for(
MInt v = 0; v < noCVars; v++) {
22576 a_variable(solverChildId, v) = a_variable(solverCellId, v);
22578 for(
MInt i = 0; i < nDim; i++) {
22579 ASSERT(!std::isnan(dQ[v][i]),
"");
22580 a_variable(solverChildId, v) += signStencil[c][i] * dQ[v][i];
22585 IF_CONSTEXPR(isDetChem<SysEqn>) {
22586 for(
MUint v = 0; v < PV->m_noSpecies; v++) {
22587 a_speciesReactionRate(solverChildId, v) = a_speciesReactionRate(solverCellId, v);
22592 for(
MInt s = 0; s < m_noSpecies; s++) {
22593 a_variable(solverChildId, CV->RHO_Y[s]) = a_variable(solverCellId, CV->RHO_Y[s]);
22597 for(
MInt v = 0; v < noCVars; v++) {
22598 a_oldVariable(solverChildId, v) = a_variable(solverChildId, v);
22600 for(
MInt v = 0; v < noFVars; v++) {
22601 a_rightHandSide(solverChildId, v) =
FFPOW2(nDim) * a_rightHandSide(solverCellId, v);
22603 for(
MInt v = 0; v < noPVars; v++) {
22604 for(
MInt i = 0; i < nDim; i++) {
22605 a_slope(solverChildId, v, i) = a_slope(solverCellId, v, i);
22610 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) {
22612 vector<MInt>::iterator findAverageId = find(m_LESAverageCells.begin(), m_LESAverageCells.end(), solverCellId);
22613 vector<MInt>::iterator findAverageChildId =
22614 find(m_LESAverageCells.begin(), m_LESAverageCells.end(), solverChildId);
22616 if(findAverageId != m_LESAverageCells.end() && !a_isHalo(solverChildId)) {
22617 if(findAverageChildId == m_LESAverageCells.end() && !a_isHalo(solverChildId)) {
22618 MInt LESAvgId = distance(m_LESAverageCells.begin(), findAverageId);
22619 for(
MInt v = 0; v < m_LESNoVarAverage; v++) {
22620 m_LESVarAverage[v].push_back(m_LESVarAverage[v][LESAvgId]);
22622 m_LESAverageCells.push_back(solverChildId);
22628 setPrimitiveVariables(solverChildId);
22630 a_bndryId(solverChildId) = -1;
22632 a_cellVolume(solverChildId) = childVolume;
22633 a_FcellVolume(solverChildId) = F1 / childVolume;
22635 a_noReconstructionNeighbors(solverChildId) = 0;
22636 for(
MInt k = 0; k < m_cells.noRecNghbrs(); k++) {
22637 a_reconstructionNeighborId(solverChildId, k) = -1;
22641#if defined _MB_DEBUG_ || !defined NDEBUG
22642 for(
MInt v = 0; v < noPVars; v++) {
22643 if(std::isnan(a_pvariable(solverChildId, v)) && a_hasProperty(solverCellId, SolverCell::IsOnCurrentMGLevel)
22644 && !a_isHalo(solverCellId)) {
22645 cerr <<
"Invalid-value in refined-Cell! "
22646 <<
" " << solverChildId <<
" " << endl;
22649 if(a_hasProperty(solverCellId, SolverCell::IsOnCurrentMGLevel) && !a_isHalo(solverCellId)
22650 && a_variable(solverChildId, CV->RHO) < m_eps) {
22651 cerr <<
"rho is zero or negative-2!" << endl;
22659 a_hasProperty(solverChildId, SolverCell::IsOnCurrentMGLevel) =
22660 a_hasProperty(solverCellId, SolverCell::IsOnCurrentMGLevel);
22661 a_hasProperty(solverChildId, SolverCell::IsInactive) = a_hasProperty(solverCellId, SolverCell::IsInactive);
22664 a_noReconstructionNeighbors(solverCellId) = 0;
22665 for(
MInt k = 0; k < m_cells.noRecNghbrs(); k++) {
22666 a_reconstructionNeighborId(solverCellId, k) = -1;
22669 if(m_sensorParticle && !a_isHalo(solverCellId) && noAddedChilds > 0) {
22670 const MInt noParticles = a_noPart(solverCellId);
22672 MInt noParticlesEach = noParticles / noAddedChilds;
22673 MInt lastChild = -1;
22674 for(
MInt child = 0; child < grid().m_maxNoChilds; child++) {
22675 const MInt childId = c_childId(solverCellId, child);
22676 if(childId < 0)
continue;
22677 a_noPart(childId) = noParticles > 0 ? noParticlesEach : 0;
22680 MInt remainingParticles = noParticles - ((c_noChildren(solverCellId) - 1) * noParticlesEach);
22681 if(lastChild > -1) {
22682 a_noPart(c_childId(solverCellId, lastChild)) = noParticles > 0 ? remainingParticles : 0;
22685 if(noAddedChilds > 0) {
22686 a_noPart(solverCellId) = 0;
22690 if(noAddedChilds > 0) {
22691 a_hasProperty(solverCellId, SolverCell::IsOnCurrentMGLevel) =
false;
22702template <MInt nDim_,
class SysEqn>
22704 const MInt solverCellId = grid().tree().grid2solver(gridCellId);
22706 ASSERT(solverCellId > -1 && solverCellId < m_cells.size(),
"");
22707 ASSERT(c_noChildren(solverCellId) > 0,
"");
22710 if(!
g_multiSolverGrid) ASSERT(m_cells.size() == grid().raw().treeb().size(),
"");
22718 const MInt noCVars = CV->noVariables;
22719 const MInt noFVars = FV->noVariables;
22720 const MInt noPVars = PV->noVariables;
22721 a_cellVolume(solverCellId) = F0;
22723 for(
MInt v = 0; v < noCVars; v++) {
22724 a_variable(solverCellId, v) = F0;
22725 if(!m_levelSetMb) {
22726 a_oldVariable(solverCellId, v) = F0;
22728 for(
MInt i = 0; i < nDim; i++) {
22729 a_slope(solverCellId, v, i) = F0;
22732 for(
MInt v = 0; v < noFVars; v++) {
22733 a_rightHandSide(solverCellId, v) = F0;
22736 MInt isInactive = 0;
22737 MInt noRemovedChilds = 0;
22738 MInt noParticles = 0;
22740 for(
MInt c = 0; c < grid().m_maxNoChilds; c++) {
22741 const MInt gridChildId = grid().raw().a_childId(gridCellId, c);
22742 const MInt childId = c_childId(solverCellId, c);
22744 if(childId < 0)
continue;
22746 if(m_sensorParticle) noParticles += a_noPart(childId);
22748 ASSERT(grid().tree().solver2grid(childId) == gridChildId,
"");
22751 if(!a_hasProperty(childId, SolverCell::IsInactive)) {
22752 const MFloat vol = a_cellVolume(childId);
22753 a_cellVolume(solverCellId) += vol;
22754 for(
MInt v = 0; v < noCVars; v++) {
22755 a_variable(solverCellId, v) += vol * a_variable(childId, v);
22756 if(!m_levelSetMb) {
22757 a_oldVariable(solverCellId, v) += vol * a_oldVariable(childId, v);
22760 for(
MInt v = 0; v < noFVars; v++) {
22761 a_rightHandSide(solverCellId, v) += a_rightHandSide(childId, v);
22763 for(
MInt v = 0; v < noPVars; v++) {
22764 for(
MInt j = 0; j < nDim; j++) {
22765 a_slope(solverCellId, v, j) += vol * a_slope(childId, v, j);
22770 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) {
22772 vector<MInt>::iterator findAverageChildId =
22773 find(m_LESAverageCells.begin(), m_LESAverageCells.end(), solverCellId);
22774 if(findAverageChildId != m_LESAverageCells.end()) {
22775 MInt LESChildId = distance(m_LESAverageCells.begin(), findAverageChildId);
22776 for(
MInt v = 0; v < m_LESNoVarAverage; v++) {
22777 m_LESVarAverage[v].erase(m_LESVarAverage[v].begin() + LESChildId);
22779 m_LESAverageCells.erase(m_LESAverageCells.begin() + LESChildId);
22789 a_bndryId(childId) = -1;
22790 this->removeCellId(childId);
22793 if(m_sensorParticle) a_noPart(solverCellId) = noParticles;
22796 if(isInactive == noRemovedChilds) {
22798 a_hasProperty(solverCellId, SolverCell::IsInactive) =
true;
22799 a_hasProperty(solverCellId, SolverCell::IsOnCurrentMGLevel) =
false;
22800 a_cellVolume(solverCellId) = c_cellVolumeAtLevel(a_level(solverCellId));
22802 a_variable(solverCellId, CV->RHO) = m_rhoInfinity;
22803 IF_CONSTEXPR(hasE<SysEqn>)
22804 a_variable(solverCellId, CV->RHO_E) = m_rhoEInfinity;
22805 for(
MInt dir = 0; dir < nDim; dir++) {
22806 a_variable(solverCellId, CV->RHO_VV[dir]) = m_rhoVVInfinity[dir];
22809 if(!a_isHalo(solverCellId)) {
22810 ASSERT(a_variable(solverCellId, CV->RHO) > 0,
"Zero density when removing childs!");
22812 for(
MInt v = 0; v < noCVars; v++) {
22813 a_variable(solverCellId, v) /=
mMax(m_volumeThreshold, a_cellVolume(solverCellId));
22814 if(!m_levelSetMb) {
22815 a_oldVariable(solverCellId, v) /=
mMax(m_volumeThreshold, a_cellVolume(solverCellId));
22818 for(
MInt v = 0; v < noPVars; v++) {
22819 for(
MInt i = 0; i < nDim; i++) {
22820 a_slope(solverCellId, v, i) /=
mMax(m_volumeThreshold, a_cellVolume(solverCellId));
22823 a_hasProperty(solverCellId, SolverCell::IsOnCurrentMGLevel) =
true;
22824 a_hasProperty(solverCellId, SolverCell::IsInactive) =
false;
22827 a_FcellVolume(solverCellId) = F1 /
mMax(m_volumeThreshold, a_cellVolume(solverCellId));
22828 setPrimitiveVariables(solverCellId);
22831 if(!
g_multiSolverGrid) ASSERT((m_cells.size() - grid().raw().treeb().size()) <= grid().m_maxNoChilds,
"");
22838template <MInt nDim_,
class SysEqn>
22840 const MInt solverCellId = grid().tree().grid2solver(gridCellId);
22842 ASSERT(gridCellId > -1 && gridCellId < grid().raw().treeb().size() && solverCellId > -1
22843 && solverCellId < m_cells.size() && grid().tree().solver2grid(solverCellId) == gridCellId,
22845 ASSERT(c_noChildren(solverCellId) == 0,
"");
22847 this->removeCellId(solverCellId);
22856template <MInt nDim_,
class SysEqn>
22858 if(cellId1 == cellId0)
return;
22860 const MInt noCVars = CV->noVariables;
22861 const MInt noFVars = FV->noVariables;
22862 const MInt noPVars = PV->noVariables;
22863 const MInt noAVars = AV->noVariables;
22864 for(
MInt v = 0; v < noCVars; v++) {
22865 std::swap(a_variable(cellId1, v), a_variable(cellId0, v));
22866 std::swap(a_oldVariable(cellId1, v), a_oldVariable(cellId0, v));
22867 if(m_dualTimeStepping) {
22868 std::swap(a_dt1Variable(cellId1, v), a_dt1Variable(cellId0, v));
22869 std::swap(a_dt2Variable(cellId1, v), a_dt2Variable(cellId0, v));
22872 for(
MInt v = 0; v < noFVars; v++) {
22873 std::swap(a_rightHandSide(cellId1, v), a_rightHandSide(cellId0, v));
22875 for(
MInt v = 0; v < noPVars; v++) {
22876 std::swap(a_pvariable(cellId1, v), a_pvariable(cellId0, v));
22877 for(
MInt i = 0; i < nDim; i++) {
22878 std::swap(a_slope(cellId1, v, i), a_slope(cellId0, v, i));
22883 for(
MInt v = 0; v < noAVars; v++) {
22884 std::swap(a_avariable(cellId1, v), a_avariable(cellId0, v));
22888 std::swap(a_cellVolume(cellId1), a_cellVolume(cellId0));
22889 std::swap(a_FcellVolume(cellId1), a_FcellVolume(cellId0));
22891 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) {
22893 vector<MInt>::iterator findId0 = find(m_LESAverageCells.begin(), m_LESAverageCells.end(), cellId0);
22894 vector<MInt>::iterator findId1 = find(m_LESAverageCells.begin(), m_LESAverageCells.end(), cellId1);
22896 if(findId0 != m_LESAverageCells.end() && findId1 != m_LESAverageCells.end()) {
22897 MInt LESId0 = distance(m_LESAverageCells.begin(), findId0);
22898 MInt LESId1 = distance(m_LESAverageCells.begin(), findId1);
22899 for(
MInt v = 0; v < m_LESNoVarAverage; v++) {
22900 std::swap(m_LESVarAverage[v][LESId0], m_LESVarAverage[v][LESId1]);
22902 std::swap(m_LESAverageCells[LESId0], m_LESAverageCells[LESId1]);
22903 }
else if(findId0 != m_LESAverageCells.end() && findId1 == m_LESAverageCells.end()) {
22904 MInt LESId0 = distance(m_LESAverageCells.begin(), findId0);
22905 m_LESAverageCells[LESId0] = cellId1;
22906 }
else if(findId0 == m_LESAverageCells.end() && findId1 != m_LESAverageCells.end()) {
22907 MInt LESId1 = distance(m_LESAverageCells.begin(), findId1);
22908 m_LESAverageCells[LESId1] = cellId0;
22913 std::swap(a_spongeFactor(cellId1), a_spongeFactor(cellId0));
22914 std::swap(a_spongeBndryId(cellId1, 0), a_spongeBndryId(cellId0, 0));
22915 std::swap(a_spongeBndryId(cellId1, 1), a_spongeBndryId(cellId0, 1));
22916 IF_CONSTEXPR(nDim == 3) { std::swap(a_spongeBndryId(cellId1, 2), a_spongeBndryId(cellId0, 2)); }
22918 const MInt bndryId0 = a_bndryId(cellId0);
22919 const MInt bndryId1 = a_bndryId(cellId1);
22920 if(bndryId0 > -1) {
22921 ASSERT(m_fvBndryCnd->m_bndryCells->a[bndryId0].m_cellId == cellId0,
"bndryId not expected");
22922 m_fvBndryCnd->m_bndryCells->a[bndryId0].m_cellId = cellId1;
22924 if(bndryId1 > -1) {
22925 ASSERT(m_fvBndryCnd->m_bndryCells->a[bndryId1].m_cellId == cellId1,
"bndryId not expected");
22926 m_fvBndryCnd->m_bndryCells->a[bndryId1].m_cellId = cellId0;
22928 std::swap(a_bndryId(cellId1), a_bndryId(cellId0));
22930 std::swap(m_cells.properties(cellId1), m_cells.properties(cellId0));
22932 if(m_sensorParticle) {
22933 std::swap(a_noPart(cellId1), a_noPart(cellId0));
22944template <MInt nDim_,
class SysEqn>
22946 grid().swapGridIds(cellId0, cellId1);
22956template <MInt nDim_,
class SysEqn>
22958 grid().resizeGridMap(m_cells.size());
22968template <MInt nDim_,
class SysEqn>
22970 return m_fvBndryCnd->checkOutside(cellId);
22980template <MInt nDim_,
class SysEqn>
22982 if(m_engineSetup) {
22986 MInt solverCellId = grid().tree().grid2solver(gridCellId);
22987 if(!grid().raw().m_allowInterfaceRefinement)
return 0;
22988 if(!a_isInterface(solverCellId))
return 0;
22989 return m_fvBndryCnd->checkOutside(coords, level);
22999template <MInt nDim_,
class SysEqn>
23001 m_surfaces.clear();
23002 m_fvBndryCnd->m_noBoundarySurfaces = 0;
23003 std::set<MInt>().swap(m_splitSurfaces);
23013template <MInt nDim_,
class SysEqn>
23016 const MInt noPVars = PV->noVariables;
23018 if(m_fvBndryCnd->m_cellCoordinatesCorrected) {
23019 m_fvBndryCnd->recorrectCellCoordinates();
23023#pragma omp parallel for
23025 for(
MInt bndryId = 0; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
23026 for(
MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
23027 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId = -1;
23028 for(
MInt i = 0; i < nDim; i++) {
23029 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = -1;
23034 m_bndryGhostCellsOffset = c_noCells();
23037#pragma omp parallel for
23039 for(
MInt c = m_bndryGhostCellsOffset; c < a_noCells(); c++) {
23041 a_isBndryGhostCell(c) =
false;
23042 a_resetPropertiesSolver(c);
23047#pragma omp parallel for
23049 for(
MInt c = 0; c < a_noCells(); c++) {
23050 a_hasProperty(c, SolverCell::IsInvalid) =
false;
23051 a_hasProperty(c, SolverCell::IsSplitCell) =
false;
23052 a_hasProperty(c, SolverCell::IsSplitChild) =
false;
23053 a_hasProperty(c, SolverCell::HasSplitFace) =
false;
23054 a_hasProperty(c, SolverCell::IsTempLinked) =
false;
23055 a_hasProperty(c, SolverCell::IsMovingBnd) =
false;
23059 m_cells.size(m_bndryGhostCellsOffset);
23060 ASSERT(m_cells.size() == c_noCells(),
"");
23064 for(
MInt bndryId = m_fvBndryCnd->m_bndryCells->size() - 1; bndryId >= offset; bndryId--) {
23065 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
23067 for(
MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
23068 MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
23069 if(ghostCellId > -1) {
23070 ASSERT(a_bndryId(ghostCellId) == -2,
"");
23071 a_bndryId(ghostCellId) = -1;
23073 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId = -1;
23076 a_bndryId(cellId) = -1;
23078 MInt size = m_fvBndryCnd->m_bndryCells->size();
23079 m_fvBndryCnd->m_bndryCells->resetSize(size - 1);
23083 if(cellId < m_bndryGhostCellsOffset) {
23084 a_noReconstructionNeighbors(cellId) = 0;
23086 m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.resize(0);
23087 m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst.resize(0);
23088 std::vector<MFloat>().swap(m_fvBndryCnd->m_bndryCell[bndryId].m_faceVertices);
23089 for(
MUint i = 0; i < m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream.size(); i++) {
23090 m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream[i].resize(0);
23092 m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream.resize(0);
23093 for(
MInt srfc = 0; srfc < FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces; srfc++) {
23094 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_noCutPoints = 0;
23095 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.resize(0);
23098 for(
MInt v = 0; v < noPVars; v++) {
23099 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] =
BC_UNSET;
23102 m_bndryCells->a[bndryId].m_noSrfcs = 0;
23104 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > -1) {
23105 MInt pm = m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId;
23106 a_cellVolume(pm) = grid().cellVolumeAtLevel(a_level(pm));
23107 a_FcellVolume(pm) = F1 /
mMax(m_volumeThreshold, a_cellVolume(pm));
23108 m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId = -1;
23111 m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId = -1;
23115 std::vector<MInt>().swap(m_splitCells);
23116 std::vector<std::vector<MInt>>().swap(m_splitChilds);
23117 std::map<MInt, MInt>().swap(m_splitChildToSplitCell);
23118 std::vector<MInt>().swap(m_associatedInternalCells);
23120 m_totalnosplitchilds = 0;
23121 m_totalnoghostcells = 0;
23134template <MInt nDim_,
class SysEqn>
23136 if(noNeighborDomains() == 0) {
23137 if(noDomains() > 1) {
23138 mTerm(1,
"Unexpected situation in updateMultiSolverInformation!");
23145 if(!m_fvBndryCnd->m_cellMerging) {
23146 mDeallocate(m_fvBndryCnd->m_nearBoundaryWindowCells);
23147 mDeallocate(m_fvBndryCnd->m_nearBoundaryHaloCells);
23148 mAlloc(m_fvBndryCnd->m_nearBoundaryWindowCells, noNeighborDomains(),
"m_nearBoundaryWindowCells", AT_);
23149 mAlloc(m_fvBndryCnd->m_nearBoundaryHaloCells, noNeighborDomains(),
"m_nearBoundaryHaloCells", AT_);
23152 mAlloc(m_mpi_request, noNeighborDomains(),
"m_mpi_request", AT_);
23153 if(m_nonBlockingComm) {
23156 mAlloc(m_mpi_receiveRequest, noNeighborDomains(),
"m_mpi_receiveRequest ", MPI_REQ_NULL, AT_);
23157 mAlloc(m_mpi_sendRequest, noNeighborDomains(),
"m_mpi_sendRequest", MPI_REQ_NULL, AT_);
23164 for(
MInt d = 0; d < noNeighborDomains(); d++) {
23165 haloCellsCnt[d] = noHaloCells(d);
23166 windowCellsCnt[d] = noWindowCells(d);
23172 mAlloc(m_maxLevelHaloCells, noNeighborDomains(), &haloCellsCnt[0],
"m_maxLevelHaloCells", AT_);
23173 mAlloc(m_maxLevelWindowCells, noNeighborDomains(), &windowCellsCnt[0],
"m_maxLevelWindowCells", AT_);
23174 mAlloc(m_noMaxLevelHaloCells, noNeighborDomains(),
"m_noMaxLevelHaloCells", 0, AT_);
23175 mAlloc(m_noMaxLevelWindowCells, noNeighborDomains(),
"m_noMaxLevelWindowCells", 0, AT_);
23179 mAlloc(m_sendBuffers, noNeighborDomains(), &windowCellsCnt[0], m_dataBlockSize,
"m_sendBuffers", AT_);
23180 mAlloc(m_receiveBuffers, noNeighborDomains(), &haloCellsCnt[0], m_dataBlockSize,
"m_receiveBuffers", AT_);
23182 if(m_nonBlockingComm) {
23185 mAlloc(m_sendBuffersNoBlocking, noNeighborDomains(), &windowCellsCnt[0], m_dataBlockSize,
"m_sendBuffersNoBlocking",
23187 mAlloc(m_receiveBuffersNoBlocking, noNeighborDomains(), &haloCellsCnt[0], m_dataBlockSize,
23188 "m_receiveBuffersNoBlocking", AT_);
23189 for(
MInt i = 0; i < noNeighborDomains(); i++) {
23190 m_mpi_receiveRequest[i] = MPI_REQUEST_NULL;
23191 m_mpi_sendRequest[i] = MPI_REQUEST_NULL;
23203template <MInt nDim_,
class SysEqn>
23205 std::vector<std::bitset<64>>& sensorCellFlag,
23206 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
23210 if(m_levelSet && !m_levelSetMb && !m_combustion) {
23211 sensorInterfaceLs(sensors, sensorCellFlag, sensorWeight, sensorOffset, sen);
23212 }
else if(m_levelSetMb && !m_constructGField && m_levelSetAdaptationScheme == 2) {
23213 sensorInterfaceLsMb(sensors, sensorCellFlag, sensorWeight, sensorOffset, sen);
23215 sensorInterfaceDelta(sensors, sensorCellFlag, sensorWeight, sensorOffset, sen);
23219template <MInt nDim_,
class SysEqn>
23221 std::vector<std::bitset<64>>& sensorCellFlag,
23222 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
23224 m_log <<
" - Sensor preparation for the interface sensor" << endl;
23226 getBoundaryDistance(distance);
23231 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
23232 inList(cellId) = 0;
23233 if(a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) {
23234 inList(cellId) = (
MInt)distance(cellId);
23238 for(
MInt level = minLevel(); level < this->m_maxSensorRefinementLevel[sen]; level++) {
23239 this->markSurrndCells(inList, m_bandWidth[level], level, m_refineDiagonals);
23243 if(m_engineSetup) {
23244 const MInt linerSet = 1;
23245 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23246 if(inList(cellId) == 0)
continue;
23247 if(a_level(cellId) == minLevel())
continue;
23248 if(c_noChildren(cellId) > 0)
continue;
23249 if(a_levelSetValuesMb(cellId, linerSet) < -(m_maxLsValue - m_eps)) {
23250 inList(cellId) = 0;
23262#pragma omp parallel for
23264 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23265 ASSERT(!a_isBndryGhostCell(cellId),
"");
23266 ASSERT(!a_isHalo(cellId),
"");
23267 ASSERT(!c_isToDelete(cellId),
"");
23268 if(inList(cellId) == 0) {
23269 if(a_level(cellId) == minLevel())
continue;
23270 if(inList(c_parentId(cellId)))
continue;
23271 if(!c_isLeafCell(cellId))
continue;
23272 const MInt gridCellId = grid().tree().solver2grid(cellId);
23273 sensors[sensorOffset + sen][gridCellId] = -1.0;
23274 sensorCellFlag[gridCellId][sensorOffset + sen] =
true;
23276 MInt lvl = this->m_maxSensorRefinementLevel[sen] - 1;
23277 if(m_linerLvlJump && a_coordinate(cellId, 0) > -0.515 && a_coordinate(cellId, 0) < 0.515) {
23278 lvl = this->m_maxSensorRefinementLevel[sen];
23280 const MInt sensorLvl = m_linerLvlJump ? lvl : this->m_maxSensorRefinementLevel[sen];
23281 if(a_level(cellId) < sensorLvl) {
23283 const MInt gridCellId = grid().tree().solver2grid(cellId);
23284 sensors[sensorOffset + sen][gridCellId] = 1.0;
23285 sensorCellFlag[gridCellId][sensorOffset + sen] =
true;
23287 MInt parent = c_parentId(cellId);
23288 if(parent > -1 && parent < c_noCells()) {
23289 MInt parentGridCellId = grid().tree().solver2grid(parent);
23290 if(parentGridCellId > -1 && parentGridCellId < grid().raw().m_noInternalCells) {
23291 sensors[sensorOffset + sen][parentGridCellId] = 1.0;
23292 sensorCellFlag[parentGridCellId][sensorOffset + sen] =
true;
23299 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
23302template <MInt nDim_,
class SysEqn>
23304 std::vector<std::bitset<64>>& sensorCellFlag,
23305 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
23307 m_log <<
" - Sensor preparation for the interface sensor" << endl;
23310 distance.fill(MFloatNaN);
23312 getBoundaryDistance(distance);
23315#pragma omp parallel for
23317 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23318 ASSERT(!a_isBndryGhostCell(cellId),
"");
23319 ASSERT(!a_isHalo(cellId),
"");
23320 ASSERT(!c_isToDelete(cellId),
"");
23321 const MInt gridId = this->grid().tree().solver2grid(cellId);
23322 const MInt level = a_level(cellId);
23324 if(level < maxRefinementLevel()) {
23325 delta =
mMin(m_outerBandWidth[level] - distance[cellId], distance[cellId] - m_innerBandWidth[level]);
23326 sensors[sensorOffset + sen][gridId] = delta;
23327 sensorCellFlag[gridId][sensorOffset + sen] =
true;
23331 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
23335template <MInt nDim_,
class SysEqn>
23337 std::vector<std::bitset<64>>& sensorCellFlag,
23338 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
23340 m_log <<
" - Sensor preparation for the interface sensor" << endl;
23345 getBoundaryDistance(distance);
23348#pragma omp parallel for
23351 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
23352 inList(cellId) = 0;
23353 if(a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) {
23354 inList(cellId) = (
MInt)distance(cellId);
23358 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23359 if(inList(cellId) == 0) {
23360 if(a_level(cellId) == minLevel())
continue;
23361 if(c_noChildren(cellId) == 0) {
23362 MInt gridCellId = grid().tree().solver2grid(cellId);
23363 sensors[sensorOffset + sen][gridCellId] = -1.0;
23364 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
23367 ASSERT(inList(cellId) > 0,
"");
23368 MInt gridCellId = grid().tree().solver2grid(cellId);
23369 if(a_level(cellId) < maxRefinementLevel()) {
23370 if(c_noChildren(cellId) > 0)
continue;
23371 if(a_isHalo(cellId))
continue;
23372 sensors[sensorOffset + sen][gridCellId] = 1.0;
23373 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
23378 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
23388template <MInt nDim_,
class SysEqn>
23390 std::vector<std::bitset<64>>& sensorCellFlag,
23391 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
MInt sen) {
23393 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
23394 cutOffCells(cellId) = 0;
23397 m_fvBndryCnd->markCutOff(cutOffCells);
23399 MIntScratchSpace bandWidth(this->m_maxSensorRefinementLevel[sen], AT_,
"bandWidth");
23400 constexpr MInt additionalLayers = 1;
23402 bandWidth[this->m_maxSensorRefinementLevel[sen] - 1] =
23403 m_bandWidth[this->m_maxSensorRefinementLevel[sen] - 1] + additionalLayers;
23406 for(
MInt i = this->m_maxSensorRefinementLevel[sen] - 2; i >= 0; i--) {
23407 bandWidth[i] = (bandWidth[i + 1] / 2) + 1;
23410 for(
MInt level = minLevel(); level < this->m_maxSensorRefinementLevel[sen]; level++) {
23411 this->markSurrndCells(cutOffCells, bandWidth[level], level, m_refineDiagonals);
23415#pragma omp parallel for
23417 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23418 ASSERT(!a_isBndryGhostCell(cellId),
"");
23419 ASSERT(!a_isHalo(cellId),
"");
23420 ASSERT(!c_isToDelete(cellId),
"");
23421 const MInt gridCellId = grid().tree().solver2grid(cellId);
23422 if(cutOffCells(cellId) > 0) {
23423 if(a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) {
23424 sensors[sensorOffset + sen][gridCellId] = 1.0;
23425 sensorCellFlag[gridCellId][sensorOffset + sen] =
true;
23426 MInt parent = c_parentId(cellId);
23427 if(parent > -1 && parent < a_noCells()) {
23428 MInt parentGridCellId = grid().tree().solver2grid(parent);
23429 if(parentGridCellId > -1 && parentGridCellId < grid().raw().m_noInternalCells) {
23430 sensors[sensorOffset + sen][parentGridCellId] = 1.0;
23431 sensorCellFlag[parentGridCellId][sensorOffset + sen] =
true;
23436 sensors[sensorOffset + sen][gridCellId] = 0.0;
23437 sensorCellFlag[gridCellId][sensorOffset + sen] =
false;
23441 if(m_engineSetup) {
23447 xmin = Context::getSolverProperty<MFloat>(
"cutOffCoordinates", m_solverId, AT_, 0);
23449 if(noCutOffBndryIds > 1) {
23450 xmax = Context::getSolverProperty<MFloat>(
"cutOffCoordinates", m_solverId, AT_, 6);
23453 const MFloat dist1 = 0.15;
23454 const MFloat dist2 = 0.25;
23456 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23457 if(a_coordinate(cellId, 0) < (xmin + dist1) && a_levelSetValuesMb(cellId, 0) > -m_maxLsValue
23458 && a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) {
23459 const MInt gridCellId = grid().tree().solver2grid(cellId);
23460 sensors[sensorOffset + sen][gridCellId] = 1.0;
23461 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
23464 if(a_coordinate(cellId, 0) > (xmax - dist1) && a_levelSetValuesMb(cellId, 0) > -m_maxLsValue
23465 && a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) {
23466 const MInt gridCellId = grid().tree().solver2grid(cellId);
23467 sensors[sensorOffset + sen][gridCellId] = 1.0;
23468 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
23471 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23472 if(a_coordinate(cellId, 0) < (xmin + dist2) && a_levelSetValuesMb(cellId, 0) > -m_maxLsValue
23473 && a_level(cellId) < this->m_maxSensorRefinementLevel[sen] - 1) {
23474 const MInt gridCellId = grid().tree().solver2grid(cellId);
23475 sensors[sensorOffset + sen][gridCellId] = 1.0;
23476 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
23479 if(a_coordinate(cellId, 0) > (xmax - dist2) && a_levelSetValuesMb(cellId, 0) > -m_maxLsValue
23480 && a_level(cellId) < this->m_maxSensorRefinementLevel[sen] - 1) {
23481 const MInt gridCellId = grid().tree().solver2grid(cellId);
23482 sensors[sensorOffset + sen][gridCellId] = 1.0;
23483 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
23489 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
23499template <MInt nDim_,
class SysEqn>
23501 std::vector<std::bitset<64>>& sensorCellFlag,
23502 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
MInt sen) {
23503 this->patchRefinement(sensors, sensorCellFlag, sensorWeight, sensorOffset, sen);
23510template <MInt nDim_,
class SysEqn>
23513 mAlloc(m_activeCellIds, a_noCells(),
"m_activeCellIds", -1, AT_);
23519template <MInt nDim_,
class SysEqn>
23522 mAlloc(m_smallCellIds, a_noCells(),
"m_smallCellIds", -1, AT_);
23524 mAlloc(m_masterCellIds, a_noCells(),
"m_masterCellIds", -1, AT_);
23531template <MInt nDim_,
class SysEqn>
23538 m_wasAdapted =
true;
23539 this->m_adaptationStep = 0;
23541 if(!isActive())
return;
23544 finalizeMpiExchange();
23545 m_fvBndryCnd->resetBndryCommunication();
23546 resetBoundaryCells();
23547 m_fvBndryCnd->resetCutOffFirst();
23548 resetCutOffCells();
23552 computeCellVolumes();
23556 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
23557 ASSERT(!a_isBndryGhostCell(cellId),
"");
23558 ASSERT(a_bndryId(cellId) == -1,
23559 "Error: bndryCellId " + std::to_string(a_bndryId(cellId)) +
" for cell " + std::to_string(cellId));
23560 ASSERT(!a_hasProperty(cellId, SolverCell::IsSplitChild),
"");
23561 if(!a_isHalo(cellId) && a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
23562 for(
MInt v = 0; v < CV->noVariables; v++) {
23563 ASSERT(!std::isnan(a_variable(cellId, v)),
"");
23566 if(!m_levelSetMb) {
23567 ASSERT(a_cellVolume(cellId) > 0,
"");
23568 ASSERT(!a_hasProperty(cellId, SolverCell::IsInactive),
"");
23573 m_adaptationLevel = maxUniformRefinementLevel();
23574 m_maxLevelBeforeAdaptation = maxLevel();
23577 if(grid().azimuthalPeriodicity()) {
23578 m_azimuthalRecConstSet =
false;
23579 m_azimuthalNearBndryInit =
false;
23583 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) {
23585 for(
MInt c = (
MInt)m_LESAverageCells.size() - 1; c >= 0; c--) {
23586 MInt cellId = m_LESAverageCells[c];
23587 if(a_isHalo(cellId)) {
23588 m_LESAverageCells.erase(m_LESAverageCells.begin() + c);
23589 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
23590 m_LESVarAverage[var].erase(m_LESVarAverage[var].begin() + c);
23603template <MInt nDim_,
class SysEqn>
23605 std::vector<MFloat>& sensorWeight,
23606 std::vector<std::bitset<64>>& sensorCellFlag,
23607 std::vector<MInt>& sensorSolverId) {
23610 MInt noSensors = this->m_noInitialSensors;
23613 const auto sensorOffset = (signed)sensors.size();
23614 ASSERT(sensorOffset == 0 || grid().raw().treeb().
noSolvers() > 1,
"");
23615 sensorCellFlag.resize(grid().raw().m_noInternalCells, sensorOffset + noSensors);
23616 sensors.resize(sensorOffset + noSensors, vector<MFloat>(grid().raw().m_noInternalCells, F0));
23617 sensorWeight.resize(sensorOffset + noSensors, -1);
23618 sensorSolverId.resize(sensorOffset + noSensors, solverId());
23624 for(
MInt sen = 0; sen < noSensors; sen++) {
23625 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
23632 this->identifyBoundaryCells();
23635 if(!this->m_adapts) {
23636 ASSERT(!m_levelSetMb,
"Currently not possible to leave the FV-Solver adaptation!");
23641 if(
globalTimeStep > 0 && m_adaptationLevel == maxUniformRefinementLevel()) {
23642 LSReconstructCellCenter();
23645 if(domainId() == 0) {
23646 cerr <<
"Setting " << noSensors <<
" sensors for fv-Solver adaptation." << endl;
23649 for(
MInt sen = 0; sen < noSensors; sen++) {
23650 (this->*(this->m_sensorFnPtr[sen]))(sensors, sensorCellFlag, sensorWeight, sensorOffset, sen);
23655 IF_CONSTEXPR(nDim == 2) {
23657 getBoundaryDistance(distance);
23661 m_geometry->getBoundingBox(p_bbox);
23664#pragma omp parallel for
23666 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23667 if(a_bndryId(cellId) != -1) {
23670 if(a_isBndryGhostCell(cellId)) {
23673 if(c_noChildren(cellId) > 0) {
23676 if(c_isToDelete(cellId)) {
23680 const MInt gridId = this->grid().tree().solver2grid(cellId);
23682 MFloat minDist = c_cellLengthAtLevel(0);
23683 for(
MInt i = 0; i < nDim; i++) {
23684 minDist =
mMin(minDist, fabs(a_coordinate(cellId, i) - bbox.
p[i]));
23685 minDist =
mMin(minDist, fabs(a_coordinate(cellId, i) - bbox.
p[nDim + i]));
23687 MFloat fac =
mMin(F1,
mMax(F0, (minDist - 5.0) / (10.0 - 5.0)));
23689 const MFloat R0 = 3.0 * m_adaptationDampingDistance;
23690 const MFloat R1 = F1B2 * c_cellLengthAtLevel(0);
23691 const MFloat r =
mMax(F0, distance[cellId] - R0) / (R1 - R0);
23692 fac = F1 / (F1 +
POW2(F4 * r));
23694 sensors[sensorOffset + sen][gridId] *= fac;
23699 ASSERT(m_freeIndices.empty(),
"");
23700 m_freeIndices.clear();
23703 ASSERT(a_noCells() == c_noCells() && c_noCells() == grid().raw().treeb().size(),
"");
23706 this->m_adaptationStep++;
23714template <MInt nDim_,
class SysEqn>
23719#pragma omp parallel for
23721 for(
MInt i = 0; i < grid().raw().noNeighborDomains(); i++) {
23722 for(
MInt j = 0; j < grid().raw().noHaloCells(i); j++) {
23723 MInt gridId = grid().raw().m_haloCells[i][j];
23724 MInt l_solverId = this->grid().tree().grid2solver(gridId);
23725 if(l_solverId < 0) {
23729 if(!grid().raw().treeb().solver(gridId, m_solverId)) {
23731 this->removeCellId(l_solverId);
23736 this->compactCells();
23739 for(
MInt gridCellId = 0; gridCellId < grid().raw().treeb().size(); gridCellId++) {
23740 ASSERT(grid().tree().solver2grid(gridCellId) == gridCellId,
"");
23741 ASSERT(grid().tree().grid2solver(gridCellId) == gridCellId,
"");
23745 grid().updateOther();
23746 updateDomainInfo(grid().domainId(), grid().noDomains(), grid().mpiComm(), AT_);
23747 this->checkNoHaloLayers();
23749 m_cells.size(c_noCells());
23750 m_totalnosplitchilds = 0;
23751 m_totalnoghostcells = 0;
23754 copyGridProperties();
23757 if(!isActive())
return;
23760 ASSERT(a_noCells() == c_noCells() && c_noCells() == grid().raw().treeb().size(),
"");
23763 m_bndryGhostCellsOffset = a_noCells();
23765 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
23766 ASSERT(!a_isBndryGhostCell(cellId),
"");
23767 ASSERT(a_bndryId(cellId) >= -1, to_string(a_bndryId(cellId)));
23772 setCellProperties();
23773 updateMultiSolverInformation(
true);
23775 exchangeDataFV(&a_pvariable(0, 0), PV->noVariables,
false, m_rotIndVarsPV);
23776 computeConservativeVariables();
23779 exchangeDataFV(&a_variable(0, 0), CV->noVariables,
false, m_rotIndVarsCV);
23780 exchangeDataFV(&a_oldVariable(0, 0), CV->noVariables,
false, m_rotIndVarsCV);
23781 exchangeProperties();
23782 IF_CONSTEXPR(isDetChem<SysEqn>) correctMajorSpeciesMassFraction();
23783 IF_CONSTEXPR(isDetChem<SysEqn>) computeMeanMolarWeights_CV();
23784 computePrimitiveVariables();
23791 if(m_sensorParticle) {
23792 exchangeData(&a_noPart(
23797 resetZonalSolverData();
23800#if defined _MB_DEBUG_ || !defined NDEBUG
23801 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23802 for(
MInt v = 0; v < PV->noVariables; v++) {
23803 if(std::isnan(a_pvariable(cellId, v)) && a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
23804 cerr <<
"Cell with invalid value 1" << cellId <<
" " << a_isHalo(cellId) <<
" "
23805 << a_hasProperty(cellId, SolverCell::IsInactive) << endl;
23811 m_freeIndices.clear();
23812 m_adaptationLevel++;
23819template <MInt nDim_,
class SysEqn>
23823 m_forceAdaptation =
false;
23824 m_adaptationSinceLastRestart =
true;
23825 m_adaptationSinceLastRestartBackup =
true;
23828 if(!isActive())
return;
23831 reInitSmallCellIdsMemory();
23834 updateMultiSolverInformation(
true);
23837 initSolutionStep(0);
23840 reInitActiveCellIdsMemory();
23842 writeListOfActiveFlowCells();
23844 if(!m_levelSetMb) initializeMaxLevelExchange();
23846 updateMaterialNo();
23848 IF_CONSTEXPR(isDetChem<SysEqn>) {
23849 computeMeanMolarWeights_CV();
23850 cutOffBoundaryCondition();
23851 applyBoundaryCondition();
23852 computeConservativeVariables();
23858 if(grid().azimuthalPeriodicity()) {
23859 cutOffBoundaryCondition();
23860 setConservativeVarsOnAzimuthalRecCells();
23865 if(m_zonal) exchangeZonalAverageCells();
23867 cutOffBoundaryCondition();
23869 applyBoundaryCondition();
23871 IF_CONSTEXPR(isDetChem<SysEqn>) { computeConservativeVariables(); }
23877 if(m_hasExternalSource) {
23878 resetExternalSources();
23881 IF_CONSTEXPR(isDetChem<SysEqn>) { computeMeanMolarWeights_PV(); }
23883#if defined(WITH_CANTERA)
23884 IF_CONSTEXPR(isDetChem<SysEqn>) {
23891 m_wasAdapted =
false;
23893#if defined _MB_DEBUG_ || !defined NDEBUG
23894 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
23895 for(
MInt v = 0; v < PV->noVariables; v++) {
23896 if(std::isnan(a_pvariable(cellId, v)) && a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
23897 cerr <<
"Cell with invalid value 2 " << cellId <<
" " << a_isHalo(cellId) <<
" "
23898 << a_hasProperty(cellId, SolverCell::IsInactive) << endl;
23910template <MInt nDim_,
class SysEqn>
23913 ASSERT(isActive(),
"solver is not active");
23915 MBool weightOnlyLeafCells =
false;
23916 weightOnlyLeafCells =
23917 Context::getSolverProperty<MBool>(
"weightOnlyLeafCellsFv", m_solverId, AT_, &weightOnlyLeafCells);
23919 const MInt noCellsGrid = grid().raw().treeb().size();
23920 const MInt offset = noCellsGrid * solverId();
23923#pragma omp parallel for
23925 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
23926 assertValidGridCellId(cellId);
23927 const MInt gridCellId = grid().tree().solver2grid(cellId);
23928 const MInt id = gridCellId + offset;
23930 solverCellWeight[
id] = (c_isLeafCell(cellId) || !weightOnlyLeafCells) ? 1.0 : 0.0;
23938template <MInt nDim_,
class SysEqn>
23942 if(m_limitWeights) {
23943 ASSERT(m_weightInactiveCell,
"");
23944 MInt count = 1 + m_weightBndryCells + m_weightCutOffCells + m_weightBc1601;
23945 weights[count] =
mMax(weights[count], 0.01 * weights[0]);
23953template <MInt nDim_,
class SysEqn>
23957 MInt noFvLoadTypes = 1;
23958 if(m_weightBndryCells) {
23959 noFvLoadTypes += 1;
23961 if(m_weightCutOffCells) {
23962 noFvLoadTypes += 1;
23964 if(m_weightBc1601) {
23965 noFvLoadTypes += 1;
23967 if(m_weightInactiveCell) {
23968 noFvLoadTypes += 1;
23970 if(m_weightNearBndryCells) {
23971 noFvLoadTypes += 1;
23973 if(m_weightLvlJumps) {
23974 noFvLoadTypes += 1;
23976 if(m_weightSmallCells) {
23977 noFvLoadTypes += 1;
23980 return noFvLoadTypes;
23985template <MInt nDim_,
class SysEqn>
23990 names[0] =
"fv_leaf_cell";
23993 if(m_weightBndryCells) {
23994 weights[count] = 5.0;
23995 names[count] =
"fv_bndry_cell";
23999 if(m_weightCutOffCells) {
24000 weights[count] = 5.0;
24001 names[count] =
"fv_cutoff_cell";
24005 if(m_weightBc1601) {
24006 weights[count] = 10.0;
24007 names[count] =
"fv_bc1601";
24011 if(m_weightInactiveCell) {
24012 weights[count] = 0.1;
24013 names[count] =
"fv_inactive_cell";
24017 if(m_weightNearBndryCells) {
24018 weights[count] = 2.0;
24019 names[count] =
"fv_nearBndry_cell";
24022 if(m_weightLvlJumps) {
24023 weights[count] = 1.5;
24024 names[count] =
"fv_lvlJump_cell";
24027 if(m_weightSmallCells) {
24028 weights[count] = 1.0;
24029 names[count] =
"fv_smallCell";
24033 if(noLoadTypes() != count) {
24034 mTerm(1,
"Count does not match noLoadTypes.");
24044template <MInt nDim_,
class SysEqn>
24049 std::fill_n(&loadQuantities[0], noLoadTypes(), 0);
24052 if(!grid().isActive()) {
24057 MInt noLeafCells = 0;
24058 MInt noBndryCells = 0;
24059 MInt noNearBndryCells = 0;
24060 MInt totalNoCutOffCells = 0;
24061 MInt noBc1601Cells = 0;
24062 MInt noLvlJumpCells = 0;
24064 for(
MInt cellId = 0; cellId < grid().noInternalCells(); cellId++) {
24065 if(c_isLeafCell(cellId) && !a_hasProperty(cellId, SolverCell::IsInactive)) {
24068 if(c_isLeafCell(cellId)) {
24069 MBool atLvlJump =
false;
24070 for(
MInt dir = 0; dir < m_noDirs; dir++) {
24071 if(c_neighborId(cellId, dir,
false) < 0 && c_parentId(cellId) > -1
24072 && c_neighborId(c_parentId(cellId), dir,
false) > -1) {
24076 if(c_neighborId(cellId, dir,
false) > -1 && !c_isLeafCell(c_neighborId(cellId, dir,
false))) {
24086 const MInt bndryId = a_bndryId(cellId);
24087 if(bndryId > -1 && c_isLeafCell(cellId)) {
24090 if(a_hasProperty(cellId, SolverCell::NearWall)) {
24091 noNearBndryCells++;
24095 for(
MInt bc = 0; bc < m_fvBndryCnd->m_noCutOffBndryCndIds; bc++) {
24096 MInt noCutOffCells = 0;
24098 const MInt bcSize = m_fvBndryCnd->m_sortedCutOffCells[bc]->size();
24099 for(
MInt i = 0; i < bcSize; i++) {
24100 const MInt cellId = m_fvBndryCnd->m_sortedCutOffCells[bc]->a[i];
24101 if(!a_isHalo(cellId)) {
24106 if(m_weightBc1601 && bc == m_fvBndryCnd->m_bc1601_bcId) {
24108 noBc1601Cells = noCutOffCells;
24111 totalNoCutOffCells += noCutOffCells;
24115 loadQuantities[0] = noLeafCells;
24119 if(m_weightBndryCells) {
24120 loadQuantities[count] = noBndryCells;
24123 if(m_weightCutOffCells) {
24124 loadQuantities[count] = totalNoCutOffCells;
24127 if(m_weightBc1601) {
24128 loadQuantities[count] = noBc1601Cells;
24131 if(m_weightInactiveCell) {
24132 loadQuantities[count] = grid().noInternalCells();
24135 if(m_weightNearBndryCells) {
24136 loadQuantities[count] = noNearBndryCells;
24139 if(m_weightLvlJumps) {
24140 loadQuantities[count] = noLvlJumpCells;
24143 if(m_weightSmallCells) {
24144 loadQuantities[count] = m_fvBndryCnd->m_smallCutCells.size();
24157template <MInt nDim_,
class SysEqn>
24160 ASSERT(isActive(),
"solver is not active");
24163 const MInt cellId = grid().tree().grid2solver(gridCellId);
24168 if(cellId < 0 || cellId >= grid().noInternalCells()) {
24169 mTerm(1,
"The given cell id is invalid.");
24176 if(c_isLeafCell(cellId) && !a_hasProperty(cellId, SolverCell::IsInactive)) {
24177 cellLoad = weights[0];
24182 if(m_weightBndryCells) {
24183 const MInt bndryId = a_bndryId(cellId);
24184 if(bndryId > -1 && c_isLeafCell(cellId)) {
24185 cellLoad += weights[count];
24190 if(m_weightCutOffCells) {
24191 for(
MInt bc = 0; bc < m_fvBndryCnd->m_noCutOffBndryCndIds; bc++) {
24192 if(m_weightBc1601 && bc == m_fvBndryCnd->m_bc1601_bcId)
continue;
24194 const MInt bcSize = m_fvBndryCnd->m_sortedCutOffCells[bc]->size();
24195 for(
MInt i = 0; i < bcSize; i++) {
24196 if(cellId == m_fvBndryCnd->m_sortedCutOffCells[bc]->a[i]) {
24197 cellLoad += weights[count + 1];
24205 if(m_weightBc1601) {
24206 const MInt bc = m_fvBndryCnd->m_bc1601_bcId;
24207 const MInt bcSize = (bc < 0) ? 0 : m_fvBndryCnd->m_sortedCutOffCells[bc]->size();
24208 for(
MInt i = 0; i < bcSize; i++) {
24209 if(cellId == m_fvBndryCnd->m_sortedCutOffCells[bc]->a[i]) {
24210 cellLoad += weights[count];
24215 if(m_weightInactiveCell) {
24216 if(cellLoad < MFloatEps) {
24217 cellLoad = weights[count];
24222 if(m_weightNearBndryCells) {
24223 if(a_hasProperty(cellId, SolverCell::NearWall)) {
24224 cellLoad += weights[count];
24228 if(m_weightLvlJumps) {
24229 MBool atLvlJump =
false;
24230 if(c_isLeafCell(cellId)) {
24231 for(
MInt dir = 0; dir < m_noDirs; dir++) {
24232 if(c_neighborId(cellId, dir,
false) < 0 && c_parentId(cellId) > -1
24233 && c_neighborId(c_parentId(cellId), dir,
false) > -1) {
24237 if(c_neighborId(cellId, dir,
false) > -1 && !c_isLeafCell(c_neighborId(cellId, dir,
false))) {
24244 cellLoad += weights[count];
24248 if(m_weightSmallCells) {
24249 if(a_cellVolume(cellId) / grid().gridCellVolume(maxLevel()) < m_fvBndryCnd->m_volumeLimitWall) {
24250 cellLoad += weights[count];
24263template <MInt nDim_,
class SysEqn>
24265 finalizeMpiExchange();
24278 if(m_hasExternalSource) {
24279 resetExternalSources();
24280 advanceExternalSource();
24289template <MInt nDim_,
class SysEqn>
24293 for(
MInt c = 0; c < m_noCellsInsideSpongeLayer; c++) {
24297 m_cellsInsideSpongeLayer[c] = -1;
24299 m_noCellsInsideSpongeLayer = 0;
24309template <MInt nDim_,
class SysEqn>
24314 if(m_fvBndryCnd->m_cellCoordinatesCorrected) {
24315 m_fvBndryCnd->recorrectCellCoordinates();
24319 a_bndryId(cellId) = -1;
24320 for(
MInt v = 0; v < FV->noVariables; v++) {
24321 a_rightHandSide(cellId, v) = F0;
24323 for(
MInt v = 0; v < PV->noVariables; v++) {
24324 a_pvariable(cellId, v) = sqrt(-F1);
24326 a_cellVolume(cellId) = F0;
24327 a_FcellVolume(cellId) = sqrt(-F1);
24330 if(grid().azimuthalPeriodicity()) {
24331 m_noAzimuthalReconstNghbrs.clear();
24332 m_azimuthalReconstNghbrIds.clear();
24333 m_azimuthalRecConsts.clear();
24342 for(
MInt bndryId = 0; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
24343 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
24344 a_bndryId(cellId) = -1;
24345 a_hasProperty(cellId, SolverCell::IsSplitCell) =
false;
24346 a_hasProperty(cellId, SolverCell::IsSplitChild) =
false;
24347 a_hasProperty(cellId, SolverCell::HasSplitFace) =
false;
24348 a_hasProperty(cellId, SolverCell::IsTempLinked) =
false;
24349 a_hasProperty(cellId, SolverCell::IsMovingBnd) =
false;
24351 for(
MInt bndryId = 0; bndryId < m_fvBndryCnd->m_maxNoBndryCells; bndryId++) {
24352 std::vector<MInt>().swap(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds);
24353 std::vector<MFloat>().swap(m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst);
24354 std::vector<MFloat>().swap(m_fvBndryCnd->m_bndryCell[bndryId].m_cellDerivRecConst);
24355 std::vector<MFloat>().swap(m_fvBndryCnd->m_bndryCell[bndryId].m_faceVertices);
24356 for(
MUint i = 0; i < m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream.size(); i++) {
24357 m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream[i].resize(0);
24359 m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream.resize(0);
24360 for(
MInt srfc = 0; srfc < FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces; srfc++) {
24361 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_noCutPoints = 0;
24362 std::vector<MFloat>().swap(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst);
24363 for(
MInt v = 0; v < PV->noVariables; v++) {
24364 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] =
BC_UNSET;
24366 for(
MInt i = 0; i < nDim; i++) {
24367 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = -1;
24370 m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId = -1;
24374 m_fvBndryCnd->m_bndryCells->resetSize(0);
24375 std::vector<MInt>().swap(m_fvBndryCnd->m_smallCutCells);
24377 resetCutOffCells();
24378 m_fvBndryCnd->resetCutOffFirst();
24380 m_fvBndryCnd->resetBndryCommunication();
24382 m_bndryGhostCellsOffset = 0;
24383 m_bndrySurfacesOffset = 0;
24384 m_totalnosplitchilds = 0;
24385 m_totalnoghostcells = 0;
24389 ASSERT(m_cells.size() == 0,
"");
24390 m_reconstructionDataSize = 0;
24392 IF_CONSTEXPR(isDetChem<SysEqn>) m_dampFactor.clear();
24395 if(!m_fvBndryCnd->m_cellMerging && m_fvBndryCnd->m_nearBoundaryHaloCells !=
nullptr) {
24396 for(
MUint i = 0; i < m_fvBndryCnd->m_nearBoundaryHaloCells->size(); i++) {
24397 std::vector<MInt>().swap(m_fvBndryCnd->m_nearBoundaryHaloCells[i]);
24398 std::vector<MInt>().swap(m_fvBndryCnd->m_nearBoundaryWindowCells[i]);
24411template <MInt nDim_,
class SysEqn>
24413 const MInt*
const noCellsToSendByDomain,
24414 const MInt*
const sortedCellId,
const MInt oldNoCells) {
24418 NEW_TIMER_GROUP(t_initTimer,
"balance solver");
24419 NEW_TIMER(t_timertotal,
"balance solver", t_initTimer);
24420 NEW_SUB_TIMER(t_variables,
"variables", t_timertotal);
24421 NEW_SUB_TIMER(t_communicator,
"communicator", t_timertotal);
24422 NEW_SUB_TIMER(t_reinit,
"reinit", t_timertotal);
24424 RECORD_TIMER_START(t_timertotal);
24425 RECORD_TIMER_START(t_variables);
24428 MFloatScratchSpace variablesBalance(oldNoCells, CV->noVariables, FUN_,
"variablesBalance");
24431 variablesBalance.
fill(-1);
24432 volumeBalance.
fill(-1);
24435 for(
MInt cellId = 0; cellId < c_noCells(); cellId++) {
24436 MInt gridCellId = grid().tree().solver2grid(cellId);
24437 for(
MInt variable = 0; variable < CV->noVariables; variable++) {
24438 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
24439 ASSERT(!std::isnan(a_variable(cellId, variable)),
"");
24441 variablesBalance(gridCellId, variable) = a_variable(cellId, variable);
24443 volumeBalance(gridCellId) = a_cellVolume(cellId);
24453 if(!grid().isActive()) {
24454 updateDomainInfo(-1, -1, MPI_COMM_NULL, AT_);
24455 mTerm(1,
"fixme: inactive ranks not supported in balance(); use balancePre/Post instead!");
24460 updateDomainInfo(grid().domainId(), grid().noDomains(), grid().mpiComm(), AT_);
24463 ASSERT(domainId() == grid().raw().domainId(),
"");
24464 ASSERT(noDomains() == grid().raw().noDomains(),
"");
24470 MFloatScratchSpace variables(noCellsToReceiveByDomain[noDomains()], CV->noVariables, FUN_,
"variables");
24471 MFloatScratchSpace cellVolumes(noCellsToReceiveByDomain[noDomains()], FUN_,
"cellVolumes");
24473 variables.
fill(-1.0);
24474 cellVolumes.
fill(-1.0);
24477 noCellsToSendByDomain, noCellsToReceiveByDomain, CV->noVariables, &variables[0]);
24479 noCellsToSendByDomain, noCellsToReceiveByDomain, 1, &cellVolumes[0]);
24486 updateMultiSolverInformation(
true);
24488 ASSERT(m_cells.size() == 0,
"");
24491 for(
MInt gridCellId = 0; gridCellId < noCellsToReceiveByDomain[noDomains()]; gridCellId++) {
24492 const MInt cellId = m_cells.size();
24494 if(!grid().raw().treeb().solver(gridCellId, m_solverId))
continue;
24499 if(!grid().raw().bitOffset()) {
24500 ASSERT(grid().tree().solver2grid(cellId) == gridCellId, to_string(cellId) +
" " + to_string(gridCellId));
24503 if(grid().domainOffset(domainId()) + (
MLong)cellId != c_globalId(cellId)) {
24504 mTerm(1,
"Global id mismatch: o" + std::to_string(grid().domainOffset(domainId())) +
" + c"
24505 + std::to_string(cellId) +
" != g" + std::to_string(c_globalId(cellId)));
24508 a_resetPropertiesSolver(cellId);
24511 for(
MInt v = 0; v < CV->noVariables; v++) {
24512 a_variable(cellId, v) = variables(gridCellId, v);
24513 a_oldVariable(cellId, v) = a_variable(cellId, v);
24515 setPrimitiveVariables(cellId);
24516 a_cellVolume(cellId) = cellVolumes(gridCellId);
24517 a_FcellVolume(cellId) = F1 /
mMax(m_volumeThreshold, a_cellVolume(cellId));
24522 m_cells.append(c_noCells() - m_cells.size());
24524 m_totalnoghostcells = 0;
24525 m_totalnosplitchilds = 0;
24527 ASSERT(m_cells.size() == c_noCells() && c_noCells() == a_noCells(),
"");
24529 m_bndryGhostCellsOffset = a_noCells();
24530 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
24531 a_bndryId(cellId) = -1;
24532 a_isBndryGhostCell(cellId) =
false;
24533 a_hasProperty(cellId, SolverCell::IsSplitChild) =
false;
24536 copyGridProperties();
24539 this->checkNoHaloLayers();
24541 RECORD_TIMER_STOP(t_variables);
24542 RECORD_TIMER_START(t_communicator);
24551 if(m_nonBlockingComm) {
24558 allocateCommunicationMemory();
24560 if(!m_fvBndryCnd->m_cellMerging) {
24561 mDeallocate(m_fvBndryCnd->m_nearBoundaryWindowCells);
24562 mDeallocate(m_fvBndryCnd->m_nearBoundaryHaloCells);
24563 mAlloc(m_fvBndryCnd->m_nearBoundaryWindowCells, noNeighborDomains(),
"m_nearBoundaryWindowCells", AT_);
24564 mAlloc(m_fvBndryCnd->m_nearBoundaryHaloCells, noNeighborDomains(),
"m_nearBoundaryHaloCells", AT_);
24567 std::vector<MInt>().swap(m_splitCells);
24568 std::vector<std::vector<MInt>>().swap(m_splitChilds);
24569 std::map<MInt, MInt>().swap(m_splitChildToSplitCell);
24570 m_totalnosplitchilds = 0;
24572 if(this->m_adaptation) {
24573 for(
MInt i = 0; i < maxNoGridCells(); i++)
24574 m_recalcIds[i] = i;
24578 exchangeData(&a_variable(0, 0), CV->noVariables);
24579 exchangeData(&a_cellVolume(0), 1);
24580 if(grid().azimuthalPeriodicity()) {
24581 mTerm(1, AT_,
"Add azimuthal periodicity, c.f. fvMb!");
24584 for(
MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
24585 setPrimitiveVariables(cellId);
24586 for(
MInt v = 0; v < CV->noVariables; v++) {
24587 a_oldVariable(cellId, v) = a_variable(cellId, v);
24589 a_FcellVolume(cellId) = F1 /
mMax(m_volumeThreshold, a_cellVolume(cellId));
24592 copyGridProperties();
24594 IF_CONSTEXPR(isDetChem<SysEqn>)
if(m_heatReleaseDamp) initHeatReleaseDamp();
24596 RECORD_TIMER_STOP(t_communicator);
24597 RECORD_TIMER_START(t_reinit);
24602 if(this->m_adaptation) {
24603 m_adaptationSinceLastRestart =
true;
24604 m_adaptationSinceLastRestartBackup =
true;
24607 RECORD_TIMER_STOP(t_reinit);
24608 RECORD_TIMER_STOP(t_timertotal);
24609 DISPLAY_TIMER(t_timertotal);
24618template <MInt nDim_,
class SysEqn>
24626 m_loadBalancingReinitStage = 0;
24634 if(!grid().isActive()) {
24636 updateDomainInfo(-1, -1, MPI_COMM_NULL, AT_);
24639 updateDomainInfo(grid().domainId(), grid().noDomains(), grid().mpiComm(), AT_);
24643 m_wasBalancedZonal =
true;
24651 updateMultiSolverInformation(
true);
24654 if(!grid().isActive()) {
24659 ASSERT(m_cells.size() == 0,
"");
24662 m_cells.append(grid().noInternalCells());
24665 for(
MInt cellId = 0; cellId < grid().noInternalCells(); cellId++) {
24666 if(grid().domainOffset(domainId()) + (
MLong)cellId != c_globalId(cellId)) {
24667 mTerm(1,
"Global id mismatch.");
24685template <MInt nDim_,
class SysEqn>
24689 if(grid().azimuthalPeriodicity()) {
24691 "This type of balance is not supported for azimuthal periodicity. Add periodic exchange of conservative "
24695 m_loadBalancingReinitStage = 1;
24698 m_cells.append(c_noCells() - m_cells.size());
24700 copyGridProperties();
24702 m_totalnoghostcells = 0;
24703 m_totalnosplitchilds = 0;
24704 ASSERT(m_cells.size() == c_noCells() && c_noCells() == a_noCells(),
"");
24707 if(!grid().isActive()) {
24711 m_bndryGhostCellsOffset = a_noCells();
24712 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
24713 a_bndryId(cellId) = -1;
24714 a_isBndryGhostCell(cellId) =
false;
24715 a_hasProperty(cellId, SolverCell::IsSplitChild) =
false;
24719 this->checkNoHaloLayers();
24723 computeDomainAndSpongeDimensions();
24726 allocateCommunicationMemory();
24728 if(!m_fvBndryCnd->m_cellMerging) {
24729 mDeallocate(m_fvBndryCnd->m_nearBoundaryWindowCells);
24730 mDeallocate(m_fvBndryCnd->m_nearBoundaryHaloCells);
24731 mAlloc(m_fvBndryCnd->m_nearBoundaryWindowCells, noNeighborDomains(),
"m_nearBoundaryWindowCells", AT_);
24732 mAlloc(m_fvBndryCnd->m_nearBoundaryHaloCells, noNeighborDomains(),
"m_nearBoundaryHaloCells", AT_);
24735 m_splitCells.clear();
24736 m_splitChilds.clear();
24737 m_splitChildToSplitCell.clear();
24738 m_totalnosplitchilds = 0;
24741 if(this->m_adaptation) {
24742 for(
MInt i = 0; i < maxNoGridCells(); i++)
24743 m_recalcIds[i] = i;
24746 exchangeData(&a_variable(0, 0), CV->noVariables);
24747 if constexpr(hasAV) exchangeData(&a_avariable(0, 0), AV->noVariables);
24748 exchangeData(&a_cellVolume(0), 1);
24749 if(grid().azimuthalPeriodicity()) {
24750 mTerm(1, AT_,
"Add azimuthal periodicity, c.f. fvMb!");
24753 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
24754 setPrimitiveVariables(cellId);
24755 for(
MInt v = 0; v < CV->noVariables; v++) {
24756 a_oldVariable(cellId, v) = a_variable(cellId, v);
24758 a_FcellVolume(cellId) = F1 /
mMax(m_volumeThreshold, a_cellVolume(cellId));
24761 copyGridProperties();
24764 determineLESAverageCells();
24765 resetZonalLESAverage();
24766 resetZonalSolverData();
24772 if(this->m_adaptation) {
24773 m_adaptationSinceLastRestart =
true;
24774 m_adaptationSinceLastRestartBackup =
true;
24777 m_loadBalancingReinitStage = 2;
24780 if(m_combustion && !m_LSSolver) {
24781 mTerm(1,
"balancePost untested case with combustion");
24783 if constexpr(isEEGas<SysEqn>) {
24784 if(m_EEGas.gasSource != 0) {
24785 m_EEGas.gasSourceCells.clear();
24794template <MInt nDim_,
class SysEqn>
24798 ASSERT(m_cells.size() == c_noCells(),
"");
24801 if(!grid().isActive()) {
24813 reInitSmallCellIdsMemory();
24816 initSolutionStep(1);
24818 reInitActiveCellIdsMemory();
24819 writeListOfActiveFlowCells();
24821 if(!m_levelSetMb) initializeMaxLevelExchange();
24824 updateMaterialNo();
24827 initCutOffBoundaryCondition();
24829 IF_CONSTEXPR(isDetChem<SysEqn>) {
24830 cutOffBoundaryCondition();
24831 applyBoundaryCondition();
24832 computeMeanMolarWeights_CV();
24833 computeConservativeVariables();
24834 computeMeanMolarWeights_CV();
24842 if(!m_levelSetMb) {
24843 initializeRungeKutta();
24849 if(m_periodicCells == 3) {
24850 mTerm(1,
"balancePost untested case with azimuthal periodicity");
24852 exchangePeriodic();
24863 m_wasBalancedZonal =
false;
24866 if(grid().azimuthalPeriodicity()) {
24870 cutOffBoundaryCondition();
24871 applyBoundaryCondition();
24874 if(grid().azimuthalPeriodicity()) {
24875 setConservativeVarsOnAzimuthalRecCells();
24882 if(calcSlopesAfterStep()) {
24883 LSReconstructCellCenter();
24884 m_fvBndryCnd->copySlopesToSmallCells();
24885 m_fvBndryCnd->updateGhostCellSlopesInviscid();
24886 m_fvBndryCnd->updateCutOffSlopesInviscid();
24890 if(m_combustion && !m_LSSolver) {
24891 setCellProperties();
24892 computePrimitiveVariablesCoarseGrid();
24893 computeConservativeVariables();
24897 if(m_levelSet && !m_combustion && !m_LSSolver) {
24898 setCellProperties();
24901 m_loadBalancingReinitStage = -1;
24909template <MInt nDim_,
class SysEqn>
24911 std::vector<std::pair<MString, MInt>>& domainInfo) {
24914 const MString namePrefix =
"b" + std::to_string(solverId()) +
"_";
24916 const MInt noCells = (isActive()) ? grid().noInternalCells() : 0;
24917 MInt noLeafCells = 0;
24918 MInt noActiveLeafCells = 0;
24919 MInt noCutOffCells = 0;
24920 MInt noBc1601Cells = 0;
24921 MInt noNearBndryCells = 0;
24922 MInt noBndrycells = 0;
24923 MInt noLvlJumpCells = 0;
24926 for(
MInt cellId = 0; cellId < grid().noInternalCells(); cellId++) {
24927 if(c_isLeafCell(cellId)) noLeafCells++;
24928 if(c_isLeafCell(cellId) && !a_hasProperty(cellId, SolverCell::IsInactive)) noActiveLeafCells++;
24929 if(a_hasProperty(cellId, SolverCell::NearWall)) {
24930 noNearBndryCells++;
24932 if(a_bndryId(cellId) > -1 && c_isLeafCell(cellId)) {
24935 if(c_isLeafCell(cellId)) {
24936 MBool atLvlJump =
false;
24937 for(
MInt dir = 0; dir < m_noDirs; dir++) {
24938 if(c_neighborId(cellId, dir,
false) < 0 && c_parentId(cellId) > -1
24939 && c_neighborId(c_parentId(cellId), dir,
false) > -1) {
24943 if(c_neighborId(cellId, dir,
false) > -1 && !c_isLeafCell(c_neighborId(cellId, dir,
false))) {
24955 for(
MInt bc = 0; bc < m_fvBndryCnd->m_noCutOffBndryCndIds; bc++) {
24957 const MInt cutOffSize = m_fvBndryCnd->m_sortedCutOffCells[bc]->size();
24958 if(bc == m_fvBndryCnd->m_bc1601_bcId) {
24959 noBc1601Cells = cutOffSize;
24961 noCutOffCells += cutOffSize;
24966 domainInfo.emplace_back(namePrefix +
"noFvCells", noCells);
24967 domainInfo.emplace_back(namePrefix +
"noFvLeafCells", noLeafCells);
24968 domainInfo.emplace_back(namePrefix +
"noFvActiveLeafCells", noActiveLeafCells);
24971 if(m_weightBndryCells) {
24972 domainInfo.emplace_back(namePrefix +
"noFvBndryCells", noBndrycells);
24976 if(m_weightCutOffCells) {
24977 domainInfo.emplace_back(namePrefix +
"noCutOffCells", noCutOffCells);
24980 if(m_weightBc1601) {
24981 domainInfo.emplace_back(namePrefix +
"noBc1601Cells", noBc1601Cells);
24985 if(m_weightNearBndryCells) {
24986 domainInfo.emplace_back(namePrefix +
"noNearBndryCells", noNearBndryCells);
24990 if(m_weightInactiveCell) {
24991 domainInfo.emplace_back(namePrefix +
"noFvInacticeCells", grid().noInternalCells());
24995 if(m_weightLvlJumps) {
24996 domainInfo.emplace_back(namePrefix +
"noFvLvlJumpCells", noLvlJumpCells);
25000 if(m_weightSmallCells) {
25001 domainInfo.emplace_back(namePrefix +
"noFvSmallCells", m_fvBndryCnd->m_smallCutCells.size());
25009template <MInt nDim_,
class SysEqn>
25015 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
25016 Gap(cellId, 0) = (
MInt)a_isGapCell(cellId);
25017 Gap(cellId, 1) = (
MInt)a_wasGapCell(cellId);
25020 exchangeDataFV(&Gap(0, 0), 2);
25022 for(
MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
25023 a_isGapCell(cellId) = (
MBool)Gap(cellId, 0);
25024 a_wasGapCell(cellId) = (
MBool)Gap(cellId, 1);
25032template <MInt nDim_,
class SysEqn>
25036 if(noNeighborDomains() == 0)
return;
25040 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
25041 propsBak[0] = a_properties(cellId);
25047 for(
MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
25048 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) =
25050 a_hasProperty(cellId, SolverCell::IsInactive) = propsBak[cellId][
maia::fv::cell::p(SolverCell::IsInactive)];
25061template <MInt nDim_,
class SysEqn>
25067 for(
MInt c = 0; c < m_cells.size(); c++) {
25068 a_hasProperty(c, SolverCell::IsCutOff) =
false;
25071 m_fvBndryCnd->resetCutOff();
25076template <MInt nDim_,
class SysEqn>
25080 MInt nghbr0, nghbr1;
25081 const MInt noPVarIds = PV->noVariables;
25082 const MInt noSrfcs = a_noSurfaces();
25083 MInt va0, va1, sl0, sl1, i;
25084 const MInt surfaceVarMemory = m_surfaceVarMemory;
25085 const MInt slopeMemory = m_slopeMemory;
25086 MFloat* surfaceVar = (
MFloat*)(&(a_surfaceVariable(0, 0, 0)));
25095 for(
MInt srfcId = 0; srfcId < noSrfcs; srfcId++) {
25097 nghbr0 = a_surfaceNghbrCellId(srfcId, 0);
25098 nghbr1 = a_surfaceNghbrCellId(srfcId, 1);
25100 sl0 = nghbr0 * slopeMemory;
25101 sl1 = nghbr1 * slopeMemory;
25104 for(
MInt varId = 0; varId < noPVarIds; varId++) {
25105 surfaceVar[va0 + varId] = a_pvariable(nghbr0, varId) + cellSlopes[sl0] * dx[i] + cellSlopes[sl0 + 1] * dx[i + 1];
25106 IF_CONSTEXPR(nDim == 3) surfaceVar[va0 + varId] += cellSlopes[sl0 + 2] * dx[i + 2];
25108 surfaceVar[va0 + varId] =
25109 mMin(surfaceVar[va0 + varId],
mMax(a_pvariable(nghbr0, varId), a_pvariable(nghbr1, varId)));
25110 surfaceVar[va0 + varId] =
25111 mMax(surfaceVar[va0 + varId],
mMin(a_pvariable(nghbr0, varId), a_pvariable(nghbr1, varId)));
25113 surfaceVar[va1 + varId] =
25114 a_pvariable(nghbr1, varId) + cellSlopes[sl1] * dx[i + nDim] + cellSlopes[sl1 + 1] * dx[i + nDim + 1];
25115 IF_CONSTEXPR(nDim == 3) surfaceVar[va1 + varId] += cellSlopes[sl1 + 2] * dx[i + nDim + 2];
25117 surfaceVar[va1 + varId] =
25118 mMin(surfaceVar[va1 + varId],
mMax(a_pvariable(nghbr0, varId), a_pvariable(nghbr1, varId)));
25119 surfaceVar[va1 + varId] =
25120 mMax(surfaceVar[va1 + varId],
mMin(a_pvariable(nghbr0, varId), a_pvariable(nghbr1, varId)));
25124 va0 += surfaceVarMemory;
25125 va1 += surfaceVarMemory;
25130 m_fvBndryCnd->correctBoundarySurfaceVariables();
25133 m_fvBndryCnd->updateGhostCellSlopesViscous();
25134 m_fvBndryCnd->updateCutOffSlopesViscous();
25138template <MInt nDim_,
class SysEqn>
25142 MInt nghbr0, nghbr1;
25143 const MInt noPVarIds = PV->noVariables;
25144 const MInt noSrfcs = a_noSurfaces();
25145 MInt va0, va1, sl0, sl1, i;
25146 const MInt surfaceVarMemory = m_surfaceVarMemory;
25147 const MInt slopeMemory = m_slopeMemory;
25148 MFloat* surfaceVar = (
MFloat*)(&(a_surfaceVariable(0, 0, 0)));
25158 for(
MInt srfcId = 0; srfcId < noSrfcs; srfcId++) {
25160 nghbr0 = a_surfaceNghbrCellId(srfcId, 0);
25161 nghbr1 = a_surfaceNghbrCellId(srfcId, 1);
25163 sl0 = nghbr0 * slopeMemory;
25164 sl1 = nghbr1 * slopeMemory;
25181 for(
MInt varId = 0; varId < noPVarIds; varId++) {
25182 surfaceVar[va0 + varId] = a_pvariable(nghbr0, varId) + cellSlopes[sl0] * dx[i]
25183 + cellSlopes[sl0 + 1] * dx[i + 1];
25184 IF_CONSTEXPR(nDim == 3) surfaceVar[va0 + varId] += cellSlopes[sl0 + 2] * dx[i + 2];
25186 surfaceVar[va1 + varId] = a_pvariable(nghbr1, varId) + cellSlopes[sl1] * dx[i + nDim]
25187 + cellSlopes[sl1 + 1] * dx[i + nDim + 1];
25188 IF_CONSTEXPR(nDim == 3) surfaceVar[va1 + varId] += cellSlopes[sl1 + 2] * dx[i + nDim + 2];
25191 if(surfaceVar[va0 + varId] >
mMax(a_pvariable(nghbr0, varId), a_pvariable(nghbr1, varId))
25192 || surfaceVar[va0 + varId] <
mMin(a_pvariable(nghbr0, varId), a_pvariable(nghbr1, varId))) {
25193 surfaceVar[va0 + varId] = a_pvariable(nghbr0, varId);
25195 if(surfaceVar[va1 + varId] >
mMax(a_pvariable(nghbr0, varId), a_pvariable(nghbr1, varId))
25196 || surfaceVar[va1 + varId] <
mMin(a_pvariable(nghbr0, varId), a_pvariable(nghbr1, varId))) {
25197 surfaceVar[va1 + varId] = a_pvariable(nghbr1, varId);
25204 va0 += surfaceVarMemory;
25205 va1 += surfaceVarMemory;
25210 m_fvBndryCnd->correctBoundarySurfaceVariables();
25213 m_fvBndryCnd->updateGhostCellSlopesViscous();
25214 m_fvBndryCnd->updateCutOffSlopesViscous();
25218template <MInt nDim_,
class SysEqn>
25222 MInt nghbr0, nghbr1;
25223 const MInt noPVarIds = PV->noVariables;
25224 const MInt noSrfcs = a_noSurfaces();
25226 const MInt surfaceVarMemory = m_surfaceVarMemory;
25227 MFloat* surfaceVar = (
MFloat*)(&(a_surfaceVariable(0, 0, 0)));
25231 MInt va1 = noPVarIds;
25234 for(
MInt srfcId = 0; srfcId < noSrfcs; srfcId++) {
25236 nghbr0 = a_surfaceNghbrCellId(srfcId, 0);
25237 nghbr1 = a_surfaceNghbrCellId(srfcId, 1);
25242 for(
MInt varId = 0; varId < PV->P; varId++) {
25243 surfaceVar[va0 + varId] = a_pvariable(nghbr0, varId);
25251 surfaceVar[va1 + varId] = a_pvariable(nghbr1, varId);
25262 surfaceVar[va0 + PV->P] = a_pvariable(nghbr0, PV->P);
25263 surfaceVar[va1 + PV->P] = a_pvariable(nghbr1, PV->P);
25266 for(
MInt varId = PV->P + 1; varId < noPVarIds; varId++) {
25267 surfaceVar[va0 + varId] = a_pvariable(nghbr0, varId);
25275 surfaceVar[va1 + varId] = a_pvariable(nghbr1, varId);
25287 va0 += surfaceVarMemory;
25288 va1 += surfaceVarMemory;
25293 m_fvBndryCnd->correctBoundarySurfaceVariables();
25296 m_fvBndryCnd->updateGhostCellSlopesViscous();
25297 m_fvBndryCnd->updateCutOffSlopesViscous();
25302template <MInt nDim_,
class SysEqn>
25307 const MInt noCells = a_noCells();
25308 MInt noNghbrIds, nghbrId;
25309 MInt noUnknowns = 0;
25310 if(m_orderOfReconstruction == 1) {
25313 if(m_orderOfReconstruction == 2) {
25314 noUnknowns = (nDim == 2) ? 5 : 9;
25316 MFloat norm, tmp, normi, avg;
25320 for(
MInt n = 0; n < nDim * (maxNoGridCells() * m_cells.noRecNghbrs()); n++) {
25326 m_reconstructionDataSize = 0;
25328 for(
MInt cellId = 0; cellId < noCells; cellId++) {
25329 a_reconstructionData(cellId) = m_reconstructionDataSize;
25330 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
25333 if(!a_hasProperty(cellId, SolverCell::IsFlux)) {
25336 if(a_isBndryGhostCell(cellId)) {
25341 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) {
25344 if(a_hasProperty(cellId, SolverCell::IsInvalid)) {
25348 if(a_bndryId(cellId) > -1) {
25349 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId > -1) {
25355 noNghbrIds = a_noReconstructionNeighbors(cellId);
25357 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
25358 nghbrId = a_reconstructionNeighborId(cellId, nghbr);
25359 for(
MInt i = 0; i < nDim; i++) {
25360 m_A[nghbr][i] = a_coordinate(nghbrId, i) - a_coordinate(cellId, i);
25363 if(m_orderOfReconstruction == 2) {
25364 for(
MInt i = 0; i < nDim; i++) {
25365 m_A[nghbr][nDim + i] =
POW2(a_coordinate(nghbrId, i) - a_coordinate(cellId, i));
25367 m_A[nghbr][2 * nDim] =
25368 (a_coordinate(nghbrId, 0) - a_coordinate(cellId, 0)) * (a_coordinate(nghbrId, 1) - a_coordinate(cellId, 1));
25369 IF_CONSTEXPR(nDim == 3) {
25370 m_A[nghbr][2 * nDim + 1] = (a_coordinate(nghbrId, 0) - a_coordinate(cellId, 0))
25371 * (a_coordinate(nghbrId, 2) - a_coordinate(cellId, 2));
25372 m_A[nghbr][2 * nDim + 2] = (a_coordinate(nghbrId, 1) - a_coordinate(cellId, 1))
25373 * (a_coordinate(nghbrId, 2) - a_coordinate(cellId, 2));
25379 for(
MInt i = 0; i < noUnknowns; i++) {
25380 for(
MInt j = 0; j < noUnknowns; j++) {
25382 for(
MInt k = 0; k < noNghbrIds; k++) {
25383 m_ATA[i][j] += m_A[k][i] * m_A[k][j];
25389 const MFloat epsilon =
POW3(c_cellLengthAtLevel(maxRefinementLevel()) / (1000.0));
25392 mTerm(1, AT_,
"error recon");
25398 for(
MInt j = 0; j < noUnknowns; j++) {
25400 for(
MInt i = 0; i < noUnknowns; i++) {
25401 tmp +=
ABS(m_ATA[i][j]);
25403 norm =
mMax(norm, tmp);
25404 normi =
mMax(normi, tmp);
25408 avg += norm * normi;
25412 for(
MInt i = 0; i < noUnknowns; i++) {
25413 for(
MInt j = 0; j < noNghbrIds; j++) {
25415 for(
MInt k = 0; k < noUnknowns; k++) {
25416 m_ATA[i][j] += m_ATAi[i][k] * m_A[j][k];
25421 m_reconstructionConstants.resize(nDim * (m_reconstructionDataSize + noNghbrIds));
25422 m_reconstructionCellIds.resize(m_reconstructionDataSize + noNghbrIds);
25423 m_reconstructionNghbrIds.resize(m_reconstructionDataSize + noNghbrIds);
25426 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
25427 nghbrId = a_reconstructionNeighborId(cellId, nghbr);
25430 m_reconstructionCellIds[m_reconstructionDataSize] = cellId;
25431 m_reconstructionNghbrIds[m_reconstructionDataSize] = nghbrId;
25434 for(
MInt d = 0; d < nDim; d++) {
25435 m_reconstructionConstants[nDim * m_reconstructionDataSize + d] = m_ATA[d][nghbr];
25438 m_reconstructionDataSize++;
25441 a_reconstructionData(noCells) = m_reconstructionDataSize;
25442 m_log <<
" -> Least-squares: average condition number of A^T A: " << avg / (
MFloat)counter << endl;
25454template <MInt nDim_,
class SysEqn>
25458 const MInt noCells = m_fvBndryCnd->m_bndryCells->size();
25459 const MInt noPVars = PV->noVariables;
25460 const MInt noSlopes = nDim * noPVars;
25461 const MInt slopeMemory = m_slopeMemory;
25462 MInt j, cellId, linkedCell;
25464 MInt reconstructionDataLocation, nghbrId;
25469 for(
MInt bndryId = 0; bndryId < noCells; bndryId++) {
25470 cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25471 j = slopeMemory * cellId;
25472 for(
MInt i = 0; i < noSlopes; i++) {
25478 for(
MInt bndryId = 0; bndryId < noCells; bndryId++) {
25479 cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25480 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
25483 linkedCell = m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId;
25484 recCellId = cellId;
25485 if(linkedCell > -1) {
25486 recCellId = linkedCell;
25488 reconstructionDataLocation = a_reconstructionData(recCellId);
25489 for(
MInt nghbr = 0; nghbr < a_noReconstructionNeighbors(recCellId); nghbr++) {
25490 nghbrId = a_reconstructionNeighborId(recCellId, nghbr);
25491 for(
MInt var = 0; var < noPVars; var++) {
25492 for(
MInt i = 0; i < nDim; i++) {
25493 a_slope(cellId, var, i) += m_reconstructionConstants[nDim * reconstructionDataLocation + i]
25494 * (a_pvariable(nghbrId, var) - a_pvariable(recCellId, var));
25497 reconstructionDataLocation++;
25509template <MInt nDim_,
class SysEqn>
25513 m_log <<
"Generating FV boundary cells..." << endl;
25517 createBoundaryCells();
25520 m_fvBndryCnd->generateBndryCells();
25522 m_log << m_fvBndryCnd->m_bndryCells->size() <<
" boundary cells created" << endl;
25535template <MInt nDim_,
class SysEqn>
25541 MBool nghbrsFound =
false;
25542 MBool nghbrExist =
false;
25543 const MInt noCellIds = a_noCells();
25544 const MInt maxNoCells = maxNoGridCells();
25546 MInt currentCellId;
25547 MInt sideId, nghbrSideId;
25554 MInt tempNghbrs[16];
25555 MInt tempNghbrs1[16];
25559 if(!m_storeNghbrIds) {
25560 mAlloc(m_storeNghbrIds, m_noDirs *
IPOW2(nDim) * maxNoCells,
"m_storeNghbrIds", -1, AT_);
25562 if(!m_identNghbrIds) {
25563 mAlloc(m_identNghbrIds, m_noDirs * maxNoCells + 1,
"m_identNghbrIds", -1, AT_);
25582 for(
MInt cellId = 0; cellId < noCellIds; cellId++) {
25584 if(!a_isBndryGhostCell(cellId)) {
25586 for(
MInt d = 0; d < nDim; d++) {
25588 coordinates[cellId * nDim + d] = a_coordinate(cellId, d);
25591 if(a_bndryId(cellId) > -1) {
25592 bndryId = a_bndryId(cellId);
25595 coordinates[cellId * nDim + d] -= m_fvBndryCnd->m_bndryCells->a[bndryId].m_coordinates[d];
25602 for(
MInt smallId = 0; smallId < m_fvBndryCnd->m_smallBndryCells->size(); smallId++) {
25603 smallCell = m_fvBndryCnd->m_smallBndryCells->a[smallId];
25604 if(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId != -1) {
25605 if(a_bndryId(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId) == -1) {
25606 for(
MInt d = 0; d < nDim; d++) {
25607 coordinates[(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId) * nDim + d] =
25608 m_fvBndryCnd->m_bndryCells->a[smallCell].m_masterCoordinates[d];
25623 for(
MInt cellId = 0; cellId < noCellIds; cellId++) {
25624 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
25625 m_identNghbrIds[cellId * m_noDirs + dirId] = pos;
25629 if(!a_isBndryGhostCell(cellId)) {
25631 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
25633 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
25634 MInt spaceId = dirId / 2;
25635 sideId = dirId % 2;
25636 nghbrSideId = (sideId + 1) % 2;
25638 nghbrExist =
false;
25642 m_identNghbrIds[cellId * m_noDirs + dirId] = pos;
25652 if(a_hasNeighbor(cellId, dirId) > 0) {
25653 if(a_level(c_neighborId(cellId, dirId)) <= maxRefinementLevel()) {
25656 nghbrId = c_neighborId(cellId, dirId);
25664 if(a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel)) {
25667 m_storeNghbrIds[pos] = nghbrId;
25676 tempNghbrs[0] = nghbrId;
25677 nghbrsFound =
false;
25684 while(nghbrsFound ==
false) {
25691 for(
MInt index = 0; index < maxIndex; index++) {
25693 ASSERT(index > -1 && index < 16,
"");
25694 nghbrId = tempNghbrs[index];
25705 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
25706 if(c_childId(nghbrId, childId) == -1) {
25710 if((coordinates[c_childId(nghbrId, childId) * nDim + spaceId]
25711 - coordinates[nghbrId * nDim + spaceId])
25712 * ((float)nghbrSideId - 0.5)
25714 nghbrChildId = c_childId(nghbrId, childId);
25716 if((c_noChildren(nghbrChildId) == 0 && a_level(nghbrChildId) <= maxRefinementLevel())
25717 || (c_noChildren(nghbrChildId) > 0 && a_level(nghbrChildId) == maxRefinementLevel())) {
25720 m_storeNghbrIds[pos] = nghbrChildId;
25726 ASSERT(k > -1 && k < 16,
25727 "Too many local child neighbors. Something might be wrong with "
25729 tempNghbrs1[k] = nghbrChildId;
25738 nghbrsFound =
true;
25742 for(
MInt l = 0; l < k; l++) {
25743 ASSERT(l > -1 && l < 16,
"");
25744 tempNghbrs[l] = tempNghbrs1[l];
25752 currentCellId = cellId;
25757 while(nghbrExist ==
false) {
25759 if(c_parentId(currentCellId) == -1) {
25765 if((coordinates[currentCellId * nDim + spaceId] - coordinates[c_parentId(currentCellId) * nDim + spaceId])
25766 * ((
float)sideId - 0.5)
25773 currentCellId = c_parentId(currentCellId);
25776 if(a_hasNeighbor(currentCellId, dirId) > 0) {
25778 nghbrId = c_neighborId(currentCellId, dirId);
25780 if(a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel)) {
25781 m_storeNghbrIds[pos] = nghbrId;
25791 m_identNghbrIds[noCellIds * m_noDirs] = pos;
25811template <MInt nDim_,
class SysEqn>
25813 IF_CONSTEXPR(nDim == 2)
mTerm(1,
"Only available in 3D. MGC not yet implemented in 2D");
25816 MBool nghbrsFound =
false;
25817 MBool nghbrExist =
false;
25818 const MInt noCellIds = a_noCells();
25819 const MInt maxNoCells = maxNoGridCells();
25821 MInt currentCellId;
25833 const MInt sideToChildren[6][4] = {{0, 2, 4, 6}, {1, 3, 5, 7}, {0, 1, 4, 5},
25834 {2, 3, 6, 7}, {0, 1, 2, 3}, {4, 5, 6, 7}};
25835 const MInt otherDir[6] = {1, 0, 3, 2, 5, 4};
25836 const MInt noChildrenPerSide =
IPOW2(nDim - 1);
25837 MBool isNonFluidSide[m_noDirs];
25838 MBool nonFluidSide =
false;
25840 if(!m_storeNghbrIds) {
25841 mAlloc(m_storeNghbrIds, m_noDirs *
IPOW2(nDim) * maxNoCells,
"m_storeNghbrIds", -1, AT_);
25843 if(!m_identNghbrIds) {
25844 mAlloc(m_identNghbrIds, m_noDirs * maxNoCells + 1,
"m_identNghbrIds", -1, AT_);
25864 for(
MInt cellId = 0; cellId < noCellIds; cellId++) {
25865 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
25866 m_identNghbrIds[cellId * m_noDirs + dirId] = pos;
25867 isNonFluidSide[dirId] =
false;
25870 bndryId = a_bndryId(cellId);
25872 if(a_hasProperty(cellId, SolverCell::IsInvalid)) {
25877 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
25880 for(
MInt face = 0; face < m_noDirs; face++) {
25881 isNonFluidSide[face] = m_fvBndryCnd->m_bndryCells->a[bndryId].m_externalFaces[face];
25889 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
25890 nghbrExist =
false;
25894 m_identNghbrIds[cellId * m_noDirs + dirId] = pos;
25896 if(isNonFluidSide[dirId]) {
25907 MInt gridcellId = cellId;
25908 if(a_hasProperty(cellId, SolverCell::IsSplitClone)) {
25909 gridcellId = m_splitChildToSplitCell.find(cellId)->second;
25913 if(a_hasNeighbor(gridcellId, dirId) > 0
25914 && (a_level(c_neighborId(gridcellId, dirId)) <= maxRefinementLevel())) {
25917 nghbrId = c_neighborId(gridcellId, dirId);
25925 if(a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel)) {
25932 if(m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2 + 1] > -1) {
25935 if(m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2] > -1) {
25936 m_storeNghbrIds[pos] = m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2];
25938 if(m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2]
25939 != m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2 + 1]) {
25940 m_storeNghbrIds[pos] = m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2];
25943 cerr <<
" warning in findNghbrIdsMGC - assumed split face with two different "
25944 "neighbors. But neighbors are identical... "
25946 cerr <<
" cell: " << cellId <<
" bndryId: " << bndryId <<
" dir: " << dirId
25947 <<
" nghbrId: " << nghbrId <<
" nghbr1 in m_bndryNghbrs: "
25948 << m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2]
25949 <<
" nghbr2 in m_bndryNghbrs: "
25950 << m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2 + 1] << endl;
25953 cerr <<
" cell: " << cellId <<
" bndryId: " << bndryId <<
" dir: " << dirId
25954 <<
" nghbrId: " << nghbrId <<
" nghbr1 in m_bndryNghbrs: "
25955 << m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2]
25956 <<
" nghbr2 in m_bndryNghbrs: "
25957 << m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2 + 1] << endl;
25959 stringstream errorMessage;
25960 errorMessage <<
" error in findNghbrIdsMGC - assumed fluid side to split "
25961 "relative, but -1 neighbor stored in m_bndryNghbrs... ";
25962 mTerm(1, AT_, errorMessage.str());
25964 }
else if(nghbrId != m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2]) {
25968 if(m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2] > -1) {
25969 m_storeNghbrIds[pos] = m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2];
25972 stringstream errorMessage;
25973 errorMessage <<
" error in findNghbrIdsMGC - assumed fluid side to split "
25974 "relative, but -1 neighbor stored in m_bndryNghbrs... "
25976 <<
" cell: " << cellId <<
" bndryId: " << bndryId <<
" dir: " << dirId
25977 <<
" nghbrId: " << nghbrId <<
" nghbr in m_bndryNghbrs: "
25978 << m_fvBndryCnd->m_bndryNghbrs[bndryId * 2 * m_noDirs + dirId * 2];
25979 mTerm(1, AT_, errorMessage.str());
25984 m_storeNghbrIds[pos] = nghbrId;
25988 m_storeNghbrIds[pos] = nghbrId;
26000 tempNghbrs[0] = nghbrId;
26001 nghbrsFound =
false;
26008 while(nghbrsFound ==
false) {
26015 for(
MInt index = 0; index < maxIndex; index++) {
26017 nghbrId = tempNghbrs[index];
26019 if(c_noChildren(nghbrId)) {
26024 for(
MInt c = 0; c < noChildrenPerSide; c++) {
26025 nghbrChildId = c_childId(nghbrId, sideToChildren[otherDir[dirId]][c]);
26027 if(nghbrChildId > -1) {
26029 if((c_noChildren(nghbrChildId) == 0 && a_level(nghbrChildId) <= maxRefinementLevel())
26030 || (c_noChildren(nghbrChildId) > 0 && a_level(nghbrChildId) == maxRefinementLevel())) {
26035 nghbrBndryId = a_bndryId(nghbrChildId);
26036 nonFluidSide =
false;
26037 if(nghbrBndryId > -1) {
26038 if(m_fvBndryCnd->m_bndryCells->a[nghbrBndryId].m_externalFaces[dirId]) {
26039 nonFluidSide =
true;
26043 if(!nonFluidSide) {
26044 m_storeNghbrIds[pos] = nghbrChildId;
26050 tempNghbrs1[k] = nghbrChildId;
26060 nghbrsFound =
true;
26064 for(
MInt l = 0; l < k; l++) {
26065 tempNghbrs[l] = tempNghbrs1[l];
26074 currentCellId = cellId;
26076 if(a_hasProperty(currentCellId, SolverCell::IsSplitClone)) {
26077 currentCellId = m_splitChildToSplitCell.find(currentCellId)->second;
26083 while(nghbrExist ==
false) {
26085 if(c_parentId(currentCellId) == -1) {
26091 for(
MInt c = 0; c < noChildrenPerSide; c++) {
26092 if(currentCellId == c_childId(c_parentId(currentCellId), sideToChildren[dirId][c])) {
26095 currentCellId = c_parentId(currentCellId);
26098 if(a_hasNeighbor(currentCellId, dirId) > 0) {
26100 nghbrId = c_neighborId(currentCellId, dirId);
26102 if(a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel)) {
26104 nghbrBndryId = a_bndryId(nghbrId);
26105 nonFluidSide =
false;
26106 if(nghbrBndryId > -1) {
26107 if(m_fvBndryCnd->m_bndryCells->a[nghbrBndryId].m_externalFaces[dirId]) {
26108 nonFluidSide =
true;
26112 if(!nonFluidSide) {
26113 m_storeNghbrIds[pos] = nghbrId;
26128 m_identNghbrIds[noCellIds * m_noDirs] = pos;
26142template <MInt nDim_,
class SysEqn>
26146 ASSERT(cellId >= 0,
"ERROR: Invalid cellId!");
26148 nghbrList.push_back(cellId);
26151 auto uniqueAdd = [&](
MInt newElement) {
26152 auto it = find(nghbrList.begin(), nghbrList.end(), newElement);
26153 if(it == nghbrList.end() && newElement >= 0) {
26154 nghbrList.push_back(newElement);
26163 static constexpr MInt diagDirs[4]{3, 2, 0, 1};
26164 for(
MInt dir = 0; dir < 2 * nDim; dir++) {
26166 for(
MInt j = m_identNghbrIds[2 * cellId * nDim + dir]; j < m_identNghbrIds[2 * cellId * nDim + dir + 1]; j++) {
26167 const MInt nghbrId = m_storeNghbrIds[j];
26168 uniqueAdd(nghbrId);
26171 for(
MInt t = m_identNghbrIds[2 * nghbrId * nDim + diagDirs[dir]];
26172 t < m_identNghbrIds[2 * nghbrId * nDim + diagDirs[dir] + 1];
26174 const MInt diagNghbr = m_storeNghbrIds[t];
26175 uniqueAdd(diagNghbr);
26185 IF_CONSTEXPR(nDim == 3) {
26186 for(
MInt dirZ = 4; dirZ < 6; dirZ++) {
26187 for(
MInt j = m_identNghbrIds[2 * cellId * nDim + dirZ]; j < m_identNghbrIds[2 * cellId * nDim + dirZ + 1]; j++) {
26188 const MInt nghbrIdZ = m_storeNghbrIds[j];
26189 for(
MInt dir = 0; dir < 4; dir++) {
26190 for(
MInt t = m_identNghbrIds[2 * nghbrIdZ * nDim + dir]; t < m_identNghbrIds[2 * nghbrIdZ * nDim + dir + 1];
26192 const MInt nghbrId = m_storeNghbrIds[t];
26193 uniqueAdd(nghbrId);
26195 for(
MInt v = m_identNghbrIds[2 * nghbrId * nDim + diagDirs[dir]];
26196 v < m_identNghbrIds[2 * nghbrId * nDim + diagDirs[dir] + 1];
26198 const MInt triDiagNghbrId = m_storeNghbrIds[v];
26199 uniqueAdd(triDiagNghbrId);
26218template <MInt nDim_,
class SysEqn>
26220 vector<MInt>& nghbrList) {
26221 ASSERT(layer > 0,
"ERROR: Invalid layer!");
26222 ASSERT(cellId >= 0,
"ERROR: Invalid cellId!");
26227 auto uniqueAdd = [&](
MInt newElement) {
26228 auto it = find(nghbrList.begin(), nghbrList.end(), newElement);
26229 if(it == nghbrList.end() && newElement >= 0) {
26230 nghbrList.push_back(newElement);
26236 vector<MInt> tempNghbrCollection{};
26241 findDirectNghbrs(cellId, nghbrList);
26246 for(
MInt currEx = 1; currEx < layer; currEx++) {
26248 for(
auto& nghbr : nghbrList) {
26249 findDirectNghbrs(nghbr, tempNghbrCollection);
26253 for(
auto& nghbr : tempNghbrCollection) {
26254 if(uniqueAdd(nghbr) && currEx + 1 < layer) {
26256 nghbrList.push_back(nghbr);
26263template <MInt nDim_,
class SysEqn>
26266 IF_CONSTEXPR(!hasE<SysEqn>)
26267 mTerm(1, AT_,
"Not compatible with SysEqn without RHO_E!");
26269 switch(m_writeOutData) {
26273 for(
MInt dimId = 0; dimId < nDim; dimId++)
26274 rhoU2 +=
POW2(m_VVInfinity[dimId]);
26275 rhoU2 *= F1B2 * m_rhoInfinity;
26279 ofl.open(
"CenterlineData");
26281 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
26282 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
26283 if(fabs(a_coordinate(cellId, 1) - c_cellLengthAtLevel(a_level(cellId) + 1)) < 0.001
26284 && fabs(a_coordinate(cellId, nDim - 1) - c_cellLengthAtLevel(a_level(cellId) + 1)) < 0.001) {
26285 for(
MInt dimId = 0; dimId < nDim; dimId++)
26286 ofl << a_coordinate(cellId, dimId) <<
" ";
26287 for(
MInt dimId = 0; dimId < nDim; dimId++)
26288 ofl << a_variable(cellId, CV->RHO_VV[dimId]) / a_variable(cellId, CV->RHO) <<
" ";
26289 ofl << a_variable(cellId, CV->RHO) <<
" ";
26298 const MFloat yOffset = 30.0;
26299 const MFloat xOffset = 15.028;
26300 const MFloat radToDeg = 360.0 / (2.0 * PI);
26301 ofl2.open(
"BoundaryData");
26303 for(
MInt bndryId = 0; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
26304 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
26305 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId >= 3000
26306 && m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId <= 3003) {
26307 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
26309 if(a_coordinate(cellId, 1) - yOffset > 0 && a_coordinate(cellId, 0) - xOffset > 0) {
26310 angle = 180 - radToDeg * atan((a_coordinate(cellId, 1) - yOffset) / (a_coordinate(cellId, 0) - xOffset));
26312 if(a_coordinate(cellId, 1) - yOffset > 0 && a_coordinate(cellId, 0) - xOffset < 0) {
26313 angle = -radToDeg * atan((a_coordinate(cellId, 1) - yOffset) / (a_coordinate(cellId, 0) - xOffset));
26315 if(a_coordinate(cellId, 1) - yOffset < 0 && a_coordinate(cellId, 0) - xOffset > 0) {
26317 - radToDeg * atan((a_coordinate(cellId, 1) - yOffset) / (a_coordinate(cellId, 0) - xOffset));
26320 - radToDeg * atan((a_coordinate(cellId, 1) - yOffset) / (a_coordinate(cellId, 0) - xOffset));
26328 for(
MInt dimId = 0; dimId < nDim; dimId++) {
26329 vv[dimId] = a_variable(cellId, CV->RHO_VV[dimId]) / a_variable(cellId, CV->RHO);
26330 vv2 +=
POW2(vv[dimId]);
26334 const MFloat p = sysEqn().pressure(a_variable(cellId, CV->RHO), vv2, a_variable(cellId, CV->RHO_E));
26335 const MFloat cp = (p - m_PInfinity) / rhoU2;
26338 const MFloat ma = sqrt(vv2) / sysEqn().speedOfSound(a_variable(cellId, CV->RHO), p);
26340 ofl2 << angle <<
" ";
26341 for(
MInt dimId = 0; dimId < nDim; dimId++)
26342 ofl << vv[dimId] <<
" ";
26345 for(
MInt dimId = 0; dimId < nDim; dimId++)
26346 ofl << a_coordinate(cellId, dimId) <<
" ";
26347 ofl2 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId <<
" ";
26355 const MInt direction = 1;
26356 IF_CONSTEXPR(direction >= nDim)
mTerm(1, AT_,
"direction>=nDim");
26357 const MFloat coordinate = 100.0;
26361 file <<
"PlaneData" << domainId();
26362 ofl.open((file.str()).c_str(), ios::out);
26364 for(
MInt c = 0; c < noInternalCells(); c++) {
26365 if(c_noChildren(c) > 0)
continue;
26367 if(a_level(c) < 0)
continue;
26369 if(a_coordinate(c, direction) < coordinate)
continue;
26371 if(a_hasNeighbor(c, 2 * direction) > 0) {
26372 if(a_coordinate(c_neighborId(c, 2 * direction), direction) > coordinate)
continue;
26378 for(
MInt i = 0; i < nDim; i++)
26379 ofl << a_coordinate(c, i) <<
" ";
26381 for(
MInt v = 0; v < CV->noVariables; v++)
26382 ofl << a_variable(c, v) <<
" ";
26391 stringstream errorMessage;
26392 errorMessage <<
"FvCartesianSolverXD::writeCenterLineVel() switch variable 'm_writeOutData' with value "
26393 << m_writeOutData <<
" not matching any case." << endl;
26394 mTerm(1, AT_, errorMessage.str());
26406template <MInt nDim_,
class SysEqn>
26410 const MInt noCVars = CV->noVariables;
26411 const MInt noPVars = PV->noVariables;
26413 const MFloat gammaMinusOne = m_gamma - 1.0;
26414 const MFloat gammaPlusOne = m_gamma + 1.0;
26417 m_TInfinity = sysEqn().temperature_IR(m_Ma);
26418 MFloat UT = m_Ma * sqrt(m_TInfinity);
26422 if(m_initialCondition == 465 || m_initialCondition == 9465) {
26428 m_UInfinity = UT *
cos(m_angle[0]) *
cos(m_angle[1]);
26429 m_VInfinity = UT * sin(m_angle[0]) *
cos(m_angle[1]);
26430 IF_CONSTEXPR(nDim == 3) m_WInfinity = UT * sin(m_angle[1]);
26431 m_VVInfinity[0] = m_UInfinity;
26432 m_VVInfinity[1] = m_VInfinity;
26433 IF_CONSTEXPR(nDim == 3) m_VVInfinity[2] = m_WInfinity;
26434 m_PInfinity = sysEqn().pressure_IR(m_TInfinity);
26436 m_rhoInfinity = sysEqn().density_IR(m_TInfinity);
26437 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
26438 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
26439 IF_CONSTEXPR(nDim == 3) m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
26440 m_rhoVVInfinity[0] = m_rhoUInfinity;
26441 m_rhoVVInfinity[1] = m_rhoVInfinity;
26442 IF_CONSTEXPR(nDim == 3) m_rhoVVInfinity[2] = m_rhoWInfinity;
26444 m_rhoEInfinity = m_PInfinity / gammaMinusOne + F1B2 * m_rhoInfinity *
POW2(UT);
26448 m_hInfinity = m_PInfinity / m_rhoInfinity * m_gamma / gammaMinusOne;
26450 sysEqn().m_muInfinity = SUTHERLANDLAW(m_TInfinity);
26453 m_DInfinity = sysEqn().m_muInfinity;
26456 m_DthInfinity = sysEqn().m_muInfinity / (m_rhoInfinity * m_Pr);
26457 m_SInfinity = F1 / m_gamma;
26461 sysEqn().m_Re0 = m_Re * sysEqn().m_muInfinity / (m_rhoInfinity * m_Ma * sqrt(m_TInfinity));
26462 m_rRe0 = 1. / sysEqn().m_Re0;
26465 const
MFloat lamVisc = SUTHERLANDLAW(m_TInfinity);
26467 const
MFloat nuTilde = chi * (lamVisc / m_rhoInfinity);
26468 m_nuTildeInfinity = nuTilde;
26470 m_kInfinity = F3B2 *
POW2(m_turbulenceDegree * m_UInfinity);
26471 m_omegaInfinity = sqrt(m_kInfinity) / (pow(0.09, 0.25) * m_referenceLength);
26474 setCombustionGequPvVariables();
26481 switch(m_initialCondition) {
26487 if(abs(m_angle[1]) > 1e-10) {
26488 mTerm(1, AT_,
"Flow component in z-diection currently not allowed for this IC!");
26503 SA = Context::getSolverProperty<MInt>(
"shockAlignment", m_solverId, AT_, &SA);
26505 mTerm(1, AT_,
"shockAlignment with z-axis not implemented yet. Feel free to do this.");
26508 if(m_VVInfinity[PV->VV[SA]] / sysEqn().speedOfSound(m_rhoInfinity, m_PInfinity) <= F1) {
26509 mTerm(1, AT_,
"shock normal Mach number to small");
26515 mAlloc(m_postShockPV, noPVars,
"m_postShockPV", F0, AT_);
26516 mAlloc(m_postShockCV, noCVars,
"m_postShockCV", F0, AT_);
26518 m_postShockPV[PV->RHO] = m_rhoInfinity * (gammaPlusOne * strength) / (gammaMinusOne * strength + F2);
26519 m_postShockCV[CV->RHO] = m_postShockPV[PV->RHO];
26521 m_postShockPV[PV->VV[!SA]] = m_VVInfinity[PV->VV[!SA]];
26522 m_postShockCV[CV->RHO_VV[!SA]] = m_postShockPV[PV->VV[!SA]] * m_postShockPV[PV->RHO];
26524 m_postShockPV[PV->VV[SA]] = m_rhoVVInfinity[CV->RHO_VV[SA]] / m_postShockPV[PV->RHO];
26525 m_postShockCV[CV->RHO_VV[SA]] = m_rhoVVInfinity[CV->RHO_VV[SA]];
26527 IF_CONSTEXPR(nDim == 3) {
26528 m_postShockPV[PV->VV[2]] = 0.0;
26529 m_postShockCV[CV->RHO_VV[2]] = 0.0;
26532 m_postShockPV[PV->P] = m_PInfinity * (F1 - m_gamma + F2 * m_gamma * strength) / gammaPlusOne;
26533 IF_CONSTEXPR(hasE<SysEqn>)
26534 m_postShockCV[CV->RHO_E] =
26535 m_postShockPV[PV->P] / gammaMinusOne
26536 + F1B2 * m_postShockPV[PV->RHO] * (
POW2(m_postShockPV[PV->U]) +
POW2(m_postShockPV[PV->V]));
26539 MInt numBranchPoints = 4;
26546 atan(F2 * (
cos(sigma) / sin(sigma)) * (strength - F1) / (
POW2(m_Ma) * (m_gamma +
cos(F2 * sigma)) + F2));
26548 MFloat Ma1_n = m_Ma * sin(sigma);
26550 MFloat Ma2 = sqrt(
POW2(m_postShockPV[PV->U]) +
POW2(m_postShockPV[PV->V]))
26551 / sysEqn().speedOfSound(m_postShockPV[PV->RHO], m_postShockPV[PV->P]);
26552 if(Ma2 <= F1)
mTerm(1, AT_,
"postshock Mach number to small");
26554 MFloat Ma2_n = Ma2 * sin(sigma - beta);
26555 MFloat Ma2_t = Ma2 *
cos(sigma - beta);
26562 MFloat ktfm_2 = -
b / (F2 *
a) - sqrt(d);
26563 MFloat ktsm_2 = -
b / (F2 *
a) + sqrt(d);
26565 kfp_2(0) = sin(sigma - beta) / (Ma2 + F1);
26566 kfp_2(1) =
cos(sigma - beta) / (Ma2 + F1);
26567 kfm_2(0) = -(Ma2_n - ktfm_2 * Ma2_n * Ma2_t) / (F1 -
POW2(Ma2_n));
26569 ksm_2(0) = -(Ma2_n - ktsm_2 * Ma2_n * Ma2_t) / (F1 -
POW2(Ma2_n));
26571 ksp_2(0) = sin(sigma - beta) / (Ma2 - F1);
26572 ksp_2(1) =
cos(sigma - beta) / (Ma2 - F1);
26575 kt_1(0) = kfp_2(1) * sqrt(m_TInfinity / (sysEqn().temperature_ES(m_postShockPV[PV->RHO], m_postShockPV[PV->P])));
26576 kt_1(1) = kfm_2(1) * sqrt(m_TInfinity / (sysEqn().temperature_ES(m_postShockPV[PV->RHO], m_postShockPV[PV->P])));
26577 kt_1(2) = ksm_2(1) * sqrt(m_TInfinity / (sysEqn().temperature_ES(m_postShockPV[PV->RHO], m_postShockPV[PV->P])));
26578 kt_1(3) = ksp_2(1) * sqrt(m_TInfinity / (sysEqn().temperature_ES(m_postShockPV[PV->RHO], m_postShockPV[PV->P])));
26580 (F1 / Ma2_t) * sqrt(m_TInfinity / (sysEqn().temperature_ES(m_postShockPV[PV->RHO], m_postShockPV[PV->P])));
26582 (Ma2_t / (
POW2(Ma2) - F1)) * sqrt(sysEqn().temperature_ES(m_postShockPV[PV->RHO], m_postShockPV[PV->P]));
26584 MInt length_kt_1 = kt_1.size();
26586 for(
MInt i = 0; i < length_kt_1; i++) {
26588 MFloat p = F2 * Ma1_n * (F1 - Ma1_t * kt) / (F1 -
POW2(Ma1_n));
26592 kn(i, 0) = (-
p / F2) + sqrt(
POW2(p / F2) - q);
26594 kn(i, 1) = (F1 - Ma1_t * kt) / Ma1_n;
26596 kn(i, 2) = (-
p / F2) - sqrt(
POW2(p / F2) - q);
26599 m_log <<
"**************************" << endl;
26600 m_log <<
"Postshock Conditions summary" << endl;
26601 m_log <<
"**************************" << endl;
26602 m_log <<
"TInfinity = " << sysEqn().temperature_ES(m_postShockPV[PV->RHO], m_postShockPV[PV->P]) << endl;
26603 m_log <<
"UInfinity = " << m_postShockPV[PV->U] << endl;
26604 m_log <<
"VInfinity = " << m_postShockPV[PV->V] << endl;
26605 IF_CONSTEXPR(nDim == 3)
m_log << "WInfinity = " << m_postShockPV[PV->W] << endl;
26606 m_log << "PInfinity = " << m_postShockPV[PV->P] << endl;
26607 m_log << "rhoInfinity(PV) = " << m_postShockPV[PV->RHO] << endl;
26608 m_log << "AInfinity = " << sysEqn().speedOfSound(m_postShockPV[PV->RHO], m_postShockPV[PV->P]) << endl;
26609 m_log << "Ma = " << Ma2 << endl;
26610 m_log << "Ma_x = " << m_postShockPV[PV->U] / sysEqn().speedOfSound(m_postShockPV[PV->RHO], m_postShockPV[PV->P])
26612 m_log << "Ma_y = " << m_postShockPV[PV->V] / sysEqn().speedOfSound(m_postShockPV[PV->RHO], m_postShockPV[PV->P])
26614 m_log << "rhoInfinity(CV) = " << m_postShockCV[CV->RHO] << endl;
26615 IF_CONSTEXPR(
hasE<SysEqn>)
26616 m_log << "rhoEInfinity = " << m_postShockCV[CV->RHO_E] << endl;
26617 m_log << "rhoUInfinity = " << m_postShockCV[CV->RHO_U] << endl;
26618 m_log << "rhoVInfinity = " << m_postShockCV[CV->RHO_V] << endl;
26619 IF_CONSTEXPR(nDim == 3)
m_log << "rhoWInfinity = " << m_postShockCV[CV->RHO_W] << endl;
26620 m_log << "******* shock wave *******" << endl;
26621 m_log << "Ma2 = " << Ma2 << endl;
26622 m_log << "Ma2_n = " << Ma2_n << endl;
26623 m_log << "Ma2_t = " << Ma2_t << endl;
26624 m_log << "sigma = " << 180.0 * sigma / PI << endl;
26625 m_log << "beta = " << 180.0 * beta / PI << endl;
26626 m_log << "***** branch points ******" << endl;
26627 m_log << "canonical form" << endl;
26628 m_log << " fast: " << kfp_2(0) << ", " << kfp_2(1) << endl;
26629 for(
MInt us = 0; us < 3; us++) {
26630 MFloat modeAngle = atan2(kt_1(0), kn(0, us));
26631 m_log <<
" upstream mode type " << us - 1
26634 << 180.0 * modeAngle / PI <<
", " << 180.0 * (modeAngle - (PI / F2 - sigma)) / PI
26636 << 180.0 * (SA * PI / F2 + (F1 - SA * F2) * modeAngle) / PI
26639 m_log <<
" slow: " << ksp_2(0) <<
", " << ksp_2(1) << endl;
26640 for(
MInt us = 0; us < 3; us++) {
26641 MFloat modeAngle = atan2(kt_1(3), kn(3, us));
26642 m_log <<
" upstream mode type " << us - 1
26645 << 180.0 * modeAngle / PI <<
", " << 180.0 * (modeAngle - (PI / F2 - sigma)) / PI <<
", "
26646 << 180.0 * (SA * PI / F2 + (F1 - SA * F2) * modeAngle) / PI << endl;
26648 m_log <<
"shock aligned form" << endl;
26649 m_log <<
" fast: " << kfm_2(0) <<
", " << kfm_2(1) << endl;
26650 for(
MInt us = 0; us < 3; us++) {
26651 MFloat modeAngle = atan2(kt_1(1), kn(1, us));
26652 m_log <<
" upstream mode type " << us - 1
26655 << 180.0 * modeAngle / PI <<
", " << 180.0 * (modeAngle - (PI / F2 - sigma)) / PI <<
", "
26656 << 180.0 * (SA * PI / F2 + (F1 - SA * F2) * modeAngle) / PI << endl;
26658 m_log <<
" slow: " << ksm_2(0) <<
", " << ksm_2(1) << endl;
26659 for(
MInt us = 0; us < 3; us++) {
26660 MFloat modeAngle = atan2(kt_1(2), kn(2, us));
26661 m_log <<
" upstream mode type " << us - 1
26664 << 180.0 * modeAngle / PI <<
", " << 180.0 * (modeAngle - (PI / F2 - sigma)) / PI <<
", "
26665 << 180.0 * (SA * PI / F2 + (F1 - SA * F2) * modeAngle) / PI << endl;
26667 m_log <<
"evanescent cases" << endl;
26668 m_log <<
" zero real number of kn and real(k_ac)==k_en:" << endl;
26669 for(
MInt us = 0; us < 3; us++) {
26670 MFloat modeAngle = atan2(kt_1(4), kn(4, us));
26671 m_log <<
" upstream mode type " << us - 1
26674 << 180.0 * modeAngle / PI <<
", " << 180.0 * (modeAngle - (PI / F2 - sigma)) / PI <<
", "
26675 << 180.0 * (SA * PI / F2 + (F1 - SA * F2) * modeAngle) / PI << endl;
26677 m_log <<
" real(k_ac)||u and max(imag(kt))" << endl;
26678 for(
MInt us = 0; us < 3; us++) {
26679 MFloat modeAngle = atan2(kt_1(5), kn(5, us));
26680 m_log <<
" upstream mode type " << us - 1
26683 << 180.0 * modeAngle / PI <<
", " << 180.0 * (modeAngle - (PI / F2 - sigma)) / PI <<
", "
26684 << 180.0 * (SA * PI / F2 + (F1 - SA * F2) * modeAngle) / PI << endl;
26694 ASSERT(isDetChem<SysEqn>,
"IC not compatible with chosen sysEqn.");
26697 m_TInfinity = m_detChem.infTemperature;
26700 UT = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[0];
26703 MPI_Bcast(&recvVel, 1, MPI_DOUBLE, 0, mpiComm(), AT_,
"recvVel");
26705 m_log <<
"Reconstructed infinity velocity:" << recvVel << endl;
26707 m_UInfinity = recvVel *
cos(m_angle[0]) *
cos(m_angle[1]);
26708 m_VInfinity = recvVel * sin(m_angle[0]) *
cos(m_angle[1]);
26709 IF_CONSTEXPR(nDim == 3) m_WInfinity = recvVel * sin(m_angle[1]);
26711 m_VVInfinity[0] = m_UInfinity;
26712 m_VVInfinity[1] = m_VInfinity;
26713 IF_CONSTEXPR(nDim == 3) m_VVInfinity[2] = m_WInfinity;
26715 m_PInfinity = m_detChem.infPressure;
26717#if defined(WITH_CANTERA)
26718 m_canteraThermo->setState_TPY(m_TInfinity, m_PInfinity, &m_YInfinity[0]);
26719 sysEqn().m_muInfinity = m_canteraTransport->viscosity();
26722 MFloat FmeanMolarWeightInfinity = F0;
26723 for(
MInt s = 0; s < m_noSpecies; s++) {
26724 FmeanMolarWeightInfinity += m_YInfinity[s] * m_fMolarMass[s];
26727 MFloat meanMolarWeightInfinity = F1 / FmeanMolarWeightInfinity;
26729 m_rhoInfinity = m_PInfinity * meanMolarWeightInfinity / m_gasConstant / m_detChem.infTemperature;
26731 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
26732 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
26733 IF_CONSTEXPR(nDim == 3) m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
26735 m_rhoVVInfinity[0] = m_rhoUInfinity;
26736 m_rhoVVInfinity[1] = m_rhoVInfinity;
26737 IF_CONSTEXPR(nDim == 3) m_rhoVVInfinity[2] = m_rhoWInfinity;
26739 const
MInt maxLineLength = 256;
26741 snprintf(
b, maxLineLength, "rhoInfinity: %.6e | muInfinity: %.6e | uInfinity: %.6e | vInfinity: %.6e |",
26742 m_rhoInfinity, sysEqn().m_muInfinity, m_UInfinity, m_VInfinity);
26744 m_log <<
b << std::endl;
26750 if(!m_levelSetMb) {
26751 m_rhoInfinity = F1;
26752 m_PInfinity = sysEqn().p_Ref();
26753 m_UInfinity = m_Ma;
26755 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
26756 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
26757 m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
26758 m_rhoEInfinity = m_PInfinity / gammaMinusOne + F1B2 * m_rhoInfinity *
POW2(m_Ma);
26759 m_hInfinity = m_PInfinity / m_rhoInfinity * m_gamma / gammaMinusOne;
26760 sysEqn().m_Re0 = m_Re * SUTHERLANDLAW(m_TInfinity) / (m_rhoInfinity * m_UInfinity);
26767 m_log <<
"Invalidating infinity variables to prevent/detect their usage for jet "
26768 "computations with a nozzle ..."
26773 const MFloat T_0 = 286.4;
26774 const MFloat T_inf = 280.2;
26775 const MFloat p_0 = 1.78e5;
26776 const MFloat p_inf = 0.97e5;
26778 const MFloat temperature_j = m_normJetTemperature * T_inf / T_0;
26779 m_nozzleExitTemp = temperature_j;
26781 const MFloat pressure_j = p_inf / (m_gamma * p_0);
26784 const MFloat rho_j = sysEqn().density_ES(pressure_j, temperature_j);
26785 m_nozzleExitRho = rho_j;
26787 const MFloat Ma_j = m_maNozzleExit * sqrt(1.0 / m_normJetTemperature);
26788 m_nozzleExitMaJet = Ma_j;
26790 const MFloat u_j = Ma_j * sqrt(temperature_j);
26791 m_nozzleExitU = u_j;
26793 const MFloat mu_j = SUTHERLANDLAW(temperature_j);
26795 m_log <<
"Ma_j = " << Ma_j << std::endl;
26796 m_log <<
"T_j = " << temperature_j << std::endl;
26797 m_log <<
"p_j = " << pressure_j << std::endl;
26798 m_log <<
"rho_j = " << rho_j << std::endl;
26799 m_log <<
"u_j = " << u_j << std::endl;
26800 m_log <<
"mu_j = " << mu_j << std::endl;
26802 sysEqn().m_Re0 = m_Re * mu_j / (rho_j * u_j);
26803 m_rRe0 = 1. / sysEqn().m_Re0;
26805 m_log <<
"Re_0 = " << sysEqn().m_Re0 << std::endl;
26806 m_log <<
"Re_j = " << m_Re <<
" " << (rho_j * u_j) / mu_j << std::endl;
26809 const MFloat pressureAmbient = pressure_j;
26810 const MFloat temperatureAmbient = temperature_j / m_normJetTemperature;
26811 const MFloat densityAmbient = sysEqn().density_ES(pressureAmbient, temperatureAmbient);
26813 m_PInfinity = pressureAmbient;
26814 m_rhoInfinity = densityAmbient;
26815 m_TInfinity = temperatureAmbient;
26817 m_log <<
"T_inf = " << m_TInfinity << std::endl;
26818 m_log <<
"p_inf = " << m_PInfinity << std::endl;
26819 m_log <<
"rho_inf = " << m_rhoInfinity << std::endl;
26823 m_log <<
"timeRef = " << m_timeRef << std::endl;
26827 for(
MInt n = 0; n < 10; n++) {
26828 const MFloat tmp = (1.0 + 0.5 * (m_gamma - 1) *
POW2(Ma_i));
26829 const MFloat exponent = -(m_gamma + 1) / (2 * (m_gamma - 1));
26830 const MFloat fkt_g =
POW2(m_outletRadius / m_inletRadius) * m_gamma * pressure_j * Ma_j / sqrt(temperature_j)
26831 - Ma_i * pow(tmp, exponent);
26833 const MFloat diff_g = pow(tmp, exponent) * (-1 +
POW2(Ma_i) * 0.5 * (m_gamma + 1.0) / tmp);
26835 Ma_i = Ma_i - fkt_g / diff_g;
26838 m_maNozzleInlet = Ma_i;
26840 const MFloat temperature_i = sysEqn().temperature_IR(Ma_i);
26841 const MFloat pressure_i = sysEqn().pressure_IR(temperature_i);
26842 const MFloat density_i = sysEqn().density_ES(pressure_i, temperature_i);
26843 const MFloat u_i = Ma_i * sqrt(temperature_i);
26845 m_nozzleInletTemp = temperature_i;
26846 m_nozzleInletP = pressure_i;
26847 m_nozzleInletRho = density_i;
26848 m_nozzleInletU = u_i;
26850 m_log <<
" Ma_i = " << Ma_i << std::endl;
26851 m_log <<
" T_i = " << temperature_i << std::endl;
26852 m_log <<
" p_i = " << pressure_i << std::endl;
26853 m_log <<
" rho_i = " << density_i << std::endl;
26854 m_log <<
" u_i = " << u_i << std::endl;
26860 m_VVInfinity[0] = m_UInfinity;
26861 m_VVInfinity[1] = m_VInfinity;
26862 m_VVInfinity[2] = m_WInfinity;
26864 m_rhoUInfinity = NAN;
26865 m_rhoVInfinity = NAN;
26866 m_rhoWInfinity = NAN;
26867 m_rhoVVInfinity[0] = m_rhoUInfinity;
26868 m_rhoVVInfinity[1] = m_rhoVInfinity;
26869 m_rhoVVInfinity[2] = m_rhoWInfinity;
26871 m_rhoEInfinity = NAN;
26874 sysEqn().m_muInfinity = NAN;
26875 m_DInfinity = sysEqn().m_muInfinity;
26876 m_DthInfinity = NAN;
26889 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "This is
a 3D IC!");
26891 m_deltaP = 64 / sysEqn().m_Re0 * F1 / m_referenceLength * F1B2 * m_rhoInfinity *
POW2(UT) / 10.0;
26893 m_deltaP = 64 / sysEqn().m_Re0 * F1 / m_referenceLength * F1B2 * m_rhoInfinity *
POW2(UT) / 5.0;
26895 m_fvBndryCnd->m_deltaP = m_deltaP;
26901 m_rhoInfinity = F1;
26902 m_PInfinity = sysEqn().p_Ref();
26903 m_UInfinity = m_Ma;
26905 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
26906 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
26907 m_rhoEInfinity = m_PInfinity / gammaMinusOne + F1B2 * m_rhoInfinity *
POW2(UT);
26908 m_hInfinity = m_PInfinity / m_rhoInfinity * m_gamma / gammaMinusOne;
26923template <MInt nDim_,
class SysEqn>
26927 const MInt noPVars = PV->noVariables;
26928 const MInt noCVars = CV->noVariables;
26929 const MFloat gammaMinusOne = m_gamma - 1.0;
26930 const MFloat FgammaMinusOne = F1 / gammaMinusOne;
26945 MBool interpolateSolutionFromStructured =
false;
26946 interpolateSolutionFromStructured = Context::getSolverProperty<MBool>(
"interpolateSolutionFromStructured", m_solverId,
26947 AT_, &interpolateSolutionFromStructured);
26948 if(interpolateSolutionFromStructured) {
26949 if(m_restart)
mTerm(1, AT_,
"'restart' and 'interpolateSolutionFromStructured' activated at the same time!");
26950 readRANSProfile(
this);
26951 computeConservativeVariables();
26952 if(m_initialCondition != 999) {
26953 if(domainId() == 0)
26954 cout <<
"\033[0;31m#### WARNING:\033[0m 'interpolateSolutionFromStructured' is set and 'initialCondition!=999'!"
26956 m_log <<
"WARNING: 'interpolateSolutionFromStructured' is set and 'initialCondition!=999'!" << endl;
26963 if((!m_restart && !m_resetInitialCondition)) {
26966 switch(m_initialCondition) {
26973 ASSERT(isDetChem<SysEqn>,
"Only compatible with detailed chemistry equation system");
26975 std::vector<MFloat> PVars(nDim + 2 + m_noSpecies, F0);
26977 PVars[PV->P] = m_detChem.infPressure;
26979 for(
MInt s = 0; s < m_noSpecies; s++) {
26980 PVars[PV->Y[s]] = m_oneDimFlame->m_profile.massFractions[s];
26983 MFloat T = m_oneDimFlame->m_profile.temperature[0];
26985 for(
MInt i = 0; i < nDim; i++) {
26986 PVars[PV->VV[i]] = F0;
26989 MFloat FmeanMolarWeight = F0, meanMolarWeight = F0;
26991 for(
MInt s = 0; s < m_noSpecies; s++) {
26992 FmeanMolarWeight += PVars[PV->Y[s]] * m_fMolarMass[s];
26994 meanMolarWeight = F1 / FmeanMolarWeight;
26996 PVars[PV->RHO] = PVars[PV->P] / T * meanMolarWeight / m_gasConstant;
26998 a_variable(cellId, CV->RHO) = PVars[PV->RHO];
27000 for(
MInt i = 0; i < nDim; i++) {
27001 a_variable(cellId, CV->RHO_VV[i]) = F0;
27004 IF_CONSTEXPR(isDetChem<SysEqn> && hasE<SysEqn>) {
27005 MFloat sensibleEnergy = F0;
27006 sysEqn().evaluateSensibleEnergy(sensibleEnergy, &PVars[0], meanMolarWeight);
27007 a_variable(cellId, CV->RHO_E) = PVars[PV->RHO] * sensibleEnergy;
27010 for(
MInt s = 0; s < m_noSpecies; ++s) {
27011 a_variable(cellId, CV->RHO_Y[s]) = PVars[PV->RHO] * PVars[PV->Y[s]];
27018 const MInt mainAxis = 0;
27019 const MFloat gasConstant = m_gasConstant;
27020 const MFloat fixedTemperatureLocation = m_oneDimFlame->m_fixedTemperatureLocation;
27021 const MInt oneDGridSize = m_oneDimFlame->m_grid.size();
27025 std::vector<MFloat> transformedGrid(oneDGridSize, F0);
27027 MInt numberPerturbations = 0;
27028 MBool perturbedFlameFront =
false;
27031 perturbedFlameFront = Context::getSolverProperty<MBool>(
"perturbedFlameFront", m_solverId, AT_);
27034 if(perturbedFlameFront)
27037 std::vector<MFloat> flameFrontPerturbationAmplitude(numberPerturbations, F0);
27038 std::vector<MFloat> flameFrontPerturbationWaveLength(numberPerturbations, F0);
27040 for(
MInt i = 0; i < numberPerturbations; ++i) {
27041 flameFrontPerturbationAmplitude[i] =
27042 Context::getSolverProperty<MFloat>(
"flameFrontPerturbationAmplitude", m_solverId, AT_, i);
27043 flameFrontPerturbationWaveLength[i] =
27044 Context::getSolverProperty<MFloat>(
"flameFrontPerturbationWaveLength", m_solverId, AT_, i);
27047 for(
MInt i = 0; i < oneDGridSize; ++i) {
27048 transformedGrid[i] = m_oneDimFlame->m_grid[i] - fixedTemperatureLocation;
27051 const MFloat oneDGridMin = m_oneDimFlame->m_grid[0] - fixedTemperatureLocation;
27052 const MFloat oneDGridMax = transformedGrid[oneDGridSize - 1];
27055 m_TInfinity = m_detChem.infTemperature;
27057 MFloat UT = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[0];
27058 m_UInfinity = UT *
cos(m_angle[0]) *
cos(m_angle[1]);
27059 m_VInfinity = UT * sin(m_angle[0]) *
cos(m_angle[1]);
27060 IF_CONSTEXPR(nDim == 3) m_WInfinity = UT * sin(m_angle[1]);
27062 m_VVInfinity[0] = m_UInfinity;
27063 m_VVInfinity[1] = m_VInfinity;
27064 IF_CONSTEXPR(nDim == 3) m_VVInfinity[2] = m_WInfinity;
27066 m_PInfinity = m_detChem.infPressure;
27068 MFloat fMeanMolarWeightInfinity = F0;
27069 for(
MInt s = 0; s < m_noSpecies; s++) {
27070 fMeanMolarWeightInfinity += m_YInfinity[s] * m_fMolarMass[s];
27073 MFloat meanMolarWeightInfinity = F1 / fMeanMolarWeightInfinity;
27075 m_rhoInfinity = m_PInfinity * meanMolarWeightInfinity / gasConstant / m_detChem.infTemperature;
27077 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
27078 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
27079 IF_CONSTEXPR(nDim == 3) m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
27081 m_rhoVVInfinity[0] = m_rhoUInfinity;
27082 m_rhoVVInfinity[1] = m_rhoVInfinity;
27083 IF_CONSTEXPR(nDim == 3) m_rhoVVInfinity[2] = m_rhoWInfinity;
27085 std::vector<
MFloat> PVars(nDim + 2 + m_noSpecies, F0);
27086 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
27088 MFloat coord = a_coordinate(cellId, mainAxis);
27089 MFloat tCoord = a_coordinate(cellId, 1);
27091 for(
MInt i = 0; i < numberPerturbations; i++) {
27092 MFloat wavenumber = F2 * PI / (flameFrontPerturbationWaveLength[i]);
27094 flameFrontPerturbationAmplitude[i] * m_oneDimFlame->m_laminarFlameThickness * sin(wavenumber * tCoord);
27097 MFloat FmeanMolarWeight = F0;
27098 MFloat meanMolarWeight = F0;
27101 PVars[PV->P] = m_detChem.infPressure;
27104 if(coord < oneDGridMin) {
27105 for(
MInt s = 0; s < m_noSpecies; s++) {
27106 PVars[PV->Y[s]] = m_oneDimFlame->m_profile.massFractions[s];
27108 T = m_oneDimFlame->m_profile.temperature[0];
27109 VV = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[0];
27112 }
else if(coord > oneDGridMax) {
27113 for(
MInt s = 0; s < m_noSpecies; s++) {
27114 PVars[PV->Y[s]] = m_oneDimFlame->m_profile.massFractions[(oneDGridSize - 1) * m_noSpecies + s];
27116 T = m_oneDimFlame->m_profile.temperature[oneDGridSize - 1];
27117 VV = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[oneDGridSize - 1];
27122 auto lowerBound = std::lower_bound(transformedGrid.begin(), transformedGrid.end(), coord);
27123 auto upperBound = std::upper_bound(transformedGrid.begin(), transformedGrid.end(), coord);
27125 MInt n0 = lowerBound - transformedGrid.begin() - 1;
27126 MInt n1 = upperBound - transformedGrid.begin();
27128 MFloat x0 = transformedGrid[n0];
27129 MFloat x1 = transformedGrid[n1];
27131 MInt offset0 = m_noSpecies * n0;
27132 MInt offset1 = m_noSpecies * n1;
27134 for(
MInt s = 0; s < m_noSpecies; s++) {
27135 MFloat Y_k_0 = m_oneDimFlame->m_profile.massFractions[offset0 + s];
27136 MFloat Y_k_1 = m_oneDimFlame->m_profile.massFractions[offset1 + s];
27137 PVars[PV->Y[s]] = Y_k_0 + (coord - x0) / (x1 - x0) * (Y_k_1 - Y_k_0);
27141 MFloat T0 = m_oneDimFlame->m_profile.temperature[n0];
27142 MFloat T1 = m_oneDimFlame->m_profile.temperature[n1];
27144 T = T0 + (coord - x0) / (x1 - x0) * (T1 - T0);
27146 MFloat VV_0 = m_oneDimFlame->m_profile.velocity[n0];
27147 MFloat VV_1 = m_oneDimFlame->m_profile.velocity[n1];
27149 VV = VV_0 + (coord - x0) / (x1 - x0) * (VV_1 - VV_0);
27150 VV *= m_detChem.laminarFlameSpeedFactor;
27153 for(
MInt s = 0; s < m_noSpecies; s++) {
27154 FmeanMolarWeight += PVars[PV->Y[s]] * m_fMolarMass[s];
27156 meanMolarWeight = F1 / FmeanMolarWeight;
27158 PVars[PV->RHO] = PVars[PV->P] / T * meanMolarWeight / gasConstant;
27160 a_variable(cellId, CV->RHO) = PVars[PV->RHO];
27162 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
27163 if(spaceId == mainAxis) {
27164 PVars[CV->RHO_VV[spaceId]] = VV;
27165 a_variable(cellId, CV->RHO_VV[spaceId]) = PVars[PV->RHO] * VV;
27167 PVars[CV->RHO_VV[spaceId]] = F0;
27168 a_variable(cellId, CV->RHO_VV[spaceId]) = F0;
27172 IF_CONSTEXPR(isDetChem<SysEqn> && hasE<SysEqn>) {
27173 MFloat sensibleEnergy = F0;
27174 sysEqn().evaluateSensibleEnergy(sensibleEnergy, &PVars[0], meanMolarWeight);
27175 a_variable(cellId, CV->RHO_E) = PVars[PV->RHO] * sensibleEnergy + 0.5 * PVars[PV->RHO] *
POW2(VV);
27178 for(
MInt s = 0; s < m_noSpecies; ++s) {
27179 a_variable(cellId, CV->RHO_Y[s]) = PVars[PV->RHO] * PVars[PV->Y[s]];
27191 const MInt mainAxis = 1;
27192 const MFloat gasConstant = m_gasConstant;
27193 const MFloat fixedTemperatureLocation = m_oneDimFlame->m_fixedTemperatureLocation;
27194 const MInt oneDGridSize = m_oneDimFlame->m_grid.size();
27201 MFloat tubeDiameter = 0.0050048822 * 2.001;
27202 MFloat flamePosition = 0.00115;
27206 std::vector<MFloat> transformedGrid(oneDGridSize, F0);
27209 for(
MInt i = 0; i < oneDGridSize; ++i) {
27210 transformedGrid[i] = m_oneDimFlame->m_grid[i] - fixedTemperatureLocation;
27213 const MFloat oneDGridMin = m_oneDimFlame->m_grid[0] - fixedTemperatureLocation;
27214 const MFloat oneDGridMax = transformedGrid[oneDGridSize - 1];
27217 m_TInfinity = m_detChem.infTemperature;
27219 MFloat UT = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[0];
27222 MPI_Bcast(&recvVel, 1, MPI_DOUBLE, 0, mpiComm(), AT_,
"recvVel");
27224 m_UInfinity = recvVel *
cos(m_angle[0]) *
cos(m_angle[1]);
27225 m_VInfinity = recvVel * sin(m_angle[0]) *
cos(m_angle[1]);
27226 IF_CONSTEXPR(nDim == 3) m_WInfinity = recvVel * sin(m_angle[1]);
27228 m_VVInfinity[0] = m_UInfinity;
27229 m_VVInfinity[1] = m_VInfinity;
27230 IF_CONSTEXPR(nDim == 3) m_VVInfinity[2] = m_WInfinity;
27232 m_PInfinity = m_detChem.infPressure;
27234 MFloat fMeanMolarWeightInfinity = F0;
27235 for(
MInt s = 0; s < m_noSpecies; s++) {
27236 fMeanMolarWeightInfinity += m_YInfinity[s] * m_fMolarMass[s];
27239 MFloat meanMolarWeightInfinity = F1 / fMeanMolarWeightInfinity;
27241 m_rhoInfinity = m_PInfinity * meanMolarWeightInfinity / gasConstant / m_detChem.infTemperature;
27243 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
27244 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
27245 IF_CONSTEXPR(nDim == 3) m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
27247 m_rhoVVInfinity[0] = m_rhoUInfinity;
27248 m_rhoVVInfinity[1] = m_rhoVInfinity;
27249 IF_CONSTEXPR(nDim == 3) m_rhoVVInfinity[2] = m_rhoWInfinity;
27251 std::vector<
MFloat> PVars(nDim + 2 + m_noSpecies, F0);
27252 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
27254 MFloat coord = a_coordinate(cellId, mainAxis);
27255 MFloat tCoord = a_coordinate(cellId, 0);
27257 MFloat FmeanMolarWeight = F0;
27258 MFloat meanMolarWeight = F0;
27261 PVars[PV->P] = m_detChem.infPressure;
27264 if(coord - flamePosition < oneDGridMin) {
27265 for(
MInt s = 0; s < m_noSpecies; s++) {
27266 PVars[PV->Y[s]] = m_oneDimFlame->m_profile.massFractions[s];
27268 T = m_oneDimFlame->m_profile.temperature[0];
27269 VV = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[0];
27272 }
else if(coord - flamePosition > oneDGridMax) {
27273 for(
MInt s = 0; s < m_noSpecies; s++) {
27274 PVars[PV->Y[s]] = m_oneDimFlame->m_profile.massFractions[(oneDGridSize - 1) * m_noSpecies + s];
27276 T = m_oneDimFlame->m_profile.temperature[oneDGridSize - 1];
27277 VV = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[oneDGridSize - 1];
27281 const MFloat transformedCoord = coord - flamePosition;
27283 auto lowerBound = std::lower_bound(transformedGrid.begin(), transformedGrid.end(), transformedCoord);
27284 auto upperBound = std::upper_bound(transformedGrid.begin(), transformedGrid.end(), transformedCoord);
27286 MInt n0 = lowerBound - transformedGrid.begin() - 1;
27287 MInt n1 = upperBound - transformedGrid.begin();
27289 MFloat x0 = transformedGrid[n0];
27290 MFloat x1 = transformedGrid[n1];
27292 MInt offset0 = m_noSpecies * n0;
27293 MInt offset1 = m_noSpecies * n1;
27295 for(
MInt s = 0; s < m_noSpecies; s++) {
27296 MFloat Y_k_0 = m_oneDimFlame->m_profile.massFractions[offset0 + s];
27297 MFloat Y_k_1 = m_oneDimFlame->m_profile.massFractions[offset1 + s];
27298 PVars[PV->Y[s]] = Y_k_0 + (transformedCoord - x0) / (x1 - x0) * (Y_k_1 - Y_k_0);
27302 MFloat T0 = m_oneDimFlame->m_profile.temperature[n0];
27303 MFloat T1 = m_oneDimFlame->m_profile.temperature[n1];
27305 T = T0 + (transformedCoord - x0) / (x1 - x0) * (T1 - T0);
27307 MFloat VV_0 = m_oneDimFlame->m_profile.velocity[n0];
27308 MFloat VV_1 = m_oneDimFlame->m_profile.velocity[n1];
27310 VV = VV_0 + (transformedCoord - x0) / (x1 - x0) * (VV_1 - VV_0);
27311 VV *= m_detChem.laminarFlameSpeedFactor;
27314 if(abs(tCoord) > tubeDiameter / F2) {
27315 for(
MInt s = 0; s < m_noSpecies; s++) {
27316 PVars[PV->Y[s]] = m_oneDimFlame->m_profile.massFractions[(oneDGridSize - 1) * m_noSpecies + s];
27318 T = m_oneDimFlame->m_profile.temperature[oneDGridSize - 1];
27324 if(coord > 0.001) {
27328 for(
MInt s = 0; s < m_noSpecies; s++) {
27329 FmeanMolarWeight += PVars[PV->Y[s]] * m_fMolarMass[s];
27331 meanMolarWeight = F1 / FmeanMolarWeight;
27333 PVars[PV->RHO] = PVars[PV->P] / T * meanMolarWeight / gasConstant;
27335 a_variable(cellId, CV->RHO) = PVars[PV->RHO];
27337 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
27338 if(spaceId == mainAxis) {
27339 PVars[CV->RHO_VV[spaceId]] = VV;
27340 a_variable(cellId, CV->RHO_VV[spaceId]) = PVars[PV->RHO] * VV;
27342 PVars[CV->RHO_VV[spaceId]] = F0;
27343 a_variable(cellId, CV->RHO_VV[spaceId]) = F0;
27347 IF_CONSTEXPR(isDetChem<SysEqn> && hasE<SysEqn>) {
27348 MFloat sensibleEnergy = F0;
27349 sysEqn().evaluateSensibleEnergy(sensibleEnergy, &PVars[0], meanMolarWeight);
27350 a_variable(cellId, CV->RHO_E) = PVars[PV->RHO] * sensibleEnergy + 0.5 * PVars[PV->RHO] *
POW2(VV);
27353 for(
MInt s = 0; s < m_noSpecies; ++s) {
27354 a_variable(cellId, CV->RHO_Y[s]) = PVars[PV->RHO] * PVars[PV->Y[s]];
27363 const MInt mainAxis = 1;
27364 const MFloat gasConstant = m_gasConstant;
27366 MFloat tubeDiameter = 0.0050048822 * 2.001;
27369 m_TInfinity = m_detChem.infTemperature;
27371 MFloat UT = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[0];
27372 m_UInfinity = UT *
cos(m_angle[0]) *
cos(m_angle[1]);
27373 m_VInfinity = UT * sin(m_angle[0]) *
cos(m_angle[1]);
27374 IF_CONSTEXPR(nDim == 3) m_WInfinity = UT * sin(m_angle[1]);
27376 m_VVInfinity[0] = m_UInfinity;
27377 m_VVInfinity[1] = m_VInfinity;
27378 IF_CONSTEXPR(nDim == 3) m_VVInfinity[2] = m_WInfinity;
27380 m_PInfinity = m_detChem.infPressure;
27382 MFloat fMeanMolarWeightInfinity = F0;
27383 for(
MInt s = 0; s < m_noSpecies; s++) {
27384 fMeanMolarWeightInfinity += m_YInfinity[s] * m_fMolarMass[s];
27387 MFloat meanMolarWeightInfinity = F1 / fMeanMolarWeightInfinity;
27389 m_rhoInfinity = m_PInfinity * meanMolarWeightInfinity / gasConstant / m_detChem.infTemperature;
27391 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
27392 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
27393 IF_CONSTEXPR(nDim == 3) m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
27395 m_rhoVVInfinity[0] = m_rhoUInfinity;
27396 m_rhoVVInfinity[1] = m_rhoVInfinity;
27397 IF_CONSTEXPR(nDim == 3) m_rhoVVInfinity[2] = m_rhoWInfinity;
27399 std::vector<
MFloat> PVars(nDim + 2 + m_noSpecies, F0);
27400 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
27403 MFloat tCoord = a_coordinate(cellId, 0);
27406 MFloat FmeanMolarWeight = F0;
27407 MFloat meanMolarWeight = F0;
27410 PVars[PV->P] = m_detChem.infPressure;
27413 for(
MInt s = 0; s < m_noSpecies; s++) {
27414 PVars[PV->Y[s]] = m_oneDimFlame->m_profile.massFractions[s];
27416 T = m_oneDimFlame->m_profile.temperature[0];
27417 VV = m_detChem.laminarFlameSpeedFactor * m_oneDimFlame->m_profile.velocity[0];
27420 if(abs(tCoord) > tubeDiameter / F2) {
27424 for(
MInt s = 0; s < m_noSpecies; s++) {
27425 FmeanMolarWeight += PVars[PV->Y[s]] * m_fMolarMass[s];
27427 meanMolarWeight = F1 / FmeanMolarWeight;
27429 PVars[PV->RHO] = PVars[PV->P] / T * meanMolarWeight / gasConstant;
27431 a_variable(cellId, CV->RHO) = PVars[PV->RHO];
27433 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
27434 if(spaceId == mainAxis) {
27435 PVars[CV->RHO_VV[spaceId]] = VV;
27436 a_variable(cellId, CV->RHO_VV[spaceId]) = PVars[PV->RHO] * VV;
27438 PVars[CV->RHO_VV[spaceId]] = F0;
27439 a_variable(cellId, CV->RHO_VV[spaceId]) = F0;
27443 IF_CONSTEXPR(isDetChem<SysEqn> && hasE<SysEqn>) {
27444 MFloat sensibleEnergy = F0;
27445 sysEqn().evaluateSensibleEnergy(sensibleEnergy, &PVars[0], meanMolarWeight);
27446 a_variable(cellId, CV->RHO_E) = PVars[PV->RHO] * sensibleEnergy + 0.5 * PVars[PV->RHO] *
POW2(VV);
27449 for(
MInt s = 0; s < m_noSpecies; ++s) {
27450 a_variable(cellId, CV->RHO_Y[s]) = PVars[PV->RHO] * PVars[PV->Y[s]];
27454 saveDebugRestartFile();
27461 MFloat rho = m_rhoInfinity;
27463 rho = Context::getSolverProperty<MFloat>(
"initialDensity", m_solverId, AT_);
27465 IF_CONSTEXPR(hasE<SysEqn>) {
27466 MFloat rhoE = m_rhoEInfinity;
27468 const MFloat p = Context::getSolverProperty<MFloat>(
"initialPressure", m_solverId, AT_);
27469 rhoE = sysEqn().internalEnergy(p, rho, 0);
27472 a_variable(cellId, CV->RHO_E) = rhoE;
27477 a_variable(cellId, CV->RHO) = rho;
27479 for(
MInt dir = 0; dir < nDim; dir++) {
27480 a_variable(cellId, CV->RHO_VV[dir]) = m_rhoVVInfinity[dir];
27483 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
27484 IF_CONSTEXPR(SysEqn::m_ransModel ==
RANS_SA_DV || SysEqn::m_ransModel ==
RANS_FS) {
27485 a_variable(cellId, CV->RHO_N) = m_rhoInfinity * m_nuTildeInfinity;
27488 a_variable(cellId, CV->RHO_K) = m_rhoInfinity * m_kInfinity;
27489 a_variable(cellId, CV->RHO_OMEGA) = m_rhoInfinity * m_omegaInfinity;
27493 for(
MInt s = 0; s < m_noSpecies; s++) {
27494 a_variable(cellId, CV->RHO_Y[s]) = 0.0;
27502 IF_CONSTEXPR(!isEEGas<SysEqn>) {
mTerm(1, AT_,
"Initial condition for Euler-Euler Simulations!"); }
27504 for(
MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
27505 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
27506 for(
MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
27507 const MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
27508 a_alphaGas(ghostCellId) = a_alphaGas(cellId);
27514 MFloat rho = m_rhoInfinity;
27516 alpha = a_alphaGas(cellId);
27517 p = a_pvariable(cellId, PV->P);
27518 if(p < 1e-8 || isnan(p)) {
27521 rho *=
p / m_PInfinity;
27524 for(
MInt i = 0; i < 3; i++) {
27525 rho += a_avariable(cellId, AV->DC);
27529 a_variable(cellId, CV->A_RHO) = rho * alpha;
27531 for(
MInt dir = 0; dir < nDim; dir++) {
27532 MFloat rhoV = m_rhoVVInfinity[dir] / m_rhoInfinity * rho;
27533 rhoV *=
p / m_PInfinity;
27534 a_variable(cellId, CV->A_RHO_VV[dir]) = rhoV * alpha;
27536 a_pvariable(cellId, PV->RHO) = rho;
27537 a_pvariable(cellId, PV->P) =
p;
27544 a_variable(cellId, CV->RHO) = F1;
27545 IF_CONSTEXPR(hasE<SysEqn>)
27546 a_variable(cellId, CV->RHO_E) = sysEqn().pressureEnergy(sysEqn().p_Ref());
27547 for(
MInt dir = 0; dir < nDim; dir++) {
27548 a_variable(cellId, CV->RHO_VV[dir]) = F0;
27550 for(
MInt s = 0; s < m_noSpecies; s++) {
27551 a_variable(cellId, CV->RHO_Y[s]) = 0.5;
27553 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
27554 IF_CONSTEXPR(SysEqn::m_ransModel ==
RANS_SA_DV || SysEqn::m_ransModel ==
RANS_FS) {
27555 a_variable(cellId, CV->RHO_N) = m_rhoInfinity * m_nuTildeInfinity;
27558 a_variable(cellId, CV->RHO_K) = m_rhoInfinity * m_kInfinity;
27559 a_variable(cellId, CV->RHO_OMEGA) = m_rhoInfinity * m_omegaInfinity;
27566 m_MaHg = Context::getSolverProperty<MFloat>(
"Ma_Hg", m_solverId, AT_);
27567 m_THg = sysEqn().temperature_IR(m_MaHg);
27568 m_UHg = m_MaHg * sqrt(m_THg);
27571 m_PHg = sysEqn().pressure_IR(m_THg);
27572 m_rhoHg = sysEqn().density_IR(m_THg);
27575 m_MaCg = Context::getSolverProperty<MFloat>(
"Ma_Cg", m_solverId, AT_);
27576 m_TCg = sysEqn().temperature_IR(m_MaCg);
27577 m_UCg = m_MaCg * sqrt(m_TCg);
27580 m_PCg = sysEqn().pressure_IR(m_TCg);
27581 m_rhoCg = sysEqn().density_IR(m_TCg);
27584 a_variable(cellId, CV->RHO) = m_rhoInfinity;
27585 IF_CONSTEXPR(hasE<SysEqn>)
27586 a_variable(cellId, CV->RHO_E) = m_rhoEInfinity;
27588 for(
MInt dir = 0; dir < nDim; dir++) {
27589 a_variable(cellId, CV->RHO_VV[dir]) = m_rhoVVInfinity[dir];
27592 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
27593 IF_CONSTEXPR(SysEqn::m_ransModel ==
RANS_SA_DV || SysEqn::m_ransModel ==
RANS_FS) {
27594 a_variable(cellId, CV->RHO_N) = m_rhoInfinity * m_nuTildeInfinity;
27597 a_variable(cellId, PV->K) = m_kInfinity;
27598 a_variable(cellId, PV->OMEGA) = m_omegaInfinity;
27602 for(
MInt s = 0; s < m_noSpecies; s++) {
27603 a_variable(cellId, CV->RHO_Y[s]) = 0.0;
27611 a_pvariable(cellId, PV->RHO) = m_rhoInfinity;
27612 a_pvariable(cellId, PV->P) = m_PInfinity;
27613 for(
MInt dir = 0; dir < nDim; dir++) {
27614 a_pvariable(cellId, PV->VV[dir]) = m_VVInfinity[dir];
27617 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
27618 IF_CONSTEXPR(SysEqn::m_ransModel ==
RANS_SA_DV || SysEqn::m_ransModel ==
RANS_FS) {
27620 MFloat r = sqrt(
POW2(a_coordinate(cellId, 1)) +
POW2(a_coordinate(cellId, 2)));
27621 a_pvariable(cellId, PV->N) = m_nuTildeInfinity + 10.0 * ((r - 114.2) * exp(-0.06 * pow(r - 114.2, F2)));
27622 a_pvariable(cellId, PV->VV[0]) = m_UInfinity * (1 - pow((r - 145.1) / 31.2, 10.0));
27626 for(
MInt s = 0; s < m_noSpecies; s++) {
27627 a_pvariable(cellId, PV->Y[s]) = 0.0;
27630 computeConservativeVariables();
27637 a_variable(cellId, CV->RHO) = m_rhoInfinity;
27639 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
27640 a_variable(cellId, CV->RHO_VV[spaceId]) = F0;
27643 IF_CONSTEXPR(hasE<SysEqn>)
27644 a_variable(cellId, CV->RHO_E) = m_PInfinity / gammaMinusOne;
27652 SA = Context::getSolverProperty<MInt>(
"shockAlignment", m_solverId, AT_, &SA);
27654 if(SA == nDim)
mTerm(1, AT_,
"shockAlignment not set");
27663 MFloat shockCoord = Context::getSolverProperty<MFloat>(
"shockCoord", m_solverId, AT_, &shockCoord);
27666 if(a_coordinate(cellId, SA) < shockCoord) {
27668 a_variable(cellId, CV->RHO) = m_rhoInfinity;
27669 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
27670 a_variable(cellId, CV->RHO_VV[spaceId]) = m_rhoVVInfinity[spaceId];
27672 IF_CONSTEXPR(hasE<SysEqn>)
27673 a_variable(cellId, CV->RHO_E) = m_rhoEInfinity;
27676 for(
MInt var = 0; var < noCVars; var++) {
27677 a_variable(cellId, var) = m_postShockCV[var];
27688 m_rhoInfinity = F1;
27690 m_PInfinity = sysEqn().pressure_ES(m_TInfinity, m_rhoInfinity);
27691 m_UInfinity = m_Ma;
27692 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
27693 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
27694 m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
27695 m_rhoEInfinity = sysEqn().internalEnergy(m_PInfinity, m_rhoInfinity,
POW2(m_UInfinity));
27696 m_hInfinity = sysEqn().enthalpy(m_PInfinity, m_rhoInfinity);
27697 sysEqn().m_Re0 = m_Re * SUTHERLANDLAW(m_TInfinity) / (m_rhoInfinity * m_UInfinity);
27701 m_geometry->getBoundingBox(&bbox[0]);
27704 const MFloat vel = F2 * m_UInfinity * a_coordinate(cellId, 1) / (bbox[1 + nDim] - bbox[1]);
27705 a_variable(cellId, CV->RHO) = m_rhoInfinity;
27706 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
27707 a_variable(cellId, CV->RHO_VV[spaceId]) = F0;
27709 a_variable(cellId, CV->RHO_U) = m_rhoInfinity * vel;
27710 IF_CONSTEXPR(hasE<SysEqn>)
27711 a_variable(cellId, CV->RHO_E) = m_PInfinity / gammaMinusOne + F1B2 * m_rhoInfinity *
POW2(vel);
27718 IF_CONSTEXPR(nDim == 2) {
27719 mTerm(-1,
"This IC has been never used in 2D! If you are sure that it works uncomment "
27722 m_log <<
"Initial condition 81 maps a solution off a source grid (incl. partition level "
27723 "shift) on a target grid";
27724 m_log <<
"using nearest neighbor data" << endl;
27726 if(ParallelIo::fileExists(
"out/restartVariables_0.Netcdf", mpiComm())) {
27727 m_log <<
"get data from own grid" << endl;
27729 stringstream variables;
27734 ParallelIo::size_type dimLen = noInternalCells();
27735 ParallelIo::size_type start = domainOffset(domainId());
27738 parallelIo.setOffset(dimLen, start);
27744 parallelIo.readArray(tmp_velocityU.getPointer(),
"variables0");
27745 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
27746 a_pvariable(i, PV->U) = tmp_velocityU.p[i];
27752 parallelIo.readArray(tmp_velocityV.getPointer(),
"variables1");
27753 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
27754 a_pvariable(i, PV->V) = tmp_velocityV.p[i];
27758 IF_CONSTEXPR(nDim == 3) {
27761 parallelIo.readArray(tmp_velocityW.getPointer(),
"variables2");
27762 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
27763 a_pvariable(i, PV->W) = tmp_velocityW.p[i];
27769 parallelIo.readArray(tmp_rho.getPointer(),
"variables3");
27770 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
27771 a_pvariable(i, PV->RHO) = tmp_rho.p[i];
27777 parallelIo.readArray(tmp_p.getPointer(),
"variables4");
27778 for(
MInt i = 0; i < (
MInt)dimLen; ++i) {
27779 a_pvariable(i, PV->P) = tmp_p.p[i];
27784 m_log <<
" reading done" << endl;
27789 m_log <<
"exchange done" << endl;
27791 computeConservativeVariables();
27794 m_log <<
"computeConservativeVariables done" << endl;
27796 LSReconstructCellCenter();
27800 m_log <<
"get data from other grid" << endl;
27805 a_pvariable(cellId, PV->RHO) = m_rhoInfinity;
27806 for(
MInt i = 0; i < nDim; i++)
27807 a_pvariable(cellId, PV->VV[i]) = m_VVInfinity[i];
27808 a_pvariable(cellId, PV->P) = m_PInfinity;
27814 MInt maxNoCellsToRead = 5 * maxNoGridCells();
27832 MInt srcFileType = 0;
27833 srcFileType = Context::getSolverProperty<MInt>(
"srcFileType", m_solverId, AT_, &srcFileType);
27837 srcGrid.readScalar(&srcNoCells,
"noCells");
27841 MFloat srcCenterOfGravity[nDim];
27845 if(srcFileType == 1) {
27846 IF_CONSTEXPR(nDim == 2)
mTerm(1, AT_, "Not for 2D!");
27847 srcLengthLevel0 = 3.5000000032596290112;
27848 srcCenterOfGravity[0] = 0.021997896999999988488;
27849 srcCenterOfGravity[1] = 0.0;
27850 srcCenterOfGravity[2] = 0.0;
27851 fileTypeFac = 100.0;
27854 } else if(srcFileType == 2) {
27855 IF_CONSTEXPR(nDim == 2)
mTerm(1, AT_, "Not for 2D!");
27856 srcLengthLevel0 = 3.0000000027939677238;
27857 srcCenterOfGravity[0] = 0.021997896999999988488;
27858 srcCenterOfGravity[1] = 0.0;
27859 srcCenterOfGravity[2] = 0.0;
27860 fileTypeFac = 100.0;
27863 } else if(srcFileType == 3) {
27864 IF_CONSTEXPR(nDim == 2)
mTerm(1, AT_, "Not for 2D!");
27865 srcGrid.readScalar(&srcLengthLevel0, "lengthLevel0");
27866 srcGrid.readScalar(&(srcCenterOfGravity[0]), "CX");
27867 srcGrid.readScalar(&(srcCenterOfGravity[1]), "CY");
27868 srcGrid.readScalar(&(srcCenterOfGravity[2]), "CZ");
27869 fileTypeFac = 100.0;
27873 srcGrid.setOffset(nDim, 0);
27874 srcGrid.readArray(&(srcCenterOfGravity[0]),
"centerOfGravity");
27875 srcGrid.readScalar(&srcLengthLevel0,
"lengthLevel0");
27876 srcGrid.readScalar(&srcMinLevel,
"minLevel");
27877 srcGrid.readScalar(&srcMaxLevel,
"maxLevel");
27881 srcLengthLevel0 *= fileTypeFac;
27882 for(
MInt dim = 0; dim < nDim; dim++)
27883 srcCenterOfGravity[dim] *= fileTypeFac;
27885 m_log <<
"srcLengthLevel0 = " << srcLengthLevel0 << endl;
27886 for(
MInt dim = 0; dim < nDim; dim++)
27887 m_log <<
"srcCenterOfGravity[" << dim <<
"] = " << srcCenterOfGravity[dim] << endl;
27889 MInt srcNmbrPartitionCells = (
MInt)srcGrid.getArraySize(
"partitionCellsId");
27890 MIntScratchSpace srcPartitionCellsGlobalId(srcNmbrPartitionCells + 1, AT_,
"srcPartitionCellsGlobalId");
27891 srcGrid.setOffset(srcNmbrPartitionCells, 0);
27892 srcGrid.readArray(srcPartitionCellsGlobalId.begin(),
"partitionCellsId");
27893 srcPartitionCellsGlobalId(srcNmbrPartitionCells) = srcNoCells;
27898 multiset<MInt> srcPartitionCellHilbertIds;
27900 vector<multimap<MLong, MInt>> higherLvlPartitionCellHilbertIds;
27902 multimap<MInt, MInt> partitionCellsToLoad;
27904 vector<MString> varNames;
27905 vector<MInt> uncollatedBndryCells;
27906 vector<MInt> uncollatedCells;
27910 MIntScratchSpace srcPartitionCellsHilbertId(srcNmbrPartitionCells, AT_,
"srcPartitionCellsHilbertId");
27911 if(ParallelIo::fileExists(
"src/srcPartitionCellsHilbertId", mpiComm())) {
27912 m_log <<
"read srcPartitionCellHilbertIds ..." << endl;
27914 srcHilbertId.setOffset(srcNmbrPartitionCells, 0);
27915 srcHilbertId.readArray(srcPartitionCellsHilbertId.begin(),
"srcPartitionCellsHilbertId");
27917 for(
MInt mcCnt = 0; mcCnt < srcNmbrPartitionCells; mcCnt++) {
27918 multiset<MInt>::iterator it = srcPartitionCellHilbertIds.end();
27919 srcPartitionCellHilbertIds.insert(it, srcPartitionCellsHilbertId(mcCnt));
27921 if(srcHilbertId.hasDataset(
"noHighLevels")) {
27922 MInt maxLvlDiff = 0;
27923 srcHilbertId.readScalar(&maxLvlDiff,
"noHighLevels");
27924 for(
MInt lDiff = 0; lDiff < maxLvlDiff; lDiff++) {
27925 higherLvlPartitionCellHilbertIds.push_back(multimap<MLong, MInt>());
27926 stringstream hilbertStr;
27927 hilbertStr <<
"higherLvlHilbertId_" << lDiff;
27928 stringstream idStr;
27929 idStr <<
"partitionCellId_" << lDiff;
27930 MInt noHighLvl = srcHilbertId.getArraySize(idStr.str());
27931 srcHilbertId.setOffset(noHighLvl, 0);
27934 srcHilbertId.readArray(tmpHilbert.begin(), hilbertStr.str());
27935 srcHilbertId.readArray(tmpId.begin(), idStr.str());
27936 for(
MInt cCnt = 0; cCnt < noHighLvl; cCnt++)
27937 higherLvlPartitionCellHilbertIds[lDiff].insert(make_pair(tmpHilbert(cCnt), tmpId(cCnt)));
27941 m_log <<
"calc srcPartitionCellHilbertIds ..." << endl;
27943 MIntScratchSpace locNoPartitionCells(noDomains(), AT_,
"locNoPartitionCells");
27944 MIntScratchSpace locPartitionCellStart(noDomains(), AT_,
"locPartitionCellStart");
27945 locNoPartitionCells.fill(srcNmbrPartitionCells / noDomains());
27946 MInt rem = srcNmbrPartitionCells % noDomains();
27947 for(
MInt dId = 0; dId < noDomains(); dId++) {
27948 locPartitionCellStart(dId) = dId * locNoPartitionCells(dId);
27949 if(dId < rem) locNoPartitionCells(dId)++;
27951 locPartitionCellStart(dId) += dId;
27953 locPartitionCellStart(dId) += rem;
27955 m_log <<
" " << locNoPartitionCells(domainId()) <<
" read operations ..." << endl;
27957 MIntScratchSpace srcPartitionCellsLvlDiff(locNoPartitionCells(domainId()), AT_,
"srcPartitionCellsLvlDiff");
27958 srcGrid.setOffset(locNoPartitionCells(domainId()), locPartitionCellStart(domainId()));
27959 srcGrid.readArray(srcPartitionCellsLvlDiff.begin(),
"partitionCellsLvlDiff");
27961 MInt maxLvlDiff = 0;
27962 for(
MInt cId = 0; cId < locNoPartitionCells(domainId()); cId++) {
27963 maxLvlDiff =
mMax(maxLvlDiff, srcPartitionCellsLvlDiff(cId));
27965 MPI_Allreduce(MPI_IN_PLACE, &maxLvlDiff, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"maxLvlDiff");
27966 m_log <<
"highest partition cell difference is " << maxLvlDiff << endl;
27972 highLvlOffset.fill(0);
27973 highLvlSum.fill(0);
27974 for(
MInt cId = 0; cId < locNoPartitionCells(domainId()); cId++) {
27975 for(
MInt lvlId = 0; lvlId < srcPartitionCellsLvlDiff(cId); lvlId++)
27976 noHighLvl(lvlId)++;
27978 for(
MInt lvlId = 0; lvlId < maxLvlDiff; lvlId++) {
27980 highLvlTmp.fill(0);
27981 highLvlTmp(domainId()) = noHighLvl(lvlId);
27982 MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, highLvlTmp.begin(), 1, MPI_INT, mpiComm(), AT_,
27983 "MPI_IN_PLACE",
"highLvlTmp.begin()");
27984 for(
MInt dom = 0; dom < domainId(); dom++) {
27985 highLvlOffset(lvlId) += highLvlTmp(dom);
27986 highLvlSum(lvlId) += highLvlTmp(dom);
27988 for(
MInt dom = domainId(); dom < noDomains(); dom++)
27989 highLvlSum(lvlId) += highLvlTmp(dom);
27990 m_log <<
"number of higher level hilbert ids to store for lvlDiff " << lvlId + 1 <<
" is "
27991 << highLvlSum(lvlId) << endl;
27994 MIntScratchSpace offTotalHigherLvl(maxLvlDiff + 1, AT_,
"offTotalHigherLvl");
27995 offTotalHigherLvl.fill(0);
27996 for(
MInt lDiff = 1; lDiff <= maxLvlDiff; lDiff++)
27997 for(
MInt lDiffi = lDiff; lDiffi <= maxLvlDiff; lDiffi++)
27998 offTotalHigherLvl(lDiffi) += highLvlSum(lDiff - 1);
27999 m_log <<
"higher level offsets in common memory" << endl;
28000 for(
MInt lDiff = 0; lDiff <= maxLvlDiff; lDiff++)
28001 m_log << offTotalHigherLvl(lDiff) << endl;
28002 MIntScratchSpace highLvlId(offTotalHigherLvl(maxLvlDiff), AT_,
"highLvlId");
28006 highLvlHilbert.fill(0);
28008 for(
MInt j = 0; j < nDim; ++j) {
28010 ss <<
"coordinates_" << j;
28011 varNames.push_back(ss.str());
28017 highLvlCnt.fill(0);
28019 for(
MInt i = 0; i < locNoPartitionCells(domainId()); i++) {
28020 MInt mcCnt = locPartitionCellStart(domainId()) + i;
28022 srcGrid.setOffset(1, srcPartitionCellsGlobalId(mcCnt));
28023 srcGrid.readArray(srcPartitionCellsCoords.begin(), varNames, nDim);
28024 srcPartitionCellsCoords(0) =
28025 (fileTypeFac * srcPartitionCellsCoords(0) - srcCenterOfGravity[0] + srcLengthLevel0 * 0.5)
28027 srcPartitionCellsCoords(1) =
28028 (fileTypeFac * srcPartitionCellsCoords(1) - srcCenterOfGravity[1] + srcLengthLevel0 * 0.5)
28030 IF_CONSTEXPR(nDim == 3)
28031 srcPartitionCellsCoords(2) =
28032 (fileTypeFac * srcPartitionCellsCoords(2) - srcCenterOfGravity[2] + srcLengthLevel0 * 0.5)
28034 srcPartitionCellsHilbertId(mcCnt) =
28035 maia::grid::hilbert::index<nDim>(&(srcPartitionCellsCoords(0)), srcMinLevel);
28036 for(
MInt lDiff = 0; lDiff < srcPartitionCellsLvlDiff(i); lDiff++) {
28037 highLvlId(offTotalHigherLvl(lDiff) + highLvlOffset(lDiff) + highLvlCnt(lDiff)) = mcCnt;
28039 maia::grid::hilbert::index<nDim>(&(srcPartitionCellsCoords(0)), (
MLong)(srcMinLevel + (lDiff + 1)));
28040 highLvlHilbert(offTotalHigherLvl(lDiff) + highLvlOffset(lDiff) + highLvlCnt(lDiff)) = tmpHilbert;
28041 highLvlCnt(lDiff)++;
28044 if(rem && domainId() >= rem) {
28046 srcGrid.setOffset(0, 0);
28047 srcGrid.readArray(srcPartitionCellsCoords.begin(), varNames, nDim);
28051 m_log <<
" done" << endl;
28052 m_log <<
" writing hilbert ids to file ..." << endl;
28057 for(
MInt lDiff = 0; lDiff < maxLvlDiff; lDiff++) {
28058 stringstream hilbertStr;
28059 hilbertStr <<
"higherLvlHilbertId_" << lDiff;
28060 stringstream idStr;
28061 idStr <<
"partitionCellId_" << lDiff;
28068 srcHilbertId.setOffset(locNoPartitionCells(domainId()), locPartitionCellStart(domainId()));
28069 srcHilbertId.writeArray(srcPartitionCellsHilbertId.begin() + locPartitionCellStart(domainId()),
28070 "srcPartitionCellsHilbertId");
28073 for(
MInt lDiff = 0; lDiff < maxLvlDiff; lDiff++) {
28074 stringstream hilbertStr;
28075 hilbertStr <<
"higherLvlHilbertId_" << lDiff;
28076 stringstream idStr;
28077 idStr <<
"partitionCellId_" << lDiff;
28078 srcHilbertId.setOffset(noHighLvl(lDiff), highLvlOffset(lDiff));
28079 srcHilbertId.writeArray(highLvlHilbert.begin() + offTotalHigherLvl(lDiff) + highLvlOffset(lDiff),
28081 srcHilbertId.writeArray(highLvlId.begin() + offTotalHigherLvl(lDiff) + highLvlOffset(lDiff), idStr.str());
28084 if(maxLvlDiff) srcHilbertId.writeScalar(maxLvlDiff,
"noHighLevels");
28087 m_log <<
" done" << endl;
28088 m_log <<
" exchange hilbert ids ..." << endl;
28089 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, srcPartitionCellsHilbertId.begin(),
28090 locNoPartitionCells.begin(), locPartitionCellStart.begin(), MPI_INT, mpiComm(), AT_,
28091 "MPI_IN_PLACE",
"srcPartitionCellsHilbertId.begin()");
28092 for(
MInt lDiff = 0; lDiff < maxLvlDiff; lDiff++) {
28095 noHighLvlTmp.fill(0);
28096 offHighLvlTmp.fill(0);
28097 noHighLvlTmp(domainId()) = noHighLvl(lDiff);
28098 MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, noHighLvlTmp.begin(), 1, MPI_INT, mpiComm(), AT_,
28099 "MPI_IN_PLACE",
"noHighLvlTmp.begin()");
28100 for(
MInt dom = 1; dom < noDomains(); dom++) {
28101 offHighLvlTmp(dom) = offHighLvlTmp(dom - 1) + noHighLvlTmp(dom - 1);
28103 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, highLvlHilbert.begin() + offTotalHigherLvl(lDiff),
28104 noHighLvlTmp.begin(), offHighLvlTmp.begin(), MPI_LONG, mpiComm(), AT_,
"MPI_IN_PLACE",
28105 "highLvlHilbert.begin() + offTotalHigherLvl(lDiff)");
28106 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, highLvlId.begin() + offTotalHigherLvl(lDiff),
28107 noHighLvlTmp.begin(), offHighLvlTmp.begin(), MPI_INT, mpiComm(), AT_,
"MPI_IN_PLACE",
28108 "highLvlId.begin() + offTotalHigherLvl(lDiff)");
28111 m_log <<
" done" << endl;
28113 for(
MInt mcCnt = 0; mcCnt < srcNmbrPartitionCells; mcCnt++) {
28114 multiset<MInt>::iterator it = srcPartitionCellHilbertIds.end();
28115 srcPartitionCellHilbertIds.insert(it, srcPartitionCellsHilbertId(mcCnt));
28117 for(
MInt lDiff = 0; lDiff < maxLvlDiff; lDiff++) {
28118 higherLvlPartitionCellHilbertIds.push_back(multimap<MLong, MInt>());
28119 for(
MInt cCnt = 0; cCnt < highLvlSum(lDiff); cCnt++) {
28120 higherLvlPartitionCellHilbertIds[lDiff].insert(make_pair(
28121 highLvlHilbert(offTotalHigherLvl(lDiff) + cCnt), highLvlId(offTotalHigherLvl(lDiff) + cCnt)));
28127 m_log <<
"done" << endl;
28129 m_log <<
"create connectivity multimap ..." << endl;
28130 for(
MInt cid = 0; cid < noInternalCells(); cid++) {
28131 if(c_noChildren(cid) > 0)
continue;
28133 xyz(0) = (a_coordinate(cid, 0) - srcCenterOfGravity[0] + srcLengthLevel0 * 0.5) / srcLengthLevel0;
28134 xyz(1) = (a_coordinate(cid, 1) - srcCenterOfGravity[1] + srcLengthLevel0 * 0.5) / srcLengthLevel0;
28135 IF_CONSTEXPR(nDim == 3)
28136 xyz(2) = (a_coordinate(cid, 2) - srcCenterOfGravity[2] + srcLengthLevel0 * 0.5) / srcLengthLevel0;
28137 MInt retVal =
maia::grid::hilbert::index<nDim>(&(xyz(0)), srcMinLevel);
28139 pair<multiset<
MInt>::iterator, multiset<
MInt>::iterator> itPair =
28140 srcPartitionCellHilbertIds.equal_range(retVal);
28143 if(itPair.first == itPair.second) {
28144 if(a_bndryId(cid) > -1) {
28145 uncollatedBndryCells.push_back(cid);
28147 uncollatedCells.push_back(cid);
28149 }
else if(
distance(itPair.first, itPair.second) == 1) {
28150 MInt locSrcPartitionCellId =
distance(srcPartitionCellHilbertIds.begin(), itPair.first);
28151 partitionCellsToLoad.insert(make_pair(locSrcPartitionCellId, cid));
28153 for(
MInt lDiff = 0; lDiff < (
MInt)higherLvlPartitionCellHilbertIds.size(); lDiff++) {
28154 MLong highRetVal = maia::grid::hilbert::index<nDim>(&(xyz(0)), (
MLong)(srcMinLevel + (lDiff + 1)));
28155 pair<multimap<MLong, MInt>::iterator, multimap<MLong, MInt>::iterator> highItPair =
28156 higherLvlPartitionCellHilbertIds[lDiff].equal_range(highRetVal);
28157 if(highItPair.first == highItPair.second) {
28158 if(a_bndryId(cid) > -1) {
28159 uncollatedBndryCells.push_back(cid);
28161 uncollatedCells.push_back(cid);
28164 }
else if(
distance(highItPair.first, highItPair.second) == 1) {
28165 MInt locSrcPartitionCellId = highItPair.first->second;
28166 partitionCellsToLoad.insert(make_pair(locSrcPartitionCellId, cid));
28169 if(lDiff == (
MInt)higherLvlPartitionCellHilbertIds.size() - 1)
28170 mTerm(1,
"this should not happen, there should not be identical hilbertIds on "
28171 "the highest level");
28177 m_log <<
"done" << endl;
28179 m_log <<
"cluster read operations ..." << endl;
28180 vector<multimap<MInt, MInt>::iterator> readClusteringIterators;
28183 MInt srcPartitionCellId;
28184 for(multimap<MInt, MInt>::iterator it = partitionCellsToLoad.begin(); it != partitionCellsToLoad.end();
28185 it = partitionCellsToLoad.upper_bound(srcPartitionCellId)) {
28187 readClusteringIterators.push_back(it);
28188 srcPartitionCellId = it->first;
28189 MInt srcPartitionCellNoOffsprings =
28190 srcPartitionCellsGlobalId(srcPartitionCellId + 1) - srcPartitionCellsGlobalId(srcPartitionCellId);
28193 MInt additionalPartitionCellNoOffsprings = 0;
28195 multimap<MInt, MInt>::iterator itNext = partitionCellsToLoad.upper_bound(srcPartitionCellId);
28196 if(itNext == partitionCellsToLoad.end())
break;
28197 MInt nextSrcPartitionCellId = itNext->first;
28198 for(
MInt i = srcPartitionCellId + 1; i <= nextSrcPartitionCellId; i++) {
28199 additionalPartitionCellNoOffsprings += srcPartitionCellsGlobalId(i + 1) - srcPartitionCellsGlobalId(i);
28201 if(additionalPartitionCellNoOffsprings + srcPartitionCellNoOffsprings > maxNoCellsToRead)
break;
28202 srcPartitionCellId = nextSrcPartitionCellId;
28205 noReadOps = readClusteringIterators.size();
28206 readClusteringIterators.push_back(partitionCellsToLoad.end());
28210 m_log <<
"done" << endl;
28212 MInt noFakeReads = 0;
28214 if(noDomains() > 1) {
28216 MPI_Allreduce(&noReadOps, &maxNoReadOps, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"noReadOps",
"maxNoReadOps");
28217 MPI_Allreduce(&noReadOps, &minNoReadOps, 1, MPI_INT, MPI_MIN, mpiComm(), AT_,
"noReadOps",
"minNoReadOps");
28218 noFakeReads = maxNoReadOps - noReadOps;
28219 m_log << maxNoReadOps <<
" max number of read operations" << endl;
28220 m_log << minNoReadOps <<
" min number of read operations" << endl;
28224 m_log <<
"get leaf cell data ..." << endl;
28233 for(
MInt noOps = 0; noOps < noReadOps; noOps++) {
28234 multimap<MInt, MInt>::iterator it = readClusteringIterators[noOps];
28235 multimap<MInt, MInt>::iterator nextIt = readClusteringIterators[noOps + 1];
28236 multimap<MInt, MInt>::iterator lastIt = prev(nextIt);
28237 MInt srcPartitionCellGlobalId = srcPartitionCellsGlobalId(it->first);
28238 MInt srcCellsToRead = 0;
28239 for(
MInt smcid = it->first; smcid <= lastIt->first; smcid++)
28240 srcCellsToRead += srcPartitionCellsGlobalId(smcid + 1) - srcPartitionCellsGlobalId(smcid);
28241 srcGrid.setOffset(srcCellsToRead, srcPartitionCellGlobalId);
28242 srcData.setOffset(srcCellsToRead, srcPartitionCellGlobalId);
28244 for(
MInt j = 0; j < nDim; ++j) {
28246 ss <<
"coordinates_" << j;
28247 varNames.push_back(ss.str());
28251 srcGrid.readArray(&srcCoords(0, 0), varNames, nDim);
28254 srcGrid.readArray(srcNoChildIds.begin(),
"noChildIds");
28256 srcGrid.readArray(srcLevel.begin(),
"level_0");
28258 for(
MInt j = 0; j <
IPOW2(nDim); ++j) {
28260 ss <<
"childIds_" << j;
28261 varNames.push_back(ss.str());
28265 srcGrid.readArray(&srcChildIds(0, 0), varNames,
IPOW2(nDim));
28268 for(
MInt i = 0; i < maxNoCellsToRead; i++)
28270 srcChildIds(i, j) -= srcPartitionCellGlobalId;
28272 for(
MInt i = 0; i < maxNoCellsToRead; i++)
28273 for(
MInt j = 0; j < nDim; j++)
28274 srcCoords(i, j) *= fileTypeFac;
28276 for(
MInt j = 0; j < noPVars; ++j) {
28278 ss <<
"variables" << j;
28279 varNames.push_back(ss.str());
28283 srcData.readArray(&srcVars(0, 0), varNames, noPVars);
28286 for(multimap<MInt, MInt>::iterator i = it; i != nextIt; advance(i, 1)) {
28289 MInt locSrcPartitionCellId = srcPartitionCellsGlobalId(i->first) - srcPartitionCellGlobalId;
28290 MInt cid = i->second;
28293 MInt srcSrcId = locSrcPartitionCellId;
28295 while(srcNoChildIds(srcSrcId)) {
28314 MFloat minDist = std::numeric_limits<MFloat>::max();
28316 for(
MInt cc = 0; cc <
IPOW2(nDim); cc++) {
28317 MInt tcid = srcChildIds(srcSrcId, cc);
28319 MFloat* srcCoord = &srcCoords(tcid, 0);
28320 MFloat hdc = srcLengthLevel0 /
IPOW2(srcLevel(tcid) + 1);
28322 MInt insideCnt = 0;
28323 for(
MInt dim = 0; dim < nDim; dim++)
28324 if(coord[dim] < srcCoord[dim] + hdc && coord[dim] >= srcCoord[dim] - hdc) insideCnt++;
28325 if(insideCnt == nDim) {
28331 for(
MInt dim = 0; dim < nDim; dim++)
28332 tmpDist += pow(coord[dim] - srcCoord[dim], F2);
28333 tmpDist = sqrt(tmpDist);
28336 if(tmpDist < minDist) {
28341 if(cc ==
IPOW2(nDim) - 1) srcSrcId = minTcid;
28345 for(
MInt var = 0; var < noPVars; var++)
28346 a_pvariable(cid, var) = srcVars(srcSrcId, var);
28351 for(
MInt fr = 0; fr < noFakeReads; fr++) {
28353 for(
MInt j = 0; j < nDim; ++j) {
28355 ss <<
"coordinates_" << j;
28356 varNames.push_back(ss.str());
28360 srcGrid.setOffset(0, 0);
28361 srcData.setOffset(0, 0);
28362 srcGrid.readArray(&srcCoords(0, 0), varNames, nDim);
28365 srcGrid.readArray(srcNoChildIds.begin(),
"noChildIds");
28367 srcGrid.readArray(srcLevel.begin(),
"level_0");
28369 for(
MInt j = 0; j <
IPOW2(nDim); ++j) {
28371 ss <<
"childIds_" << j;
28372 varNames.push_back(ss.str());
28376 srcGrid.readArray(&srcChildIds(0, 0), varNames,
IPOW2(nDim));
28379 for(
MInt j = 0; j < noPVars; ++j) {
28381 ss <<
"variables" << j;
28382 varNames.push_back(ss.str());
28386 srcData.readArray(&srcVars(0, 0), varNames, noPVars);
28391 m_log <<
"done" << endl;
28394 MInt sumUncollated = uncollatedCells.size();
28395 MPI_Allreduce(MPI_IN_PLACE, &sumUncollated, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
28397 m_log << sumUncollated <<
" uncollated cells" << endl;
28400 MInt sumUncollatedBndry = 0;
28401 set<MInt> allUncollatedBndryGlobalIds;
28403 MIntScratchSpace noGlobalUncollatedBndry(noDomains(), AT_,
"noGlobalUncollatedBndry");
28404 MIntScratchSpace noGlobalUncollatedBndryOffset(noDomains() + 1, AT_,
"noGlobalUncollatedBndryOffset");
28405 noGlobalUncollatedBndry.fill(0);
28406 noGlobalUncollatedBndryOffset.fill(0);
28407 noGlobalUncollatedBndry[domainId()] = uncollatedBndryCells.size();
28408 MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, noGlobalUncollatedBndry.begin(), 1, MPI_INT, mpiComm(), AT_,
28409 "MPI_IN_PLACE",
"noGlobalUncollatedBndry.begin()");
28410 for(
MInt dom = 0; dom < noDomains(); dom++) {
28411 sumUncollatedBndry += noGlobalUncollatedBndry[dom];
28412 noGlobalUncollatedBndryOffset[dom + 1] = sumUncollatedBndry;
28414 MIntScratchSpace globalUncollatedBndry(sumUncollatedBndry, AT_,
"globalUncollatedBndry");
28415 for(
MInt cnt = 0; cnt < (
MInt)uncollatedBndryCells.size(); cnt++) {
28416 MInt globalId = c_globalId(uncollatedBndryCells[cnt]);
28417 globalUncollatedBndry[noGlobalUncollatedBndryOffset[domainId()] + cnt] = globalId;
28419 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, globalUncollatedBndry.begin(),
28420 noGlobalUncollatedBndry.begin(), noGlobalUncollatedBndryOffset.begin(), MPI_INT, mpiComm(),
28421 AT_,
"MPI_IN_PLACE",
"globalUncollatedBndry.begin()");
28422 for(
MInt cnt = 0; cnt < sumUncollatedBndry; cnt++)
28423 allUncollatedBndryGlobalIds.insert(allUncollatedBndryGlobalIds.end(), noGlobalUncollatedBndry[cnt]);
28426 m_log << sumUncollatedBndry <<
" uncollated bndry cells" << endl;
28427 if(sumUncollatedBndry)
28428 m_log <<
"WARNING that is almost an ERROR: we have non "
28429 <<
"collated boundary cells in initial consdition 8111" << endl
28430 <<
"i will try to fix it, but we will see" << endl;
28435 m_log <<
"exchange done" << endl;
28438 for(
MInt cnt = 0; cnt < (
MInt)uncollatedBndryCells.size(); cnt++) {
28439 MInt cid = uncollatedBndryCells[cnt];
28440 cerr <<
"fixing uncollated state for cell " << c_globalId(cid) << endl;
28442 for(
MInt var = 0; var < noPVars; var++)
28443 a_pvariable(cid, var) = F0;
28445 MInt validNghbrs = 0;
28447 for(
MInt dir = 0; dir < a_noReconstructionNeighbors(cid); dir++) {
28448 MInt nid = a_reconstructionNeighborId(cid, dir);
28449 cerr <<
" rec nghbr " << dir <<
", neighborId " << nid << endl;
28451 if(a_isBndryGhostCell(nid)) {
28452 cerr <<
"-- is ghost cell" << endl;
28456 if(allUncollatedBndryGlobalIds.find(c_globalId(nid)) != allUncollatedBndryGlobalIds.end()) {
28457 cerr <<
"-- neighbor " << c_globalId(nid) <<
" is also uncollated" << endl;
28462 for(
MInt var = 0; var < noPVars; var++)
28463 a_pvariable(cid, var) += a_pvariable(nid, var);
28465 if(!validNghbrs)
mTerm(1,
"no valid nghbrs for initialisation of uncollated boundary cell");
28467 for(
MInt var = 0; var < noPVars; var++)
28468 a_pvariable(cid, var) /= validNghbrs;
28474 m_log <<
"exchange done" << endl;
28478 saveRestartFile(
false);
28481 computeConservativeVariables();
28482 LSReconstructCellCenter();
28488 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "This IC is untested in 2D! If it works uncomment this warning.");
28492 computeInitialPressureLossForChannelFlow();
28494 m_fvBndryCnd->m_deltaP = m_deltaP;
28496 MFloat factor, perturbation;
28497 MFloat UT = m_Ma * sqrt(m_TInfinity);
28499 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
28500 if(cellId % 2 == 0) {
28507 a_variable(cellId, CV->RHO) = m_rhoInfinity;
28509 for(
MUint d = 0; d < nDim; d++) {
28513 perturbation = (
MFloat(rand()) / RAND_MAX) * 0.001 * UT * factor;
28514 a_variable(cellId, CV->RHO_VV[d]) = F2B3 * m_rhoVVInfinity[d] + perturbation;
28518 const MFloat pressure = m_PInfinity - m_deltaP * (a_coordinate(cellId, 0) - m_domainBoundaries[0]);
28520 for(
MUint d = 0; d < nDim; d++)
28521 velPOW2 +=
POW2(a_variable(cellId, CV->RHO_VV[d]));
28522 IF_CONSTEXPR(hasE<SysEqn>)
28523 a_variable(cellId, CV->RHO_E) = pressure / gammaMinusOne + (F1B2 * velPOW2) / m_rhoInfinity;
28532 m_rhoInfinity = F1;
28534 m_PInfinity = sysEqn().pressure_ES(m_TInfinity, m_rhoInfinity);
28535 m_UInfinity = m_Ma;
28536 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
28537 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
28538 m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
28539 m_rhoEInfinity = sysEqn().internalEnergy(m_PInfinity, m_rhoInfinity,
POW2(m_UInfinity));
28540 m_hInfinity = sysEqn().enthalpy(m_PInfinity, m_rhoInfinity);
28541 sysEqn().m_Re0 = m_Re * SUTHERLANDLAW(m_TInfinity) / (m_rhoInfinity * m_UInfinity);
28545 for(
MInt i = 0; i < nDim; i++) {
28546 bbox[i] = numeric_limits<MFloat>::max();
28547 bbox[nDim + i] = numeric_limits<MFloat>::lowest();
28550 if(a_isHalo(cellId))
continue;
28551 if(a_isPeriodic(cellId))
continue;
28552 for(
MInt i = 0; i < nDim; i++) {
28553 bbox[i] =
mMin(bbox[i], a_coordinate(cellId, i) - F1B2 * c_cellLengthAtCell(cellId));
28554 bbox[nDim + i] =
mMax(bbox[nDim + i], a_coordinate(cellId, i) + F1B2 * c_cellLengthAtCell(cellId));
28557 MPI_Allreduce(MPI_IN_PLACE, &bbox[0], nDim, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
"bbox[0]");
28558 MPI_Allreduce(MPI_IN_PLACE, &bbox[nDim], nDim, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
28562 IF_CONSTEXPR(nDim == 3) { FX = F2; }
28567 const MFloat x = (a_coordinate(cellId, 0) - bbox[0]) / (bbox[nDim] - bbox[0]);
28568 const MFloat y = (a_coordinate(cellId, 1) - bbox[1]) / (bbox[nDim + 1] - bbox[1]);
28570 IF_CONSTEXPR(nDim == 3) { z = (a_coordinate(cellId, 2) - bbox[2]) / (bbox[nDim + 2] - bbox[2]); }
28574 const MFloat u = m_Ma * sin(FX * PI * x) *
cos(FX * PI *
y) *
cos(F2 * PI * z);
28575 const MFloat v = -m_Ma *
cos(FX * PI * x) * sin(FX * PI *
y) *
cos(F2 * PI * z);
28578 IF_CONSTEXPR(nDim == 3) {
28580 + F1B16 *
POW2(m_Ma) * m_rhoInfinity * (
cos(F4 * PI * x) +
cos(F4 * PI *
y)) * (
cos(F4 * PI * z) + F2);
28583 p = m_PInfinity + F1B4 *
POW2(m_Ma) * m_rhoInfinity * (
cos(F2 * PI * x) + sin(F2 * PI *
y));
28585 const MFloat rho = sysEqn().density_ES(p, m_TInfinity);
28586 a_variable(cellId, CV->RHO) = rho;
28587 a_variable(cellId, CV->RHO_U) = rho * u;
28588 a_variable(cellId, CV->RHO_V) = rho * v;
28589 a_variable(cellId, CV->RHO_W) = rho * w;
28590 IF_CONSTEXPR(hasE<SysEqn>) {
28591 a_variable(cellId, CV->RHO_E) = sysEqn().internalEnergy(p, rho, (
POW2(u) +
POW2(v) +
POW2(w)));
28599 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "Only works for 3D!");
28600 const
MFloat time0 = MPI_Wtime();
28601 computeCellVolumes();
28602 const
MInt fftLevel = maxUniformRefinementLevel();
28603 const
MFloat DX = c_cellLengthAtLevel(fftLevel);
28604 if(fftLevel > maxUniformRefinementLevel()) {
28605 mTerm(1, AT_,
"Isotropic mesh expected (0).");
28608 m_geometry->getBoundingBox(bbox);
28610 for(
MInt i = 0; i < nDim; i++) {
28611 bbox[i] = numeric_limits<MFloat>::max();
28612 bbox[nDim + i] = numeric_limits<MFloat>::lowest();
28615 if(a_isHalo(cellId))
continue;
28616 if(a_isPeriodic(cellId))
continue;
28617 if(a_isBndryGhostCell(cellId))
continue;
28618 for(
MInt i = 0; i < nDim; i++) {
28619 bbox[i] =
mMin(bbox[i], a_coordinate(cellId, i) - F1B2 * c_cellLengthAtCell(cellId));
28620 bbox[nDim + i] =
mMax(bbox[nDim + i], a_coordinate(cellId, i) + F1B2 * c_cellLengthAtCell(cellId));
28623 MPI_Allreduce(MPI_IN_PLACE, &bbox[0], nDim, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
"bbox[0]");
28624 MPI_Allreduce(MPI_IN_PLACE, &bbox[nDim], nDim, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
28630 const MFloat dxeps = 0.1 * DX;
28631 MInt nx = (bbox[3] - bbox[0] + dxeps) / DX;
28632 MInt ny = (bbox[4] - bbox[1] + dxeps) / DX;
28633 MInt nz = (bbox[5] - bbox[2] + dxeps) / DX;
28634 const MInt size = nx * ny * nz;
28636 m_rhoInfinity = F1;
28638 m_PInfinity = sysEqn().pressure_ES(m_TInfinity, m_rhoInfinity);
28639 m_UInfinity = m_Ma;
28642 m_rhoUInfinity = m_rhoInfinity * m_UInfinity;
28643 m_rhoVInfinity = m_rhoInfinity * m_VInfinity;
28644 m_rhoWInfinity = m_rhoInfinity * m_WInfinity;
28645 m_rhoEInfinity = sysEqn().internalEnergy(m_PInfinity, m_rhoInfinity,
POW2(m_UInfinity));
28646 m_hInfinity = sysEqn().enthalpy(m_PInfinity, m_rhoInfinity);
28647 sysEqn().m_muInfinity = SUTHERLANDLAW(m_TInfinity);
28648 sysEqn().m_Re0 = m_Re * sysEqn().m_muInfinity / (m_rhoInfinity * m_UInfinity);
28650 m_VVInfinity[0] = m_UInfinity;
28651 m_VVInfinity[1] = m_VInfinity;
28652 m_VVInfinity[2] = m_WInfinity;
28653 m_rhoVVInfinity[0] = m_rhoUInfinity;
28654 m_rhoVVInfinity[1] = m_rhoVInfinity;
28655 m_rhoVVInfinity[2] = m_rhoWInfinity;
28667 m_Re = Context::getSolverProperty<MFloat>(
"ReLambdaRestart", m_solverId, AT_);
28668 sysEqn().m_Re0 = m_Re * SUTHERLANDLAW(m_TInfinity) / (m_rhoInfinity * m_UInfinity);
28669 if(domainId() == 0) cerr <<
"Loading out/restartVariables_init.Netcdf" << endl;
28670 loadGridFlowVarsPar(
"out/restartVariables_init.Netcdf");
28671 exchangeDataFV(&a_pvariable(0, 0), noPVars,
false, m_rotIndVarsPV);
28672 computeConservativeVariables();
28673 m_log <<
"Restart Reynolds number: " << setprecision(15) << m_Re <<
" (Re_L=" << m_Re * (bbox[3] - bbox[0])
28675 <<
" " << sysEqn().m_Re0 << endl;
28679 MBool goodSpectrum =
false;
28681 while(!goodSpectrum) {
28682 const MInt spectrumId = 2;
28683 const MFloat kpRatio = F4;
28684 fftw_complex* uPhysField;
28685 fftw_complex* nabla2P;
28689 seed =
maia::math::initFft(uPhysField, nabla2P, nx, ny, nz, kpRatio, spectrumId, fftInfo, mpiComm(),
true);
28691 MInt maxRank = fftInfo[0];
28692 MInt local_n0 = fftInfo[1];
28693 MInt local_0_start = fftInfo[2];
28694 MInt alloc_local = fftInfo[3];
28697 MInt sendIdsSize = 0;
28700 MPI_Allgather(&locOffsetIds, 1, MPI_INT, &offsetsIds[0], 1, MPI_INT, mpiComm(), AT_,
"locOffsetIds",
28707 if(a_isHalo(cellId))
continue;
28708 if(a_isBndryGhostCell(cellId))
continue;
28709 if(a_level(cellId) != fftLevel)
continue;
28710 MFloat actualCellLength = c_cellLengthAtCell(cellId);
28711 MInt xPos = floor((F1B2 * nx + (a_coordinate(cellId, 0) - F1B2 * (actualCellLength)) / DX) + 0.1);
28712 MInt yPos = floor((F1B2 * ny + (a_coordinate(cellId, 1) - F1B2 * (actualCellLength)) / DX) + 0.1);
28713 MInt zPos = floor((F1B2 * nz + (a_coordinate(cellId, 2) - F1B2 * (actualCellLength)) / DX) + 0.1);
28715 MInt nghbrDomain =
mMin(maxRank - 1, pos / (size / maxRank));
28716 while(pos < offsetsIds(nghbrDomain) || pos >= offsetsIds(nghbrDomain + 1)) {
28717 if(pos < offsetsIds(nghbrDomain)) nghbrDomain--;
28718 if(pos >= offsetsIds(nghbrDomain + 1)) nghbrDomain++;
28720 if(nghbrDomain >= maxRank)
mTerm(1, AT_,
"wrong domain");
28721 noSendIds(nghbrDomain)++;
28726 sendIdsOffsets[0] = 0;
28727 sendIdsOffsetsTmp[0] = 0;
28729 sendIdsOffsets[nghbrDomain + 1] = sendIdsOffsets[nghbrDomain] + noSendIds[nghbrDomain];
28730 sendIdsOffsetsTmp[nghbrDomain + 1] = sendIdsOffsets[nghbrDomain] + noSendIds[nghbrDomain];
28736 if(a_isHalo(cellId))
continue;
28737 if(a_isBndryGhostCell(cellId))
continue;
28738 if(a_level(cellId) != fftLevel)
continue;
28739 MFloat actualCellLength = c_cellLengthAtCell(cellId);
28740 MInt xPos = floor((F1B2 * nx + (a_coordinate(cellId, 0) - F1B2 * (actualCellLength)) / DX) + 0.1);
28741 MInt yPos = floor((F1B2 * ny + (a_coordinate(cellId, 1) - F1B2 * (actualCellLength)) / DX) + 0.1);
28742 MInt zPos = floor((F1B2 * nz + (a_coordinate(cellId, 2) - F1B2 * (actualCellLength)) / DX) + 0.1);
28744 MInt nghbrDomain =
mMin(maxRank - 1, pos / (size / maxRank));
28745 while(pos < offsetsIds(nghbrDomain) || pos >= offsetsIds(nghbrDomain + 1)) {
28746 if(pos < offsetsIds(nghbrDomain)) nghbrDomain--;
28747 if(pos >= offsetsIds(nghbrDomain + 1)) nghbrDomain++;
28749 if(nghbrDomain >= maxRank)
mTerm(1, AT_,
"wrong domain");
28750 sendIds[sendIdsOffsetsTmp[nghbrDomain]++] = pos;
28754 MPI_Alltoall(&noSendIds[0], 1, MPI_INT, &noRecvIds[0], 1, MPI_INT, mpiComm(), AT_,
"noSendIds[0]",
28758 recvIdsOffsets[0] = 0;
28759 MInt recvIdsSize = 0;
28761 recvIdsOffsets[nghbrDomain + 1] = recvIdsOffsets[nghbrDomain] + noRecvIds[nghbrDomain];
28762 recvIdsSize += noRecvIds[nghbrDomain];
28768 MPI_Alltoallv(&sendIds[0], &noSendIds[0], &sendIdsOffsets[0], MPI_INT, &recvIds[0], &noRecvIds[0],
28769 &recvIdsOffsets[0], MPI_INT, mpiComm(), AT_,
"sendIds[0]",
"recvIds[0]");
28774 sendVarsOffsets[0] = 0;
28775 sendVarsOffsetsTmp[0] = 0;
28776 MInt sendVarsSize = 0;
28778 sendVarsOffsets[i + 1] = sendVarsOffsets[i] + noRecvIds[i] * 4;
28779 sendVarsOffsetsTmp[i + 1] = sendVarsOffsetsTmp[i] + noRecvIds[i] * 4;
28780 noSendVars[i] = noRecvIds[i] * 4;
28781 sendVarsSize += noRecvIds[i] * 4;
28783 if(recvIdsSize != 0) {
28792 MFloat upr[3] = {F0, F0, F0};
28793 for(
MInt i = 0; i < recvIdsSize; i++) {
28794 MInt pos = recvIds[i];
28795 ASSERT(pos > -1 && pos < size,
"");
28796 if(!(pos >= ((
MInt)local_0_start) * nx * ny && pos < ((
MInt)(local_0_start + local_n0) * ny * nx))) {
28797 mTerm(1, AT_,
"Position not available on this domain(1).");
28799 MInt localPos = pos - (((
MInt)local_0_start) * ny * nz);
28800 if(3 * localPos + 2 > alloc_local) {
28801 mTerm(1, AT_,
"index exceeds array(1)");
28803 sendVars[i * 4] = uPhysField[3 * localPos][0];
28804 sendVars[i * 4 + 1] = uPhysField[3 * localPos + 1][0];
28805 sendVars[i * 4 + 2] = uPhysField[3 * localPos + 2][0];
28806 sendVars[i * 4 + 3] = nabla2P[localPos][0];
28807 MFloat u = uPhysField[3 * localPos][0];
28808 MFloat v = uPhysField[3 * localPos + 1][0];
28809 MFloat w = uPhysField[3 * localPos + 2][0];
28816 MPI_Allreduce(MPI_IN_PLACE, &cnt, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"cnt");
28817 MPI_Allreduce(MPI_IN_PLACE, &upr, 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"upr");
28819 MFloat uprime0 = sqrt(F1B3 * (upr[0] + upr[1] + upr[2]) / cnt);
28821 fftw_free(uPhysField);
28822 fftw_free(nabla2P);
28826 recvVarsOffsets[0] = 0;
28827 MInt recvVarsSize = 0;
28829 recvVarsOffsets[i + 1] = recvVarsOffsets[i] + noSendIds[i] * 4;
28830 noRecvVars[i] = noSendIds[i] * 4;
28831 recvVarsSize += noSendIds[i] * 4;
28839 MPI_Alltoallv(&sendVars[0], &noSendVars[0], &sendVarsOffsets[0], MPI_DOUBLE, &recvVars[0], &noRecvVars[0],
28840 &recvVarsOffsets[0], MPI_DOUBLE, mpiComm(), AT_,
"sendVars[0]",
"recvVars[0]");
28847 if(a_isHalo(cellId))
continue;
28848 if(a_isBndryGhostCell(cellId))
continue;
28849 if(a_level(cellId) != fftLevel)
continue;
28852 MFloat actualCellLength = c_cellLengthAtCell(cellId);
28853 MInt xPos = floor((F1B2 * nx + (a_coordinate(cellId, 0) - F1B2 * (actualCellLength)) / DX) + 0.1);
28854 MInt yPos = floor((F1B2 * ny + (a_coordinate(cellId, 1) - F1B2 * (actualCellLength)) / DX) + 0.1);
28855 MInt zPos = floor((F1B2 * nz + (a_coordinate(cellId, 2) - F1B2 * (actualCellLength)) / DX) + 0.1);
28857 MInt nghbrDomain =
mMin(maxRank - 1, pos / (size / maxRank));
28858 while(pos < offsetsIds(nghbrDomain) || pos >= offsetsIds(nghbrDomain + 1)) {
28859 if(pos < offsetsIds(nghbrDomain)) nghbrDomain--;
28860 if(pos >= offsetsIds(nghbrDomain + 1)) nghbrDomain++;
28862 if(nghbrDomain >= maxRank)
mTerm(1, AT_,
"wrong domain");
28863 if(sendIds[sendIdsOffsets[nghbrDomain]] != pos)
mTerm(1, AT_,
"pos mismatch");
28864 MFloat u = recvVars[sendIdsOffsets[nghbrDomain] * 4];
28865 MFloat v = recvVars[sendIdsOffsets[nghbrDomain] * 4 + 1];
28866 MFloat w = recvVars[sendIdsOffsets[nghbrDomain] * 4 + 2];
28867 MFloat p = recvVars[sendIdsOffsets[nghbrDomain] * 4 + 3];
28868 sendIdsOffsets[nghbrDomain]++;
28872 a_pvariable(cellId, PV->U) = u;
28873 a_pvariable(cellId, PV->V) = v;
28874 a_pvariable(cellId, PV->W) = w;
28875 a_pvariable(cellId, PV->P) = m_PInfinity +
p *
POW2(m_UInfinity);
28879 MPI_Allreduce(MPI_IN_PLACE, &cnt, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"cnt");
28880 MPI_Allreduce(MPI_IN_PLACE, &upr, 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"upr");
28882 MFloat uprime1 = sqrt(F1B3 * (upr[0] + upr[1] + upr[2]) / cnt);
28883 upr[0] = sqrt(upr[0] / cnt);
28884 upr[1] = sqrt(upr[1] / cnt);
28885 upr[2] = sqrt(upr[2] / cnt);
28887 if(fabs(uprime0 - uprime1) > exp(-10))
mTerm(1, AT_,
"Communication went wrong.");
28889 if(domainId() == 0)
28890 cerr <<
"initial urpime: " << upr[0] <<
" " << upr[1] <<
" " << upr[2] <<
" (" << uprime1 <<
")" << endl;
28900 if(a_isHalo(cellId))
continue;
28901 if(a_isBndryGhostCell(cellId))
continue;
28902 if(a_level(cellId) != fftLevel)
continue;
28904 MFloat u = a_pvariable(cellId, PV->U) * m_UInfinity / uprime1;
28905 MFloat v = a_pvariable(cellId, PV->V) * m_UInfinity / uprime1;
28906 MFloat w = a_pvariable(cellId, PV->W) * m_UInfinity / uprime1;
28907 MFloat p = a_pvariable(cellId, PV->P);
28908 MFloat rho = sysEqn().density_ES(p, m_TInfinity);
28909 a_variable(cellId, CV->RHO) = rho;
28910 a_variable(cellId, CV->RHO_U) = rho * u;
28911 a_variable(cellId, CV->RHO_V) = rho * v;
28912 a_variable(cellId, CV->RHO_W) = rho * w;
28913 IF_CONSTEXPR(hasE<SysEqn>) {
28914 a_variable(cellId, CV->RHO_E) = sysEqn().internalEnergy(p, rho, (
POW2(u) +
POW2(v) +
POW2(w)));
28916 a_pvariable(cellId, PV->U) = u;
28917 a_pvariable(cellId, PV->V) = v;
28918 a_pvariable(cellId, PV->W) = w;
28919 a_pvariable(cellId, PV->P) =
p;
28920 a_pvariable(cellId, PV->RHO) = rho;
28923 exchangeDataFV(&a_variable(0, 0), noCVars,
false, m_rotIndVarsPV);
28924 exchangeDataFV(&a_pvariable(0, 0), noPVars,
false, m_rotIndVarsCV);
28926 MFloat umean[3] = {F0, F0, F0};
28927 MFloat urms[6] = {F0, F0, F0, F0, F0, F0};
28928 MFloat reyn[6] = {F0, F0, F0, F0, F0, F0};
28929 MFloat aniso[6] = {F0, F0, F0, F0, F0, F0};
28930 MFloat dudx[3] = {F0, F0, F0};
28931 MFloat skew[4] = {F0, F0, F0, F0};
28933 if(a_isHalo(cellId))
continue;
28934 if(a_isBndryGhostCell(cellId))
continue;
28935 if(a_level(cellId) != fftLevel)
continue;
28936 MFloat u = a_pvariable(cellId, PV->U);
28937 MFloat v = a_pvariable(cellId, PV->V);
28938 MFloat w = a_pvariable(cellId, PV->W);
28939 for(
MInt i = 0; i < nDim; i++) {
28940 MInt n0 = (a_hasNeighbor(cellId, 2 * i) > 0) ? c_neighborId(cellId, 2 * i) :
cellId;
28941 MInt n1 = (a_hasNeighbor(cellId, 2 * i + 1) > 0) ? c_neighborId(cellId, 2 * i + 1) :
cellId;
28942 if(n0 == n1)
continue;
28943 dudx[i] +=
POW2((a_pvariable(n1, PV->VV[i]) - a_pvariable(n0, PV->VV[i]))
28944 / (a_coordinate(n1, i) - a_coordinate(n0, i)));
28945 skew[i] +=
POW3((a_pvariable(n1, PV->VV[i]) - a_pvariable(n0, PV->VV[i]))
28946 / (a_coordinate(n1, i) - a_coordinate(n0, i)));
28948 urms[0] +=
POW2(u);
28949 urms[1] +=
POW2(v);
28950 urms[2] +=
POW2(w);
28958 MPI_Allreduce(MPI_IN_PLACE, &urms[0], 6, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"urms[0]");
28959 MPI_Allreduce(MPI_IN_PLACE, &umean[0], 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"umean[0]");
28960 MPI_Allreduce(MPI_IN_PLACE, &dudx[0], 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"dudx[0]");
28961 MPI_Allreduce(MPI_IN_PLACE, &skew[0], 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"skew[0]");
28962 skew[3] = ((skew[0] + skew[1] + skew[2]) / (F3 * cnt)) / pow((dudx[0] + dudx[1] + dudx[2]) / (F3 * cnt), 1.5);
28963 for(
MInt i = 0; i < 3; i++)
28964 skew[i] = (skew[i] / cnt) / pow(dudx[i] / cnt, 1.5);
28965 for(
MInt i = 0; i < 6; i++)
28966 reyn[i] = urms[i] / cnt;
28967 for(
MInt i = 0; i < 6; i++)
28968 aniso[i] = urms[i] / (urms[0] + urms[1] + urms[2]);
28969 for(
MInt i = 0; i < 3; i++)
28971 for(
MInt i = 0; i < 6; i++)
28972 urms[i] = sqrt(fabs(urms[i]) / cnt);
28973 for(
MInt i = 0; i < 3; i++)
28975 for(
MInt i = 0; i < 3; i++)
28980 for(
MInt i = 0; i < 3; i++)
28981 lambda[i] = urms[i] / sqrt(dudx[i]);
28983 if(domainId() == 0)
28984 cerr <<
"u_mean: " << umean[0] <<
" " << umean[1] <<
" " << umean[2] <<
" (" << (
MInt)cnt <<
")" << endl;
28985 if(domainId() == 0)
28986 cerr <<
"u_rms/u_inf: " << urms[0] / m_UInfinity <<
" " << urms[1] / m_UInfinity <<
" "
28987 << urms[2] / m_UInfinity <<
" " << urms[3] / m_UInfinity <<
" " << urms[4] / m_UInfinity <<
" "
28988 << urms[5] / m_UInfinity <<
" (" << F1B3 * (urms[0] + urms[1] + urms[2]) / m_UInfinity <<
")" << endl;
28989 if(domainId() == 0)
28990 cerr <<
"skewness: " << skew[0] <<
" " << skew[1] <<
" " << skew[2] <<
" (" << skew[3] <<
")" << endl;
28991 if(domainId() == 0)
28992 cerr <<
"Anisotropy: " << aniso[0] <<
" " << aniso[1] <<
" " << aniso[2] <<
" " << aniso[3] <<
" "
28993 << aniso[4] <<
" " << aniso[5] << endl;
28994 if(domainId() == 0)
28995 cerr <<
"Reynolds stress: " << reyn[0] <<
" " << reyn[1] <<
" " << reyn[2] <<
" " << reyn[3] <<
" "
28996 << reyn[4] <<
" " << reyn[5] << endl;
28997 if(domainId() == 0)
28998 cerr <<
"Realizability 1: " << reyn[3] * reyn[3] <<
" <= " << reyn[0] * reyn[1] <<
", " << reyn[4] * reyn[4]
28999 <<
" <= " << reyn[0] * reyn[2] <<
", " << reyn[5] * reyn[5] <<
" <= " << reyn[1] * reyn[2] << endl;
29000 if(domainId() == 0)
29001 cerr <<
"Realizability 2: det = "
29002 << reyn[0] * reyn[1] * reyn[2] + F2 * reyn[3] * reyn[4] * reyn[5] - reyn[0] * reyn[5] * reyn[5]
29003 - reyn[1] * reyn[4] * reyn[4] - reyn[2] * reyn[4] * reyn[4]
29004 <<
" >= 0" << endl;
29009 const MFloat time1 = MPI_Wtime();
29010 m_log <<
"initFFT time " << time1 - time0 << endl;
29025 mTerm(1, AT_,
"Undefined ReLambda for LES grid.");
29027 m_Re = Context::getSolverProperty<MFloat>(
"ReLambdaOverwrite", m_solverId, AT_) / m_referenceLength;
29028 sysEqn().m_Re0 = m_Re * SUTHERLANDLAW(m_TInfinity) / (m_rhoInfinity * m_UInfinity);
29029 m_log <<
"Overwritten Reynolds number: " << setprecision(15) << m_Re
29030 <<
" (Re_L=" << m_Re * (bbox[3] - bbox[0]) <<
")"
29031 <<
" " << sysEqn().m_Re0 << endl;
29047 m_Re = Context::getSolverProperty<MFloat>(
"ReLambda", m_solverId, AT_) / m_referenceLength;
29048 m_Re *= F3 / (lambda[0] + lambda[1] + lambda[2]);
29050 sysEqn().m_Re0 = m_Re * SUTHERLANDLAW(m_TInfinity) / (m_rhoInfinity * m_UInfinity);
29051 m_log <<
"Computed Reynolds number: " << setprecision(15) << m_Re <<
" (Re_L=" << m_Re * (bbox[3] - bbox[0])
29053 <<
" " << sysEqn().m_Re0 << endl;
29055 MFloat mue = SUTHERLANDLAW(m_TInfinity) / sysEqn().m_Re0;
29056 for(
MInt i = 0; i < 3; i++)
29057 Rel[i] = m_rhoInfinity * urms[i] * lambda[i] / mue;
29059 m_rhoInfinity * F1B3 * (urms[0] + urms[1] + urms[2]) * F1B3 * (lambda[0] + lambda[1] + lambda[2]) / mue;
29060 for(
MInt i = 0; i < 3; i++)
29061 eps[i] = (15.0 * sysEqn().m_muInfinity * dudx[i]) * (bbox[nDim + i] - bbox[i])
29062 / (sysEqn().m_Re0 *
POW3(urms[i]));
29063 if(domainId() == 0)
29064 cerr <<
"lambda: " << lambda[0] <<
" " << lambda[1] <<
" " << lambda[2] <<
" ("
29065 << F1B3 * (lambda[0] + lambda[1] + lambda[2]) <<
")" << endl;
29066 if(domainId() == 0)
29067 cerr <<
"eps: " << eps[0] <<
" " << eps[1] <<
" " << eps[2] <<
" (" << F1B3 * (eps[0] + eps[1] + eps[2])
29069 if(domainId() == 0)
29070 cerr <<
"Re_lambda: " << Rel[0] <<
" " << Rel[1] <<
" " << Rel[2] <<
" (" << Rel[3] <<
", "
29071 << F1B3 * (Rel[0] + Rel[1] + Rel[2]) <<
")" << endl;
29072 if(domainId() == 0)
29073 cerr <<
"Kolmogorov length: "
29074 << pow(sysEqn().m_muInfinity / sysEqn().m_Re0, 0.75) / pow(F1B3 * (eps[0] + eps[1] + eps[2]), 0.25)
29078 MFloat maxd =
mMax(fabs(Rel[0] - Rel[1]),
mMax(fabs(Rel[0] - Rel[2]), fabs(Rel[1] - Rel[2])));
29079 if(maxd < F1)
m_log <<
"spectrum " << maxd <<
" " << F1B3 * (Rel[0] + Rel[1] + Rel[2]) <<
" " << seed << endl;
29082 goodSpectrum =
true;
29083 if(domainId() == 0)
m_log <<
"spectrum " << seed << endl;
29087 if(domainId() == 0) cerr <<
"seed " << seed << endl;
29088 m_randomDeviceSeed = seed;
29091 if(fftLevel < maxRefinementLevel()) {
29093 if(a_isHalo(cellId))
continue;
29094 if(a_isBndryGhostCell(cellId))
continue;
29095 if(a_level(cellId) <= fftLevel)
continue;
29096 if(c_noChildren(cellId) > 0)
continue;
29097 MInt parentId = c_parentId(cellId);
29098 while(a_level(parentId) != fftLevel) {
29099 parentId = c_parentId(parentId);
29101 if(a_level(parentId) == fftLevel) {
29102 for(
MInt varId = 0; varId < noCVars; varId++) {
29103 a_variable(cellId, varId) = a_variable(parentId, varId);
29105 for(
MInt varId = 0; varId < noPVars; varId++) {
29106 a_pvariable(cellId, varId) = a_pvariable(parentId, varId);
29112 exchangeDataFV(&a_pvariable(0, 0), noPVars,
false, m_rotIndVarsPV);
29113 exchangeDataFV(&a_variable(0, 0), noCVars,
false, m_rotIndVarsCV);
29125 const MFloat radius = (nDim == 3) ? sqrt(
POW2(a_coordinate(cellId, 1)) +
POW2(a_coordinate(cellId, 2)))
29126 : a_coordinate(cellId, 1);
29129 if(radius <= 1.5 * m_jetHeight) {
29131 const MFloat jet = F1B2 * (1.0 + tanh((m_jetHeight - radius) / (2 * m_momentumThickness)));
29133 const MFloat profile_T = sysEqn().CroccoBusemann(m_Ma, jet);
29135 a_variable(cellId, CV->RHO) = m_rhoInfinity / profile_T;
29139 a_variable(cellId, CV->RHO_U) = a_variable(cellId, CV->RHO) * jet * m_VVInfinity[0];
29140 a_variable(cellId, CV->RHO_V) = F0;
29141 IF_CONSTEXPR(nDim == 3) a_variable(cellId, CV->RHO_W) = F0;
29143 IF_CONSTEXPR(
hasE<SysEqn>)
29144 a_variable(cellId, CV->RHO_E) =
29145 m_PInfinity / gammaMinusOne
29146 + F1B2 *
POW2(a_variable(cellId, CV->RHO_U)) / (a_variable(cellId, CV->RHO));
29151 a_variable(cellId, CV->RHO) = m_rhoInfinity;
29152 a_variable(cellId, CV->RHO_V) = F0;
29153 a_variable(cellId, CV->RHO_U) = F0;
29154 IF_CONSTEXPR(nDim == 3) a_variable(cellId, CV->RHO_W) = F0;
29155 IF_CONSTEXPR(
hasE<SysEqn>)
29156 a_variable(cellId, CV->RHO_E) =
29157 m_PInfinity / gammaMinusOne + F1B2 *
POW2(a_variable(cellId, CV->RHO_U)) / m_rhoInfinity;
29172 const MFloat radius = nDim == 3 ? sqrt(
POW2(a_coordinate(cellId, 1)) +
POW2(a_coordinate(cellId, 2)))
29173 : a_coordinate(
cellId, 1);
29175 if(radius <= m_primaryJetRadius) {
29179 const MFloat jet = F1B2 * (1 + tanh((m_primaryJetRadius - radius) / (m_momentumThickness / 2)));
29181 const MFloat profile_T = sysEqn().CroccoBusemann(m_Ma, jet) * m_densityRatio;
29183 a_variable(cellId, CV->RHO) = m_rhoInfinity / profile_T;
29185 a_variable(cellId, CV->RHO_U) = a_variable(cellId, CV->RHO) * m_targetVelocityFactor * F1B2
29186 * (1 + tanh((m_primaryJetRadius - radius) / (m_momentumThickness / 2)));
29187 a_variable(cellId, CV->RHO_V) = F0;
29188 IF_CONSTEXPR(nDim == 3) a_variable(cellId, CV->RHO_W) = F0;
29190 IF_CONSTEXPR(
hasE<SysEqn>)
29191 a_variable(cellId, CV->RHO_E) =
29192 m_PInfinity / gammaMinusOne
29193 + F1B2 *
POW2(a_variable(cellId, CV->RHO_U)) / (a_variable(cellId, CV->RHO));
29196 else if(radius <= m_secondaryJetRadius && m_primaryJetRadius <= radius) {
29199 const MFloat jet = F1B2 * (1 + tanh((m_secondaryJetRadius - radius) / (2 * m_momentumThickness)));
29201 const MFloat profile_T = sysEqn().CroccoBusemann(m_Ma, jet);
29203 a_variable(cellId, CV->RHO) = m_rhoInfinity / profile_T;
29204 a_variable(cellId, CV->RHO_U) = a_variable(cellId, CV->RHO) * m_targetVelocityFactor
29205 * m_targetVelocityFactor * F1B2
29206 * (1 + tanh((m_secondaryJetRadius - radius) / (2 * m_momentumThickness)));
29207 a_variable(cellId, CV->RHO_V) = F0;
29208 IF_CONSTEXPR(nDim == 3) a_variable(cellId, CV->RHO_W) = F0;
29210 IF_CONSTEXPR(
hasE<SysEqn>)
29211 a_variable(cellId, CV->RHO_E) =
29212 m_PInfinity / gammaMinusOne
29213 + F1B2 *
POW2(a_variable(cellId, CV->RHO_U)) / a_variable(cellId, CV->RHO);
29219 a_variable(cellId, CV->RHO) = m_rhoInfinity;
29220 a_variable(cellId, CV->RHO_U) = F0;
29221 a_variable(cellId, CV->RHO_V) = F0;
29222 IF_CONSTEXPR(nDim == 3) a_variable(cellId, CV->RHO_W) = F0;
29223 IF_CONSTEXPR(
hasE<SysEqn>)
29224 a_variable(cellId, CV->RHO_E) =
29225 m_PInfinity / gammaMinusOne + F1B2 *
POW2(a_variable(cellId, CV->RHO_U)) / m_rhoInfinity;
29239 const MFloat outletRadius = m_outletRadius;
29240 const MFloat scale = 1.0;
29241 const MFloat nozzleExit = 2.5959;
29244 const MFloat mach_j = m_nozzleExitMaJet;
29245 const MFloat temperature_j = m_nozzleExitTemp;
29246 const MFloat density_j = m_nozzleExitRho;
29248 const MFloat pressureAmbient = m_PInfinity;
29249 const MFloat densityAmbient = m_rhoInfinity;
29252 const MFloat x = a_coordinate(cellId, 0);
29254 a_variable(cellId, CV->RHO) = densityAmbient;
29255 a_variable(cellId, CV->RHO_U) = 0.0;
29256 a_variable(cellId, CV->RHO_V) = 0.0;
29257 a_variable(cellId, CV->RHO_W) = 0.0;
29258 IF_CONSTEXPR(hasE<SysEqn>)
29259 a_variable(cellId, CV->RHO_E) = sysEqn().internalEnergy(pressureAmbient, densityAmbient, 0.0);
29263 const MFloat radius = sqrt(
POW2(a_coordinate(cellId, 1) - 0.0) +
POW2(a_coordinate(cellId, 2) - 0.0));
29265 MFloat splineRadius = m_inletRadius;
29266 MFloat Ma_x = m_maNozzleInlet;
29269 if((x >= -1.0 * scale) && (x < 0.0 * scale)) {
29270 splineRadius = m_inletRadius;
29271 Ma_x = m_maNozzleInlet;
29274 if((x >= 0.0 * scale) && (x < 0.25 * scale)) {
29275 splineRadius = (0.000352 * x * x * x) / (scale * scale) - (0.678568 * x * x) / scale + 0.84 * scale;
29276 Ma_x = m_maNozzleInlet;
29279 if((x >= 0.25 * scale) && (x < 2.19473 * scale)) {
29280 splineRadius = -(0.049195 * x * x * x) / (scale * scale) + (0.236615 * x * x) / scale - 0.445812 * x
29285 if((x >= 2.19473 * scale) && (x < 2.5959 * scale)) {
29286 splineRadius = -(0.00011 * x * x * x) / (scale * scale) + (0.00072617 * x * x) / scale - 0.08883 * x
29287 + 0.727624 * scale;
29292 const MInt newtonSteps = 5;
29293 for(
MInt n = 0; n < newtonSteps; n++) {
29294 const MFloat fkt_g =
POW2(m_outletRadius / splineRadius) * m_maNozzleExit
29295 / pow(1 / (sysEqn().temperature_IR(m_maNozzleExit)), 3);
29296 const MFloat diff_g = -625 * (1 -
POW2(Ma_x)) / pow(
POW2(Ma_x) + 5, 4);
29297 Ma_x = Ma_x - fkt_g / diff_g;
29301 if((x >= -1.0 * scale) && (x < 0.0 * scale)) {
29302 splineRadius = m_inletRadius;
29303 Ma_x = m_maNozzleInlet;
29306 if((x <= nozzleExit * scale) && (radius <= splineRadius)) {
29308 const MFloat temperature_x = sysEqn().temperature_IR(Ma_x);
29309 const MFloat pressure_x = sysEqn().pressure_IR(temperature_x);
29310 const MFloat density_x = sysEqn().density_ES(pressure_x, temperature_x);
29311 const MFloat u_jet = Ma_x * sysEqn().speedOfSound(temperature_x);
29312 const MFloat deltaMomentum = m_momentumThickness * splineRadius;
29313 const MFloat jet = tanh((splineRadius - radius) / (2.0 * deltaMomentum));
29316 a_variable(cellId, CV->RHO) = density_x / sysEqn().CroccoBusemann(Ma_x, jet);
29320 a_variable(cellId, CV->RHO_U) = a_variable(cellId, CV->RHO) * u_jet * jet;
29321 a_variable(cellId, CV->RHO_V) = 0.0;
29322 a_variable(cellId, CV->RHO_W) = 0.0;
29324 IF_CONSTEXPR(hasE<SysEqn>) {
29325 a_variable(cellId, CV->RHO_E) =
29326 sysEqn().internalEnergy(pressure_x, a_variable(cellId, CV->RHO),
POW2(u_jet * jet));
29329 }
else if((x >= nozzleExit * scale) && (x <= 4.5 * scale) && (radius <= outletRadius)) {
29331 const MFloat xFactor = 0.5 * (1.0 +
cos(PI / ((4.5 - nozzleExit) * scale) * (x - nozzleExit * scale)));
29332 const MFloat deltaMomentum = m_momentumThickness * outletRadius;
29334 const MFloat u_jet = xFactor * m_maNozzleExit * sqrt(temperature_j);
29335 const MFloat jet = tanh((outletRadius - radius) / (2.0 * deltaMomentum));
29338 const MFloat density_crocco = density_j / sysEqn().CroccoBusemann(mach_j, jet);
29342 a_variable(cellId, CV->RHO) = densityAmbient + (density_crocco - densityAmbient) * xFactor;
29344 a_variable(cellId, CV->RHO_U) = a_variable(cellId, CV->RHO) * u_jet * jet;
29345 a_variable(cellId, CV->RHO_V) = 0.0;
29346 a_variable(cellId, CV->RHO_W) = 0.0;
29348 IF_CONSTEXPR(hasE<SysEqn>) {
29349 a_variable(cellId, CV->RHO_E) =
29350 pressureAmbient / (m_gamma - 1)
29351 + 0.5 *
POW2(a_variable(cellId, CV->RHO_U)) / (a_variable(cellId, CV->RHO));
29360 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "Pipe IC in 2D meaningless, because of the use of deltaP_pipe!");
29374 MBool fluctuations = false;
29375 fluctuations =
Context::getSolverProperty<
MBool>("fluctuations", m_solverId, AT_, &fluctuations);
29377 MFloat UT = m_Ma * sqrt(m_TInfinity);
29379 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
29380 m_deltaP = 0.3164 / sqrt(sqrt(sysEqn().m_Re0)) * m_referenceLength * F1B2 * m_rhoInfinity *
POW2(UT);
29382 m_fvBndryCnd->m_deltaP = m_deltaP;
29386 sqrt((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) * (a_coordinate(cellId, 1) - m_rotAxisCoord[0])
29387 + (a_coordinate(cellId, 2) - m_rotAxisCoord[1]) * (a_coordinate(cellId, 2) - m_rotAxisCoord[1]));
29390 if((a_coordinate(cellId, 0) > 4.0 && a_coordinate(cellId, 0) < 1.0)
29391 && radius_1 > 0.45) {
29394 if(cellId % 2 == 0) {
29401 if(!fluctuations) {
29405 a_variable(cellId, CV->RHO) = m_rhoInfinity;
29406 a_variable(cellId, CV->RHO_VV[0]) = m_rhoVVInfinity[0] * 2.0 * (1.0 - (radius_1 / 0.5) * (radius_1 / 0.5))
29407 + (
MFloat(rand()) / RAND_MAX) * 0.005 * UT * fk;
29408 for(
MInt d = 1; d < nDim; d++) {
29409 a_variable(cellId, CV->RHO_VV[d]) = m_rhoVVInfinity[d] + (
MFloat(rand()) / RAND_MAX) * 0.005 * UT * fk;
29411 const MFloat pressure = m_PInfinity;
29414 for(
MInt d = 0; d < nDim; d++)
29415 velPOW2 +=
POW2(a_variable(cellId, CV->RHO_VV[d]));
29416 IF_CONSTEXPR(hasE<SysEqn>)
29417 a_variable(cellId, CV->RHO_E) = pressure / gammaMinusOne + F1B2 * velPOW2 / m_rhoInfinity;
29424 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "Pipe IC with 3D features in 2D meaningless!");
29426 MFloat UT = m_Ma * sqrt(m_TInfinity);
29427 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
29428 m_deltaP = 3.0 * 64.0 / sysEqn().m_Re0 * F1 / m_referenceLength * F1B2 * m_rhoInfinity *
POW2(m_UInfinity);
29429 m_fvBndryCnd->m_deltaP = m_deltaP;
29432 sqrt((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) * (a_coordinate(cellId, 1) - m_rotAxisCoord[0])
29433 + (a_coordinate(cellId, 2) - m_rotAxisCoord[1]) * (a_coordinate(cellId, 2) - m_rotAxisCoord[1]));
29436 if((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) >= 0 && (a_coordinate(cellId, 2) - m_rotAxisCoord[1]) >= 0) {
29437 phi_1 = asin((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) / radius_1);
29438 }
else if((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) >= 0
29439 && (a_coordinate(cellId, 2) - m_rotAxisCoord[1]) < 0) {
29440 phi_1 = PI - asin((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) / radius_1);
29441 }
else if((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) < 0
29442 && (a_coordinate(cellId, 2) - m_rotAxisCoord[1]) < 0) {
29443 phi_1 = PI - asin((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) / radius_1);
29445 phi_1 = 2 * PI + asin((a_coordinate(cellId, 1) - m_rotAxisCoord[0]) / radius_1);
29458 a_variable(cellId, CV->RHO) = m_rhoInfinity;
29459 a_variable(cellId, CV->RHO_VV[0]) = m_rhoVVInfinity[0] + (
MFloat(rand()) / RAND_MAX) * 0.0005 * UT * fk;
29460 a_variable(cellId, CV->RHO_VV[1]) =
29461 m_rhoVVInfinity[1] *
cos(phi_1) / 29.0 * radius_1 + (
MFloat(rand()) / RAND_MAX) * 0.0005 * UT * fk;
29462 a_variable(cellId, CV->RHO_VV[2]) =
29463 -m_rhoVVInfinity[1] * sin(phi_1) / 29.0 * radius_1 + (
MFloat(rand()) / RAND_MAX) * 0.0005 * UT * fk;
29464 const MFloat pressure = m_PInfinity;
29466 IF_CONSTEXPR(hasE<SysEqn>)
29467 a_variable(cellId, CV->RHO_E) =
29468 pressure / gammaMinusOne
29470 * (
POW2(m_rhoVVInfinity[0]) +
POW2(m_rhoVVInfinity[1] *
cos(phi_1) / 29.0 * radius_1)
29471 +
POW2(m_rhoVVInfinity[1] * sin(phi_1) / 29.0 * radius_1)))
29477 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "Pipe IC with 3D features in 2D meaningless!");
29480 MFloat UT = m_Ma * sqrt(m_TInfinity);
29481 m_deltaP = 0.3164 / sqrt(sqrt(sysEqn().m_Re0)) * F5 * m_referenceLength * F1B2 * m_rhoInfinity *
POW2(UT);
29483 m_fvBndryCnd->m_deltaP = m_deltaP;
29484 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
29485 const MFloat pressure = m_PInfinity;
29487 a_variable(cellId, CV->RHO) = m_rhoInfinity;
29489 a_variable(cellId, CV->RHO_U) = F0;
29490 if(fabs(a_coordinate(cellId, 0)) < 0.2 || fabs(a_coordinate(cellId, 2)) < 0.2) {
29491 a_variable(cellId, CV->RHO_V) = m_rhoVInfinity;
29493 a_variable(cellId, CV->RHO_V) = F0;
29495 a_variable(cellId, CV->RHO_W) = F0;
29497 IF_CONSTEXPR(hasE<SysEqn>)
29498 a_variable(cellId, CV->RHO_E) =
29499 pressure / gammaMinusOne
29501 * (
POW2(a_variable(cellId, CV->RHO_VV[0])) +
POW2(a_variable(cellId, CV->RHO_VV[1]))
29502 +
POW2(a_variable(cellId, CV->RHO_VV[2]))))
29509 IF_CONSTEXPR(nDim == 2)
mTerm(-1, AT_, "Pipe flow only implemented in 3D.");
29511 MFloat noPeriodicDirs = 0;
29512 for(
MInt dim = 0; dim < nDim; dim++) {
29513 if(grid().periodicCartesianDir(dim)) {
29514 m_volumeForcingDir = dim;
29518 if(noPeriodicDirs > 1)
mTerm(1, AT_,
"Only one periodic direction is implemented for the pipe case");
29519 if(m_volumeForcingDir == -1)
mTerm(-1, AT_,
"IC 22 requires a volumeForcingDir");
29522 MInt Re_r = Context::getSolverProperty<MFloat>(
"Re", m_solverId, AT_) * m_pipeRadius;
29523 m_pipeRadius = Context::getSolverProperty<MFloat>(
"pipeRadius", m_solverId, AT_);
29525 MBool fluctuations =
false;
29526 fluctuations = Context::getSolverProperty<MBool>(
"pipeFluctuations", m_solverId, AT_, &fluctuations);
29527 MFloat fluctuationsPercentage = 0.005;
29528 fluctuationsPercentage =
29529 Context::getSolverProperty<MFloat>(
"pipeFluctuationsPercentage", m_solverId, AT_, &fluctuationsPercentage);
29532 const MInt rDir1 = ((m_volumeForcingDir + 1) % nDim);
29533 const MInt rDir2 = ((rDir1 + 1) % nDim);
29534 if(rDir1 == rDir2 || rDir1 == m_volumeForcingDir || rDir2 == m_volumeForcingDir)
29535 mTerm(-1, AT_,
"Inconsistent dirs.");
29537 const MFloat pipeLength = computeDomainLength(m_volumeForcingDir);
29539 cerr0 <<
"Intialized with IC 22: found pipeRadius = " << m_pipeRadius <<
" and pipeLength = " << pipeLength
29540 <<
". Fluctuations: " << fluctuations <<
" (" << fluctuationsPercentage <<
")" << endl;
29543 MFloat uMax = F2 * m_UInfinity;
29545 lambda = 32.0 / Re_r;
29546 if(domainId() == 0) cerr <<
"IC 22, using case Re<1500" << endl;
29548 lambda = 0.316 / pow(Re_r * F2, 0.25);
29549 if(domainId() == 0) cerr <<
"IC 22, using case Re>=1500" << endl;
29551 MFloat reTau = Re_r * sqrt(lambda / F8);
29552 MFloat uTau = reTau * m_Ma * sqrt(m_TInfinity) / Re_r;
29553 MFloat deltaP = F2 * m_rhoInfinity *
POW2(uTau) * (pipeLength) / m_pipeRadius;
29554 m_volumeAcceleration[m_volumeForcingDir] = deltaP / (m_rhoInfinity * pipeLength);
29556 MFloat rMin = m_pipeRadius / F2;
29557 MFloat ampl = uMax * (F1 -
POW2((m_pipeRadius - rMin / F4) / m_pipeRadius));
29559 if(a_isHalo(cellId))
continue;
29560 if(a_isPeriodic(cellId))
continue;
29561 if(a_isBndryGhostCell(cellId))
continue;
29563 const MFloat r = sqrt(
POW2(a_coordinate(cellId, rDir1)) +
POW2(a_coordinate(cellId, rDir2)));
29568 if(r <= m_pipeRadius) {
29572 u = (
dist > rMin ? (F1 -
POW2(r / rMin)) * uMax : sin(
dist / rMin * F2 * M_PI) * ampl);
29574 u = (F1 -
POW2(r / m_pipeRadius)) * uMax;
29577 if(cellId % 2 == 0)
29583 MFloat fluct = fluctuationsPercentage * m_UInfinity * fk;
29584 a_pvariable(cellId, PV->VV[m_volumeForcingDir]) = u + (
MFloat(rand()) / RAND_MAX) * fluct;
29585 a_pvariable(cellId, PV->VV[rDir1]) = (
MFloat(rand()) / RAND_MAX) * fluct;
29586 a_pvariable(cellId, PV->VV[rDir2]) = (
MFloat(rand()) / RAND_MAX) * fluct;
29587 a_pvariable(cellId, PV->P) = m_PInfinity;
29588 a_pvariable(cellId, PV->RHO) = sysEqn().density_ES(m_PInfinity, m_TInfinity);
29591 computeConservativeVariables();
29596 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "This is
a 3D IC!");
29597 MFloat UT = m_Ma * sqrt(m_TInfinity);
29599 m_deltaP = 64 / sysEqn().m_Re0 * F1 / m_referenceLength * F1B2 * m_rhoInfinity *
POW2(UT) / 10.0;
29601 m_deltaP = 64 / sysEqn().m_Re0 * F1 / m_referenceLength * F1B2 * m_rhoInfinity *
POW2(UT) / 5.0;
29603 m_log <<
" Initializing pressure difference: m_deltaP = " << m_deltaP
29604 <<
" (built with m_Re0 = " << sysEqn().m_Re0 <<
" , refLength = " << m_referenceLength <<
")" << endl;
29606 a_variable(cellId, CV->RHO) = 1.0;
29607 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
29608 a_variable(cellId, CV->RHO_VV[spaceId]) = 0;
29610 IF_CONSTEXPR(hasE<SysEqn>)
29611 a_variable(cellId, CV->RHO_E) = sysEqn().pressureEnergy(sysEqn().p_Ref());
29616 for(
MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
29617 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
29618 for(
MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
29619 for(
MInt v = 0; v < PV->noVariables; v++) {
29621 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[v] =
29622 a_pvariable(cellId, v);
29623 a_pvariable(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId, v) =
29624 a_pvariable(cellId, v);
29635 IF_CONSTEXPR(nDim == 2)
mTerm(-1, "This is
a 3D IC!");
29636 IF_CONSTEXPR(!
hasPV_C<SysEqn>::value)
mTerm(1, AT_, "SysEqn not suitable!");
29639 MFloat activationTemperature = 30;
29640 MFloat alpha = F1 - F1 /
mMax(1.1, m_burntUnburntTemperatureRatio);
29641 MFloat beta = alpha * activationTemperature / m_burntUnburntTemperatureRatio;
29642 MFloat filteredFlameThickness = 10.0 * m_subfilterVariance * c_cellLengthAtLevel(maxRefinementLevel());
29643 MFloat theta = F0, c = F0, x, xCoord, zCoord;
29644 MFloat jetArea = F0, jetInflowArea = F0, massflux = F0;
29645 MFloat factor1, factor2;
29649 xCoord = a_coordinate(cellId, 0);
29650 zCoord = a_coordinate(cellId, 2);
29652 if((xCoord > -m_radiusFlameTube - err) && (xCoord < m_radiusFlameTube + err)
29653 && (zCoord > -m_jetHalfLength - err) && (zCoord < m_jetHalfLength + err)) {
29654 MFloat minXG =
ABS(xCoord) - (m_jetHalfWidth + err);
29655 MFloat minZG =
ABS(zCoord) - (m_jetHalfLength + err);
29658 x = sqrt(2.0 - 1.0) * m_initialFlameHeight * maxG + a_coordinate(cellId, 1) - m_yOffsetFlameTube;
29661 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
29662 c = m_c0 * exp(x / filteredFlameThickness);
29665 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
29666 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
29670 x = a_coordinate(cellId, 1) - 1.0;
29672 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
29673 c = m_c0 * exp(x / filteredFlameThickness);
29675 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
29676 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
29680 a_variable(cellId, CV->RHO) =
29681 m_rhoFlameTube + (m_rhoFlameTube / m_burntUnburntTemperatureRatio - m_rhoFlameTube) * theta;
29683 a_variable(cellId, CV->RHO_U) = F0;
29684 a_variable(cellId, CV->RHO_W) = F0;
29686 factor1 = a_coordinate(cellId, 0);
29688 factor2 = a_coordinate(cellId, 2);
29691 if(fabs(a_coordinate(cellId, 0)) <= m_jetHalfWidth && fabs(a_coordinate(cellId, 2)) <= m_jetHalfLength
29692 && fabs(a_coordinate(cellId, 1)) <= 4.5) {
29693 a_variable(cellId, CV->RHO_V) = a_variable(cellId, CV->RHO) * m_Ma
29694 * (F1B2 * (1 + tanh(m_shearLayerThickness * (factor1 + m_jetHalfWidth)))
29695 * (1 - tanh(m_shearLayerThickness * (factor1 - m_jetHalfWidth)))
29697 * (F1B2 * (1 + tanh(m_shearLayerThickness * (factor2 + m_jetHalfLength)))
29698 * (1 - tanh(m_shearLayerThickness * (factor2 - m_jetHalfLength)))
29701 jetArea =
POW2(c_cellLengthAtCell(cellId));
29702 if(cellId < noInternalCells() && c_isLeafCell(cellId)) {
29703 massflux += a_variable(cellId, CV->RHO_V) * jetArea;
29704 jetInflowArea += jetArea;
29707 a_variable(cellId, CV->RHO_V) = a_variable(cellId, CV->RHO) * m_Ma * 0.5;
29715 a_variable(cellId, CV->RHO_C) = a_variable(cellId, CV->RHO) * c;
29718 MPI_Allreduce(MPI_IN_PLACE, &massflux, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"massflux");
29719 MPI_Allreduce(MPI_IN_PLACE, &jetInflowArea, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
29723 massflux /= jetInflowArea;
29726 m_jetPressure = sysEqn().p_Ref();
29727 for(
MInt i = 0; i < 20; i++) {
29728 m_jetPressure = pow((1 - gammaMinusOne / F2 * pow(m_jetPressure, -2.0 / m_gamma) *
POW2(massflux)),
29729 (m_gamma * FgammaMinusOne));
29731 m_jetDensity = sysEqn().density_IR_P(m_jetPressure);
29732 m_jetPressure = m_jetPressure / m_gamma;
29733 m_jetTemperature = sysEqn().temperature_ES(m_jetDensity, m_jetPressure);
29734 m_log <<
"calculated pressure" << m_jetPressure << endl;
29735 m_log <<
"calculated density" << m_jetDensity << endl;
29736 m_log <<
"calculated temperature" << m_jetTemperature << endl;
29737 m_log <<
"calculated massflux" << massflux << endl;
29741 IF_CONSTEXPR(hasE<SysEqn>)
29742 a_variable(cellId, CV->RHO_E) =
29743 m_jetPressure / gammaMinusOne + F1B2 *
POW2(a_variable(cellId, CV->RHO_V)) / m_rhoInfinity;
29753 MFloat activationTemperature = 30;
29754 MFloat alpha = F1 - F1 /
mMax(1.1, m_burntUnburntTemperatureRatio);
29755 MFloat beta = alpha * activationTemperature / m_burntUnburntTemperatureRatio;
29756 MFloat filteredFlameThickness = 10.0 * m_subfilterVariance * c_cellLengthAtLevel(maxRefinementLevel());
29757 MFloat theta = F0, c = F0, x, xCoord, zCoord;
29758 MFloat jetArea = F0, jetInflowArea = F0, massflux = F0;
29763 xCoord = a_coordinate(cellId, 0);
29764 zCoord = a_coordinate(cellId, 2);
29765 radius = sqrt(
POW2(xCoord) +
POW2(zCoord));
29767 if((radius > -0.52 - err) && (radius < 0.52 + err)) {
29768 MFloat maxG =
ABS(radius) - (0.52 + err);
29769 x = sqrt(2.0 - 1.0) * m_initialFlameHeight * maxG + a_coordinate(cellId, 1) - m_yOffsetFlameTube;
29772 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
29773 c = m_c0 * exp(x / filteredFlameThickness);
29776 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
29777 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
29781 x = a_coordinate(cellId, 1) - 1.0;
29783 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
29784 c = m_c0 * exp(x / filteredFlameThickness);
29786 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
29787 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
29791 a_variable(cellId, CV->RHO) =
29792 m_rhoFlameTube + (m_rhoFlameTube / m_burntUnburntTemperatureRatio - m_rhoFlameTube) * theta;
29794 a_variable(cellId, CV->RHO_U) = F0;
29795 a_variable(cellId, CV->RHO_W) = F0;
29797 radius = sqrt(
POW2(xCoord) +
POW2(zCoord));
29800 if(radius <= 0.52 && fabs(a_coordinate(cellId, 1)) <= 4.5) {
29801 a_variable(cellId, CV->RHO_V) = a_variable(cellId, CV->RHO) * m_Ma
29802 * (F1B2 * (1 + tanh(m_shearLayerThickness * (radius + 0.5)))
29803 * (1 - tanh(m_shearLayerThickness * (radius - 0.5)))
29806 jetArea =
POW2(c_cellLengthAtCell(cellId));
29807 if(cellId < noInternalCells() && c_isLeafCell(cellId)) {
29808 massflux += a_variable(cellId, CV->RHO_V) * jetArea;
29809 jetInflowArea += jetArea;
29812 a_variable(cellId, CV->RHO_V) = a_variable(cellId, CV->RHO) * m_Ma * 0.5;
29816 a_variable(cellId, CV->RHO_C) = a_variable(cellId, CV->RHO) * c;
29819 MPI_Allreduce(MPI_IN_PLACE, &massflux, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"massflux");
29820 MPI_Allreduce(MPI_IN_PLACE, &jetInflowArea, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
29824 massflux /= jetInflowArea;
29827 m_jetPressure = sysEqn().p_Ref();
29828 for(
MInt i = 0; i < 20; i++) {
29829 m_jetPressure = pow((1 - gammaMinusOne / F2 * pow(m_jetPressure, -2.0 / m_gamma) *
POW2(massflux)),
29830 (m_gamma * FgammaMinusOne));
29832 m_jetDensity = sysEqn().density_IR_P(m_jetPressure);
29833 m_jetPressure = m_jetPressure / m_gamma;
29834 m_jetTemperature = sysEqn().temperature_ES(m_jetDensity, m_jetPressure);
29835 m_log <<
"calculated pressure" << m_jetPressure << endl;
29836 m_log <<
"calculated density" << m_jetDensity << endl;
29837 m_log <<
"calculated temperature" << m_jetTemperature << endl;
29838 m_log <<
"calculated massflux" << massflux << endl;
29842 IF_CONSTEXPR(hasE<SysEqn>)
29843 a_variable(cellId, CV->RHO_E) =
29844 m_jetPressure / gammaMinusOne + F1B2 *
POW2(a_variable(cellId, CV->RHO_V)) / m_rhoInfinity;
29852 if(Context::getSolverProperty<MString>(
"solvertype", m_solverId, AT_) !=
"MAIA_FV_APE") {
29853 mTerm(1,
"this initial condition is for the FV_APE solver only");
29858 MFloat pulse_center_length_unnormed = 0.0;
29859 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
29860 pulse_center_length_unnormed += std::pow(a_coordinate(cellId, spaceId) - 0.5, 2.0);
29863 IF_CONSTEXPR(hasE<SysEqn>)
29864 a_variable(cellId, CV->RHO_E) = m_rhoEInfinity;
29865 a_variable(cellId, CV->RHO) = m_rhoInfinity;
29868 for(
MInt spaceId = 1; spaceId < nDim; spaceId++) {
29869 a_variable(cellId, CV->RHO_VV[spaceId]) = 0;
29872 a_variable(cellId, CV->RHO_VV[0]) =
29873 m_rhoVVInfinity[0] * (1.0 + std::exp(-pulse_center_length_unnormed * 20.0));
29896 const MFloat gamma = Context::getSolverProperty<MFloat>(
"circulation", m_solverId, AT_);
29909 const MFloat rC = Context::getSolverProperty<MFloat>(
"coreRadius", m_solverId, AT_);
29913 nC = Context::getSolverProperty<MInt>(
"coreModelExponent", m_solverId, AT_, &nC);
29916 const MFloat omega = gamma / 4. / PI;
29918 const MFloat by = sin(omega * t);
29923 const MFloat x = a_coordinate(cellId, 0);
29924 const MFloat y = a_coordinate(cellId, 1);
29926 const MFloat thetaPos = atan2(
y - by, x - bx);
29928 const MFloat thetaNeg = atan2(
y + by, x + bx);
29933 ux += rPos / (rC * rC + rPos * rPos) * sin(thetaPos);
29934 ux += rNeg / (rC * rC + rNeg * rNeg) * sin(thetaNeg);
29936 ux += rPos / pow(pow(rC, 2 * nC) + pow(rPos, 2 * nC), 1.0 / nC) * sin(thetaPos);
29937 ux += rNeg / pow(pow(rC, 2 * nC) + pow(rNeg, 2 * nC), 1.0 / nC) * sin(thetaNeg);
29939 ux *= -gamma / 2. / PI;
29944 uy += rPos / (rC * rC + rPos * rPos) *
cos(thetaPos);
29945 uy += rNeg / (rC * rC + rNeg * rNeg) *
cos(thetaNeg);
29947 uy += rPos / pow(pow(rC, 2 * nC) + pow(rPos, 2 * nC), 1.0 / nC) *
cos(thetaPos);
29948 uy += rNeg / pow(pow(rC, 2 * nC) + pow(rNeg, 2 * nC), 1.0 / nC) *
cos(thetaNeg);
29950 uy *= gamma / 2. / PI;
29953 const MFloat p = 1. / m_gamma - 0.5 * rho * (ux * ux + uy * uy);
29956 a_variable(cellId, CV->RHO) = rho;
29957 a_variable(cellId, CV->RHO_VV[0]) = rho * ux;
29958 a_variable(cellId, CV->RHO_VV[1]) = rho * uy;
29959 IF_CONSTEXPR(hasE<SysEqn>) {
29960 a_variable(cellId, CV->RHO_E) = sysEqn().internalEnergy(p, rho, (ux * ux + uy * uy));
29964 a_pvariable(cellId, PV->P) =
p;
29965 a_pvariable(cellId, PV->RHO) = rho;
29966 a_pvariable(cellId, PV->U) = ux;
29967 a_pvariable(cellId, PV->V) = uy;
29985 MFloat activationTemperature = 30;
29986 MFloat alpha = F1 - F1 /
mMax(1.1, m_burntUnburntTemperatureRatio);
29987 MFloat beta = alpha * activationTemperature / m_burntUnburntTemperatureRatio;
29988 MFloat filteredFlameThickness = 10.0 * m_subfilterVariance * c_cellLengthAtLevel(maxRefinementLevel());
29989 MFloat theta = F0, c = F0, x;
29991 MFloat deltaX = m_flameRadiusOffset;
29998 if((a_coordinate(cellId, 0) <= m_radiusFlameTube + m_xOffsetFlameTube + err)
29999 && (a_coordinate(cellId, 0) >= -m_radiusFlameTube + m_xOffsetFlameTube - err)) {
30000 x = sqrt(2.0 - 1.0) * (
ABS(a_coordinate(cellId, 0) - m_xOffsetFlameTube) - m_radiusFlameTube)
30001 + a_coordinate(cellId, 1) - m_yOffsetFlameTube;
30004 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
30005 c = m_c0 * exp(x / filteredFlameThickness);
30008 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
30009 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
30013 }
else if((a_coordinate(cellId, 0) <= (m_radiusFlameTube2 + m_xOffsetFlameTube2 + err))
30014 && (a_coordinate(cellId, 0) >= (-m_radiusFlameTube2 + m_xOffsetFlameTube2 - err))) {
30015 x = sqrt(2.0 - 1.0) * (
ABS(a_coordinate(cellId, 0) - m_xOffsetFlameTube2) - m_radiusFlameTube2)
30016 + a_coordinate(cellId, 1) - m_yOffsetFlameTube2;
30019 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
30020 c = m_c0 * exp(x / filteredFlameThickness);
30022 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
30023 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
30026 }
else if(((a_coordinate(cellId, 0) > (m_radiusFlameTube + m_xOffsetFlameTube + err))
30027 || (a_coordinate(cellId, 0) < (-m_radiusFlameTube + m_xOffsetFlameTube - err)))
30028 && (a_coordinate(cellId, 0) >= 0.0)) {
30029 x = a_coordinate(cellId, 1) + 0.5;
30031 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
30032 c = m_c0 * exp(x / filteredFlameThickness);
30034 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
30035 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
30038 }
else if(((a_coordinate(cellId, 0) > (m_radiusFlameTube2 + m_xOffsetFlameTube2 + err))
30039 || (a_coordinate(cellId, 0) < (-m_radiusFlameTube2 + m_xOffsetFlameTube2 - err)))
30040 && (a_coordinate(cellId, 0) < 0.0)) {
30041 x = a_coordinate(cellId, 1) + 0.5;
30043 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
30044 c = m_c0 * exp(x / filteredFlameThickness);
30046 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
30047 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
30052 }
else if(m_plenum) {
30054 if((a_coordinate(cellId, 0) <= m_radiusFlameTube + m_xOffsetFlameTube + err)
30055 && (a_coordinate(cellId, 0) >= -m_radiusFlameTube + m_xOffsetFlameTube - err)) {
30056 x = sqrt(2.0 - 1.0) * (
ABS(a_coordinate(cellId, 0) - m_xOffsetFlameTube) - m_radiusFlameTube)
30057 + a_coordinate(cellId, 1) - m_yOffsetFlameTube;
30060 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
30061 c = m_c0 * exp(x / filteredFlameThickness);
30064 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
30065 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
30071 }
else if((a_coordinate(cellId, 0) > m_radiusFlameTube + err)
30072 || (a_coordinate(cellId, 0) < -(m_radiusFlameTube + err))) {
30073 x = a_coordinate(cellId, 1) + 0.5;
30075 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
30076 c = m_c0 * exp(x / filteredFlameThickness);
30078 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
30079 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
30084 x = sqrt(2.0 - 1.0) * (
ABS(a_coordinate(cellId, 0) - m_xOffsetFlameTube) - (m_radiusFlameTube + deltaX))
30085 + a_coordinate(cellId, 1) - m_yOffsetFlameTube;
30088 theta = (F1 - F1 / beta) * exp(x / filteredFlameThickness);
30089 c = m_c0 * exp(x / filteredFlameThickness);
30092 theta = F1 - F1 / beta * exp((F1 - beta) * x / filteredFlameThickness);
30093 c = F1 - (F1 - m_c0) * exp(-x * m_c0 / ((F1 - m_c0) * filteredFlameThickness));
30100 a_variable(cellId, CV->RHO) =
30101 m_rhoFlameTube + (m_rhoFlameTube / m_burntUnburntTemperatureRatio - m_rhoFlameTube) * theta;
30103 a_variable(cellId, CV->RHO_U) = F0;
30104 a_variable(cellId, CV->RHO_V) =
30105 a_variable(cellId, CV->RHO) * m_velocityFlameTube;
30106 IF_CONSTEXPR(hasE<SysEqn>)
30107 a_variable(cellId, CV->RHO_E) =
30108 m_pressureFlameTube / gammaMinusOne + F1B2 *
POW2(m_velocityFlameTube) * a_variable(cellId, CV->RHO);
30111 a_variable(cellId, CV->RHO_C) = a_variable(cellId, CV->RHO) * c;
30114 a_variable(cellId, CV->RHO_V) =
30115 a_variable(cellId, CV->RHO) * m_velocityFlameTube;
30116 IF_CONSTEXPR(hasE<SysEqn>)
30117 a_variable(cellId, CV->RHO_E) =
30118 m_pressureFlameTube / gammaMinusOne + F1B2 *
POW2(m_velocityFlameTube) * a_variable(cellId, CV->RHO);
30130 stringstream errorMessage;
30131 errorMessage <<
"WARNING: Initial condition " << m_initialCondition <<
", does not exist" << endl;
30132 if(domainId() == 0) {
30133 cerr << errorMessage.str() << endl;
30135 m_log << errorMessage.str() << endl;
30139 a_variable(cellId, CV->RHO) = m_rhoInfinity;
30140 for(
MInt spaceId = 0; spaceId < nDim; spaceId++) {
30141 a_variable(cellId, CV->RHO_VV[spaceId]) = m_rhoVVInfinity[spaceId];
30143 IF_CONSTEXPR(hasE<SysEqn>)
30144 a_variable(cellId, CV->RHO_E) = m_rhoEInfinity;
30151 for(
MInt bndryId = 0; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
30152 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
30153 for(
MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
30154 MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
30155 for(
MInt varId = 0; varId < noCVars; varId++) {
30156 a_variable(ghostCellId, varId) = a_variable(cellId, varId);
30162 if(!m_combustion) {
30176 L = Context::getSolverProperty<MFloat>(
"pressureDropLength", m_solverId, AT_, &L);
30177 m_deltaPL = m_deltaP * L;
30178 m_fvBndryCnd->m_deltaP = m_deltaP;
30179 m_fvBndryCnd->m_deltaPL = m_deltaPL;
30184 for(
MInt varId = 0; varId < noCVars; varId++) {
30185 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
30190 if(m_dualTimeStepping) {
30192 for(
MInt varId = 0; varId < noCVars; varId++) {
30193 a_dt1Variable(cellId, varId) = a_variable(cellId, varId);
30194 a_dt2Variable(cellId, varId) = a_variable(cellId, varId);
30199 m_log <<
"**************************" << endl;
30200 m_log <<
"Initial Condition summary" << endl;
30201 m_log <<
"**************************" << endl;
30202 m_log <<
"Re = " << m_Re << endl;
30203 m_log <<
"Re0 = " << sysEqn().m_Re0 << endl;
30204 m_log <<
"Ma = " << m_Ma << endl;
30205 m_log <<
"TInfinity = " << m_TInfinity << endl;
30206 m_log <<
"UInfinity = " << m_UInfinity << endl;
30207 m_log <<
"VInfinity = " << m_VInfinity << endl;
30208 IF_CONSTEXPR(nDim == 3) {
m_log <<
"WInfinity = " << m_WInfinity << endl; }
30209 m_log <<
"PInfinity = " << m_PInfinity << endl;
30210 m_log <<
"rhoInfinity = " << m_rhoInfinity << endl;
30211 m_log <<
"rhoEInfinity = " << m_rhoEInfinity << endl;
30212 m_log <<
"muInfinity = " << sysEqn().m_muInfinity << endl;
30213 m_log <<
"DInfinity = " << m_DInfinity << endl;
30214 m_log <<
"DthInfinity = " << m_DthInfinity << endl;
30215 m_log <<
"timeRef = " << m_timeRef << endl;
30217 checkInfinityVarsConsistency();
30220 if(!m_restart && !m_resetInitialCondition) {
30222 for(
MInt v = 0; v < CV->noVariables; v++) {
30223 if(std::isnan(a_variable(cellId, v))) {
30224 cerr <<
"Variable " << v <<
" cellId : " <<
cellId << endl;
30225 mTerm(1, AT_,
"Invalid initialcondition formulation!");
30234template <MInt nDim_,
class SysEqn>
30238 std::vector<MFloat> infVars{};
30239 std::vector<MString> infVarNames{};
30241 infVars.push_back(m_UInfinity);
30242 infVarNames.push_back(
"m_UInfinity");
30243 infVars.push_back(m_VInfinity);
30244 infVarNames.push_back(
"m_VInfinity");
30245 IF_CONSTEXPR(nDim == 3) {
30246 infVars.push_back(m_WInfinity);
30247 infVarNames.push_back(
"m_WInfinity");
30249 infVars.push_back(m_PInfinity);
30250 infVarNames.push_back(
"m_PInfinity");
30251 infVars.push_back(m_TInfinity);
30252 infVarNames.push_back(
"m_TInfinity");
30253 infVars.push_back(m_DthInfinity);
30254 infVarNames.push_back(
"m_DthInfinity");
30255 infVars.push_back(sysEqn().m_muInfinity);
30256 infVarNames.push_back(
"m_muInfinity");
30257 infVars.push_back(m_DInfinity);
30258 infVarNames.push_back(
"m_DInfinity");
30259 infVars.push_back(m_SInfinity);
30260 infVarNames.push_back(
"m_SInfinity");
30261 infVars.push_back(m_hInfinity);
30262 infVarNames.push_back(
"m_hInfinity");
30264 infVars.push_back(m_VVInfinity[0]);
30265 infVarNames.push_back(
"m_VVInfinity[0]");
30266 infVars.push_back(m_VVInfinity[1]);
30267 infVarNames.push_back(
"m_VVInfinity[1]");
30268 IF_CONSTEXPR(nDim == 3) {
30269 infVars.push_back(m_VVInfinity[2]);
30270 infVarNames.push_back(
"m_VVInfinity[2]");
30273 infVars.push_back(m_rhoUInfinity);
30274 infVarNames.push_back(
"m_rhoUInfinity");
30275 infVars.push_back(m_rhoVInfinity);
30276 infVarNames.push_back(
"m_rhoVInfinity");
30277 IF_CONSTEXPR(nDim == 3) {
30278 infVars.push_back(m_rhoWInfinity);
30279 infVarNames.push_back(
"m_rhoWInfinity");
30281 infVars.push_back(m_rhoEInfinity);
30282 infVarNames.push_back(
"m_rhoEInfinity");
30283 infVars.push_back(m_rhoInfinity);
30284 infVarNames.push_back(
"m_rhoInfinity");
30286 infVars.push_back(m_rhoVVInfinity[0]);
30287 infVarNames.push_back(
"m_rhoVVInfinity[0]");
30288 infVars.push_back(m_rhoVVInfinity[1]);
30289 infVarNames.push_back(
"m_rhoVVInfinity[1]");
30290 IF_CONSTEXPR(nDim == 3) {
30291 infVars.push_back(m_rhoVVInfinity[2]);
30292 infVarNames.push_back(
"m_rhoVVInfinity[2]");
30295 infVars.push_back(m_Ma);
30296 infVarNames.push_back(
"m_Ma");
30297 infVars.push_back(sysEqn().m_Re0);
30298 infVarNames.push_back(
"m_Re0");
30299 infVars.push_back(m_rRe0);
30300 infVarNames.push_back(
"m_rRe0");
30301 infVars.push_back(m_timeRef);
30302 infVarNames.push_back(
"m_timeRef");
30303 infVars.push_back(m_deltaP);
30304 infVarNames.push_back(
"m_deltaP");
30305 infVars.push_back(m_strouhal);
30306 infVarNames.push_back(
"m_strouhal");
30307 infVars.push_back(m_timeStep);
30308 infVarNames.push_back(
"m_timeStep");
30312 const MInt noInfVars = infVars.size();
30313 std::vector<MFloat> recvInfVars(noInfVars);
30315 if(infVars.size() != infVarNames.size()) {
30316 mTerm(1,
"number of infinity variables mismatch");
30319 if(domainId() == 0) {
30320 std::copy(infVars.begin(), infVars.end(), recvInfVars.begin());
30322 std::fill(recvInfVars.begin(), recvInfVars.end(), -1.0);
30327 for(
MInt i = 0; i < noInfVars; i++) {
30329 if(std::isnan(recvInfVars[i]) && std::isnan(infVars[i])) {
30331 "Infinity variable '" + infVarNames[i] +
"' is NaN on multiple ranks, check if this is correct!";
30332 m_log << msg << std::endl;
30333 if(domainId() == 0) {
30334 std::cerr << msg << std::endl;
30338 if(!
approx(recvInfVars[i], infVars[i], MFloatEps)) {
30339 mTerm(1,
"Infinity variable '" + infVarNames[i]
30340 +
"' is inconsistent among ranks, domainId=" + std::to_string(domainId())
30341 +
", value=" + std::to_string(infVars[i]) +
", recvValue=" + std::to_string(recvInfVars[i]));
30359template <MInt nDim_,
class SysEqn>
30363 IF_CONSTEXPR(nDim == 2)
30364 mTerm(1, "Info: untested in 2D. By now only used in 3D."
30365 " To use in 2D delete this warning.");
30377 MFloat ReTau =
Context::getSolverProperty<
MFloat>("ReTau", m_solverId, AT_) / m_referenceLength;
30382 m_deltaP =
POW2(m_Ma * ReTau * sqrt(m_TInfinity) / m_Re) * m_rhoInfinity / m_referenceLength;
30384 m_fvBndryCnd->m_deltaP = m_deltaP;
30393template <
MInt nDim_, class SysEqn>
30397 if(m_jet && !m_levelSet) {
30398 switch(m_jetType) {
30402 IF_CONSTEXPR(nDim == 2)
mTerm(-1,
"This case is designed for 3D!");
30404 const MInt noCells = a_noCells();
30408 for(cellId = 0; cellId < noCells; cellId++) {
30409 MFloat jet, uy1 = 0, uy11 = 0, ur0 = 0, ur = 0, u = 0, w = 0, radius, angle, swtrad, swtxsgn, swtzsgn;
30410 MFloat dx, dy, dz, angle2;
30412 dx = a_coordinate(cellId, 0);
30413 dy = a_coordinate(cellId, 1);
30414 dz = a_coordinate(cellId, 2);
30415 radius = sqrt(
POW2(dy) +
POW2(dz));
30416 if(fabs(radius) > 1.5 * m_jetHeight)
continue;
30418 swtrad = 0.5 * F1 * (radius - 0.01 + abs(radius - 0.01)) / (abs(radius - 0.01) + 1e-32);
30419 swtxsgn = 0.5 * F1 * (dy + abs(dy)) / (abs(dy) + 1e-32);
30420 swtzsgn = 0.5 * F1 * (dz + abs(dz)) / (abs(dz) + 1e-32);
30421 angle = abs(dy) / (radius + 1e-32) * swtrad;
30422 angle = acos(angle);
30423 angle = angle * swtxsgn * swtzsgn + (PI - angle) * (1 - swtxsgn) * swtzsgn
30424 + (PI + angle) * (1 - swtxsgn) * (1 - swtzsgn) - angle * swtxsgn * (1 - swtzsgn);
30429 - tanh(m_shearLayerThickness * (((dx) - (m_jetHeight)) / (m_jetHeight))
30430 * (((dx) + (m_jetHeight)) / (m_jetHeight))))
30432 radius = radius + 0.0000000000000001;
30434 uy1 = 2 * 0.5 / radius * (radius - 0.5) / 0.01
30435 * exp(-log(2) * (
POW2(dx - 0.49) +
POW2(radius - 0.5)) /
POW2(0.01)) * jet;
30436 ur0 = -2 * 0.5 / radius * (dx - 0.49) / 0.01
30437 * exp(-log(2) * (
POW2(dx - 0.49) +
POW2(radius - 0.5)) /
POW2(0.01)) * jet;
30440 angle2 = atan2(dz, dy);
30445 for(
MInt i = 0; i < m_modeNumbers; i++) {
30449 const MFloat a = -1.0 + (float)rand() / ((float)RAND_MAX / (1.0 - (-1.0)));
30450 const MFloat phi = 0.00 + (float)rand() / ((float)RAND_MAX / (2 * acos(-1) - 0.00));
30452 az +=
a * cos(phi + i * angle2);
30454 uy11 = (m_forceCoefficient * az * uy1);
30455 ur = (m_forceCoefficient * az * ur0);
30456 u = ur * cos(angle2);
30457 w = ur * sin(angle2);
30458 a_rightHandSide(cellId, CV->RHO_U) += (a_cellVolume(cellId) * m_rhoInfinity * uy11);
30459 a_rightHandSide(cellId, CV->RHO_V) += (a_cellVolume(cellId) * m_rhoInfinity * u);
30460 a_rightHandSide(cellId, CV->RHO_W) += (a_cellVolume(cellId) * m_rhoInfinity * w);
30468 if(!m_jetForcing) {
30476 std::vector<MFloat> randAng{};
30477 randAng.resize(m_modeNumbers);
30478 std::vector<MFloat> randAmp{};
30479 randAmp.resize(m_modeNumbers);
30484 mTerm(1,
"Properties RNGSeed or seedRNGWithTime not compatible with jetForcing");
30486 for(
MInt i = 0; i < 10; i++) {
30490 const MInt randSeed = rand();
30494 std::default_random_engine gen(randSeed);
30495 std::uniform_real_distribution<MFloat> ampDist(-1., 1.);
30496 std::uniform_real_distribution<MFloat> angDist(0., 2 * PI);
30499 for(
MInt i = 0; i < m_modeNumbers; i++) {
30500 randAmp[i] = ampDist(gen);
30501 randAng[i] = angDist(gen);
30504 const MFloat r0 = m_jetHeight;
30505 const MFloat x0 = m_jetForcingPosition;
30506 const MFloat deltaY = c_cellLengthAtLevel(maxLevel());
30507 const MInt noCells = a_noCells();
30509 for(
MInt cellId = 0; cellId < noCells; cellId++) {
30510 const MFloat dx = a_coordinate(cellId, 0);
30511 const MFloat dy = a_coordinate(cellId, 1);
30512 const MFloat dz = a_coordinate(cellId, 2);
30516 const MFloat u0 = m_UInfinity;
30519 if(fabs(radius) / r0 <= 1.5) {
30520 MFloat prefac = 2.0 * r0 / (radius * deltaY);
30521 prefac *= exp(-log(2.0) * (
POW2(dx - x0) +
POW2(radius - r0)) /
POW2(deltaY)) * u0;
30522 const MFloat u_ring = prefac * (radius - r0);
30523 const MFloat v_ring = -1.0 * prefac * (dx - x0);
30524 const MFloat angle = atan2(dz, dy);
30527 for(
MInt i = 0; i < m_modeNumbers; i++) {
30528 randFluct += randAmp[i] * cos(randAng[i] + i * angle);
30530 const MFloat u_ax = (m_forceCoefficient * randFluct * u_ring);
30531 const MFloat u_rad = (m_forceCoefficient * randFluct * v_ring);
30532 const MFloat v = u_rad * cos(angle);
30533 const MFloat w = u_rad * sin(angle);
30535 if(m_jetType == 19517) {
30536 a_rightHandSide(cellId, CV->RHO_U) += (a_cellVolume(cellId) * m_rhoInfinity * u_ax);
30537 a_rightHandSide(cellId, CV->RHO_V) += (a_cellVolume(cellId) * m_rhoInfinity * v);
30538 a_rightHandSide(cellId, CV->RHO_W) += (a_cellVolume(cellId) * m_rhoInfinity * w);
30540 const MFloat rho = a_variable(cellId, CV->RHO);
30545 a_variable(cellId, CV->RHO_U) += (rho * u_ax);
30546 a_variable(cellId, CV->RHO_V) += (rho * v);
30547 a_variable(cellId, CV->RHO_W) += (rho * w);
30556 IF_CONSTEXPR(nDim == 2)
mTerm(-1,
"This case is designed for 3D!");
30558 const MInt noCells = a_noCells();
30563 for(cellId = 0; cellId < noCells; cellId++) {
30564 MFloat jet, uy1 = 0, uy11 = 0, ur0 = 0, ur = 0, u = 0, w = 0, radius, radius2, angle, swtrad, swtxsgn,
30566 MFloat dx, dy, dz, angle2;
30568 dx = a_coordinate(cellId, 0);
30569 dy = a_coordinate(cellId, 1);
30570 dz = a_coordinate(cellId, 2);
30571 radius = sqrt(
POW2(dy) +
POW2(dz));
30572 swtrad = 0.5 * F1 * (radius - 0.01 + abs(radius - 0.01)) / (abs(radius - 0.01) + 1e-32);
30573 swtxsgn = 0.5 * F1 * (dy + abs(dy)) / (abs(dy) + 1e-32);
30574 swtzsgn = 0.5 * F1 * (dz + abs(dz)) / (abs(dz) + 1e-32);
30575 angle = abs(dy) / (radius + 1e-32) * swtrad;
30576 angle = acos(angle);
30577 angle = angle * swtxsgn * swtzsgn + (PI - angle) * (1 - swtxsgn) * swtzsgn
30578 + (PI + angle) * (1 - swtxsgn) * (1 - swtzsgn) - angle * swtxsgn * (1 - swtzsgn);
30581 if(radius <= m_primaryJetRadius) {
30584 - tanh(m_shearLayerThickness * (((dx) - (m_jetHeight)) / (m_jetHeight))
30585 * (((dx) + (m_jetHeight)) / (m_jetHeight))))
30587 radius = radius + 0.0000000000000001;
30589 uy1 = 2 * m_primaryJetRadius / radius * (radius - m_primaryJetRadius) / 0.01
30590 * exp(-log(2) * (
POW2(dx - 0.49) +
POW2(radius - m_primaryJetRadius)) /
POW2(0.01)) * jet;
30591 ur0 = -2 * m_primaryJetRadius / radius * (dx - 0.49) / 0.01
30592 * exp(-log(2) * (
POW2(dx - 0.49) +
POW2(radius - m_primaryJetRadius)) /
POW2(0.01)) * jet;
30595 angle2 = atan2(dz, dy);
30599 for(
MInt i = 0; i < m_modeNumbers; i++) {
30600 a[i] = -1.0 + (float)rand() / ((float)RAND_MAX / (1.0 - (-1.0)));
30601 phi[i] = 0.00 + (float)rand() / ((float)RAND_MAX / (2 * acos(-1) - 0.00));
30603 az +=
a[i] * cos(phi[i] + i * angle2);
30605 uy11 = (m_forceCoefficient * az * uy1);
30606 ur = (m_forceCoefficient * az * ur0);
30607 u = ur * cos(angle2);
30608 w = ur * sin(angle2);
30611 else if(radius <= m_secondaryJetRadius) {
30612 radius2 = radius - m_primaryJetRadius;
30615 - tanh(m_shearLayerThickness * (((dx) - (m_jetHeight)) / (m_jetHeight))
30616 * (((dx) + (m_jetHeight)) / (m_jetHeight))))
30618 radius2 = radius2 + 0.0000000000000001;
30620 uy1 = 2 * m_secondaryJetRadius / radius * (radius - m_secondaryJetRadius) / 0.01
30621 * exp(-log(2) * (
POW2(dx - 0.49) +
POW2(radius - m_secondaryJetRadius)) /
POW2(0.01)) * jet;
30622 ur0 = -2 * m_secondaryJetRadius / radius * (dx - 0.49) / 0.01
30623 * exp(-log(2) * (
POW2(dx - 0.49) +
POW2(radius - m_secondaryJetRadius)) /
POW2(0.01)) * jet;
30626 angle2 = atan2(dz, dy);
30630 for(
MInt i = 0; i < 16; i++) {
30631 a[i] = -1.0 + (float)rand() / ((float)RAND_MAX / (1.0 - (-1.0)));
30632 phi[i] = 0.00 + (float)rand() / ((float)RAND_MAX / (2 * acos(-1) - 0.00));
30642 az +=
a[i] * cos(phi[i] + (i)*angle2);
30644 uy11 = (m_forceCoefficient * az * uy1);
30645 ur = (m_forceCoefficient * az * ur0);
30646 u = ur * cos(angle2);
30647 w = ur * sin(angle2);
30649 a_rightHandSide(cellId, CV->RHO_U) += (a_cellVolume(cellId) * m_rhoInfinity * uy11);
30650 a_rightHandSide(cellId, CV->RHO_V) += (a_cellVolume(cellId) * m_rhoInfinity * u);
30651 a_rightHandSide(cellId, CV->RHO_W) += (a_cellVolume(cellId) * m_rhoInfinity * w);
30660 stringstream errorMessage;
30661 errorMessage <<
"FvCartesianSolverXD::updateJet() switch variable 'm_jetType' with value " << m_jetType
30662 <<
" not matching any case." << endl;
30663 mTerm(1, AT_, errorMessage.str());
30679template <MInt nDim_,
class SysEqn>
30696 MBool bndryRfnJump =
false;
30697 bndryRfnJump = Context::getSolverProperty<MBool>(
"bndryRfnJump", m_solverId, AT_, &bndryRfnJump);
30703 for(
MInt dimId = 0; dimId < nDim; dimId++) {
30704 coordinates[dimId] = a_coordinate(cellId, dimId);
30705 if(a_bndryId(cellId) > -1) {
30706 MInt bndryId = a_bndryId(cellId);
30708 coordinates[dimId] -= m_fvBndryCnd->m_bndryCells->a[bndryId].m_coordinates[dimId];
30712 for(
MInt smallId = 0; smallId < m_fvBndryCnd->m_smallBndryCells->size(); smallId++) {
30713 const MInt smallCell = m_fvBndryCnd->m_smallBndryCells->a[smallId];
30714 if(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId != -1) {
30715 if(a_bndryId(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId) == -1
30716 && m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId == cellId) {
30717 for(
MInt dimId = 0; dimId < nDim; dimId++) {
30718 coordinates[dimId] = m_fvBndryCnd->m_bndryCells->a[smallCell].m_masterCoordinates[dimId];
30726 m_surfaces.append();
30728 const MInt spaceId = dirId / 2;
30729 const MInt sideId = dirId % 2;
30730 const MInt otherSideId = (sideId + 1) % 2;
30733 a_surfaceOrientation(srfcId) = spaceId;
30735 a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
30736 a_surfaceNghbrCellId(srfcId, otherSideId) =
cellId;
30739 a_surfaceArea(srfcId) = F1;
30741 MFloat cellHalfLength[nDim];
30742 for(
MInt dimId = 0; dimId < nDim; dimId++) {
30743 cellHalfLength[dimId] = c_cellLengthAtLevel(a_level(cellId) + 1);
30746 a_surfaceCoordinate(srfcId, spaceId) = coordinates[spaceId] + F2 * ((
MFloat)sideId - F1B2) * cellHalfLength[spaceId];
30748 for(
MInt dimId = 0; dimId < nDim; dimId++) {
30749 if(dimId != spaceId) {
30751 a_surfaceArea(srfcId) *= F2 * cellHalfLength[dimId];
30753 a_surfaceCoordinate(srfcId, dimId) = coordinates[dimId];
30756 if(m_bndryRfnJumpInformation_[cellId] != -1 && nghbrId == m_bndryRfnJumpInformation_[cellId]) {
30757 a_surfaceArea(srfcId) = F0;
30763 delete[] coordinates;
30781template <MInt nDim_,
class SysEqn>
30785 const MInt noCells = a_noCells();
30786 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
30788 MBoolScratchSpace surfaceCreated(noBndryCells, m_noDirs, AT_,
"surfaceCreated");
30789 for(
MInt i = 0; i < noBndryCells; i++) {
30790 for(
MInt j = 0; j < m_noDirs; j++) {
30791 surfaceDenied(i, j) =
false;
30792 surfaceCreated(i, j) =
false;
30796 MInt otherDir[2 * nDim];
30797 for(
MInt dim = 0; dim < nDim; dim++) {
30798 otherDir[2 * dim] = 2 * dim + 1;
30799 otherDir[2 * dim + 1] = 2 * dim;
30802 m_surfaces.
size(m_bndryCellSurfacesOffset);
30807 for(
MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
30808 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
30810 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
30813 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
30814 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_externalFaces[dirId]) {
30815 surfaceDenied(bndryId, dirId) =
true;
30818 if(m_identNghbrIds[cellId * m_noDirs + dirId] < m_identNghbrIds[cellId * m_noDirs + dirId + 1]) {
30819 nghbrId = m_storeNghbrIds[m_identNghbrIds[cellId * m_noDirs + dirId]];
30820 if(a_level(cellId) < a_level(nghbrId)) {
30827 if(a_bndryId(nghbrId) < 0) {
30831 MBool createSrfc =
true;
30833 MInt oldSrfcId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_associatedSrfc[dirId];
30834 if(oldSrfcId >= 0) {
30835 ASSERT(a_surfaceNghbrCellId(oldSrfcId, 0) > -1 && a_surfaceNghbrCellId(oldSrfcId, 1) > -1,
"");
30840 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > -1) {
30841 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == nghbrId
30842 || m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId
30843 == m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId) {
30844 createSrfc =
false;
30845 surfaceDenied(bndryId, dirId) =
true;
30848 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId > -1) {
30849 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == (
MInt)cellId
30850 || m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId
30851 == m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId) {
30852 createSrfc =
false;
30853 surfaceDenied(bndryId, dirId) =
true;
30856 if(a_isPeriodic(cellId) && a_isPeriodic(nghbrId)) {
30857 createSrfc =
false;
30858 surfaceDenied(bndryId, dirId) =
true;
30863 if(a_isHalo(cellId) && a_isHalo(nghbrId)) {
30864 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == -1
30865 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == -1) {
30866 createSrfc =
false;
30867 surfaceDenied(bndryId, dirId) =
true;
30876 if((a_level(cellId) > a_level(nghbrId)) || ((a_level(cellId) == a_level(nghbrId)) && dirId % 2 == 0)) {
30877 surfaceCreated(bndryId, dirId) =
true;
30879 if(oldSrfcId != counter) {
30880 m_surfaces.copy(oldSrfcId, counter);
30881 m_surfaces.erase(oldSrfcId);
30882 m_fvBndryCnd->m_bndryCells->a[bndryId].m_associatedSrfc[dirId] = counter;
30883 if(a_level(cellId) == a_level(nghbrId)) {
30884 m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_associatedSrfc[otherDir[dirId]] = counter;
30894 while(a_noSurfaces() > counter) {
30895 MInt size = a_noSurfaces();
30896 m_surfaces.erase(size - 1);
30897 m_surfaces.size(size - 1);
30901 m_bndryCellSurfacesOffset = a_noSurfaces();
30904 MInt srfcId = a_noSurfaces();
30905 MLong sumSrfc = srfcId;
30906 MPI_Allreduce(MPI_IN_PLACE, &sumSrfc, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"sumSrfc");
30907 m_log <<
"DEBUG: " << sumSrfc <<
" number of surfaces after first loop" << endl;
30912 for(
MInt cellId = 0; cellId < noCells; cellId++) {
30913 if(a_isBndryGhostCell(cellId)) {
30917 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
30922 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
30923 for(
MInt nghbr = m_identNghbrIds[cellId * m_noDirs + dirId];
30924 nghbr < m_identNghbrIds[cellId * m_noDirs + dirId + 1];
30926 MBool createSrfc =
false;
30927 const MInt nghbrId = m_storeNghbrIds[nghbr];
30928 ASSERT(nghbrId > -1,
"");
30929 if(a_bndryId(cellId) > -1 && a_bndryId(nghbrId) > -1) {
30930 if((surfaceDenied(a_bndryId(cellId), dirId) ==
false
30931 || surfaceDenied(a_bndryId(nghbrId), otherDir[dirId]) ==
false)
30932 && (surfaceCreated(a_bndryId(cellId), dirId) ==
false
30933 && surfaceCreated(a_bndryId(nghbrId), otherDir[dirId]) ==
false)) {
30938 if(a_bndryId(cellId) == -1 || a_bndryId(nghbrId) == -1) {
30947 if(a_bndryId(cellId) > -1) {
30948 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId == nghbrId) {
30949 createSrfc =
false;
30953 if(a_bndryId(nghbrId) > -1) {
30954 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == cellId) {
30955 createSrfc =
false;
30960 if(a_isPeriodic(cellId) && a_isPeriodic(nghbrId)) {
30961 createSrfc =
false;
30965 if(a_isHalo(cellId) && a_isHalo(nghbrId)) {
30966 createSrfc =
false;
30971 if((a_level(cellId) > a_level(nghbrId)) || ((a_level(cellId) == a_level(nghbrId)) && dirId % 2 == 0)) {
30972 computeSrfcs(cellId, nghbrId, dirId, srfcId);
30981 for(
MInt srfc = 0; srfc < a_noSurfaces(); srfc++) {
30982 MInt nghbr0 = a_surfaceNghbrCellId(srfc, 0);
30983 MInt nghbr1 = a_surfaceNghbrCellId(srfc, 1);
30984 MInt dir = a_surfaceOrientation(srfc);
30985 MInt dir0 = 2 * dir + 1;
30986 MInt dir1 = 2 * dir;
30987 if(a_bndryId(nghbr0) > -1) {
30988 m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbr0)].m_associatedSrfc[dir0] = srfc;
30990 if(a_bndryId(nghbr1) > -1) {
30991 m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbr1)].m_associatedSrfc[dir1] = srfc;
30994 sumSrfc = a_noSurfaces();
30995 MPI_Allreduce(MPI_IN_PLACE, &sumSrfc, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"sumSrfc");
30996 MPI_Allreduce(MPI_IN_PLACE, &nmbr1, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"nmbr1");
30997 MPI_Allreduce(MPI_IN_PLACE, &nmbr2, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"nmbr2");
30998 m_log <<
"DEBUG: " << nmbr1 <<
" number of cells skipped: boundaryId ==-2" << endl;
30999 m_log <<
"DEBUG: " << nmbr2 <<
" number of cells skipped: IsOnCurrentMGLevel" << endl;
31000 m_log <<
"DEBUG: " << sumSrfc <<
" number of surfaces after second loop" << endl;
31007template <MInt nDim_,
class SysEqn>
31009 IF_CONSTEXPR(nDim == 2) {
mTerm(1,
"Only available in 3D. MGC not yet implemented in 2D."); }
31011 checkForSrfcsMGC_2_();
31028template <MInt nDim_,
class SysEqn>
31031 MBool createSrfc =
true;
31032 MInt cell, counter;
31033 MInt srfcId, bndryId2, cell2;
31034 MInt nghbrId = 0, oldSrfcId, size;
31035 MInt noCells = a_noCells();
31036 MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
31037 MBool** surfaceDenied =
new MBool*[noBndryCells];
31038 MBoolScratchSpace surfaceDenied_scratch(noBndryCells * m_noDirs, AT_,
"surfaceDenied_scratch");
31039 for(
MInt i = 0; i < noBndryCells; i++) {
31040 surfaceDenied[i] = &surfaceDenied_scratch.
p[m_noDirs * i];
31041 for(
MInt j = 0; j < m_noDirs; j++) {
31042 surfaceDenied[i][j] =
false;
31045 MBool** surfaceCreated =
new MBool*[noBndryCells];
31046 MBoolScratchSpace surfaceCreated_scratch(noBndryCells * m_noDirs, AT_,
"surfaceCreated_scratch");
31047 for(
MInt i = 0; i < noBndryCells; i++) {
31048 surfaceCreated[i] = &surfaceCreated_scratch.
p[m_noDirs * i];
31049 for(
MInt j = 0; j < m_noDirs; j++) {
31050 surfaceCreated[i][j] =
false;
31053 constexpr MInt otherDir[] = {1, 0, 3, 2, 5, 4};
31054 MInt nghbr0, nghbr1;
31057 m_surfaces.size(m_bndryCellSurfacesOffset);
31062 for(
MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
31063 cell = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
31065 if(m_fvBndryCnd->m_splitParents[bndryId] >= 0) {
31068 if(!a_hasProperty(cell, SolverCell::IsInvalid)) {
31069 if(a_hasProperty(cell, SolverCell::IsOnCurrentMGLevel)) {
31070 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
31071 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_externalFaces[dirId]) {
31072 surfaceDenied[bndryId][dirId] =
true;
31074 if(m_identNghbrIds[cell * m_noDirs + dirId] < m_identNghbrIds[cell * m_noDirs + dirId + 1]) {
31075 nghbrId = m_storeNghbrIds[m_identNghbrIds[cell * m_noDirs + dirId]];
31076 if(a_level(cell) < a_level(nghbrId)) {
31083 if(a_bndryId(nghbrId) < 0) {
31087 if(a_hasProperty(nghbrId, SolverCell::IsInvalid)) {
31093 oldSrfcId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_associatedSrfc[dirId];
31094 if(oldSrfcId >= 0) {
31099 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > -1) {
31100 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == nghbrId
31101 || m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId
31102 == m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId) {
31103 createSrfc =
false;
31104 surfaceDenied[bndryId][dirId] =
true;
31107 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId > -1) {
31108 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == (
MInt)cell
31109 || m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId
31110 == m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId) {
31111 createSrfc =
false;
31112 surfaceDenied[bndryId][dirId] =
true;
31115 if(a_isPeriodic(cell) && a_isPeriodic(nghbrId)) {
31116 createSrfc =
false;
31117 surfaceDenied[bndryId][dirId] =
true;
31122 if(a_isHalo(cell) && a_isHalo(nghbrId)) {
31123 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == -1
31124 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == -1) {
31125 createSrfc =
false;
31126 surfaceDenied[bndryId][dirId] =
true;
31135 oldSrfcId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_associatedSrfc[dirId];
31137 if((a_level(cell) > a_level(nghbrId)) || ((a_level(cell) == a_level(nghbrId)) && dirId % 2 == 0)) {
31138 surfaceCreated[bndryId][dirId] =
true;
31140 if(oldSrfcId != counter) {
31141 m_surfaces.copy(oldSrfcId, counter);
31142 m_surfaces.erase(oldSrfcId);
31143 m_fvBndryCnd->m_bndryCells->a[bndryId].m_associatedSrfc[dirId] = counter;
31144 if(a_level(cell) == a_level(nghbrId)) {
31145 m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_associatedSrfc[otherDir[dirId]] = counter;
31150 }
else if(oldSrfcId < -1) {
31153 srfcId = m_fvBndryCnd->m_splitSurfaces[-oldSrfcId * 6];
31154 nghbr0 = a_surfaceNghbrCellId(srfcId, 0);
31155 nghbr1 = a_surfaceNghbrCellId(srfcId, 1);
31156 if(nghbr0 == cell) {
31166 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > -1) {
31167 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == nghbrId
31168 || m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId
31169 == m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId) {
31170 createSrfc =
false;
31171 surfaceDenied[bndryId][dirId] =
true;
31174 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId > -1) {
31175 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == (
MInt)cell
31176 || m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId
31177 == m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId) {
31178 createSrfc =
false;
31179 surfaceDenied[bndryId][dirId] =
true;
31182 if(a_isPeriodic(cell) && a_isPeriodic(nghbrId)) {
31183 createSrfc =
false;
31184 surfaceDenied[bndryId][dirId] =
true;
31189 if(a_isHalo(cell) && a_isHalo(nghbrId)) {
31190 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == -1
31191 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == -1) {
31192 createSrfc =
false;
31193 surfaceDenied[bndryId][dirId] =
true;
31203 if((a_level(cell) > a_level(nghbrId)) || ((a_level(cell) == a_level(nghbrId)) && dirId % 2 == 0)) {
31204 surfaceCreated[bndryId][dirId] =
true;
31206 if(srfcId != counter) {
31207 m_surfaces.copy(srfcId, counter);
31208 m_surfaces.erase(srfcId);
31209 m_fvBndryCnd->m_splitSurfaces[-oldSrfcId * 6] = counter;
31215 srfcId = m_fvBndryCnd->m_splitSurfaces[-oldSrfcId * 6 + 3];
31216 nghbr0 = a_surfaceNghbrCellId(srfcId, 0);
31217 nghbr1 = a_surfaceNghbrCellId(srfcId, 1);
31218 if(nghbr0 == cell) {
31228 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > -1) {
31229 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == nghbrId
31230 || m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId
31231 == m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId) {
31232 createSrfc =
false;
31233 surfaceDenied[bndryId][dirId] =
true;
31236 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId > -1) {
31237 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == (
MInt)cell
31238 || m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId
31239 == m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId) {
31240 createSrfc =
false;
31241 surfaceDenied[bndryId][dirId] =
true;
31244 if(a_isPeriodic(cell) && a_isPeriodic(nghbrId)) {
31245 createSrfc =
false;
31246 surfaceDenied[bndryId][dirId] =
true;
31251 if(a_isHalo(cell) && a_isHalo(nghbrId)) {
31252 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == -1
31253 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == -1) {
31254 createSrfc =
false;
31255 surfaceDenied[bndryId][dirId] =
true;
31265 if((a_level(cell) > a_level(nghbrId)) || ((a_level(cell) == a_level(nghbrId)) && dirId % 2 == 0)) {
31266 surfaceCreated[bndryId][dirId] =
true;
31268 if(srfcId != counter) {
31269 m_surfaces.copy(srfcId, counter);
31270 m_surfaces.erase(srfcId);
31271 m_fvBndryCnd->m_splitSurfaces[-oldSrfcId * 6 + 3] = counter;
31279 for(
MInt child = 0; child < 3; child++) {
31280 bndryId2 = m_fvBndryCnd->m_splitChildren[bndryId * 3 + child];
31281 if(bndryId2 == -1) {
31284 cell2 = m_fvBndryCnd->m_bndryCells->a[bndryId2].m_cellId;
31285 if(!a_hasProperty(cell2, SolverCell::IsInvalid)) {
31286 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
31287 if(m_fvBndryCnd->m_bndryCells->a[bndryId2].m_externalFaces[dirId]) {
31288 surfaceDenied[bndryId2][dirId] =
true;
31290 if(m_identNghbrIds[cell2 * m_noDirs + dirId] < m_identNghbrIds[cell2 * m_noDirs + dirId + 1]) {
31291 nghbrId = m_storeNghbrIds[m_identNghbrIds[cell2 * m_noDirs + dirId]];
31292 if(a_level(cell2) < a_level(nghbrId)) {
31299 if(a_bndryId(nghbrId) < 0) {
31308 if(m_fvBndryCnd->m_bndryCells->a[bndryId2].m_linkedCellId > -1) {
31309 if(m_fvBndryCnd->m_bndryCells->a[bndryId2].m_linkedCellId == nghbrId
31310 || m_fvBndryCnd->m_bndryCells->a[bndryId2].m_linkedCellId
31311 == m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId) {
31312 createSrfc =
false;
31313 surfaceDenied[bndryId2][dirId] =
true;
31316 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId > -1) {
31317 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == (
MInt)cell2
31318 || m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId
31319 == m_fvBndryCnd->m_bndryCells->a[bndryId2].m_linkedCellId) {
31320 createSrfc =
false;
31321 surfaceDenied[bndryId2][dirId] =
true;
31324 if(a_isPeriodic(cell2) && a_isPeriodic(nghbrId)) {
31325 createSrfc =
false;
31326 surfaceDenied[bndryId2][dirId] =
true;
31331 if(a_isHalo(cell2) && a_isHalo(nghbrId)) {
31332 if(m_fvBndryCnd->m_bndryCells->a[bndryId2].m_linkedCellId == -1
31333 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == -1) {
31334 createSrfc =
false;
31335 surfaceDenied[bndryId2][dirId] =
true;
31345 oldSrfcId = m_fvBndryCnd->m_bndryCells->a[bndryId2].m_associatedSrfc[dirId];
31347 if(oldSrfcId == -1) {
31351 if(oldSrfcId >= 0) {
31354 if((a_level(cell2) > a_level(nghbrId)) || ((a_level(cell2) == a_level(nghbrId)) && dirId % 2 == 0)) {
31355 surfaceCreated[bndryId2][dirId] =
true;
31357 if(oldSrfcId != counter) {
31358 m_surfaces.copy(oldSrfcId, counter);
31359 m_surfaces.erase(oldSrfcId);
31360 m_fvBndryCnd->m_bndryCells->a[bndryId2].m_associatedSrfc[dirId] = counter;
31361 if(a_level(cell2) == a_level(nghbrId)) {
31362 m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_associatedSrfc[otherDir[dirId]] = counter;
31373 createSrfc =
false;
31376 while(a_noSurfaces() > counter) {
31377 size = a_noSurfaces();
31378 m_surfaces.erase(size - 1);
31379 m_surfaces.size(size - 1);
31383 m_bndryCellSurfacesOffset = a_noSurfaces();
31386 srfcId = a_noSurfaces();
31388 for(
MInt cellId = 0; cellId < noCells; cellId++) {
31389 if(a_isBndryGhostCell(cellId)) {
31392 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
31396 for(
MInt dirId = 0; dirId < m_noDirs; dirId++) {
31397 for(
MInt nghbr = m_identNghbrIds[cellId * m_noDirs + dirId];
31398 nghbr < m_identNghbrIds[cellId * m_noDirs + dirId + 1];
31400 createSrfc =
false;
31401 nghbrId = m_storeNghbrIds[nghbr];
31403 if(a_bndryId(cellId) > -1 && a_bndryId(nghbrId) > -1) {
31404 if((surfaceDenied[a_bndryId(cellId)][dirId] ==
false
31405 || surfaceDenied[a_bndryId(nghbrId)][otherDir[dirId]] ==
false)
31406 && (surfaceCreated[a_bndryId(cellId)][dirId] ==
false
31407 && surfaceCreated[a_bndryId(nghbrId)][otherDir[dirId]] ==
false)) {
31412 if(a_bndryId(cellId) == -1 || a_bndryId(nghbrId) == -1) {
31421 if(a_bndryId(cellId) > -1) {
31422 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId == nghbrId) {
31423 createSrfc =
false;
31427 if(a_bndryId(nghbrId) > -1) {
31428 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == cellId) {
31429 createSrfc =
false;
31434 if(a_isPeriodic(cellId) && a_isPeriodic(nghbrId)) {
31435 createSrfc =
false;
31439 if(a_isHalo(cellId) && a_isHalo(nghbrId)) {
31440 createSrfc =
false;
31445 if((a_level(cellId) > a_level(nghbrId)) || ((a_level(cellId) == a_level(nghbrId)) && dirId % 2 == 0)) {
31446 computeSrfcs(cellId, nghbrId, dirId, srfcId);
31455 delete[] surfaceDenied;
31457 delete[] surfaceCreated;
31458 surfaceCreated = 0;
31460 for(
MInt srfc = 0; srfc < a_noSurfaces(); srfc++) {
31461 nghbr0 = a_surfaceNghbrCellId(srfc, 0);
31462 nghbr1 = a_surfaceNghbrCellId(srfc, 1);
31463 MInt dir = a_surfaceOrientation(srfc);
31464 MInt dir0 = 2 * dir + 1;
31465 MInt dir1 = 2 * dir;
31466 if(a_bndryId(nghbr0) > -1) {
31467 m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbr0)].m_associatedSrfc[dir0] = srfc;
31469 if(a_bndryId(nghbr1) > -1) {
31470 m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbr1)].m_associatedSrfc[dir1] = srfc;
31478template <MInt nDim_,
class SysEqn>
31480 IF_CONSTEXPR(nDim == 2) {
mTerm(1,
"Only meaningful in 3D."); }
31482 correctBoundarySurfaces_();
31486template <MInt nDim_,
class SysEqn>
31490 const MInt noCells = a_noCells();
31491 const MInt noBCCells = m_fvBndryCnd->m_bndryCells->size();
31492 const MInt noSurfaces = a_noSurfaces();
31493 const MFloat eps = c_cellLengthAtLevel(maxRefinementLevel()) * 0.00001;
31497 m_surfaces.size(m_bndrySurfacesOffset);
31499 for(
MInt bc = 0; bc < noBCCells; bc++) {
31500 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bc].m_cellId;
31501 for(
MInt d = 0; d < nDim; d++) {
31502 area[d * noCells + cellId] = F0;
31506 for(
MInt s = 0; s < noSurfaces; s++) {
31507 MInt i = a_surfaceOrientation(s);
31508 area[i * noCells + a_surfaceNghbrCellId(s, 0)] -= a_surfaceArea(s);
31509 area[i * noCells + a_surfaceNghbrCellId(s, 1)] += a_surfaceArea(s);
31512 for(
MInt bc = 0; bc < noBCCells; bc++) {
31513 if(m_fvBndryCnd->m_bndryCells->a[bc].m_linkedCellId == -1) {
31514 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bc].m_cellId;
31516 if(a_isHalo(cellId))
continue;
31518 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
31520 if(c_noChildren(cellId) > 0)
continue;
31523 MBool check =
false;
31524 for(
MInt d = 0; d < m_noDirs; d++) {
31525 if(a_hasNeighbor(cellId, d) > 0) {
31526 if(c_noChildren(c_neighborId(cellId, d)) > 0) {
31532 for(
MInt d = 0; d < nDim; d++) {
31533 if(
ABS(area[d * noCells + cellId]) > eps) {
31536 for(
MInt dd = 0; dd < nDim; dd++) {
31537 if(m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_normalVector[dd] > F0) {
31538 totalArea +=
POW2(
ABS(m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_normalVector[dd])
31539 * m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_area
31540 + area[dd * noCells + cellId]);
31541 area[dd * noCells + cellId] =
ABS(m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_normalVector[dd])
31542 * m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_area
31543 + area[dd * noCells + cellId];
31545 totalArea +=
POW2(
ABS(m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_normalVector[dd])
31546 * m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_area
31547 - area[dd * noCells + cellId]);
31548 area[dd * noCells + cellId] = -
ABS(m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_normalVector[dd])
31549 * m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_area
31550 - area[dd * noCells + cellId];
31554 m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_area = sqrt(totalArea);
31555 for(
MInt dd = 0; dd < nDim; dd++) {
31556 m_fvBndryCnd->m_bndryCells->a[bc].m_srfcs[0]->m_normalVector[dd] =
31557 area[dd * noCells + cellId] / sqrt(totalArea);
31570template <MInt nDim_,
class SysEqn>
31572 IF_CONSTEXPR(nDim == 2) {
mTerm(1,
"Azimuthal periodicity concept meaningful only in 3D."); }
31574 computeRecConstPeriodic_();
31582template <MInt nDim_,
class SysEqn>
31587 MBool nonlinear =
true;
31588 MInt maxNoNghbrs = 200;
31589 MInt matrix_dim = nDim + 1;
31591 matrix_dim = 3 * nDim + 1;
31607 MInt sortedId = -1;
31609 MInt offset_cell = 0;
31611 MInt noSendingCells = 0;
31614 for(
MInt d = 0; d < noDomains(); d++) {
31615 noSendingCells += m_noPerCellsToSend[d];
31619 mAlloc(m_reconstructionDataPeriodic, noSendingCells + 1,
"m_reconstructionDataPeriodic", -1, AT_);
31620 mAlloc(m_reconstructionConstantsPeriodic, (noSendingCells * maxNoNghbrs * 2),
"m_reconstructionConstantsPeriodic", F0,
31623 m_reconstructionDataPeriodic[0] = 0;
31625 for(
MInt d = 0; d < noDomains(); d++) {
31626 for(
MInt c = 0; c < m_noPerCellsToSend[d]; c++) {
31627 cell_Id =
static_cast<MInt>(m_periodicDataToSend[d][6 + c * m_noPeriodicData]);
31628 sortedId =
static_cast<MInt>(m_periodicDataToSend[d][5 + c * m_noPeriodicData]);
31631 MFloat normalizationFactor =
FPOW2(a_level(cell_Id)) / c_cellLengthAtLevel(0);
31635 counter_ = getAdjacentLeafCells<2, true>(cell_Id, 2, nghbrList_, layerId_);
31638 if(counter_ > maxNoNghbrs) {
31639 mTerm(1, AT_,
"raise noMaxNghbrs");
31690 for(
MInt n = 0; n < counter_; n++) {
31691 n_Id = nghbrList_[n];
31695 if(a_hasProperty(n_Id, SolverCell::IsPeriodicWithRot)) {
31698 if(!a_hasProperty(n_Id, SolverCell::IsOnCurrentMGLevel)) {
31701 if(c_noChildren(n_Id) > 0) {
31704 if(n_Id == cell_Id) {
31708 m_reconstructionConstantsPeriodic[offset_cell + k_] = nghbrList_[n];
31716 for(
MInt i = 0; i < nDim; i++) {
31717 mat(k_, cnt) = (a_coordinate(n_Id, i) - m_periodicCellDataDom[d][i + sortedId * m_noPeriodicCellData])
31718 * normalizationFactor;
31719 dx +=
POW2(a_coordinate(n_Id, i) - m_periodicCellDataDom[d][i + sortedId * m_noPeriodicCellData]);
31727 for(
MInt i = 0; i < nDim; i++) {
31730 *
POW2((a_coordinate(n_Id, i) - m_periodicCellDataDom[d][i + sortedId * m_noPeriodicCellData])
31731 * normalizationFactor);
31735 for(
MInt i = 0; i < nDim; i++) {
31736 for(
MInt j = i + 1; j < nDim; j++) {
31737 mat(k_, cnt) = (a_coordinate(n_Id, j) - m_periodicCellDataDom[d][j + sortedId * m_noPeriodicCellData])
31738 * (a_coordinate(n_Id, i) - m_periodicCellDataDom[d][i + sortedId * m_noPeriodicCellData])
31739 *
POW2(normalizationFactor);
31748 if(!a_hasProperty(cell_Id, SolverCell::IsPeriodicWithRot))
31750 m_reconstructionConstantsPeriodic[offset_cell + k_] = cell_Id;
31757 for(
MInt i = 0; i < nDim; i++) {
31758 mat(k_, cnt) = (a_coordinate(cell_Id, i) - m_periodicCellDataDom[d][i + sortedId * m_noPeriodicCellData])
31759 * normalizationFactor;
31760 dx +=
POW2(a_coordinate(cell_Id, i) - m_periodicCellDataDom[d][i + sortedId * m_noPeriodicCellData]);
31768 for(
MInt i = 0; i < nDim; i++) {
31771 *
POW2((a_coordinate(cell_Id, i) - m_periodicCellDataDom[d][i + sortedId * m_noPeriodicCellData])
31772 * normalizationFactor);
31777 for(
MInt i = 0; i < nDim; i++) {
31778 for(
MInt j = i + 1; j < nDim; j++) {
31780 (a_coordinate(cell_Id, j) - m_periodicCellDataDom[d][j + sortedId * m_noPeriodicCellData])
31781 * (a_coordinate(cell_Id, i) - m_periodicCellDataDom[d][i + sortedId * m_noPeriodicCellData])
31782 *
POW2(normalizationFactor);
31795 for(
MInt l = 0; l < k_; l++) {
31796 for(
MInt i = 0; i < matrix_dim - 1; i++) {
31797 matInv(1 + i, l) *= normalizationFactor;
31802 for(
MInt l = 0; l < k_; l++) {
31803 m_reconstructionConstantsPeriodic[offset_cell + k_ + l] = matInv(0, l);
31804 if((offset_cell + k_ + l) > (noSendingCells * maxNoNghbrs * 2)) {
31805 mTerm(1, AT_,
"raise noSendingCells");
31810 offset_cell += 2 * k_;
31812 m_reconstructionDataPeriodic[off_ + c + 1] = offset_cell;
31815 off_ += m_noPerCellsToSend[d];
31820template <MInt nDim_,
class SysEqn>
31822 IF_CONSTEXPR(nDim == 2) {
mTerm(1,
"Azimuthal periodicity concept meaningful only in 3D."); }
31824 identPeriodicCells_();
31832template <MInt nDim_,
class SysEqn>
31836 m_noPeriodicCellData = PV->noVariables;
31837 m_noPeriodicData = m_noPeriodicCellData + 2;
31839 MFloat periodic_coord[2];
31840 periodic_coord[0] = 0.0;
31841 periodic_coord[1] = 0.0;
31842 if(m_periodicCells == 2 || m_periodicCells == 3) {
31843 for(
MInt i = 0; i < 2; i++) {
31844 periodic_coord[i] = Context::getSolverProperty<MFloat>(
"periodic_coord", m_solverId, AT_, i);
31848 MInt m_maxNoPeriodicCells = 0;
31849 m_maxNoPeriodicCells = Context::getSolverProperty<MInt>(
"maxNoPeriodicCells", m_solverId, AT_, &m_maxNoPeriodicCells);
31851 m_sortedPeriodicCells->setSize(0);
31853 MFloat z_min_1, z_min_2, z_min_11, z_min_12;
31854 MFloat halfLength_1, halfLength_2;
31866 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
31867 xmax =
mMax(xmax, a_coordinate(cellId, 0));
31868 ymax =
mMax(ymax, a_coordinate(cellId, 1));
31869 zmax =
mMax(zmax, a_coordinate(cellId, 2));
31870 xmin =
mMin(xmin, a_coordinate(cellId, 0));
31871 ymin =
mMin(ymin, a_coordinate(cellId, 1));
31872 zmin =
mMin(zmin, a_coordinate(cellId, 2));
31881 if(m_periodicCells == 1) {
31882 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
31883 a_hasProperty(cellId, SolverCell::IsPeriodicWithRot) =
false;
31885 if(a_isBndryGhostCell(cellId) || c_noChildren(cellId) != 0
31886 || !a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
31891 halfLength_1 = c_cellLengthAtLevel(a_level(cellId) + 1);
31892 halfLength_2 = c_cellLengthAtLevel(maxLevel() + 1);
31894 z_min_1 = -6.3137515147 * a_coordinate(cellId, 1) + 1462.750302935;
31895 z_min_2 = -0.1583844403 * a_coordinate(cellId, 1) + 231.6768880649;
31896 z_min_11 = -6.3137515147 * (a_coordinate(cellId, 1) - halfLength_1) + 1462.750302935;
31897 z_min_12 = -0.1583844403 * (a_coordinate(cellId, 1) + halfLength_1) + 231.6768880649;
31901 a_coordinate(cellId, 1) < m_rotAxisCoord[0] && a_coordinate(cellId, 2) <= z_min_1
31902 && a_coordinate(cellId, 2) >= z_min_2)
31904 a_coordinate(cellId, 1) < m_rotAxisCoord[0] && a_coordinate(cellId, 2) > z_min_1
31905 && (a_coordinate(cellId, 2) - halfLength_1) < z_min_11
31908 a_coordinate(cellId, 1) > (m_rotAxisCoord[0] - 4.0 * halfLength_2)
31909 && a_coordinate(cellId, 1) < m_rotAxisCoord[0] && a_coordinate(cellId, 2) < z_min_2
31910 && (a_coordinate(cellId, 2) + halfLength_1) > z_min_12
31913 (fabs(a_coordinate(cellId, 1) - m_rotAxisCoord[0]) < halfLength_1 * 2.0)
31914 && (fabs(a_coordinate(cellId, 2) - m_rotAxisCoord[1]) < halfLength_1 * 2.0))) {
31918 m_sortedPeriodicCells->a[m_sortedPeriodicCells->size()] = cellId;
31919 a_hasProperty(cellId, SolverCell::IsPeriodicWithRot) =
true;
31920 m_sortedPeriodicCells->append();
31922 }
else if(m_periodicCells == 2 || m_periodicCells == 3) {
31923 m_fvBndryCnd->recorrectCellCoordinates();
31925 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
31926 a_hasProperty(cellId, SolverCell::IsPeriodicWithRot) =
false;
31928 if(a_isBndryGhostCell(cellId) || c_noChildren(cellId) != 0
31929 || !a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
31934 a_coordinate(cellId, 0) > periodic_coord[0] && a_coordinate(cellId, 0) < periodic_coord[1]) {
31938 m_sortedPeriodicCells->a[m_sortedPeriodicCells->size()] = cellId;
31939 a_hasProperty(cellId, SolverCell::IsPeriodicWithRot) =
true;
31940 m_sortedPeriodicCells->append();
31942 m_fvBndryCnd->rerecorrectCellCoordinates();
31945 if(m_maxNoPeriodicCells < m_sortedPeriodicCells->size()) {
31946 mTerm(1, AT_,
"raise max periodc cells");
31950 m_log <<
"*************************" << endl;
31951 m_log <<
"PeriodicCells Identified" << endl;
31952 m_log <<
"*************************" << endl;
31954 xmax += c_cellLengthAtLevel(minLevel());
31955 ymax += c_cellLengthAtLevel(minLevel());
31956 zmax += c_cellLengthAtLevel(minLevel());
31957 xmin -= c_cellLengthAtLevel(minLevel());
31958 ymin -= c_cellLengthAtLevel(minLevel());
31959 zmin -= c_cellLengthAtLevel(minLevel());
31963 MInt noPeriodicCells;
31964 noPeriodicCells = m_sortedPeriodicCells->size();
31967 mAlloc(m_noPeriodicCellsDom, noDomains(),
"m_noPeriodicCellsDom", -1, AT_);
31969 for(
MInt i = 0; i < noDomains(); i++) {
31970 m_noPeriodicCellsDom[i] = 0;
31973 MPI_Allgather(&noPeriodicCells, 1, MPI_INT, m_noPeriodicCellsDom, 1, MPI_INT, mpiComm(), AT_,
"noPeriodicCells",
31974 "m_noPeriodicCellsDom");
31980 m_periodicCellDataDom =
new MFloat*[noDomains()];
31981 for(
MInt domains = 0; domains < noDomains(); domains++) {
31982 m_periodicCellDataDom[domains] =
new MFloat[m_noPeriodicCellsDom[domains] * m_noPeriodicCellData];
31984 m_log <<
"*************************" << endl;
31985 m_log <<
"Alloc Memory" << endl;
31986 m_log <<
"*************************" << endl;
31990 x_mid = (periodic_coord[0] + periodic_coord[1]) / 2.0;
31992 if(m_periodicCells == 1) {
31993 for(
MInt id = 0;
id < noPeriodicCells;
id++) {
31994 for(
MInt dim = 0; dim < 3; dim++) {
31995 m_periodicCellDataDom[domainId()][dim + m_noPeriodicCellData *
id] =
31996 a_coordinate(m_sortedPeriodicCells->a[
id], dim);
31998 m_periodicCellDataDom[domainId()][3 + m_noPeriodicCellData *
id] = -1;
31999 z_min_45 = -a_coordinate(m_sortedPeriodicCells->a[
id], 1) + 400 - c_cellLengthAtLevel(minLevel()) / 10.0;
32001 if(a_coordinate(m_sortedPeriodicCells->a[
id], 2) >= z_min_45) {
32002 m_periodicCellDataDom[domainId()][4 + m_noPeriodicCellData *
id] = -1.0;
32004 m_periodicCellDataDom[domainId()][4 + m_noPeriodicCellData *
id] = 1.0;
32007 }
else if(m_periodicCells == 2 || m_periodicCells == 3) {
32008 for(
MInt id = 0;
id < noPeriodicCells;
id++) {
32009 for(
MInt dim = 0; dim < 3; dim++) {
32010 m_periodicCellDataDom[domainId()][dim + m_noPeriodicCellData *
id] =
32011 a_coordinate(m_sortedPeriodicCells->a[
id], dim);
32013 m_periodicCellDataDom[domainId()][3 + m_noPeriodicCellData *
id] = -1;
32015 if(a_coordinate(m_sortedPeriodicCells->a[
id], 2) < x_mid) {
32016 m_periodicCellDataDom[domainId()][4 + m_noPeriodicCellData *
id] = -1.0;
32018 m_periodicCellDataDom[domainId()][4 + m_noPeriodicCellData *
id] = 1.0;
32025 send_Req.
fill(MPI_REQUEST_NULL);
32026 recv_Req.
fill(MPI_REQUEST_NULL);
32029 for(
MInt snd = 0; snd < domainId(); snd++) {
32030 if(m_noPeriodicCellsDom[snd] > 0) {
32031 MInt bufSize = m_noPeriodicCellsDom[snd] * m_noPeriodicCellData;
32032 MPI_Irecv(m_periodicCellDataDom[snd], bufSize, MPI_DOUBLE, snd, 0, mpiComm(), &recv_Req[snd], AT_,
32033 "m_periodicCellDataDom[snd]");
32036 for(
MInt rcv = 0; rcv < noDomains(); rcv++) {
32037 if(rcv != domainId()) {
32038 if(m_noPeriodicCellsDom[domainId()] > 0) {
32039 MInt bufSize = m_noPeriodicCellsDom[domainId()] * m_noPeriodicCellData;
32040 MPI_Isend(m_periodicCellDataDom[domainId()], bufSize, MPI_DOUBLE, rcv, 0, mpiComm(), &send_Req[rcv], AT_,
32041 "m_periodicCellDataDom[domainId()]");
32046 if(domainId() < noDomains() - 1) {
32047 for(
MInt snd = domainId() + 1; snd < noDomains(); snd++) {
32048 if(m_noPeriodicCellsDom[snd] > 0) {
32049 MInt bufSize = m_noPeriodicCellsDom[snd] * m_noPeriodicCellData;
32050 MPI_Irecv(m_periodicCellDataDom[snd], bufSize, MPI_DOUBLE, snd, 0, mpiComm(), &recv_Req[snd], AT_,
32051 "m_periodicCellDataDom[snd]");
32056 MPI_Waitall(noDomains(), &recv_Req[0], MPI_STATUSES_IGNORE, AT_);
32057 MPI_Waitall(noDomains(), &send_Req[0], MPI_STATUSES_IGNORE, AT_);
32061 MFloat c_x, c_y, c_z, c_x_rot, c_y_rot, c_z_rot;
32062 MBool rotated =
false;
32063 MBool found =
false;
32065 MInt rot_counter = 0;
32068 m_fvBndryCnd->recorrectCellCoordinates();
32071 m_log <<
"*************************" << endl;
32072 m_log <<
"Build Tree" << endl;
32073 m_log <<
"*************************" << endl;
32076 const MInt maxNoNghbrs_ = 45;
32082 MInt noCells = noInternalCells();
32084 vector<Point<3>> pts;
32085 for(
MInt cellId = 0; cellId < noCells; ++cellId) {
32086 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) && !a_isBndryGhostCell(cellId) && !a_isHalo(cellId)
32087 && c_isLeafCell(cellId)) {
32088 Point<3> a(a_coordinate(cellId, 0), a_coordinate(cellId, 1), a_coordinate(cellId, 2), cellId);
32096 MFloat eps_ = c_cellLengthAtLevel(maxRefinementLevel()) / 100.0;
32099 m_log <<
"*************************" << endl;
32100 m_log <<
"Tree Built" << endl;
32101 m_log <<
"*************************" << endl;
32104 for(
MInt domain = 0; domain < noDomains(); domain++) {
32105 for(
MInt cell = 0; cell < m_noPeriodicCellsDom[domain]; cell++) {
32108 c_x = m_periodicCellDataDom[domain][0 + m_noPeriodicCellData * cell];
32109 c_y = m_periodicCellDataDom[domain][1 + m_noPeriodicCellData * cell];
32110 c_z = m_periodicCellDataDom[domain][2 + m_noPeriodicCellData * cell];
32113 z_min_45 = -c_y + 400 - c_cellLengthAtLevel(minLevel()) / 10.0;
32115 if(m_periodicCells == 1) {
32116 if(c_z < z_min_45) {
32120 c_y_rot = cos(72.0 / 180.0 * PI) * (c_y - m_rotAxisCoord[0])
32121 + sin(72.0 / 180.0 * PI) * (c_z - m_rotAxisCoord[1]) + m_rotAxisCoord[0];
32122 c_z_rot = -sin(72.0 / 180.0 * PI) * (c_y - m_rotAxisCoord[0])
32123 + cos(72.0 / 180.0 * PI) * (c_z - m_rotAxisCoord[1]) + m_rotAxisCoord[1];
32125 m_periodicCellDataDom[domain][1 + m_noPeriodicCellData * cell] = c_y_rot;
32126 m_periodicCellDataDom[domain][2 + m_noPeriodicCellData * cell] = c_z_rot;
32130 z_min_1 = -6.3137515147 * c_y + 1462.750302935;
32131 z_min_2 = -0.1583844403 * c_y + 231.6768880649;
32134 if((c_z >= (z_min_2 - eps_) && c_z <= (z_min_1 + eps_) && c_y <= m_rotAxisCoord[0])
32135 || rot_counter == 2
32144 c_y_rot = cos(72.0 / 180.0 * PI) * (c_y - m_rotAxisCoord[0])
32145 - sin(72.0 / 180.0 * PI) * (c_z - m_rotAxisCoord[1]) + m_rotAxisCoord[0];
32146 c_z_rot = +sin(72.0 / 180.0 * PI) * (c_y - m_rotAxisCoord[0])
32147 + cos(72.0 / 180.0 * PI) * (c_z - m_rotAxisCoord[1]) + m_rotAxisCoord[0];
32149 m_periodicCellDataDom[domain][1 + m_noPeriodicCellData * cell] = c_y_rot;
32150 m_periodicCellDataDom[domain][2 + m_noPeriodicCellData * cell] = c_z_rot;
32154 z_min_1 = -6.3137515147 * c_y + 1462.750302935;
32155 z_min_2 = -0.1583844403 * c_y + 231.6768880649;
32157 if((c_z >= (z_min_2 - eps_) && c_z <= (z_min_1 + eps_) && c_y <= m_rotAxisCoord[0])
32158 || rot_counter == 2
32164 }
else if(m_periodicCells == 2 || m_periodicCells == 3) {
32168 c_x_rot = periodic_coord[1] - (periodic_coord[0] - c_x);
32171 m_periodicCellDataDom[domain][0 + m_noPeriodicCellData * cell] = c_x_rot;
32175 c_x_rot = (c_x - periodic_coord[1]) + periodic_coord[0];
32178 m_periodicCellDataDom[domain][0 + m_noPeriodicCellData * cell] = c_x_rot;
32183 if((c_x >= xmin && c_x <= xmax) && (c_y >= ymin) && (c_y <= ymax) && (c_z >= zmin) && (c_z <= zmax)) {
32184 distance = -1.1111;
32187 MFloat delta_x = fabs(a_coordinate(cI, 0) - c_x - eps_);
32188 MFloat delta_y = fabs(a_coordinate(cI, 1) - c_y);
32189 MFloat delta_z = fabs(a_coordinate(cI, 2) - c_z);
32191 halfLength = c_cellLengthAtLevel(a_level(cI) + 1);
32193 if(distance < 0.0) {
32194 mTerm(1, AT_,
"negative distance");
32196 if(delta_x <= halfLength && delta_y <= halfLength && delta_z <= halfLength && distance >= 0.0) {
32198 m_periodicCellDataDom[domain][3 + m_noPeriodicCellData * cell] = cI;
32199 m_periodicCellDataDom[domain][4 + m_noPeriodicCellData * cell] =
32200 m_periodicCellDataDom[domain][4 + m_noPeriodicCellData * cell] * rot_counter;
32202 if(rot_counter > 2 || rot_counter < -2) {
32207 }
else if((delta_x > halfLength || delta_y > halfLength || delta_z > halfLength)
32208 && distance <= 8.0 * halfLength) {
32210 counter_ = getAdjacentLeafCells<2, false>(cI, 1, nghbrList_, layerId_);
32212 for(
MInt k = 0; k < counter_; k++) {
32213 MInt nghbr_Id = nghbrList_[k];
32217 if(!a_hasProperty(nghbr_Id, SolverCell::IsOnCurrentMGLevel)) {
32220 if(a_isBndryGhostCell(nghbr_Id)) {
32223 if(a_isHalo(nghbr_Id)) {
32226 if(c_noChildren(nghbr_Id) != 0) {
32229 delta_x = fabs(a_coordinate(nghbr_Id, 0) - c_x - eps_);
32230 delta_y = fabs(a_coordinate(nghbr_Id, 1) - c_y);
32231 delta_z = fabs(a_coordinate(nghbr_Id, 2) - c_z);
32234 halfLength = c_cellLengthAtLevel(a_level(nghbr_Id) + 1);
32235 if(delta_x <= halfLength && delta_y <= halfLength && delta_z <= halfLength) {
32237 m_periodicCellDataDom[domain][3 + m_noPeriodicCellData * cell] = nghbr_Id;
32238 m_periodicCellDataDom[domain][4 + m_noPeriodicCellData * cell] =
32239 m_periodicCellDataDom[domain][4 + m_noPeriodicCellData * cell]
32242 if(rot_counter > 2 || rot_counter < -2) {
32254 m_periodicCellDataDom[domain][3 + m_noPeriodicCellData * cell] = -1;
32255 m_periodicCellDataDom[domain][4 + m_noPeriodicCellData * cell] =
32256 m_periodicCellDataDom[domain][4 + m_noPeriodicCellData * cell] * rot_counter;
32257 if(noDomains() == 1) {
32258 cout <<
"nothing found: " << domainId() <<
" cx: " << c_x <<
" cy: " << c_y <<
" cz: " << c_z
32259 <<
" cx_r: " << c_x <<
" cy_r: " << c_y <<
" cz_r: " << c_z << endl;
32260 mTerm(1, AT_,
"NOTHING FOUND");
32268 m_fvBndryCnd->rerecorrectCellCoordinates();
32274 m_noPerCellsToSend =
new MInt[noDomains()];
32275 m_noPerCellsToReceive =
new MInt[noDomains()];
32278 for(
MInt dom = 0; dom < noDomains(); dom++) {
32279 m_noPerCellsToSend[dom] = 0;
32280 for(
MInt c = 0; c < m_noPeriodicCellsDom[dom]; c++) {
32281 if(m_periodicCellDataDom[dom][3 + m_noPeriodicCellData * c] >= 0) {
32282 m_noPerCellsToSend[dom] = m_noPerCellsToSend[dom] + 1;
32287 m_noPerCellsToReceive[domainId()] = m_noPerCellsToSend[domainId()];
32289 for(
MInt dom = 0; dom < noDomains(); dom++) {
32297 for(
MInt snd = 0; snd < domainId(); snd++) {
32298 MPI_Recv(&m_noPerCellsToReceive[snd], 1, MPI_INT, snd, 0, mpiComm(), &status, AT_,
"m_noPerCellsToReceive[snd]");
32300 for(
MInt rcv = 0; rcv < noDomains(); rcv++) {
32301 if(rcv != domainId()) {
32302 MPI_Send(&m_noPerCellsToSend[rcv], 1, MPI_INT, rcv, 0, mpiComm(), AT_,
"m_noPerCellsToSend[rcv]");
32306 if(domainId() < noDomains() - 1) {
32307 for(
MInt snd = domainId() + 1; snd < noDomains(); snd++) {
32308 MPI_Recv(&m_noPerCellsToReceive[snd], 1, MPI_INT, snd, 0, mpiComm(), &status, AT_,
"m_noPerCellsToReceive[snd]");
32313 for(
MInt dom = 0; dom < noDomains(); dom++) {
32319 m_log <<
"*************************" << endl;
32320 m_log <<
"AllocateMemory 2" << endl;
32321 m_log <<
"*************************" << endl;
32325 m_periodicDataToSend =
new MFloat*[noDomains()];
32327 m_noPeriodicCellData = PV->noVariables;
32328 m_noPeriodicData = m_noPeriodicCellData + 2;
32332 for(
MInt dom = 0; dom < noDomains(); dom++) {
32333 m_periodicDataToSend[dom] =
new MFloat[m_noPerCellsToSend[dom] * m_noPeriodicData];
32337 m_periodicDataToReceive =
new MFloat*[noDomains()];
32339 for(
MInt dom = 0; dom < noDomains(); dom++) {
32340 m_periodicDataToReceive[dom] =
new MFloat[m_noPerCellsToReceive[dom] * m_noPeriodicData];
32345 for(
MInt dom = 0; dom < noDomains(); dom++) {
32347 for(
MInt c = 0; c < m_noPeriodicCellsDom[dom]; c++) {
32348 if(m_periodicCellDataDom[dom][3 + m_noPeriodicCellData * c] >= 0) {
32350 m_periodicDataToSend[dom][5 + counting * m_noPeriodicData] = c;
32351 m_periodicDataToSend[dom][6 + counting * m_noPeriodicData] =
32352 m_periodicCellDataDom[dom][3 + m_noPeriodicCellData * c];
32358 m_log <<
"*************************" << endl;
32359 m_log <<
"Connectivity Matrix created" << endl;
32360 m_log <<
"*************************" << endl;
32366template <MInt nDim_,
class SysEqn>
32370 IF_CONSTEXPR(nDim == 2)
32371 mTerm(1,
"By now only used in 3D. If you want to use it in 2D,"
32372 " just remove this warning.");
32378 MInt noCells = noInternalCells();
32381 for(
MInt id = 0;
id < noCells;
id++) {
32387 if(a_bndryId(
id) == -1) {
32388 for(
MInt dir = 0; dir < m_noDirs; dir++) {
32389 if(a_hasNeighbor(
id, dir) > 0) {
32390 nghbrId = c_neighborId(
id, dir);
32391 if(a_bndryId(nghbrId) > -1) {
32395 if(c_parentId(
id) == -1) {
32397 }
else if(a_hasNeighbor(c_parentId(
id), dir) == 0) {
32402 if(noNghbr && bndNghbr && !a_isPeriodic(
id) && !a_hasProperty(
id, SolverCell::IsCutOff)
32403 && !a_hasProperty(
id, SolverCell::IsNotGradient) && c_noChildren(
id) == 0) {
32404 a_hasProperty(
id, SolverCell::IsInvalid) =
true;
32406 m_log <<
id <<
" is invalid";
32407 for(
MInt spaceId = 0; spaceId < nDim; spaceId++)
32408 m_log <<
" " << a_coordinate(
id, spaceId);
32410 m_log << a_isInterface(
id) <<
" " << a_isPeriodic(
id) <<
" " << a_hasProperty(
id, SolverCell::IsCutOff) << endl;
32411 for(
MInt dir = 0; dir < m_noDirs; dir++) {
32412 if(a_hasNeighbor(
id, dir) > 0) {
32413 m_log <<
"direction " << dir <<
" " << c_neighborId(
id, dir) <<
" " << a_bndryId(c_neighborId(
id, dir))
32417 a_variable(
id, CV->RHO) = 2.0;
32439template <MInt nDim_,
class SysEqn>
32443 MFloat& Strouhal = m_static_crankAngle_Strouhal;
32444 MFloat& initialCad = m_static_crankAngle_initialCad;
32446 if(initialCad < 0) {
32447 Strouhal = Context::getSolverProperty<MFloat>(
"Strouhal", m_solverId, AT_, &Strouhal);
32449 initialCad = Context::getSolverProperty<MFloat>(
"initialCrankAngle", m_solverId, AT_, &initialCad);
32457template <MInt nDim_,
class SysEqn>
32459 IF_CONSTEXPR(nDim == 3) {
mTerm(1,
"Only available in 2D."); }
32461 computeSamplingTimeStep_();
32471template <MInt nDim_,
class SysEqn>
32475 if(m_timeStepMethod != 17511 && !m_combustion) {
32477 "this function should only be called with timeStepMethod 17511 "
32478 "and combustion enabled");
32481 if(!m_combustion) {
32482 stringstream errorMessage;
32483 errorMessage <<
"ERROR: combustion is turned off, this time step method is especially written "
32484 "for combustion cases ... exiting";
32485 mTerm(1, AT_, errorMessage.str());
32489 MFloat cycleTime, sampleTime;
32491 const MFloat slOverU = m_flameSpeed / m_MaFlameTube;
32492 const MFloat Lf = m_realRadiusFlameTube * tan(acos(slOverU));
32494 const MFloat slantLength = Af * F1B2;
32495 const MFloat rLaminarFlameThickness = 1. / m_laminarFlameThickness;
32496 MFloat rFlameSpeed = 1. / m_flameSpeed;
32497 MFloat DInfinityFlameTube = SUTHERLANDLAW(m_temperatureFlameTube);
32498 MFloat ReFl = m_rPr * rLaminarFlameThickness * DInfinityFlameTube * m_MaFlameTube
32501 MFloat sigma = m_subfilterVariance * c_cellLengthAtLevel(maxRefinementLevel());
32510 cycleTime = (F2 * PI) / m_flameStrouhal;
32511 sampleTime = cycleTime / m_samplesPerCycle;
32514 m_log <<
"*****************************" << endl;
32515 m_log <<
"2D Flame test case properties" << endl;
32516 m_log <<
"*****************************" << endl << endl;
32517 m_log <<
"flame tube radius (used for levelSet BC): " << m_radiusFlameTube << endl;
32518 m_log <<
"flame tube real radius: " << m_realRadiusFlameTube << endl;
32519 m_log <<
"nominal flame length L_f: " << Lf << endl;
32520 m_log <<
"nominal slant flame length: " << slantLength << endl;
32521 m_log <<
"nominal flame surface area: " << Af << endl;
32522 m_log <<
"uncurved flame tip angle in Grad: " << atan(m_realRadiusFlameTube / Lf) * 180. / PI << endl;
32523 m_log <<
"laminar flame speed: " << m_flameSpeed << endl;
32524 m_log <<
"laminar flame thickness: " << m_laminarFlameThickness << endl;
32525 m_log <<
"subfilter variance sigma: " << sigma << endl;
32526 m_log <<
"******************************" << endl;
32527 m_log <<
"Corrugated Flamelet regime:" << endl;
32528 m_log <<
"lf < l_kolmogorov -> Ka_F < 1" << endl;
32529 m_log <<
"******************************" << endl;
32530 if(domainId() == 0) {
32531 cerr <<
"*****************************" << endl;
32532 cerr <<
"2D Flame test case properties" << endl;
32533 cerr <<
"*****************************" << endl << endl;
32534 cerr <<
"flame tube radius (used for levelSet BC): " << m_radiusFlameTube << endl;
32535 cerr <<
"flame tube real radius: " << m_realRadiusFlameTube << endl;
32536 cerr <<
"nominal flame length L_f: " << Lf << endl;
32537 cerr <<
"nominal slant flame length: " << slantLength << endl;
32538 cerr <<
"nominal flame surface area: " << Af << endl;
32539 cerr <<
"uncurved flame tip angle in Grad: " << atan(m_realRadiusFlameTube / Lf) * 180. / PI << endl;
32540 cerr <<
"laminar flame speed: " << m_flameSpeed << endl;
32541 cerr <<
"laminar flame thickness: " << m_laminarFlameThickness << endl;
32542 cerr <<
"subfilter variance sigma: " << sigma << endl;
32545 if((m_subfilterVariance < m_laminarFlameThickness)) {
32546 m_log <<
"+Case 1: sigma (=filter size) < laminar flame thickness" << endl;
32547 m_log <<
" *Conclusion: flame is resolved -> filtered flame thickness = laminar flame thickness" << endl;
32548 m_log <<
" *Conclusion: no turbulent contribution" << endl;
32549 m_log <<
" *Info: filtered flame speed s_F = s_l laminar flame speed" << endl;
32550 m_log <<
" *Info: Dth_turb,F (subfilter eddy diffusivity) = Dth_lam (laminar diffusivity) " << endl;
32552 m_log <<
"+Case 2: sigma (=filter size) > laminar flame thickness" << endl;
32553 m_log <<
" *Conclusion: sub-filter flame front wrinkling increases the resolved burning velocity" << endl;
32554 m_log <<
" *Conclusion: filtered flame speed s_F > s_l (laminar flame speed)" << endl;
32555 m_log <<
" *Info: if the flame front is not altered by turbulence," << endl;
32556 m_log <<
" the chemical time scale of the turbulent flame time_c_F" << endl;
32557 m_log <<
" remains the same as the laminar one time_c" << endl;
32560 m_log <<
"mach number inlet: " << m_Ma << endl;
32561 m_log <<
"mach number in flame tube: " << m_MaFlameTube << endl;
32562 m_log <<
"Re (ref. to stagnation point): " << sysEqn().m_Re0 << endl;
32563 m_log <<
"Re (ref. to infinity values): " << m_Re << endl;
32564 m_log <<
"Re (ref. to the flame properties): " << ReFl << endl;
32565 if((ReFl < (m_Re - 10.0)) || (ReFl > (m_Re + 10.0))) {
32566 if(domainId() == 0) {
32567 cerr <<
"Warning: Your Reynolds number should be Re= " << ReFl <<
" , but it is chosen to Re= " << m_Re << endl;
32569 m_log <<
"Warning: Your Reynolds number should be Re= " << ReFl <<
" , but it is chosen to Re= " << m_Re << endl;
32571 m_log <<
"Re (ref. to the flame properties and to the flame tube diameter): " << ReFl * F2 * m_realRadiusFlameTube
32573 m_log <<
"markstein length (controls the flame curvature): " << m_marksteinLength << endl;
32583 m_log <<
"CFL number: " << m_cfl << endl;
32584 m_log <<
"smallest Cell distance according to max refinement Level: " << c_cellLengthAtLevel(maxRefinementLevel())
32586 m_log.precision(16);
32587 m_log <<
"reference time (=u_0): " << m_timeRef << endl;
32588 m_log <<
"time step according to the CFL condition: " << timeStep(
true) * m_timeRef << endl;
32589 m_log.precision(9);
32591 m_log <<
"cycleTime (nondim): " << cycleTime << endl;
32592 m_log <<
"sampleTime (nondim): " << sampleTime << endl;
32593 if(m_structuredFlameOutput || m_forcing) {
32594 m_noTimeStepsBetweenSamples = 0;
32595 for(
MInt n = 1; n < 10000000; n++) {
32596 if(sampleTime / (
MFloat)(n) < timeStep(
true)) {
32597 forceTimeStep(sampleTime / (
MFloat)(n));
32598 m_noTimeStepsBetweenSamples = n;
32602 sampleTime = m_noTimeStepsBetweenSamples * timeStep(
true);
32603 cycleTime = sampleTime * m_samplesPerCycle;
32605 if(m_noTimeStepsBetweenSamples == 0) {
32606 mTerm(1, AT_,
"Time step calculation error");
32609 if(m_neutralFlameStrouhal > 0) {
32610 flameStr = m_neutralFlameStrouhal * Lf / (F2 * PI);
32611 if(domainId() == 0) {
32612 cerr <<
"Be careful, strouhal number is based on length one, not on flame length (for "
32613 "neutral markstein length computation) "
32615 cerr <<
"time step due to sampling (depends on the Strouhal number) (phys): " << timeStep(
true) * m_timeRef
32617 cerr <<
"Excitation frequency f = " << m_neutralFlameStrouhal / (F2 * PI) << endl;
32618 cerr <<
"Excitation frequency f (phys) = " << m_neutralFlameStrouhal / (F2 * PI * m_timeRef) << endl;
32619 cerr <<
"flame Strouhal number Stf (based on Lf) = " << flameStr << endl;
32620 cerr <<
"flame Strouhal number Stf (based on Lf phys) = " << flameStr / m_timeRef << endl;
32621 cerr <<
"check flame Strouhal number Stf = 1/t * Lf / u_mean = " << 1. / cycleTime * Lf << endl;
32623 m_log <<
"time step due to sampling (depends on the Strouhal number) (phys): " << timeStep(
true) * m_timeRef
32625 m_log <<
"Excitation frequency f = " << m_neutralFlameStrouhal / (F2 * PI) << endl;
32626 m_log <<
"Excitation frequency f (phys) = " << m_neutralFlameStrouhal / (F2 * PI * m_timeRef) << endl;
32627 m_log <<
"flame Strouhal number Stf (based on Lf) = " << flameStr << endl;
32628 m_log <<
"flame Strouhal number Stf (based on Lf phys) = " << flameStr / m_timeRef << endl;
32629 m_log <<
"check flame Strouhal number Stf = 1/t * Lf / u_mean= " << 1. / cycleTime * Lf << endl;
32630 if(((flameStr < (1. / cycleTime * Lf - 0.05)) || (flameStr > (1. / cycleTime * Lf + 0.05))) && domainId() == 0) {
32631 cerr <<
"Warning: Your flame strouhal is = " << flameStr <<
" , but it is checked to = " << 1. / cycleTime * Lf
32634 m_log <<
"wave number (based on length one!!) omega=St/1.0: " << m_flameStrouhal
32636 m_log <<
"wave number (based on length one!!) omega=St/1.0 (phys): " << m_flameStrouhal / m_timeRef
32638 if(domainId() == 0) {
32639 cerr <<
"wave number (based on length one!!) omega=St/1.0: " << m_flameStrouhal
32641 cerr <<
"wave number (based on length one!!) omega=St/1.0 (phys): " << m_flameStrouhal / m_timeRef
32645 flameStr = m_flameStrouhal / (F2 * PI);
32646 m_log <<
"time step due to sampling (depends on the Strouhal number) (phys): " << timeStep(
true) * m_timeRef
32648 m_log <<
"Excitation frequency f = " << m_strouhal / (F2 * PI) << endl;
32649 m_log <<
"flame Strouhal number Stf (based on Lf) = " << flameStr << endl;
32650 m_log <<
"check flame Strouhal number Stf = 1/t * Lf / u_mean = " << 1. / cycleTime * Lf << endl;
32651 m_log <<
"wave number (based on flame length!!) omega=St/L_f: " << m_flameStrouhal << endl;
32653 if(domainId() == 0) {
32654 cerr <<
"time step due to sampling (depends on the Strouhal number) (phys): " << timeStep(
true) * m_timeRef
32656 cerr <<
"Excitation frequency f = " << m_strouhal / (F2 * PI) << endl;
32657 cerr <<
"flame Strouhal number Stf (based on Lf) = " << flameStr << endl;
32658 cerr <<
"check flame Strouhal number Stf = 1/t * Lf / u_mean = " << 1. / cycleTime * Lf << endl;
32659 cerr <<
"wave number (based on flame length!!) omega=St/L_f: " << m_flameStrouhal << endl;
32664 m_log <<
"excitation amplitude at the inlet: " << m_forcingAmplitude * m_VInfinity << endl;
32665 m_log <<
"excitation amplitude in the flame tube: " << m_forcingAmplitude * m_VInfinity * m_inletTubeAreaRatio
32667 m_log <<
"excitation amplitude in the flame tube in % (ref. to the laminar flame speed): "
32668 << m_forcingAmplitude * m_VInfinity * m_inletTubeAreaRatio / m_flameSpeed * 100.0 <<
" %" << endl;
32669 m_log <<
"excitation amplitude in the flame tube in % (ref. to inflow velocity): "
32670 << m_forcingAmplitude * m_VInfinity * m_inletTubeAreaRatio * 100.0 <<
" %" << endl;
32672 if(domainId() == 0) {
32673 cerr <<
"excitation amplitude at the inlet: " << m_forcingAmplitude * m_VInfinity << endl;
32674 cerr <<
"excitation amplitude in the flame tube: " << m_forcingAmplitude * m_VInfinity * m_inletTubeAreaRatio
32676 cerr <<
"excitation amplitude in the flame tube in % (ref. to the laminar flame speed): "
32677 << m_forcingAmplitude * m_VInfinity * m_inletTubeAreaRatio / m_flameSpeed * 100.0 <<
" %" << endl;
32678 cerr <<
"excitation amplitude in the flame tube in % (ref. to inflow velocity): "
32679 << m_forcingAmplitude * m_inletTubeAreaRatio * 100.0 <<
" %" << endl;
32681 if(m_samplingStartIteration < 0) {
32682 cerr <<
"ERROR: set samplingStartIteration to some value" << endl;
32685 m_samplingStartCycle = (
MInt)(m_samplingStartIteration / (m_samplesPerCycle * m_noTimeStepsBetweenSamples));
32691 m_samplingEndCycle = m_samplingStartCycle + m_noSamplingCycles;
32693 if(m_structuredFlameOutput && m_forcing) {
32694 switch(m_structuredFlameOutputLevel) {
32696 m_log <<
"Warning: structured Output on finest level because unknown "
32697 "structuredFlameOutputLevel"
32699 if(domainId() == 0) {
32700 cerr <<
"Warning: structured Output on finest level because unknown "
32701 "structuredFlameOutputLevel"
32706 if(domainId() == 0) {
32707 cerr <<
"Warning: structuredFlameOutput is on, but structuredOuputLevel is set to "
32708 << m_structuredFlameOutputLevel << endl;
32709 cerr <<
"Warning: no structured Output" << endl;
32711 m_log <<
"Warning: structuredFlameOutput is on, but structuredOuputLevel is set to "
32712 << m_structuredFlameOutputLevel << endl;
32713 m_log <<
"Warning: no structured Output" << endl;
32716 m_log <<
"structured Output for single flame (old version): " << endl;
32719 m_log <<
"structured Output for single flame (optimized version): " << endl;
32722 m_log <<
"structured Output for single flame with plenum (optimized version): " << endl;
32725 m_log <<
"structured Output for single flame with plenum, ascii output of whole domain "
32726 "(optimized version): "
32730 m_log <<
"structured Output for single flame with plenum, ascii output of whole domain + "
32731 "dPdT source tem (optimized version): "
32735 m_log <<
"unstructured Output for single flame, netcdf output of whole domain: " << endl;
32738 m_log <<
"cycleTime (nondim, adapted): " << cycleTime << endl;
32739 m_log <<
"sampleTime (nondim, adapted): " << sampleTime << endl;
32740 m_log <<
"number of timesteps between samples: " << m_noTimeStepsBetweenSamples << endl;
32741 m_log <<
"sampling Start cycle: " << m_samplingStartCycle << endl;
32742 m_log <<
" start flameSurfaceArea - Output at Iteration: "
32743 << m_samplingStartCycle * m_samplesPerCycle * m_noTimeStepsBetweenSamples << endl;
32744 m_log <<
" end flameSurfaceArea - Output at Iteration: "
32745 << m_samplingEndCycle * m_samplesPerCycle * m_noTimeStepsBetweenSamples << endl;
32747 if(domainId() == 0) {
32748 cerr <<
"cycleTime (nondim): " << cycleTime << endl;
32749 cerr <<
"sampleTime (nondim): " << sampleTime << endl;
32750 cerr <<
"number of timesteps between samples: " << m_noTimeStepsBetweenSamples << endl;
32751 cerr <<
"sampling Start cycle: " << m_samplingStartCycle << endl;
32752 cerr <<
" start flameSurfaceArea - Output at Iteration: "
32753 << m_samplingStartCycle * m_samplesPerCycle * m_noTimeStepsBetweenSamples << endl;
32754 cerr <<
" end flameSurfaceArea - Output at Iteration: "
32755 << m_samplingEndCycle * m_samplesPerCycle * m_noTimeStepsBetweenSamples << endl;
32758 if((
g_timeSteps + m_restartTimeStep) < m_samplingEndCycle * m_samplesPerCycle * m_noTimeStepsBetweenSamples) {
32759 if(!m_forceNoTimeSteps) {
32761 if(domainId() == 0) {
32762 cerr <<
"WARNING: timeSteps changed from : " <<
g_timeSteps;
32764 g_timeSteps = m_samplingEndCycle * m_samplesPerCycle * m_noTimeStepsBetweenSamples + 5000 - m_restartTimeStep;
32765 if(domainId() == 0) {
32771 m_log <<
"WARNING: timeSteps are NOT adapted to the required number of time steps (used "
32772 "for reference testcases)";
32773 if(domainId() == 0) {
32774 cerr <<
"WARNING: timeSteps are NOT adapted to the required number of time steps (used for "
32775 "reference testcases)";
32780 if(m_structuredFlameOutput && !m_forcing) {
32781 if(domainId() == 0) {
32782 cerr <<
"Warning: Forcing ist turned off, but structuredFlameOutput is on" << endl;
32784 m_log <<
"Warning: Forcing ist turned off, but structuredFlameOutput is on" << endl;
32785 switch(m_structuredFlameOutputLevel) {
32787 m_log <<
"Warning: structured Output on finest level because unknown "
32788 "structuredFlameOutputLevel"
32790 if(domainId() == 0) {
32791 cerr <<
"Warning: structured Output on finest level because unknown "
32792 "structuredFlameOutputLevel"
32797 if(domainId() == 0) {
32798 cerr <<
"Warning: structuredFlameOutput is on, but structuredOuputLevel is set to "
32799 << m_structuredFlameOutputLevel << endl;
32800 cerr <<
"Warning: no structured Output" << endl;
32802 m_log <<
"Warning: structuredFlameOutput is on, but structuredOuputLevel is set to "
32803 << m_structuredFlameOutputLevel << endl;
32804 m_log <<
"Warning: no structured Output" << endl;
32807 m_log <<
"structured Output for single flame (old version): " << endl;
32810 m_log <<
"structured Output for single flame (optimized version): " << endl;
32813 m_log <<
"structured Output for single flame with plenum (optimized version): " << endl;
32816 m_log <<
"structured Output for single flame, ascii output of whole domain (optimized "
32821 m_log <<
"structured Output for single flame with plenum, ascii output of whole domain "
32822 "+ dPdT source tem (optimized version): "
32826 m_log <<
"unstructured Output for single flame, netcdf output of whole domain: " << endl;
32829 m_log <<
"cycleTime: " << cycleTime << endl;
32830 m_log <<
"sampleTime: " << sampleTime << endl;
32831 m_log <<
"number of timesteps between samples: " << m_noTimeStepsBetweenSamples << endl;
32832 m_log <<
"sampling Start cycle: " << m_samplingStartCycle << endl;
32833 m_log <<
" start flameSurfaceArea - Output at Iteration: "
32834 << m_samplingStartCycle * m_samplesPerCycle * m_noTimeStepsBetweenSamples << endl;
32836 if(m_noTimeStepsBetweenSamples == -1) {
32838 "Error no time steps between samples is not calculated, prbably wron "
32839 "structuredFlameOutput");
32841 if(domainId() == 0) {
32842 cerr <<
"cycleTime: " << cycleTime << endl;
32843 cerr <<
"sampleTime: " << sampleTime << endl;
32844 cerr <<
"number of timesteps between samples: " << m_noTimeStepsBetweenSamples << endl;
32845 cerr <<
"sampling Start cycle: " << m_samplingStartCycle << endl;
32846 cerr <<
" start flameSurfaceArea - Output at Iteration: "
32847 << m_samplingStartCycle * m_samplesPerCycle * m_noTimeStepsBetweenSamples << endl;
32850 if(!m_structuredFlameOutput && m_forcing) {
32851 if(domainId() == 0) {
32852 cerr <<
"Warning: Forcing ist turned on, but structuredFlameOutput is off" << endl;
32853 cerr <<
"Warning: There will be no structured Output and no flameSurfaceArea - Output" << endl;
32855 m_log <<
"Warning: Forcing ist turned on, but structuredFlameOutput is off" << endl;
32856 m_log <<
"Warning: There will be no structured Output and no flameSurfaceArea - Output" << endl;
32859 m_log <<
"no structured Output, structuredFlameOutput= " << m_structuredFlameOutput << endl;
32863 for(
MInt bcId = 0; bcId < m_noSpongeBndryCndIds; bcId++) {
32864 bcSpId = m_spongeBndryCndIds[bcId];
32866 if(m_spongeTimeDependent[bcId]) {
32868 m_log <<
"*************************************************************" << endl;
32869 m_log <<
"Additional Information for time dependent sponge boundary Id: " << bcSpId << endl;
32870 m_log <<
"*************************************************************" << endl;
32871 m_log <<
"sponge end iteration= " << m_spongeEndIteration[bcId] << endl;
32872 m_log <<
"sigma_max(t=" << m_spongeEndIteration[bcId] <<
") = "
32873 << m_sigmaSpongeBndryId[bcId] / tanh(F1)
32875 - (m_spongeEndIteration[bcId] - m_spongeStartIteration[bcId])
32876 / (m_spongeEndIteration[bcId] - m_spongeStartIteration[bcId])))
32878 m_log <<
"sponge end time = " << m_spongeEndIteration[bcId] * (timeStep(
true) * m_timeRef) << endl << endl;
32883 if(m_forcing &&
approx(flameStr, -1.0, MFloatEps)) {
32884 mTerm(1, AT_,
"Error flame strouhal number based on Lf not determined");
32886 if(domainId() == 0) {
32888 datei = fopen(
"flameLog",
"a+");
32889 fprintf(datei,
" %-10.10f", sampleTime);
32890 fprintf(datei,
" %-10.10f", m_realRadiusFlameTube);
32891 fprintf(datei,
" %-10.10f", m_flameSpeed);
32892 fprintf(datei,
" %-10.10f", m_MaFlameTube);
32893 fprintf(datei,
" %-10.10f", m_timeRef);
32894 fprintf(datei,
" %-10.10f", flameStr);
32895 fprintf(datei,
" %-10.10f", m_forcingAmplitude);
32896 fprintf(datei,
" %-10.10f", m_rhoFlameTube);
32897 fprintf(datei,
" %-10.10f", m_Ma);
32898 fprintf(datei,
" %d", m_samplingStartCycle);
32899 fprintf(datei,
" %d", m_samplingEndCycle);
32900 fprintf(datei,
" %d", (
MInt)m_samplesPerCycle);
32901 fprintf(datei,
" %-10.10f", m_marksteinLength);
32902 fprintf(datei,
" %-10.10f", m_laminarFlameThickness);
32903 fprintf(datei,
" %-10.10f", ReFl);
32904 fprintf(datei,
" %-10.10f", m_burntUnburntTemperatureRatio);
32905 fprintf(datei,
" %-10.10f", m_flameStrouhal);
32906 fprintf(datei,
"\n");
32922template <MInt nDim_,
class SysEqn>
32924 IF_CONSTEXPR(nDim == 3)
mTerm(1,
"Not available in 3D.");
32926 if(!m_divergenceTreatment) {
32930 constexpr MInt index0[2] = {1, 0};
32931 const MInt noPVars = PV->noVariables;
32932 const MInt noData = m_surfaceVarMemory;
32933 const MInt noSurfaces = a_noSurfaces();
32934 const MInt slopeMemory = m_slopeMemory;
32935 const MFloat gammaMinusOne = m_gamma - 1.0;
32936 const MFloat FgammaMinusOne = F1 / gammaMinusOne;
32937 const MFloat gFGMO = m_gamma * FgammaMinusOne;
32938 MInt* nghbrs = (
MInt*)(&(a_surfaceNghbrCellId(0, 0)));
32940 MFloat* area = &a_surfaceArea(0);
32942 MFloat* var = (
MFloat*)(&(a_surfaceVariable(0, 0, 0)));
32950 const MFloat rhoUDth = sysEqn().m_muInfinity * m_rPr;
32952 for(
MInt srfcId = 0; srfcId < noSurfaces; srfcId++) {
32955 const MInt i = srfcId * noData;
32956 const MFloat u = F1B2 * (var[i] + var[i + noPVars]);
32957 const MFloat v = F1B2 * (var[i + 1] + var[i + noPVars + 1]);
32958 const MFloat rho = F1B2 * (var[i + 2] + var[i + noPVars + 2]);
32959 const MFloat Frho = F1 / rho;
32960 const MFloat p = F1B2 * (var[i + 3] + var[i + noPVars + 3]);
32963 const MFloat T = sysEqn().temperature_ES(rho, p);
32966 const MInt id0 = a_surfaceOrientation(srfcId);
32967 const MInt id1 = index0[id0];
32970 const MFloat dAOverRe0 = area[srfcId] * m_rRe0;
32973 const MFloat mue = SUTHERLANDLAW(T);
32975 const MFloat lambda = m_rPr * mue;
32979 lambda * gFGMO * Frho
32980 * ((a_surfaceFactor(srfcId, 0) * slope[nghbrs[2 * srfcId] * slopeMemory + PV->P * nDim + id0]
32981 + a_surfaceFactor(srfcId, 1) * slope[nghbrs[2 * srfcId + 1] * slopeMemory + PV->P * nDim + id0])
32983 * (a_surfaceFactor(srfcId, 0) * slope[nghbrs[2 * srfcId] * slopeMemory + PV->RHO * nDim + id0]
32984 + a_surfaceFactor(srfcId, 1) * slope[nghbrs[2 * srfcId + 1] * slopeMemory + PV->RHO * nDim + id0]));
32995 if(m_divergenceTreatment) {
32996 if(a_surfaceCoordinate(srfcId, 1) < 0.0341) {
32999 * (a_surfaceFactor(srfcId, 0) * (F2 * slope[nghbrs[2 * srfcId] * slopeMemory + id0 * nDim + id0])
33000 + a_surfaceFactor(srfcId, 1) * (F2 * slope[nghbrs[2 * srfcId + 1] * slopeMemory + id0 * nDim + id0]));
33003 * (a_surfaceFactor(srfcId, 0)
33004 * (slope[nghbrs[2 * srfcId] * slopeMemory + id0 * nDim + id1]
33005 + slope[nghbrs[2 * srfcId] * slopeMemory + id1 * nDim + id0])
33006 + a_surfaceFactor(srfcId, 1)
33007 * (slope[nghbrs[2 * srfcId + 1] * slopeMemory + id0 * nDim + id1]
33008 + slope[nghbrs[2 * srfcId + 1] * slopeMemory + id1 * nDim + id0]));
33013 * (a_surfaceFactor(srfcId, 0)
33014 * (F4B3 * slope[nghbrs[2 * srfcId] * slopeMemory + id0 * nDim + id0]
33015 - F2B3 * (slope[nghbrs[2 * srfcId] * slopeMemory + id1 * nDim + id1]))
33016 + a_surfaceFactor(srfcId, 1)
33017 * (F4B3 * slope[nghbrs[2 * srfcId + 1] * slopeMemory + id0 * nDim + id0]
33018 - F2B3 * (slope[nghbrs[2 * srfcId + 1] * slopeMemory + id1 * nDim + id1])));
33021 * (a_surfaceFactor(srfcId, 0)
33022 * (slope[nghbrs[2 * srfcId] * slopeMemory + id0 * nDim + id1]
33023 + slope[nghbrs[2 * srfcId] * slopeMemory + id1 * nDim + id0])
33024 + a_surfaceFactor(srfcId, 1)
33025 * (slope[nghbrs[2 * srfcId + 1] * slopeMemory + id0 * nDim + id1]
33026 + slope[nghbrs[2 * srfcId + 1] * slopeMemory + id1 * nDim + id0]));
33031 * (a_surfaceFactor(srfcId, 0)
33032 * (F4B3 * slope[nghbrs[2 * srfcId] * slopeMemory + id0 * nDim + id0]
33033 - F2B3 * (slope[nghbrs[2 * srfcId] * slopeMemory + id1 * nDim + id1]))
33034 + a_surfaceFactor(srfcId, 1)
33035 * (F4B3 * slope[nghbrs[2 * srfcId + 1] * slopeMemory + id0 * nDim + id0]
33036 - F2B3 * (slope[nghbrs[2 * srfcId + 1] * slopeMemory + id1 * nDim + id1])));
33039 * (a_surfaceFactor(srfcId, 0)
33040 * (slope[nghbrs[2 * srfcId] * slopeMemory + id0 * nDim + id1]
33041 + slope[nghbrs[2 * srfcId] * slopeMemory + id1 * nDim + id0])
33042 + a_surfaceFactor(srfcId, 1)
33043 * (slope[nghbrs[2 * srfcId + 1] * slopeMemory + id0 * nDim + id1]
33044 + slope[nghbrs[2 * srfcId + 1] * slopeMemory + id1 * nDim + id0]));
33055 a_surfaceFlux(srfcId, FV->RHO_U) -= dAOverRe0 * tau.
p[0];
33056 a_surfaceFlux(srfcId, FV->RHO_V) -= dAOverRe0 * tau.
p[1];
33057 IF_CONSTEXPR(hasE<SysEqn>)
33058 a_surfaceFlux(srfcId, FV->RHO_E) -= dAOverRe0 * (u * tau.
p[0] + v * tau.
p[1] + q);
33062 a_surfaceFlux(srfcId, FV->RHO_C) -=
33063 dAOverRe0 * rhoUDth
33064 * (a_surfaceFactor(srfcId, 0) * slope[nghbrs[2 * srfcId] * slopeMemory + PV->C * nDim + id0]
33065 + a_surfaceFactor(srfcId, 1) * slope[nghbrs[2 * srfcId + 1] * slopeMemory + PV->C * nDim + id0]);
33075template <MInt nDim_,
class SysEqn>
33077 IF_CONSTEXPR(nDim == 3)
mTerm(1,
"Not available in 3D.");
33081 MInt index0[2] = {1, 0};
33082 const MInt noPVars = PV->noVariables;
33083 const MInt noData = m_surfaceVarMemory;
33084 const MInt noSurfaces = a_noSurfaces();
33085 const MInt slopeMemory = m_slopeMemory;
33089 const MFloat gammaMinusOne = m_gamma - 1.0;
33090 const MFloat FgammaMinusOne = F1 / gammaMinusOne;
33091 const MFloat gFGMO = m_gamma * FgammaMinusOne;
33094 MInt* nghbrs = (
MInt*)(&(a_surfaceNghbrCellId(0, 0)));
33096 MFloat* area = &a_surfaceArea(0);
33098 MFloat* var = (
MFloat*)(&(a_surfaceVariable(0, 0, 0)));
33103 rhoUDth = m_DthInfinity * m_rhoFlameTube;
33105 for(
MInt srfcId = 0; srfcId < noSurfaces; srfcId++) {
33108 i = srfcId * noData;
33109 u = F1B2 * (var[i] + var[i + noPVars]);
33110 v = F1B2 * (var[i + 1] + var[i + noPVars + 1]);
33111 rho = F1B2 * (var[i + 2] + var[i + noPVars + 2]);
33113 p = F1B2 * (var[i + 3] + var[i + noPVars + 3]);
33116 T = sysEqn().temperature_ES(rho, p);
33119 id0 = a_surfaceOrientation(srfcId);
33123 dAOverRe0 = area[srfcId] * m_rRe0;
33126 mue = SUTHERLANDLAW(T);
33128 lambda = m_rPr * mue;
33131 q = lambda * gFGMO * Frho
33132 * ((a_surfaceFactor(srfcId, 0) * slope[nghbrs[2 * srfcId] * slopeMemory + PV->P * nDim + id0]
33133 + a_surfaceFactor(srfcId, 1) * slope[nghbrs[2 * srfcId + 1] * slopeMemory + PV->P * nDim + id0])
33135 * (a_surfaceFactor(srfcId, 0) * slope[nghbrs[2 * srfcId] * slopeMemory + PV->RHO * nDim + id0]
33136 + a_surfaceFactor(srfcId, 1) * slope[nghbrs[2 * srfcId + 1] * slopeMemory + PV->RHO * nDim + id0]));
33149 * (a_surfaceFactor(srfcId, 0)
33150 * (F4B3 * slope[nghbrs[2 * srfcId] * slopeMemory + id0 * nDim + id0]
33151 - F2B3 * (slope[nghbrs[2 * srfcId] * slopeMemory + id1 * nDim + id1]))
33152 + a_surfaceFactor(srfcId, 1)
33153 * (F4B3 * slope[nghbrs[2 * srfcId + 1] * slopeMemory + id0 * nDim + id0]
33154 - F2B3 * (slope[nghbrs[2 * srfcId + 1] * slopeMemory + id1 * nDim + id1])));
33157 * (a_surfaceFactor(srfcId, 0)
33158 * (slope[nghbrs[2 * srfcId] * slopeMemory + id0 * nDim + id1]
33159 + slope[nghbrs[2 * srfcId] * slopeMemory + id1 * nDim + id0])
33160 + a_surfaceFactor(srfcId, 1)
33161 * (slope[nghbrs[2 * srfcId + 1] * slopeMemory + id0 * nDim + id1]
33162 + slope[nghbrs[2 * srfcId + 1] * slopeMemory + id1 * nDim + id0]));
33165 a_surfaceFlux(srfcId, FV->RHO_U) -= dAOverRe0 * tau.
p[0];
33166 a_surfaceFlux(srfcId, FV->RHO_V) -= dAOverRe0 * tau.
p[1];
33167 IF_CONSTEXPR(hasE<SysEqn>)
33168 a_surfaceFlux(srfcId, FV->RHO_E) -= dAOverRe0 * (u * tau.
p[0] + v * tau.
p[1] + q);
33172 a_surfaceFlux(srfcId, FV->RHO_C) -=
33173 dAOverRe0 * rhoUDth
33174 * (a_surfaceFactor(srfcId, 0) * slope[nghbrs[2 * srfcId] * slopeMemory + PV->C * nDim + id0]
33175 + a_surfaceFactor(srfcId, 1) * slope[nghbrs[2 * srfcId + 1] * slopeMemory + PV->C * nDim + id0]);
33181template <MInt nDim_,
class SysEqn>
33185 IF_CONSTEXPR(nDim == 3)
mTerm(-1,
"Info: untested in 3D. By now only used in 2D.");
33194 if(m_force1DFiltering) {
33195 for(
MInt id = 0;
id < m_noActiveCells;
id++) {
33196 const MInt cellId = m_activeCellIds[
id];
33197 a_variable(cellId, 0) = F0;
33202 for(
MInt id = 0;
id < m_noActiveCells;
id++) {
33203 const MInt cellId = m_activeCellIds[
id];
33205 if(c_noChildren(cellId) == 0) {
33208 MBool grandparent =
false;
33209 for(
MInt ch = 0; ch <
IPOW2(nDim); ch++) {
33210 if(c_childId(cellId, ch) == -1) {
33213 if(c_noChildren(c_childId(cellId, ch)) > 0) {
33214 grandparent =
true;
33222 for(
MInt varId = 0; varId < CV->noVariables; varId++) {
33223 a_variable(cellId, varId) = F0;
33225 for(
MInt ch = 0; ch <
IPOW2(nDim); ch++) {
33226 if(c_childId(cellId, ch) == -1) {
33229 for(
MInt varId = 0; varId < CV->noVariables; varId++) {
33230 a_variable(cellId, varId) += a_variable(c_childId(cellId, ch), varId);
33233 for(
MInt varId = 0; varId < CV->noVariables; varId++) {
33234 a_variable(cellId, varId) /= (
MFloat)c_noChildren(cellId);
33237 for(
MInt ch = 0; ch <
IPOW2(nDim); ch++) {
33238 if(c_childId(cellId, ch) == -1) {
33241 for(
MInt varId = 0; varId < CV->noVariables; varId++) {
33242 a_variable(c_childId(cellId, ch), varId) =
33243 F1B2 * (a_variable(c_childId(cellId, ch), varId) + a_variable(cellId, varId));
33356template <MInt nDim_,
class SysEqn>
33361 std::ignore = mode;
33367 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
33368 a_hasProperty(cellId, SolverCell::IsInvalid) =
false;
33369 a_hasProperty(cellId, SolverCell::IsPeriodicWithRot) =
false;
33372 grid().updateGridInfo();
33374 setCellProperties();
33377 generateBndryCells();
33379 IF_CONSTEXPR(nDim == 3) {
33380 if(m_fvBndryCnd->m_multipleGhostCells) {
33388 if(m_periodicCells == 0) {
33394 m_fvBndryCnd->correctCellCoordinates();
33401 m_fvBndryCnd->correctCoarseBndryCells();
33403 IF_CONSTEXPR(nDim == 3) {
33409 if(m_periodicCells == 1 || m_periodicCells == 2 || m_periodicCells == 3) identPeriodicCells();
33412 if(m_fvBndryCnd->m_multipleGhostCells) findNghbrIdsMGC();
33415 if(m_fvBndryCnd->m_cellMerging) {
33418 IF_CONSTEXPR(nDim == 2) {
33419 m_fvBndryCnd->detectSmallBndryCells();
33420 m_log <<
"Connecting master and slave cells...";
33421 m_fvBndryCnd->mergeCells();
33423 else IF_CONSTEXPR(nDim == 3) {
33424 if(m_fvBndryCnd->m_multipleGhostCells)
33425 m_fvBndryCnd->detectSmallBndryCellsMGC();
33427 m_fvBndryCnd->detectSmallBndryCells();
33428 m_log <<
"Connecting master and slave cells...";
33430 if(m_fvBndryCnd->m_multipleGhostCells)
33431 m_fvBndryCnd->mergeCellsMGC();
33433 m_fvBndryCnd->mergeCells();
33435 m_log <<
" found " << m_fvBndryCnd->m_smallBndryCells->size() <<
"small cells." << endl;
33438 m_fvBndryCnd->setBCTypes();
33439 computeCellVolumes();
33440 m_fvBndryCnd->setNearBoundaryRecNghbrs();
33441 m_fvBndryCnd->computeImagePointRecConst();
33442 if(m_fvBndryCnd->m_smallCellRHSCorrection) {
33443 m_fvBndryCnd->initSmallCellRHSCorrection();
33445 m_fvBndryCnd->initSmallCellCorrection();
33450 if(m_writeOutData) {
33451 cerr <<
"Writing out center line and boundary data" << endl;
33452 applyInitialCondition();
33453 writeCenterLineVel();
33458 IF_CONSTEXPR(nDim == 2) { findNghbrIds(); }
33459 else IF_CONSTEXPR(nDim == 3) {
33460 if(!m_fvBndryCnd->m_multipleGhostCells) findNghbrIds();
33463 m_log <<
"Creating surfaces...";
33465 m_bndryCellSurfacesOffset = a_noSurfaces();
33466 IF_CONSTEXPR(nDim == 2) {
33467 checkForSrfcsMGC();
33469 else IF_CONSTEXPR(nDim == 3) {
33470 if(m_fvBndryCnd->m_multipleGhostCells)
33471 checkForSrfcsMGC_2();
33473 checkForSrfcsMGC();
33477 m_fvBndryCnd->correctMasterSlaveSurfaces();
33478 m_log <<
"ok" << endl;
33482 m_log <<
"Creating ghost cells...";
33483 m_bndryGhostCellsOffset = a_noCells();
33484 IF_CONSTEXPR(nDim == 2) { m_fvBndryCnd->computeGhostCells(); }
33485 else IF_CONSTEXPR(nDim == 3) {
33486 if(m_fvBndryCnd->m_multipleGhostCells)
33487 m_fvBndryCnd->computeGhostCellsMGC();
33489 m_fvBndryCnd->computeGhostCells();
33491 m_log <<
"ok" << endl;
33494 setCellProperties();
33496 IF_CONSTEXPR(nDim == 2) {
33497 m_log <<
"Setting the neighbor arrays...";
33500 m_log <<
"ok" << endl;
33502 else IF_CONSTEXPR(nDim == 3) {
33503 if(!m_fvBndryCnd->m_multipleGhostCells) {
33504 m_log <<
"Setting the neighbor arrays...";
33507 m_log <<
"ok" << endl;
33513 m_log <<
"Adding body surfaces...";
33514 m_bndrySurfacesOffset = a_noSurfaces();
33515 IF_CONSTEXPR(nDim == 2) { m_fvBndryCnd->addBoundarySurfaces(); }
33516 else IF_CONSTEXPR(nDim == 3) {
33517 if(m_fvBndryCnd->m_multipleGhostCells) {
33518 m_fvBndryCnd->addBoundarySurfacesMGC();
33520 m_fvBndryCnd->addBoundarySurfaces();
33522 correctBoundarySurfaces();
33523 m_fvBndryCnd->addBoundarySurfaces();
33527 m_log <<
"ok" << endl;
33528 m_log <<
" *** All surfaces created" << endl;
33530 m_log <<
"Tagging cells needed for the surface flux computation...";
33531 tagCellsNeededForSurfaceFlux();
33532 m_log <<
"ok" << endl;
33537 m_log <<
"Fill nghbrInterface...";
33538 setNghbrInterface();
33539 m_log <<
"ok" << endl;
33541 m_log <<
"Filling cell surface mapping...";
33542 cellSurfaceMapping();
33543 m_log <<
"ok" << endl;
33545 m_log <<
"Setting upwind coefficient...";
33546 setUpwindCoefficient();
33547 m_log <<
"ok" << endl;
33550 m_log <<
"Computing plane vectors...";
33551 m_fvBndryCnd->computePlaneVectors();
33552 m_log <<
"ok" << endl;
33555 m_log <<
"Initializing the least-squares reconstruction...";
33558 buildLeastSquaresStencilSimple();
33559 m_log <<
"ok" << endl;
33562 m_log <<
"Initializing the viscous flux computation...";
33563 initViscousFluxComputation();
33564 m_log <<
"ok" << endl;
33566 if(grid().azimuthalPeriodicity()) {
33567 initAzimuthalReconstruction();
33568 computeAzimuthalReconstructionConstants();
33571 m_log <<
"Initializing boundary conditions...";
33573 m_fvBndryCnd->initBndryCnds();
33575 initCutOffBoundaryCondition();
33577 IF_CONSTEXPR(nDim == 3) {
33578 if(m_fvBndryCnd->m_multipleGhostCells) m_fvBndryCnd->computeReconstructionConstants_interpolation();
33580 m_log <<
"ok" << endl;
33582 m_log <<
"Computing reconstruction constants...";
33584 if(m_fvBndryCnd->m_cellMerging)
33585 computeReconstructionConstants();
33587 computeReconstructionConstantsSVD();
33588 m_log <<
"ok" << std::endl;
33590 IF_CONSTEXPR(nDim == 3) {
33592 if(m_periodicCells == 1) computeRecConstPeriodic();
33595 if(m_checkCellSurfaces) checkCellSurfaces();
33598 computeCellSurfaceDistanceVectors();
33606 computeCellVolumes();
33609 if(m_writeCutCellsToGridFile) {
33610 m_log <<
"Writing cut cells to grid file...";
33611 m_fvBndryCnd->recorrectCellCoordinates();
33612 writeCutCellsToGridFile();
33613 m_fvBndryCnd->rerecorrectCellCoordinates();
33614 m_log <<
"ok" << endl;
33620 for(
MInt smallId = 0; smallId < m_fvBndryCnd->m_smallBndryCells->size(); smallId++) {
33621 smallCell = m_fvBndryCnd->m_smallBndryCells->a[smallId];
33622 if(a_bndryId(m_fvBndryCnd->m_bndryCells->a[smallCell].m_linkedCellId) == -1) {
33626 MLong smallCells = m_fvBndryCnd->m_smallBndryCells->size();
33627 MPI_Allreduce(MPI_IN_PLACE, &smallCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"smallCells");
33629 checkGhostCellIntegrity();
33636 IF_CONSTEXPR(nDim == 3) { updateMaterialNo(); }
33639 m_cellInterpolationIndex.resize(a_noCells());
33640 std::fill(m_cellInterpolationIndex.begin(), m_cellInterpolationIndex.end(), -1);
33641 m_cellInterpolationMatrix.clear();
33642 m_cellInterpolationIds.clear();
33646 restartWMSurfaces();
33651 if(m_wmSurfaceProbeInterval > 0) {
33652 initWMSurfaceProbes();
33656 if(m_saSrfcProbeInterval > 0) {
33657 initSpanAvgSrfcProbes();
33660 if(m_wallNormalOutput && m_normalOutputInterval) {
33661 computeWallNormalPointCoords();
33662 findWallNormalCellIds();
33665 if(m_useSandpaperTrip) {
33666 initSandpaperTrip();
33669 if(m_useChannelForce) {
33670 initChannelForce();
33674 resetImplicitCoefficients();
33679 m_log <<
"_________________________________________________________________" << endl << endl;
33681 m_log <<
"_________________________________________________________________" << endl << endl;
33682 m_log << setfill(
' ');
33683 m_log <<
"number of cells " << setw(7) << a_noCells() << endl;
33684 m_log <<
"number of surfaces " << setw(7) << a_noSurfaces() << endl;
33685 m_log <<
"total number of small cells on all process " << setw(7) << smallCells << endl;
33686 m_log <<
"number of internal master cells " << setw(7) << countFMC << endl;
33687 m_log <<
"minimum grid level " << setw(7) << minLevel() << endl;
33688 m_log <<
"maximum grid level " << setw(7) << maxLevel() << endl << endl;
33689 m_log <<
"level | total no cells | no of leaf cells | ghost cells | bndry cells" << endl;
33690 for(
MInt level = maxLevel(); level >= minLevel(); level--) {
33695 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
33696 if(a_isBndryGhostCell(cellId)) {
33697 if(a_level(cellId) == level) {
33702 }
else if(a_level(cellId) == level) {
33704 if(a_hasProperty(cellId, SolverCell::IsSplitClone))
continue;
33705 if(c_isLeafCell(cellId)) {
33708 if(a_bndryId(cellId) > -1) {
33713 m_log << setfill(
' ');
33714 m_log << setw(3) << level <<
" " << setw(12) << total <<
" " << setw(16) << leaf <<
" " << setw(14) << ghost
33715 <<
" " << setw(14) << bnd << endl;
33719 MFloat maxC[] = {-10000.0, -10000.0, -10000.0};
33720 MFloat minC[] = {10000.0, 10000.0, 10000.0};
33721 for(
MInt c = 0; c < noInternalCells(); c++) {
33722 if(!a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) {
33728 if(a_isPeriodic(c)) {
33731 const MFloat cellLength = c_cellLengthAtCell(c);
33732 for(
MInt i = 0; i < nDim; i++) {
33733 maxC[i] =
mMax(maxC[i], a_coordinate(c, i) + F1B2 * cellLength);
33734 minC[i] =
mMin(minC[i], a_coordinate(c, i) - F1B2 * cellLength);
33737 m_log <<
"_________________________________________________________________" << endl << endl;
33739 m_log <<
"Physical domain boundaries: " << endl;
33740 m_log <<
"min (x,y" << (nDim == 3 ?
",z): (" :
"): (") << minC[0] <<
"," << minC[1];
33741 IF_CONSTEXPR(nDim == 3)
m_log <<
"," << minC[2];
33742 m_log <<
")" << endl;
33743 m_log <<
"max (x,y" << (nDim == 3 ?
",z): (" :
"): (") << maxC[0] <<
"," << maxC[1];
33744 IF_CONSTEXPR(nDim == 3)
m_log <<
"," << maxC[2];
33745 m_log <<
")" << endl;
33747 m_log <<
"_________________________________________________________________" << endl << endl;
33749 m_log <<
"Process " << domainId() <<
" finished initialization" << endl;
33766template <MInt nDim_,
class SysEqn>
33770 m_log <<
"Initializing Sandpaper Trip... ";
33772 IF_CONSTEXPR(nDim == 2) {
33773 cerr <<
"Tripping not implemented for 2D" << endl;
33777 IF_CONSTEXPR(nDim == 3) {
33778 m_tripAirfoil =
false;
33781 m_tripAirfoil = Context::getSolverProperty<MBool>(
"tripAirfoil", m_solverId, AT_, &m_tripAirfoil);
33786 mAlloc(m_tripDelta1, m_tripNoTrips,
"m_tripDelta1", 1.0, AT_);
33787 mAlloc(m_tripXOrigin, m_tripNoTrips,
"m_tripXOrigin", 0.0, AT_);
33788 mAlloc(m_tripXLength, m_tripNoTrips,
"m_tripXLength", 4.0, AT_);
33789 mAlloc(m_tripYOrigin, m_tripNoTrips,
"m_tripYOrigin", 0.0, AT_);
33790 mAlloc(m_tripYHeight, m_tripNoTrips,
"m_tripYHeight", 1.0, AT_);
33791 mAlloc(m_tripCutoffZ, m_tripNoTrips,
"m_tripCutoffZ", 1.7, AT_);
33792 mAlloc(m_tripMaxAmpSteady, m_tripNoTrips,
"m_tripMaxAmpSteady", 0.0, AT_);
33793 mAlloc(m_tripMaxAmpFluc, m_tripNoTrips,
"m_tripMaxAmpFluc", 0.005, AT_);
33794 mAlloc(m_tripDeltaTime, m_tripNoTrips,
"m_tripDeltaTime", 4.0, AT_);
33795 mAlloc(m_tripTimeStep, m_tripNoTrips,
"m_tripTimeStep", 0, AT_);
33796 mAlloc(m_tripNoCells, m_tripNoTrips,
"m_tripNoCells", 0, AT_);
33797 mAlloc(m_tripCellOffset, m_tripNoTrips,
"m_tripCellOffset", 0, AT_);
33799 for(
MInt i = 0; i < m_tripNoTrips; i++) {
33800 m_tripDelta1[i] = Context::getSolverProperty<MFloat>(
"tripDelta1", m_solverId, AT_, &m_tripDelta1[i], i);
33802 if(!m_tripAirfoil) {
33803 m_tripXOrigin[i] = Context::getSolverProperty<MFloat>(
"tripXOrigin", m_solverId, AT_, &m_tripXOrigin[i], i);
33805 m_tripYOrigin[i] = Context::getSolverProperty<MFloat>(
"tripYOrigin", m_solverId, AT_, &m_tripYOrigin[i], i);
33811 tripX = Context::getSolverProperty<MFloat>(
"tripXLength", m_solverId, AT_, &tripX);
33813 m_tripXLength[i] = m_tripDelta1[i] * tripX;
33818 tripY = Context::getSolverProperty<MFloat>(
"tripYHeight", m_solverId, AT_, &tripY);
33820 m_tripYHeight[i] = m_tripDelta1[i] * tripY;
33824 tripZ = Context::getSolverProperty<MFloat>(
"tripCutoffZ", m_solverId, AT_, &tripZ);
33826 m_tripCutoffZ[i] = m_tripDelta1[i] * tripZ;
33828 m_tripMaxAmpSteady[i] =
33829 Context::getSolverProperty<MFloat>(
"tripMaxAmpSteady", m_solverId, AT_, &m_tripMaxAmpSteady[i], i);
33831 m_tripMaxAmpFluc[i] =
33832 Context::getSolverProperty<MFloat>(
"tripMaxAmpFluc", m_solverId, AT_, &m_tripMaxAmpFluc[i], i);
33834 m_tripNoModes = 100;
33836 MFloat timeCutoff = 4.0;
33838 timeCutoff = Context::getSolverProperty<MFloat>(
"tripDeltaTime", m_solverId, AT_, &timeCutoff);
33840 m_tripDeltaTime[i] = timeCutoff * m_tripDelta1[i] / m_UInfinity;
33841 m_tripTimeStep[i] = (
MInt)(m_time / m_tripDeltaTime[i]);
33845 mTerm(1,
"Properties RNGSeed or seedRNGWithTime not compatible with SandpaperTrip!");
33848 m_tripDomainWidth = 0.0;
33850 m_tripUseRestart =
false;
33852 m_tripUseRestart = Context::getSolverProperty<MBool>(
"tripUseRestart", m_solverId, AT_, &m_tripUseRestart);
33855 if(m_tripAirfoil) {
33856 mAlloc(m_tripAirfoilBndryId, m_tripNoTrips,
"m_tripAirfoilBndryId", 0, AT_);
33857 mAlloc(m_tripAirfoilSide, m_tripNoTrips,
"m_tripAirfoilSide", 0, AT_);
33858 mAlloc(m_tripAirfoilChordPos, m_tripNoTrips,
"m_tripAirfoilChordPos", 0.0, AT_);
33859 mAlloc(m_tripAirfoilNosePos, nDim,
"m_tripAirfoilNoisePos", 0.0, AT_);
33860 mAlloc(m_tripAirfoilForceDir, nDim * m_tripNoTrips,
"m_tripAirfoilForceDir", 0.0, AT_);
33862 m_tripAirfoilChordLength =
33863 Context::getSolverProperty<MFloat>(
"tripAirfoilChordLength", m_solverId, AT_, &m_tripAirfoilChordLength);
33864 m_tripAirfoilAOA = Context::getSolverProperty<MFloat>(
"tripAirfoilAOA", m_solverId, AT_, &m_tripAirfoilAOA);
33865 for(
MInt dim = 0; dim < nDim; dim++) {
33866 m_tripAirfoilNosePos[dim] =
33867 Context::getSolverProperty<MFloat>(
"tripAirfoilNosePos", m_solverId, AT_, &m_tripAirfoilNosePos[dim], dim);
33869 for(
MInt i = 0; i < m_tripNoTrips; i++) {
33870 m_tripAirfoilBndryId[i] =
33871 Context::getSolverProperty<MInt>(
"tripAirfoilBndryId", m_solverId, AT_, &m_tripAirfoilBndryId[i], i);
33872 m_tripAirfoilSide[i] =
33873 Context::getSolverProperty<MInt>(
"tripAirfoilSide", m_solverId, AT_, &m_tripAirfoilSide[i], i);
33874 m_tripAirfoilChordPos[i] =
33875 Context::getSolverProperty<MFloat>(
"tripAirfoilChordPos", m_solverId, AT_, &m_tripAirfoilChordPos[i], i);
33876 if(m_tripAirfoilChordPos[i] < 0.0 || m_tripAirfoilChordPos[i] > 1.0)
33877 mTerm(-1,
"tripAirfoilChordPos not within the allowed range of 0.0 to 1.0");
33882 for(
MInt i = 0; i < m_tripNoTrips; i++) {
33883 if(m_tripAirfoil) {
33887 MInt avgWeight = 0;
33888 for(
MInt bCellId = 0; bCellId < m_fvBndryCnd->m_bndryCells->size(); bCellId++) {
33889 MInt bc = m_tripAirfoilBndryId[i];
33890 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bCellId].m_cellId;
33891 MFloat eta = (a_coordinate(cellId, 0) - m_tripAirfoilNosePos[0]) * cos(m_tripAirfoilAOA * PI / 180.0)
33892 - (a_coordinate(cellId, 1) - m_tripAirfoilNosePos[1]) * sin(m_tripAirfoilAOA * PI / 180.0);
33893 MFloat zeta = (a_coordinate(cellId, 0) - m_tripAirfoilNosePos[0]) * sin(m_tripAirfoilAOA * PI / 180.0)
33894 + (a_coordinate(cellId, 1) - m_tripAirfoilNosePos[1]) * cos(m_tripAirfoilAOA * PI / 180.0);
33895 MFloat dEta = abs(eta - (m_tripAirfoilChordPos[i] * m_tripAirfoilChordLength));
33896 if(dEta <= 0.5 * c_cellLengthAtLevel(maxRefinementLevel())) {
33897 if((m_tripAirfoilSide[i] > 0 && zeta > 0.0) || (m_tripAirfoilSide[i] < 0 && zeta < 0.0)) {
33898 for(
MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bCellId].m_noSrfcs; srfc++) {
33902 if(m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcs[srfc]->m_bndryCndId == bc) {
33903 for(
MInt dim = 0; dim < nDim; dim++) {
33904 m_tripAirfoilForceDir[i * nDim + dim] =
33905 m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcs[srfc]->m_normalVector[dim];
33906 m_tripXOrigin[i] = m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcs[srfc]->m_coordinates[0];
33907 m_tripYOrigin[i] = m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcs[srfc]->m_coordinates[1];
33918 MPI_Allreduce(&avgWeight, &avgWeight, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"avgWeight",
"avgWeight");
33919 MPI_Allreduce(&m_tripXOrigin[i], &m_tripXOrigin[i], 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"m_tripXOrigin",
33921 MPI_Allreduce(&m_tripYOrigin[i], &m_tripYOrigin[i], 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"m_tripYOrigin",
33923 for(
MInt dim = 0; dim < nDim; dim++) {
33924 MPI_Allreduce(&m_tripAirfoilForceDir[i * nDim + dim], &m_tripAirfoilForceDir[i * nDim + dim], 1, MPI_DOUBLE,
33925 MPI_SUM, mpiComm(), AT_,
"m_tripAirfoilForceDir",
"m_tripAirfoilForceDir");
33926 m_tripAirfoilForceDir[i * nDim + dim] /= avgWeight;
33928 m_tripXOrigin[i] /= avgWeight;
33929 m_tripYOrigin[i] /= avgWeight;
33931 if(avgWeight > 0) {
33932 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
33933 MFloat maxR2 =
POW2(2 * m_tripXLength[i]) +
POW2(2 * m_tripYHeight[i]);
33935 POW2(a_coordinate(cellId, 0) - m_tripXOrigin[i]) +
POW2(a_coordinate(cellId, 1) - m_tripYOrigin[i]);
33936 if(cellR2 < maxR2) {
33937 m_tripCellIds.push_back(cellId);
33938 m_tripCoords.push_back(a_coordinate(cellId, 2));
33939 a_isSandpaperTripCell(cellId) =
true;
33943 m_tripNoCells[i] = m_tripCellIds.size() - m_tripCellOffset[i];
33946 m_tripCellOffset[i] = m_tripCellOffset[i - 1] + m_tripNoCells[i - 1];
33949 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
33950 MFloat maxR2 =
POW2(2 * m_tripXLength[i]) +
POW2(2 * m_tripYHeight[i]);
33952 POW2(a_coordinate(cellId, 0) - m_tripXOrigin[i]) +
POW2(a_coordinate(cellId, 1) - m_tripYOrigin[i]);
33953 if(cellR2 < maxR2) {
33954 m_tripCellIds.push_back(cellId);
33955 m_tripCoords.push_back(a_coordinate(cellId, 2));
33956 a_isSandpaperTripCell(cellId) =
true;
33959 m_tripNoCells[i] = m_tripCellIds.size() - m_tripCellOffset[i];
33962 MInt tripTotalNoCells = m_tripCellIds.size();
33965 geometry().getBoundingBox(&bbox[0]);
33966 m_tripDomainWidth = bbox[5] - bbox[2];
33968 m_log <<
"=================================================" << endl
33969 <<
" SANDPAPER TRIP PROPERTIES " << endl
33970 <<
"=================================================" << endl;
33971 for(
MInt i = 0; i < m_tripNoTrips; ++i) {
33972 m_log <<
"######### TRIP NUMBER " << i <<
" ###########" << endl
33973 <<
"tripXOrigin: " << m_tripXOrigin[i] << endl
33974 <<
"tripXLength: " << m_tripXLength[i] << endl
33975 <<
"tripYOrigin: " << m_tripYOrigin[i] << endl
33976 <<
"tripYHeight: " << m_tripYHeight[i] << endl
33977 <<
"tripMaxAmpFluc: " << m_tripMaxAmpFluc[i] << endl
33978 <<
"tripNoModes: " << m_tripNoModes << endl
33979 <<
"tripDeltaTime: " << m_tripDeltaTime[i] << endl
33980 <<
"tripTimeStep: " << m_tripTimeStep[i] << endl
33981 <<
"tripDomainWidth: " << m_tripDomainWidth << endl
33982 <<
"###########################################" << endl;
33984 m_log <<
"=================================================" << endl;
33986 if(tripTotalNoCells > 0) {
33987 mAlloc(m_tripG, m_tripNoTrips * tripTotalNoCells,
"m_tripG", F0, AT_);
33988 mAlloc(m_tripH1, m_tripNoTrips * tripTotalNoCells,
"m_tripH1", F0, AT_);
33989 mAlloc(m_tripH2, m_tripNoTrips * tripTotalNoCells,
"m_tripH2", F0, AT_);
33991 mAlloc(m_tripModesG, m_tripNoTrips * 2 * m_tripNoModes,
"m_tripModesG", F0, AT_);
33992 mAlloc(m_tripModesH1, m_tripNoTrips * 2 * m_tripNoModes,
"m_tripModesH1", F0, AT_);
33993 mAlloc(m_tripModesH2, m_tripNoTrips * 2 * m_tripNoModes,
"m_tripModesH2", F0, AT_);
33995 if(m_restart && m_tripUseRestart) {
33996 m_log <<
"Reading Sandpaper Trip Vars... ";
33998 stringstream fileName;
33999 if(m_useNonSpecifiedRestartFile) {
34000 fileName << restartDir() <<
"tripRestart" << ParallelIo::fileExt();
34002 if(!isMultilevel()) {
34003 fileName << restartDir() <<
"tripRestart_" << m_restartTimeStep << ParallelIo::fileExt();
34005 mTerm(-1,
"loading Sandpaper trip variables not implemented for multiLevel");
34010 ParallelIo parallelIo(fileName.str(), PIO_READ, mpiComm());
34012 ParallelIo::size_type dataSize = m_tripNoTrips * 2 * m_tripNoModes;
34014 parallelIo.setOffset(dataSize, 0);
34015 parallelIo.readArray(&m_tripModesG[0],
"tripModesG");
34016 parallelIo.readArray(&m_tripModesH1[0],
"tripModesH1");
34017 parallelIo.readArray(&m_tripModesH2[0],
"tripModesH2");
34019 m_log <<
"ok." << endl;
34022 for(
MInt i = 0; i < m_tripNoTrips; ++i) {
34023 const MInt offsetModes = i * 2 * m_tripNoModes;
34024 tripFourierCoefficients(&m_tripModesG[offsetModes], m_tripNoModes, m_tripDomainWidth, m_tripCutoffZ[i]);
34025 tripFourierCoefficients(&m_tripModesH1[offsetModes], m_tripNoModes, m_tripDomainWidth, m_tripCutoffZ[i]);
34026 tripFourierCoefficients(&m_tripModesH2[offsetModes], m_tripNoModes, m_tripDomainWidth, m_tripCutoffZ[i]);
34030 for(
MInt i = 0; i < m_tripNoTrips; ++i) {
34031 const MInt offset = m_tripCellOffset[i];
34032 const MInt offsetModes = i * 2 * m_tripNoModes;
34033 tripForceCoefficients(&m_tripModesG[offsetModes], &m_tripG[offset], &m_tripCoords[0], m_tripNoCells[i],
34035 tripForceCoefficients(&m_tripModesH1[offsetModes], &m_tripH1[offset], &m_tripCoords[0], m_tripNoCells[i],
34037 tripForceCoefficients(&m_tripModesH2[offsetModes], &m_tripH2[offset], &m_tripCoords[0], m_tripNoCells[i],
34043template <MInt nDim_,
class SysEqn>
34047 for(
MInt ii = 0; ii < m_tripNoTrips; ii++) {
34048 const MFloat t = m_time + m_timeStep * m_RKalpha[m_RKStep];
34049 const MInt tripTime = (
MInt)(t / m_tripDeltaTime[ii]);
34050 const MFloat p = t / m_tripDeltaTime[ii] - tripTime;
34051 const MFloat b = 3 * pow(p, 2) - 2 * pow(p, 3);
34052 const MInt offset = m_tripCellOffset[ii];
34053 const MInt offsetModes = ii * 2 * m_tripNoModes;
34055 if(tripTime > m_tripTimeStep[ii]) {
34056 m_tripTimeStep[ii] = tripTime;
34059 for(
MInt k = 0; k < m_tripNoCells[ii]; k++) {
34060 if(m_tripNoCells[ii] > 0) m_tripH1[offset + k] = m_tripH2[offset + k];
34063 for(
MInt n = 0; n < m_tripNoModes; n++) {
34064 m_tripModesH1[offsetModes + n] = m_tripModesH2[offsetModes + n];
34068 tripFourierCoefficients(&m_tripModesH2[offsetModes], m_tripNoModes, m_tripDomainWidth, m_tripCutoffZ[ii]);
34070 tripForceCoefficients(&m_tripModesH2[offsetModes], &m_tripH2[offset], &m_tripCoords[0], m_tripNoCells[ii],
34075 for(
MInt cell = 0; cell < m_tripNoCells[ii]; cell++) {
34077 const MFloat forceStrength =
34078 (m_tripMaxAmpSteady[ii] * m_tripG[offset + cell]
34079 + m_tripMaxAmpFluc[ii] * ((1.0 -
b) * m_tripH1[offset + cell] +
b * m_tripH2[offset + cell]));
34080 const MInt cellId = m_tripCellIds[cell];
34081 const MFloat x = a_coordinate(cellId, 0);
34082 const MFloat y = a_coordinate(cellId, 1);
34085 exp(-
POW2((x - m_tripXOrigin[ii]) / m_tripXLength[ii]) -
POW2((
y - m_tripYOrigin[ii]) / m_tripYHeight[ii]))
34087 if(!m_tripAirfoil) {
34089 a_rightHandSide(cellId, CV->RHO_V) -= force * a_pvariable(cellId, PV->RHO) * a_cellVolume(cellId);
34091 IF_CONSTEXPR(hasE<SysEqn>)
34092 a_rightHandSide(cellId, CV->RHO_E) -=
34093 force * a_pvariable(cellId, PV->RHO) * a_pvariable(cellId, PV->V) * a_cellVolume(cellId);
34095 const MFloat nx = m_tripAirfoilForceDir[ii * nDim + 0];
34096 const MFloat ny = m_tripAirfoilForceDir[ii * nDim + 1];
34097 a_rightHandSide(cellId, CV->RHO_U) -= force * a_pvariable(cellId, PV->RHO) * a_cellVolume(cellId) * nx;
34098 a_rightHandSide(cellId, CV->RHO_V) -= force * a_pvariable(cellId, PV->RHO) * a_cellVolume(cellId) * ny;
34100 IF_CONSTEXPR(hasE<SysEqn>)
34101 a_rightHandSide(cellId, CV->RHO_E) -= force * a_pvariable(cellId, PV->RHO)
34102 * (a_pvariable(cellId, PV->U) * nx + a_pvariable(cellId, PV->V) * ny)
34103 * a_cellVolume(cellId);
34109template <MInt nDim_,
class SysEqn>
34111 m_log <<
"writing Sandpaper Trip Vars... ";
34113 stringstream fileName;
34114 if(m_useNonSpecifiedRestartFile) {
34115 fileName << restartDir() <<
"tripRestart" << ParallelIo::fileExt();
34117 if(!isMultilevel()) {
34118 fileName << restartDir() <<
"tripRestart_" <<
globalTimeStep << ParallelIo::fileExt();
34120 mTerm(-1,
"writing Sandpaper trip variables not implemented for multiLevel");
34125 ParallelIo parallelIo(fileName.str(), PIO_REPLACE, mpiComm());
34127 MInt dataSize = m_tripNoModes * 2 * m_tripNoTrips;
34129 parallelIo.defineArray(PIO_FLOAT,
"tripModesG", dataSize);
34130 parallelIo.defineArray(PIO_FLOAT,
"tripModesH1", dataSize);
34131 parallelIo.defineArray(PIO_FLOAT,
"tripModesH2", dataSize);
34133 if(domainId() == 0) {
34134 parallelIo.setOffset(dataSize, 0);
34135 parallelIo.writeArray(&m_tripModesG[0],
"tripModesG");
34136 parallelIo.writeArray(&m_tripModesH1[0],
"tripModesH1");
34137 parallelIo.writeArray(&m_tripModesH2[0],
"tripModesH2");
34140 parallelIo.setOffset(0, 0);
34141 parallelIo.writeArray(&m_tripModesG[0],
"tripModesG");
34142 parallelIo.writeArray(&m_tripModesH1[0],
"tripModesH1");
34143 parallelIo.writeArray(&m_tripModesH2[0],
"tripModesH2");
34145 m_log <<
" ok." << endl;
34148template <MInt nDim_,
class SysEqn>
34151 MFloat maxLocalValue = -999999.0;
34152 MFloat minLocalValue = 999999.0;
34154 MFloat* phik = &modes[noModes];
34156 for(
MInt k = 0; k < noCells; k++) {
34157 const MFloat z = coords[k];
34158 for(
MInt n = 0; n < noModes; n++) {
34159 forceCoef[k] += sin(z * ak[n] + phik[n]);
34162 maxLocalValue =
mMax(maxLocalValue, forceCoef[k]);
34163 minLocalValue =
mMin(minLocalValue, forceCoef[k]);
34167 MFloat maxGlobalValue = 0.0;
34168 MFloat minGlobalValue = 0.0;
34169 MPI_Allreduce(&maxLocalValue, &maxGlobalValue, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"maxLocalValue",
34171 MPI_Allreduce(&minLocalValue, &minGlobalValue, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"minLocalValue",
34175 for(
MInt k = 0; k < noCells; k++) {
34176 forceCoef[k] = 2 * (forceCoef[k] - minGlobalValue) / (maxGlobalValue - minGlobalValue) - 1.0;
34180template <MInt nDim_,
class SysEqn>
34183 const MFloat minWavenumber = 2 * PI / maxWaveLength;
34184 const MFloat maxWavenumber = 2 * PI / minWaveLength;
34187 MFloat* phik = &modes[noModes];
34188 if(domainId() == 0) {
34189 for(
MInt n = 0; n < noModes; n++) {
34190 ak[n] = (maxWavenumber - minWavenumber) * (rand() /
MFloat(RAND_MAX)) + minWavenumber;
34191 phik[n] = 2 * PI * rand() /
MFloat(RAND_MAX);
34195 MPI_Bcast(&ak[0], noModes, MPI_DOUBLE, 0, mpiComm(), AT_,
"ak[0]");
34196 MPI_Bcast(&phik[0], noModes, MPI_DOUBLE, 0, mpiComm(), AT_,
"phik[0]");
34199template <MInt nDim_,
class SysEqn>
34203 const MFloat channelReTau = Context::getSolverProperty<MFloat>(
"channelReTau", m_solverId, AT_, &channelReTau);
34206 m_channelVolumeForce =
POW2(channelReTau / sysEqn().m_Re0);
34209template <MInt nDim_,
class SysEqn>
34212 for(
MInt cellId = 0; cellId < c_noCells(); cellId++) {
34213 a_rightHandSide(cellId, CV->RHO_U) -= m_channelVolumeForce * a_pvariable(cellId, PV->RHO) * a_cellVolume(cellId);
34214 a_rightHandSide(cellId, CV->RHO_E) -=
34215 m_channelVolumeForce * a_pvariable(cellId, PV->RHO) * a_pvariable(cellId, PV->U) * a_cellVolume(cellId);
34220template <MInt nDim_,
class SysEqn>
34224 const MInt noVars = 16;
34228 MInt probeBcId = 3399;
34229 probeBcId = Context::getSolverProperty<MInt>(
"saSrfcBcId", m_solverId, AT_, &probeBcId);
34231 m_saSrfcProbeStart = Context::getSolverProperty<MInt>(
"saSrfcProbeStart", m_solverId, AT_, &m_saSrfcProbeStart);
34234 mTerm(1,
"length of saSrfcProbesX and length of saSrfcProbesSide must match!");
34236 m_saSrfcProbeIds.resize(m_saNoSrfcProbes);
34237 m_saSrfcProbeSrfcs.resize(m_saNoSrfcProbes);
34239 for(
MInt p = 0; p < m_saNoSrfcProbes; p++) {
34240 m_saSrfcProbeIds[p].clear();
34241 m_saSrfcProbeSrfcs[p].clear();
34243 const MFloat probeCoord = Context::getSolverProperty<MFloat>(
"saSrfcProbesX", m_solverId, AT_, &probeCoord, p);
34244 const MInt probeSide = Context::getSolverProperty<MInt>(
"saSrfcProbesSide", m_solverId, AT_, &probeSide, p);
34246 for(
MInt bCellId = 0; bCellId < m_bndryCells->size(); bCellId++) {
34247 MInt cellId = m_bndryCells->a[bCellId].m_cellId;
34248 if(!a_isHalo(cellId)) {
34249 if(abs(a_coordinate(cellId, 0) - probeCoord) < F1B2 * c_cellLengthAtLevel(maxRefinementLevel()) + m_eps) {
34250 for(
MInt srfc = 0; srfc < m_bndryCells->a[bCellId].m_noSrfcs; srfc++) {
34251 if(m_bndryCells->a[bCellId].m_srfcs[srfc]->m_bndryCndId == probeBcId) {
34252 const MFloat ny = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_normalVector[1];
34253 if(ny * (
MFloat)probeSide > 0) {
34254 m_saSrfcProbeIds[p].push_back(cellId);
34255 m_saSrfcProbeSrfcs[p].push_back(srfc);
34266 mAlloc(m_saSrfcProbeBuffer, m_saNoSrfcProbes * noVars,
"m_saSrfcProbeBuffer", 0.0, AT_);
34269 for(
MInt p = 0; p < m_saNoSrfcProbes; p++) {
34270 localNoSamples[p] = m_saSrfcProbeIds[p].
size();
34273 if(domainId() == 0) {
34274 mAlloc(m_saSrfcProbeNoSamples, m_saNoSrfcProbes,
"m_saSrfcProbeNoSamples", 0, AT_);
34276 MPI_Reduce(&localNoSamples[0], &m_saSrfcProbeNoSamples[0], m_saNoSrfcProbes, MPI_INT, MPI_SUM, 0, mpiComm(), AT_,
34277 "&localNoSamples[0]",
"&m_saSrfcProbeNoSamples[0]");
34280template <MInt nDim_,
class SysEqn>
34284 const MInt noVars = 16;
34287 memset(&(m_saSrfcProbeBuffer[0]), 0.0, m_saNoSrfcProbes * noVars *
sizeof(
MFloat));
34290 for(
MInt p = 0; p < m_saNoSrfcProbes; p++) {
34291 for(
MUint s = 0; s < m_saSrfcProbeIds[p].size(); s++) {
34292 const MInt cellId = m_saSrfcProbeIds[p][s];
34293 const MInt srfc = m_saSrfcProbeSrfcs[p][s];
34294 const MInt bCellId = a_bndryId(cellId);
34295 const MInt wmSrfcId = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_wmSrfcId;
34297 MFloat pSrfc = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_primVars[PV->P];
34298 MFloat rhoSrfc = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_primVars[PV->RHO];
34299 MFloat uSrfc = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_primVars[PV->U];
34300 MFloat vSrfc = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_primVars[PV->V];
34301 MFloat wSrfc = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_primVars[PV->W];
34302 MFloat TSrfc = sysEqn().temperature_ES(rhoSrfc, pSrfc);
34303 MFloat mueSrfc = SUTHERLANDLAW(TSrfc);
34305 MFloat nx = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_normalVector[0];
34306 MFloat ny = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_normalVector[1];
34307 MFloat nz = m_bndryCells->a[bCellId].m_srfcs[srfc]->m_normalVector[2];
34309 MFloat dudn = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_normalDeriv[PV->U];
34310 MFloat dvdn = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_normalDeriv[PV->V];
34311 MFloat dwdn = m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_normalDeriv[PV->W];
34313 MFloat tau_w = mueSrfc * (dudn * ny - dvdn * nx) / sysEqn().m_Re0;
34318 if(wmSrfcId > -1) {
34319 mue_wm += m_wmSurfaces[wmSrfcId].m_wmMUEWM;
34320 tau_wm += (mueSrfc + mue_wm) * (dudn * ny - dvdn * nx) / sysEqn().m_Re0;
34324 m_saSrfcProbeBuffer[noVars * p + 0] += m_bndryCells->a[bCellId].m_srfcs[srfc]->m_coordinates[0];
34325 m_saSrfcProbeBuffer[noVars * p + 1] += nx;
34326 m_saSrfcProbeBuffer[noVars * p + 2] += ny;
34327 m_saSrfcProbeBuffer[noVars * p + 3] += nz;
34328 m_saSrfcProbeBuffer[noVars * p + 4] += uSrfc;
34329 m_saSrfcProbeBuffer[noVars * p + 5] += vSrfc;
34330 m_saSrfcProbeBuffer[noVars * p + 6] += wSrfc;
34331 m_saSrfcProbeBuffer[noVars * p + 7] += rhoSrfc;
34332 m_saSrfcProbeBuffer[noVars * p + 8] += pSrfc;
34333 m_saSrfcProbeBuffer[noVars * p + 9] += mueSrfc;
34334 m_saSrfcProbeBuffer[noVars * p + 10] += dudn;
34335 m_saSrfcProbeBuffer[noVars * p + 11] += dvdn;
34336 m_saSrfcProbeBuffer[noVars * p + 12] += dwdn;
34337 m_saSrfcProbeBuffer[noVars * p + 13] += tau_w;
34338 m_saSrfcProbeBuffer[noVars * p + 14] += mue_wm;
34339 m_saSrfcProbeBuffer[noVars * p + 15] += tau_wm;
34343 if(domainId() == 0) {
34344 MPI_Reduce(MPI_IN_PLACE, &m_saSrfcProbeBuffer[0], noVars * m_saNoSrfcProbes, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_,
34345 "MPI_IN_PLACE",
"&m_saSrfcProbeBuffer[0]");
34347 MPI_Reduce(&m_saSrfcProbeBuffer[0], &m_saSrfcProbeBuffer[0], noVars * m_saNoSrfcProbes, MPI_DOUBLE, MPI_SUM, 0,
34348 mpiComm(), AT_,
"&m_saSrfcProbeBuffer[0]",
"&m_saSrfcProbeBuffer[0]");
34351 if(domainId() == 0) {
34352 for(
MInt p = 0; p < m_saNoSrfcProbes; p++) {
34355 stringstream filename;
34356 filename << outputDir() << m_saSrfcProbeDir <<
"/"
34357 <<
"spanAvgSrfcProbes_" << p;
34358 datei = fopen(filename.str().c_str(),
"a");
34362 fprintf(datei,
"0: globalTimeStep");
34363 fprintf(datei,
" 1: x");
34364 fprintf(datei,
" 2: nx");
34365 fprintf(datei,
" 3: ny");
34366 fprintf(datei,
" 4: nz");
34367 fprintf(datei,
" 5: u_srfc");
34368 fprintf(datei,
" 6: v_srfc");
34369 fprintf(datei,
" 7: w_srfc");
34370 fprintf(datei,
" 8: rho_srfc");
34371 fprintf(datei,
" 9: p_srfc");
34372 fprintf(datei,
" 10: mue_srfc");
34373 fprintf(datei,
" 11: dudn");
34374 fprintf(datei,
" 12: dvdn");
34375 fprintf(datei,
" 13: dwdn");
34376 fprintf(datei,
" 14: tau_w");
34377 fprintf(datei,
" 15: mue_wm");
34378 fprintf(datei,
" 16: tau_wm");
34379 fprintf(datei,
"\n");
34384 for(
MInt v = 0; v < noVars; v++) {
34385 fprintf(datei,
"%f ", m_saSrfcProbeBuffer[noVars * p + v] / m_saSrfcProbeNoSamples[p]);
34387 fprintf(datei,
"\n");
34393template <MInt nDim_,
class SysEqn>
34396 timerValue[0] = RETURN_TIMER_TIME(m_timers[Timers::WMExchange]);
34397 timerValue[1] = RETURN_TIMER_TIME(m_timers[Timers::WMSurfaceLoop]);
34398 timerValue[2] = RETURN_TIMER_TIME(m_timers[Timers::WMFluxCorrection]);
34400 for(
MInt i = 0; i < 3; i++) {
34401 if(domainId() == 0) {
34402 MPI_Reduce(MPI_IN_PLACE, &timerValue[i], 1, MPI_DOUBLE, MPI_MAX, 0, mpiComm(), AT_,
"MPI_IN_PLACE",
34405 MPI_Reduce(&timerValue[i], &timerValue[i], 1, MPI_DOUBLE, MPI_MAX, 0, mpiComm(), AT_,
"&timerValue[i]",
34410 if(domainId() == 0) {
34411 MPI_Reduce(MPI_IN_PLACE, &m_wmIterator, 1, MPI_INT, MPI_MAX, 0, mpiComm(), AT_,
"MPI_IN_PLACE",
"&m_wmIterator");
34413 MPI_Reduce(&m_wmIterator, &m_wmIterator, 1, MPI_INT, MPI_MAX, 0, mpiComm(), AT_,
"&m_wmIterator",
"&m_wmIterator");
34417 if(domainId() == 0) {
34419 stringstream filename;
34420 filename << outputDir() <<
"wmTimers";
34421 datei = fopen(filename.str().c_str(),
"a");
34423 fprintf(datei,
"WMExchange: %f ", timerValue[0]);
34424 fprintf(datei,
"WMSurfaceLoop: %f ", timerValue[1]);
34425 fprintf(datei,
"WMFluxCorrection: %f ", timerValue[2]);
34426 fprintf(datei,
"WMIterator: %d ", m_wmIterator);
34427 fprintf(datei,
"\n");
34441template <MInt nDim_,
class SysEqn>
34445 m_log <<
"Computing Wall Normal Point Coordinates ... " << endl;
34447 MInt noSegments = m_normalNoPoints - 1;
34448 MFloat segmentLength = m_normalLength / noSegments;
34450 MInt size = m_bndryCells->size();
34451 MInt k = m_normalSamplingSide.size();
34454 sampleUsage.
fill(0);
34456 for(
MInt i = 0; i < size; i++) {
34457 MInt cellId = m_bndryCells->a[i].m_cellId;
34458 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
34459 if(!a_hasProperty(cellId, SolverCell::IsHalo)) {
34460 for(
MInt srfc = 0; srfc < m_bndryCells->a[i].m_noSrfcs; srfc++) {
34461 MInt cellCnd = m_bndryCells->a[i].m_srfcs[srfc]->m_bndryCndId;
34462 if(cellCnd == m_normalBcId) {
34463 MFloat dist = c_cellLengthAtCell(cellId) / 2;
34464 MFloat x = (a_coordinate(cellId, 0) - m_bndryCells->a[i].m_coordinates[0]);
34472 z = (a_coordinate(cellId, 2) - m_bndryCells->a[i].m_coordinates[2]);
34477 for(
MInt o = 0; o < k; o++) {
34478 if(sampleUsage[o] == 0) {
34479 MFloat xCompare = m_normalSamplingCoords[o * 2];
34482 zCompare = m_normalSamplingCoords[o * 2 + 1];
34485 if((xCompare <= xUpper) && (xCompare >= xLower) && (zCompare <= zUpper) && (zCompare >= zLower)) {
34486 MInt side = m_normalSamplingSide[o];
34487 MFloat ny = m_bndryCells->a[i].m_srfcs[srfc]->m_normalVector[1];
34489 if(((side < 0) && (ny < 0)) || ((side > 0) && (ny > 0))) {
34490 sampleUsage[o] = 1;
34491 m_wallSetupOrigin.push_back(xCompare);
34492 m_wallSetupOrigin.push_back(zCompare);
34493 m_wallSetupOriginSide.push_back(side);
34495 MFloat initCoordx = m_bndryCells->a[i].m_srfcs[srfc]->m_coordinates[0];
34496 MFloat initCoordy = m_bndryCells->a[i].m_srfcs[srfc]->m_coordinates[1];
34499 MFloat nx = m_bndryCells->a[i].m_srfcs[srfc]->m_normalVector[0];
34502 m_wallNormalVectors.push_back(nx);
34503 m_wallNormalVectors.push_back(ny);
34506 initCoordz = m_bndryCells->a[i].m_srfcs[srfc]->m_coordinates[2];
34507 nz = m_bndryCells->a[i].m_srfcs[srfc]->m_normalVector[2];
34510 MFloat r = sqrt(nx * nx + ny * ny + nz * nz);
34511 MFloat scalingFactor = segmentLength / r;
34513 MFloat stepX = nx * scalingFactor;
34514 MFloat stepY = ny * scalingFactor;
34515 MFloat stepZ = nz * scalingFactor;
34517 for(
MInt step = 0; step <= noSegments; step++) {
34518 MFloat coordX = initCoordx + (step * stepX);
34519 MFloat coordY = initCoordy + (step * stepY);
34521 m_wallNormalPointCoords.push_back(coordX);
34522 m_wallNormalPointCoords.push_back(coordY);
34525 MFloat coordZ = initCoordz + (step * stepZ);
34526 m_wallNormalPointCoords.push_back(coordZ);
34539 m_log <<
"done." << endl;
34543template <MInt nDim_,
class SysEqn>
34549 m_log <<
"Finding Wall Normal Cell Ids ... " << endl;
34551 ScratchSpace<MInt> localNoWallNormalPointCoords(noDomains(), AT_,
"localNoWallNormalPointCoords");
34552 localNoWallNormalPointCoords.
fill(0);
34554 ScratchSpace<MInt> localNoWallNormalPoints(noDomains(), AT_,
"localNoWallNormalPoints");
34555 localNoWallNormalPoints.
fill(0);
34557 localNoWallNormalPointCoords[domainId()] = m_wallNormalPointCoords.
size();
34559 localNoWallNormalPoints[domainId()] = (m_wallNormalPointCoords.size() / nDim);
34561 MPI_Allgather(&localNoWallNormalPointCoords[domainId()], 1, MPI_INT, &localNoWallNormalPointCoords[0], 1, MPI_INT,
34562 mpiComm(), AT_,
"localNoWallNormalPointCoords",
"localNoWallNormalPointCoords");
34563 MPI_Allgather(&localNoWallNormalPoints[domainId()], 1, MPI_INT, &localNoWallNormalPoints[0], 1, MPI_INT, mpiComm(),
34564 AT_,
"localNoWallNormalPoints",
"localNoWallNormalPoints");
34567 m_wallNormalPointDomains.resize(localNoWallNormalPoints[domainId()]);
34568 std::fill(m_wallNormalPointDomains.begin(), m_wallNormalPointDomains.end(), -1);
34571 m_wallNormalPointCellIDs.resize(localNoWallNormalPoints[domainId()]);
34572 std::fill(m_wallNormalPointCellIDs.begin(), m_wallNormalPointCellIDs.end(), -1);
34574 std::vector<MInt> tempNeghbrIds;
34575 tempNeghbrIds.clear();
34578 m_neighborPointIds.resize(localNoWallNormalPoints[domainId()]);
34579 std::fill(m_neighborPointIds.begin(), m_neighborPointIds.end(), tempNeghbrIds);
34581 for(
MInt dom = 0; dom < noDomains(); dom++) {
34582 MInt noCoords = localNoWallNormalPointCoords[dom];
34583 MInt noPoints = localNoWallNormalPoints[dom];
34587 std::vector<MInt> domainContainingCell;
34588 domainContainingCell.clear();
34590 std::vector<MInt> normalPointCellId;
34591 normalPointCellId.clear();
34593 std::vector<MInt> placement;
34597 std::vector<MInt> neghbrIds;
34601 std::vector<std::vector<MInt>> neghbrIdsofId;
34602 neghbrIdsofId.clear();
34605 std::vector<MInt> oneDimNeghbrs;
34606 oneDimNeghbrs.clear();
34608 std::vector<MInt> noOfNeghbrs;
34609 noOfNeghbrs.clear();
34612 sendCoordsBuffer.
fill(0.0);
34615 ScratchSpace<MInt> allDomainsContainingCell(noPoints, AT_,
"allDomainsContainingCell");
34616 allDomainsContainingCell.
fill(-1);
34619 allNormalPointCellIds.
fill(-1);
34622 noNeighbors.
fill(-1);
34624 ScratchSpace<MInt> allNeighbors(noPoints * ((pow(3, nDim) - 1) * pow(2, nDim) + 1), AT_,
"allNeighbors");
34625 allNeighbors.
fill(-1);
34628 std::vector<std::vector<MInt>> allNeghbrIdsofId;
34629 allNeghbrIdsofId.clear();
34633 allPlacements.
fill(-1);
34636 ScratchSpace<MInt> bufferNoWallNormalPoints(noDomains(), AT_,
"bufferNoWallNormalPoints");
34637 bufferNoWallNormalPoints.
fill(0);
34640 bufferNoNeighbor.
fill(0);
34644 bufferPointOffsets.
fill(0);
34646 ScratchSpace<MInt> bufferNeighborOffsets(noDomains(), AT_,
"bufferNeighborOffsets");
34647 bufferNeighborOffsets.
fill(0);
34650 if(domainId() == dom) {
34651 for(
MInt c = 0; c < noCoords; c++) {
34652 sendCoordsBuffer[c] = m_wallNormalPointCoords[c];
34657 MPI_Bcast(&sendCoordsBuffer[0], noCoords, MPI_DOUBLE, dom, mpiComm(), AT_,
"sendCoordsBuffer");
34660 for(
MInt p = 0; p < noPoints; p++) {
34662 MFloat pointCoords[nDim];
34664 pointCoords[0] = sendCoordsBuffer[nDim * p];
34665 pointCoords[1] = sendCoordsBuffer[nDim * p + 1];
34668 pointCoords[2] = sendCoordsBuffer[nDim * p + 2];
34672 tmpId = grid().raw().findContainingLeafCell(pointCoords);
34675 if(tmpId != -1 && !a_hasProperty(tmpId, SolverCell::IsHalo)) {
34677 neghbrIds = findWallNormalNeighbors(tmpId);
34679 std::vector<MInt> deleteElements;
34680 deleteElements.clear();
34682 for(
MInt i = 0; i <
MInt(neghbrIds.size()); i++) {
34685 MFloat dist_factor = 2.4;
34686 MFloat dist_x = a_coordinate(neghbrIds[i], 0) - a_coordinate(tmpId, 0);
34687 MFloat dist_y = a_coordinate(neghbrIds[i], 1) - a_coordinate(tmpId, 1);
34690 MFloat dist_ref = grid().cellLengthAtLevel(a_level(tmpId));
34693 dist_z = a_coordinate(neghbrIds[i], 2) - a_coordinate(tmpId, 2);
34696 if(abs(dist_x) < 0.05 * dist_ref || abs(dist_y) < 0.05 * dist_ref || abs(dist_z) < 0.05 * dist_ref) {
34700 if((abs(dist_x) < 0.05 * dist_ref && abs(dist_y) < 0.05 * dist_ref)
34701 || (abs(dist_x) < 0.05 * dist_ref && abs(dist_z) < 0.05 * dist_ref)
34702 || (abs(dist_y) < 0.05 * dist_ref && abs(dist_z) < 0.05 * dist_ref)) {
34703 dist_factor = 1.33;
34706 distance = sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z);
34707 if(distance > dist_factor * grid().cellLengthAtLevel(a_level(tmpId))) {
34708 deleteElements.push_back(i);
34712 for(
MInt i = 0; i <
MInt(deleteElements.size()); i++) {
34713 MInt eraseElement = deleteElements.end()[-1 - i];
34714 neghbrIds.erase(neghbrIds.begin() + eraseElement);
34718 MInt d = domainId();
34720 domainContainingCell.push_back(d);
34722 normalPointCellId.push_back(tmpId);
34724 placement.push_back(p);
34726 neghbrIdsofId.push_back(neghbrIds);
34734 oneDimNeghbrs.clear();
34735 for(
MInt i = 0; i <
MInt(neghbrIdsofId.size()); i++) {
34736 noOfNeghbrs.push_back(
MInt(neghbrIdsofId[i].size()));
34737 for(
MInt j = 0; j <
MInt(neghbrIdsofId[i].size()); j++) {
34738 oneDimNeghbrs.push_back(neghbrIdsofId[i][j]);
34742 bufferNoWallNormalPoints[domainId()] = normalPointCellId.
size();
34744 for(
MInt i = 0; i <
MInt(neghbrIdsofId.size()); i++) {
34745 bufferNoNeighbor[domainId()] += neghbrIdsofId[i].
size();
34748 MPI_Allgather(&bufferNoNeighbor[domainId()], 1, MPI_INT, &bufferNoNeighbor[0], 1, MPI_INT, mpiComm(), AT_,
34749 "bufferNoNeighbor",
"bufferNoNeighbor");
34751 MPI_Allgather(&bufferNoWallNormalPoints[domainId()], 1, MPI_INT, &bufferNoWallNormalPoints[0], 1, MPI_INT,
34752 mpiComm(), AT_,
"bufferNoWallNormalPoints",
"bufferNoWallNormalPoints");
34755 for(
MInt d = 0; d < noDomains(); d++) {
34757 bufferPointOffsets[d] = bufferPointOffsets[d - 1] + bufferNoWallNormalPoints[d - 1];
34758 bufferNeighborOffsets[d] = bufferNeighborOffsets[d - 1] + bufferNoNeighbor[d - 1];
34763 MPI_Gatherv(&domainContainingCell[0], bufferNoWallNormalPoints[domainId()], MPI_INT, &allDomainsContainingCell[0],
34764 &bufferNoWallNormalPoints[0], &bufferPointOffsets[0], MPI_INT, dom, mpiComm(), AT_,
34765 "domainContainingCell",
"allDomainsContainingCell");
34768 MPI_Gatherv(&normalPointCellId[0], bufferNoWallNormalPoints[domainId()], MPI_INT, &allNormalPointCellIds[0],
34769 &bufferNoWallNormalPoints[0], &bufferPointOffsets[0], MPI_INT, dom, mpiComm(), AT_,
34770 "normalPointCellId",
"allNormalPointCellIds");
34773 MPI_Gatherv(&placement[0], bufferNoWallNormalPoints[domainId()], MPI_INT, &allPlacements[0],
34774 &bufferNoWallNormalPoints[0], &bufferPointOffsets[0], MPI_INT, dom, mpiComm(), AT_,
"placement",
34778 MPI_Gatherv(&oneDimNeghbrs[0], bufferNoNeighbor[domainId()], MPI_INT, &allNeighbors[0], &bufferNoNeighbor[0],
34779 &bufferNeighborOffsets[0], MPI_INT, dom, mpiComm(), AT_,
"oneDimNeghbrs",
"allNeighbors");
34782 MPI_Gatherv(&noOfNeghbrs[0], bufferNoWallNormalPoints[domainId()], MPI_INT, &noNeighbors[0],
34783 &bufferNoWallNormalPoints[0], &bufferPointOffsets[0], MPI_INT, dom, mpiComm(), AT_,
"noOfNeghbrs",
34786 if(domainId() == dom) {
34788 MInt count_next = 0;
34789 std::vector<MInt> tempVec;
34791 for(
MInt k = 0; k < noPoints; k++) {
34792 count_next = count_next + noNeighbors[k];
34793 for(
MInt j = count; j < count_next; j++) {
34794 tempVec.push_back(allNeighbors[j]);
34797 allNeghbrIdsofId.push_back(tempVec);
34798 count = count_next;
34802 for(
MInt c = 0; c < noPoints; c++) {
34803 MInt p = allPlacements[c];
34805 m_wallNormalPointDomains[p] = allDomainsContainingCell[c];
34806 m_wallNormalPointCellIDs[p] = allNormalPointCellIds[c];
34807 m_neighborPointIds[p] = allNeghbrIdsofId[c];
34815template <MInt nDim_,
class SysEqn>
34819 m_log <<
"Find Neighbor Points of Wall Normal Point" << endl;
34821 const MInt tmpId = pointId;
34822 MInt tempNeghbrId = 0;
34825 std::vector<MInt> neghbrIds;
34828 std::vector<MInt> dirOfNeghbrIds;
34829 dirOfNeghbrIds.clear();
34831 std::vector<MInt> diagNeghbrIds;
34832 diagNeghbrIds.clear();
34834 std::vector<std::vector<MInt>> dirOfDiagNeghbrIds;
34835 dirOfDiagNeghbrIds.clear();
34838 if(tmpId != -1 && !a_hasProperty(tmpId, SolverCell::IsHalo)) {
34840 if(!a_isBndryGhostCell(tmpId)) {
34841 if(a_hasProperty(tmpId, SolverCell::IsOnCurrentMGLevel)) {
34842 for(
MInt dir = 0; dir < m_noDirs; dir++) {
34843 if(a_hasNeighbor(tmpId, dir) > 0 && checkNeighborActive(tmpId, dir)) {
34844 tempNeghbrId = c_neighborId(tmpId, dir);
34845 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
34846 neghbrIds.push_back(tempNeghbrId);
34847 dirOfNeghbrIds.push_back(dir);
34850 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
34851 if(c_childId(tempNeghbrId, childId) == -1) {
34854 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
34855 dirOfNeghbrIds.push_back(dir);
34862 for(
MInt dir = 0; dir < 2; dir++) {
34863 if(a_hasNeighbor(neghbrIds[dir], 2) > 0 && checkNeighborActive(neghbrIds[dir], 2)) {
34864 tempNeghbrId = c_neighborId(neghbrIds[dir], 2);
34865 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
34866 diagNeghbrIds.push_back(tempNeghbrId);
34867 dirOfDiagNeghbrIds.push_back({dir, 2});
34870 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
34871 if(c_childId(tempNeghbrId, childId) == -1) {
34874 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
34875 dirOfDiagNeghbrIds.push_back({dir, 2});
34880 if(a_hasNeighbor(neghbrIds[dir], 3) > 0 && checkNeighborActive(neghbrIds[dir], 3)) {
34881 tempNeghbrId = c_neighborId(neghbrIds[dir], 3);
34882 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
34883 diagNeghbrIds.push_back(tempNeghbrId);
34884 dirOfDiagNeghbrIds.push_back({dir, 3});
34887 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
34888 if(c_childId(tempNeghbrId, childId) == -1) {
34891 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
34892 dirOfDiagNeghbrIds.push_back({dir, 3});
34900 for(
MInt i = 0; i <
MInt(neghbrIds.size()); i++) {
34902 if(dirOfNeghbrIds[i] == 0 || dirOfNeghbrIds[i] == 1) {
34908 if(dirOfNeghbrIds[i] == 2 || dirOfNeghbrIds[i] == 3) {
34914 if(dirOfNeghbrIds[i] == 4 || dirOfNeghbrIds[i] == 5) {
34921 for(
MInt j = 0; j < 4; j++) {
34922 if(a_hasNeighbor(neghbrIds[i], tempDir[j]) > 0 && checkNeighborActive(neghbrIds[i], tempDir[j])) {
34923 tempNeghbrId = c_neighborId(neghbrIds[i], tempDir[j]);
34924 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
34925 diagNeghbrIds.push_back(tempNeghbrId);
34926 dirOfDiagNeghbrIds.push_back({dirOfNeghbrIds[i], tempDir[j]});
34929 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
34930 if(c_childId(tempNeghbrId, childId) == -1) {
34933 diagNeghbrIds.push_back(c_childId(tempNeghbrId, childId));
34934 dirOfDiagNeghbrIds.push_back({dirOfNeghbrIds[i], tempDir[j]});
34943 if(neghbrIds.size() > 5) {
34944 for(
MInt dir = 1; dir < nDim; dir++) {
34945 MInt dirOfNeghbr = 2 * dir + 2;
34946 if(dirOfNeghbr == 6) {
34949 if(a_hasNeighbor(neghbrIds[2 * dir], dirOfNeghbr) > 0
34950 && checkNeighborActive(neghbrIds[2 * dir], dirOfNeghbr)) {
34951 tempNeghbrId = c_neighborId(neghbrIds[2 * dir], dirOfNeghbr);
34952 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
34953 diagNeghbrIds.push_back(tempNeghbrId);
34956 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
34957 if(c_childId(tempNeghbrId, childId) == -1) {
34960 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
34965 if(a_hasNeighbor(neghbrIds[2 * dir], dirOfNeghbr + 1) > 0
34966 && checkNeighborActive(neghbrIds[2 * dir], dirOfNeghbr + 1)) {
34967 tempNeghbrId = c_neighborId(neghbrIds[2 * dir], dirOfNeghbr + 1);
34968 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
34969 diagNeghbrIds.push_back(tempNeghbrId);
34972 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
34973 if(c_childId(tempNeghbrId, childId) == -1) {
34976 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
34981 if(a_hasNeighbor(neghbrIds[2 * dir + 1], dirOfNeghbr) > 0
34982 && checkNeighborActive(neghbrIds[2 * dir + 1], dirOfNeghbr)) {
34983 tempNeghbrId = c_neighborId(neghbrIds[2 * dir + 1], dirOfNeghbr);
34984 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
34985 diagNeghbrIds.push_back(tempNeghbrId);
34989 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
34990 if(c_childId(tempNeghbrId, childId) == -1) {
34993 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
34998 if(a_hasNeighbor(neghbrIds[2 * dir + 1], dirOfNeghbr + 1) > 0
34999 && checkNeighborActive(neghbrIds[2 * dir + 1], dirOfNeghbr + 1)) {
35000 tempNeghbrId = c_neighborId(neghbrIds[2 * dir + 1], dirOfNeghbr + 1);
35001 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
35002 diagNeghbrIds.push_back(tempNeghbrId);
35005 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
35006 if(c_childId(tempNeghbrId, childId) == -1) {
35009 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
35017 if(diagNeghbrIds.size() > 3) {
35018 for(
MInt dir = 0; dir < 4; dir++) {
35019 if(a_hasNeighbor(diagNeghbrIds[dir], 4) > 0 && checkNeighborActive(diagNeghbrIds[dir], 4)) {
35020 tempNeghbrId = c_neighborId(diagNeghbrIds[dir], 4);
35021 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
35022 diagNeghbrIds.push_back(tempNeghbrId);
35025 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
35026 if(c_childId(tempNeghbrId, childId) == -1) {
35029 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
35034 if(a_hasNeighbor(diagNeghbrIds[dir], 5) > 0 && checkNeighborActive(diagNeghbrIds[dir], 5)) {
35035 tempNeghbrId = c_neighborId(diagNeghbrIds[dir], 5);
35036 if(a_hasProperty(tempNeghbrId, SolverCell::IsOnCurrentMGLevel)) {
35037 diagNeghbrIds.push_back(tempNeghbrId);
35040 for(
MInt childId = 0; childId <
IPOW2(nDim); childId++) {
35041 if(c_childId(tempNeghbrId, childId) == -1) {
35044 neghbrIds.push_back(c_childId(tempNeghbrId, childId));
35056 neghbrIds.insert(neghbrIds.end(), diagNeghbrIds.begin(), diagNeghbrIds.end());
35057 sort(neghbrIds.begin(), neghbrIds.end());
35058 neghbrIds.erase(unique(neghbrIds.begin(), neghbrIds.end()), neghbrIds.end());
35060 neghbrIds.push_back(tmpId);
35061 m_log <<
"done" << endl;
35066template <MInt nDim_,
class SysEqn>
35068 std::vector<MInt> neighborList) {
35071 m_log <<
"Interpolate Wall Normal Point Variables ... " << endl;
35073 MFloat result = -99999999.9;
35074 const MInt tmpId = localId;
35075 MFloat pointCoords[nDim];
35081 InverseMatrix.
set(0.0);
35086 std::vector<MInt> neghbrIds;
35088 neghbrIds = neighborList;
35089 const MInt noNeghbrs = neghbrIds.size();
35092 if(noNeghbrs < ((nDim + 1) * 2)) {
35093 return a_pvariable(tmpId, variable);
35096 if(!neghbrIds.empty() && neghbrIds.back() != tmpId) {
35097 cout <<
"WrongList " << endl;
35098 neghbrIds = findWallNormalNeighbors(tmpId);
35101 originX = a_coordinate(tmpId, 0);
35102 originY = a_coordinate(tmpId, 1);
35103 pointCoords[0] = coords[0];
35104 pointCoords[1] = coords[1];
35107 originZ = a_coordinate(tmpId, 2);
35108 pointCoords[2] = coords[2];
35127 for(
MInt nId = 0; nId < noNeghbrs; nId++) {
35132 const MInt tmpNeghbrId = neghbrIds[nId];
35133 if(tmpNeghbrId < 0) {
35134 mTerm(1,
"neighborId < 0 during normal point interpolation");
35137 x = a_coordinate(tmpNeghbrId, 0) - originX;
35138 y = a_coordinate(tmpNeghbrId, 1) - originY;
35140 z = a_coordinate(tmpNeghbrId, 2) - originZ;
35143 const MFloat var = a_pvariable(tmpNeghbrId, variable);
35154 sumVarX += var * x;
35155 sumVarY += var *
y;
35156 sumVarZ += var * z;
35161 LMatrix(0, 0) = noNeghbrs;
35162 LMatrix(1, 1) = sumX2;
35163 LMatrix(2, 2) = sumY2;
35165 LMatrix(0, 1) = LMatrix(1, 0) = sumX;
35166 LMatrix(0, 2) = LMatrix(2, 0) = sumY;
35168 LMatrix(1, 2) = LMatrix(2, 1) = sumXY;
35170 LMatrix(0, 0) = noNeghbrs;
35171 LMatrix(1, 1) = sumX2;
35172 LMatrix(2, 2) = sumY2;
35173 LMatrix(3, 3) = sumZ2;
35175 LMatrix(0, 1) = LMatrix(1, 0) = sumX;
35176 LMatrix(0, 2) = LMatrix(2, 0) = sumY;
35177 LMatrix(0, 3) = LMatrix(3, 0) = sumZ;
35179 LMatrix(1, 2) = LMatrix(2, 1) = sumXY;
35180 LMatrix(1, 3) = LMatrix(3, 1) = sumXZ;
35182 LMatrix(2, 3) = LMatrix(3, 2) = sumYZ;
35185 MFloat normFactor =
FPOW2(2 * a_level(tmpId)) / grid().cellLengthAtLevel(0);
35187 for(
MInt i = 0; i < nDim + 1; i++) {
35188 for(
MInt j = 0; j < nDim + 1; j++) {
35189 LMatrix(i, j) *= normFactor;
35199 std::fill_n(&rightVector[0], nDim + 1, 0.0);
35200 std::fill_n(&coeffVector[0], nDim + 1, 0.0);
35202 rightVector[0] = sumVar;
35203 rightVector[1] = sumVarX;
35204 rightVector[2] = sumVarY;
35206 rightVector[3] = sumVarZ;
35209 for(
MInt i = 0; i < nDim + 1; i++) {
35210 rightVector[i] *= normFactor;
35213 for(
MInt i = 0; i < nDim + 1; i++) {
35214 for(
MInt j = 0; j < nDim + 1; j++) {
35215 coeffVector[i] += InverseMatrix(i, j) * rightVector[j];
35219 result = coeffVector[0] + coeffVector[1] * (pointCoords[0] - originX) + coeffVector[2] * (pointCoords[1] - originY);
35221 result += coeffVector[3] * (pointCoords[2] - originZ);
35229template <MInt nDim_,
class SysEqn>
35233 const MInt noVars = PV->noVariables;
35235 ScratchSpace<MInt> localNoWallNormalPoints(noDomains(), AT_,
"localNoWallNormalPoints");
35236 localNoWallNormalPoints.
fill(0);
35238 ScratchSpace<MInt> localNoWallNormalCoords(noDomains(), AT_,
"localNoWallNormalPoints");
35239 localNoWallNormalCoords.
fill(0);
35241 localNoWallNormalPoints[domainId()] = m_wallNormalPointCellIDs.
size();
35242 localNoWallNormalCoords[domainId()] = m_wallNormalPointCoords.
size();
35244 MPI_Allgather(&localNoWallNormalPoints[domainId()], 1, MPI_INT, &localNoWallNormalPoints[0], 1, MPI_INT, mpiComm(),
35245 AT_,
"localNoWallNormalPoints",
"localNoWallNormalPoints");
35246 MPI_Allgather(&localNoWallNormalCoords[domainId()], 1, MPI_INT, &localNoWallNormalCoords[0], 1, MPI_INT, mpiComm(),
35247 AT_,
"localNoWallNormalCoords",
"localNoWallNormalCoords");
35250 ScratchSpace<MFloat> outVariables(localNoWallNormalPoints[domainId()] * noVars, AT_,
"outVariables");
35251 outVariables.
fill(-99999999.9);
35252 ScratchSpace<MFloat> outVariablesTransformed(localNoWallNormalPoints[domainId()], AT_,
"outVariablesTransformed");
35253 outVariablesTransformed.
fill(-99999999.9);
35255 for(
MInt dom = 0; dom < noDomains(); dom++) {
35256 MInt noPoints = localNoWallNormalPoints[dom];
35257 MInt noCoords = localNoWallNormalCoords[dom];
35259 std::vector<MInt> placement;
35261 std::vector<MFloat> variables;
35265 sendDomainsBuffer.
fill(-1);
35268 sendLocalIdsBuffer.
fill(-1);
35271 sendLocalCoordsBuffer.
fill(0.0);
35273 ScratchSpace<MInt> sendLocalNeighborsBuffer(noPoints * ((pow(3, nDim) - 1) * pow(2, nDim) + 1), AT_,
35274 "sendLocalNeighborsBuffer");
35275 sendLocalIdsBuffer.
fill(-1);
35276 ScratchSpace<MInt> sendLocalNoNeighborsBuffer(noPoints, AT_,
"sendLocalNoNeighborsBuffer");
35277 sendLocalIdsBuffer.
fill(-1);
35281 allPlacements.
fill(-1);
35284 allVariables.
fill(-99999999.9);
35288 bufferNoVariables.
fill(0);
35291 bufferVarsOffsets.
fill(0);
35294 bufferNoPoints.
fill(0);
35296 bufferPointOffsets.
fill(0);
35299 if(domainId() == dom) {
35300 std::vector<MInt> localNeighbors;
35301 localNeighbors.clear();
35302 for(
MInt c = 0; c < noPoints; c++) {
35303 sendDomainsBuffer[c] = m_wallNormalPointDomains[c];
35304 sendLocalIdsBuffer[c] = m_wallNormalPointCellIDs[c];
35305 sendLocalNoNeighborsBuffer[c] = m_neighborPointIds[c].
size();
35306 for(
MInt position = 0; position <
MInt(m_neighborPointIds[c].size()); position++) {
35307 localNeighbors.push_back(m_neighborPointIds[c][position]);
35310 for(
MInt neighbor = 0; neighbor <
MInt(localNeighbors.size()); neighbor++) {
35311 sendLocalNeighborsBuffer[neighbor] = localNeighbors[neighbor];
35313 for(
MInt co = 0; co < noCoords; co++) {
35314 sendLocalCoordsBuffer[co] = m_wallNormalPointCoords[co];
35318 MPI_Bcast(&sendDomainsBuffer[0], noPoints, MPI_INT, dom, mpiComm(), AT_,
"sendDomainsBuffer");
35319 MPI_Bcast(&sendLocalIdsBuffer[0], noPoints, MPI_INT, dom, mpiComm(), AT_,
"sendLocalIdsBuffer");
35320 MPI_Bcast(&sendLocalCoordsBuffer[0], noCoords, MPI_DOUBLE, dom, mpiComm(), AT_,
"sendLocalCoordsBuffer");
35321 MPI_Bcast(&sendLocalNoNeighborsBuffer[0], noPoints, MPI_INT, dom, mpiComm(), AT_,
"sendLocalNoNeighborsBuffer");
35322 MPI_Bcast(&sendLocalNeighborsBuffer[0], noPoints * 209, MPI_INT, dom, mpiComm(), AT_,
"sendLocalNeighborsBuffer");
35325 MInt count_next = 0;
35326 std::vector<std::vector<MInt>> neighborList;
35327 neighborList.clear();
35329 std::vector<MInt> tempVec;
35332 for(
MInt k = 0; k < noPoints; k++) {
35333 count_next = count_next + sendLocalNoNeighborsBuffer[k];
35334 for(
MInt j = count; j < count_next; j++) {
35335 tempVec.push_back(sendLocalNeighborsBuffer[j]);
35338 neighborList.push_back(tempVec);
35339 count = count_next;
35344 for(
MInt p = 0; p < noPoints; p++) {
35345 MInt originDomain = sendDomainsBuffer[p];
35346 if(originDomain == domainId()) {
35347 MInt localId = sendLocalIdsBuffer[p];
35348 placement.push_back(p);
35350 MFloat localCoords[nDim];
35351 localCoords[0] = sendLocalCoordsBuffer[nDim * p];
35352 localCoords[1] = sendLocalCoordsBuffer[nDim * p + 1];
35354 localCoords[2] = sendLocalCoordsBuffer[nDim * p + 2];
35358 for(
MInt v = 0; v < noVars; v++) {
35360 MFloat var = a_pvariable(localId, v);
35361 MFloat interpolatedVar = interpolateWallNormalPointVars(v, localCoords, localId, neighborList[p]);
35362 if(m_useWallNormalInterpolation) {
35363 variables.push_back(interpolatedVar);
35365 variables.push_back(var);
35371 bufferNoVariables[domainId()] = variables.
size() * 2;
35372 bufferNoPoints[domainId()] = placement.
size();
35375 MPI_Allgather(&bufferNoVariables[domainId()], 1, MPI_INT, &bufferNoVariables[0], 1, MPI_INT, mpiComm(), AT_,
35376 "bufferNoVariables",
"bufferNoVariables");
35378 MPI_Allgather(&bufferNoPoints[domainId()], 1, MPI_INT, &bufferNoPoints[0], 1, MPI_INT, mpiComm(), AT_,
35379 "bufferNoPoints",
"bufferNoPoints");
35381 for(
MInt d = 0; d < noDomains(); d++) {
35383 bufferVarsOffsets[d] = bufferVarsOffsets[d - 1] + bufferNoVariables[d - 1];
35384 bufferPointOffsets[d] = bufferPointOffsets[d - 1] + bufferNoPoints[d - 1];
35388 MPI_Gatherv(&placement[0], bufferNoPoints[domainId()], MPI_INT, &allPlacements[0], &bufferNoPoints[0],
35389 &bufferPointOffsets[0], MPI_INT, dom, mpiComm(), AT_,
"placement",
"allPlacements");
35391 MPI_Gatherv(&variables[0], bufferNoVariables[domainId()], MPI_FLOAT, &allVariables[0], &bufferNoVariables[0],
35392 &bufferVarsOffsets[0], MPI_FLOAT, dom, mpiComm(), AT_,
"variables",
"allVariables");
35395 if(domainId() == dom) {
35396 for(
MInt c = 0; c < noPoints; c++) {
35397 MInt p = allPlacements[c];
35399 for(
MInt v = 0; v < noVars; v++) {
35400 outVariables[p * noVars + v] = allVariables[c * noVars + v];
35408 if(domainId() == 0) {
35410 if(m_useWallNormalInterpolation) {
35411 interpolated =
"interpolated";
35413 cerr <<
"Writing " << interpolated <<
" NETCDF wallNormalData at time step " <<
globalTimeStep <<
" ... ";
35425 for(
MInt p = 0; p < localNoWallNormalPoints[domainId()]; p++) {
35426 if((p % m_normalNoPoints) == 0) {
35427 nx = m_wallNormalVectors[n * 2];
35428 ny = m_wallNormalVectors[n * 2 + 1];
35432 u = outVariables[p * noVars];
35433 v = outVariables[p * noVars + 1];
35438 tg1 = (nx * cos((3 * PI) / 2) - ny * sin((3 * PI) / 2));
35439 tg2 = (nx * sin((3 * PI) / 2) + ny * cos((3 * PI) / 2));
35440 }
else if(ny < 0) {
35441 tg1 = (nx * cos(PI / 2) - ny * sin(PI / 2));
35442 tg2 = (nx * sin(PI / 2) + ny * cos(PI / 2));
35445 ut = u * tg1 + v * tg2;
35447 outVariablesTransformed[p] = ut;
35455 if(m_useWallNormalInterpolation) {
35456 dataFileName = outputDir() +
"/pp_normals/interpolatedWallNormalData_" + to_string(
globalTimeStep) +
".Netcdf";
35458 dataFileName = outputDir() +
"/pp_normals/wallNormalData_" + to_string(
globalTimeStep) +
".Netcdf";
35461 ParallelIo parallelIo(dataFileName, PIO_REPLACE, mpiComm());
35463 MInt localNoNormalPoints = m_wallNormalPointCoords.size() / nDim;
35465 MInt workaround = 0;
35466 if(localNoNormalPoints == 0) {
35470 ParallelIo::size_type pointOffset;
35471 ParallelIo::size_type globalNoPoints;
35473 ParallelIo::size_type normalOffset;
35474 ParallelIo::size_type globalNoNormals;
35476 parallelIo.calcOffset(localNoNormalPoints, &pointOffset, &globalNoPoints, mpiComm());
35477 parallelIo.calcOffset(m_noWallNormals, &normalOffset, &globalNoNormals, mpiComm());
35479 parallelIo.defineScalar(PIO_INT,
"points_per_normal");
35480 parallelIo.defineScalar(PIO_FLOAT,
"normal_length");
35481 parallelIo.defineScalar(PIO_FLOAT,
"segment_length");
35483 parallelIo.defineArray(PIO_FLOAT,
"originCoordX", globalNoNormals);
35484 parallelIo.defineArray(PIO_FLOAT,
"originCoordZ", globalNoNormals);
35485 parallelIo.defineArray(PIO_INT,
"originSide", globalNoNormals);
35487 parallelIo.defineArray(PIO_FLOAT,
"coordinate_x", globalNoPoints);
35488 parallelIo.defineArray(PIO_FLOAT,
"coordinate_y", globalNoPoints);
35490 parallelIo.defineArray(PIO_FLOAT,
"coordinate_z", globalNoPoints);
35493 parallelIo.defineArray(PIO_FLOAT,
"variable_U_t", globalNoPoints);
35495 parallelIo.defineArray(PIO_FLOAT,
"variable_rho", globalNoPoints);
35496 parallelIo.defineArray(PIO_FLOAT,
"variable_p", globalNoPoints);
35498 MFloat segmentLength = m_normalLength / (m_normalNoPoints - 1);
35500 parallelIo.writeScalar(m_normalNoPoints,
"points_per_normal");
35501 parallelIo.writeScalar(m_normalLength,
"normal_length");
35502 parallelIo.writeScalar(segmentLength,
"segment_length");
35504 if(workaround == 0) {
35505 parallelIo.setOffset(localNoNormalPoints, pointOffset);
35507 parallelIo.writeArray(&m_wallNormalPointCoords[0],
"coordinate_x", nDim);
35508 parallelIo.writeArray(&m_wallNormalPointCoords[1],
"coordinate_y", nDim);
35510 parallelIo.writeArray(&m_wallNormalPointCoords[2],
"coordinate_z", nDim);
35513 parallelIo.writeArray(&outVariablesTransformed[0],
"variable_U_t", 1);
35516 parallelIo.writeArray(&outVariables[2],
"variable_rho", noVars);
35517 parallelIo.writeArray(&outVariables[3],
"variable_p", noVars);
35519 parallelIo.writeArray(&outVariables[3],
"variable_rho", noVars);
35520 parallelIo.writeArray(&outVariables[4],
"variable_p", noVars);
35523 parallelIo.setOffset(m_noWallNormals, normalOffset);
35525 parallelIo.writeArray(&m_wallSetupOrigin[0],
"originCoordX", 2);
35526 parallelIo.writeArray(&m_wallSetupOrigin[1],
"originCoordZ", 2);
35527 parallelIo.writeArray(&m_wallSetupOriginSide[0],
"originSide", 1);
35530 parallelIo.setOffset(localNoNormalPoints, pointOffset);
35531 parallelIo.writeArray(&workaround,
"coordinate_x", 1);
35532 parallelIo.writeArray(&workaround,
"coordinate_y", 1);
35535 parallelIo.writeArray(&workaround,
"coordinate_z", 1);
35538 parallelIo.writeArray(&workaround,
"variable_U_t", 1);
35540 parallelIo.writeArray(&workaround,
"variable_rho", 1);
35541 parallelIo.writeArray(&workaround,
"variable_p", 1);
35543 parallelIo.setOffset(m_noWallNormals, normalOffset);
35545 parallelIo.writeArray(&workaround,
"originCoordX", 1);
35546 parallelIo.writeArray(&workaround,
"originCoordZ", 1);
35547 parallelIo.writeArray(&workaround,
"originSide", 1);
35552 if(domainId() == 0) {
35553 cerr <<
"ok" << endl;
35559template <MInt nDim_,
class SysEqn>
35561 std::ofstream logfile;
35562 logfile.open(name +
"_" + std::to_string(domainId()));
35565 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
35566 logfile << cellId <<
" g" << c_globalId(cellId);
35567 logfile <<
" " << a_properties(cellId);
35568 logfile <<
" bnd" << a_bndryId(cellId) << std::endl;
35570 logfile << std::endl;
35573 const MInt noBndryCells = m_bndryCells->size();
35574 for(
MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
35575 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
35577 logfile <<
"b" << bndryId <<
" g" << c_globalId(cellId) <<
" " << cellId <<
" " << a_bndryId(cellId) <<
" leaf"
35578 << c_isLeafCell(cellId) <<
" halo" << a_isHalo(cellId) <<
" " << a_properties(cellId) << std::endl;
35586template <MInt nDim,
class SysEqn>
35590 if(grid().noAzimuthalNeighborDomains() == 0)
return;
35597 windowBuff.fill(0);
35599 this->m_azimuthalCartRecCoord.clear();
35600 this->m_azimuthalCartRecCoord.resize(rcvSize * nDim);
35601 MFloat angle = grid().azimuthalAngle();
35605 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35606 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
35607 MInt cellId = grid().azimuthalHaloCell(i, j);
35608 ASSERT(a_isPeriodic(cellId),
"azimuthal halo is not isPeriodic!");
35611 for(
MInt d = 0; d < nDim; d++) {
35612 recCoord[d] = c_coordinate(cellId, d);
35615 MInt side = grid().determineAzimuthalBoundarySide(recCoord);
35617 grid().rotateCartesianCoordinates(recCoord, (side * angle));
35619 ASSERT(!cellOutside(cellId),
"Halo outside!");
35621 for(
MInt d = 0; d < nDim; d++) {
35622 haloBuff[sndCnt++] = recCoord[d];
35628 grid().azimuthalHaloCells(), mpiComm(), haloBuff.getPointer(), windowBuff.getPointer(),
35632 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35633 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
35634 for(
MInt d = 0; d < nDim; d++) {
35635 this->m_azimuthalCartRecCoord[rcvCnt] = windowBuff[rcvCnt];
35640 for(
MInt d = 0; d < nDim; d++) {
35641 point[d] = this->m_azimuthalCartRecCoord[rcvCnt - nDim + d];
35643 if(!this->inCell(grid().azimuthalWindowCell(i, j), point, F1 + pow(10, -12))) {
35644 mTerm(1, AT_,
"Point not inside");
35654template <MInt nDim,
class SysEqn>
35658 if(domainId() == 0) {
35659 cerr <<
"Init Azimuthal Reconstruction...";
35662 m_planeInterp =
false;
35663 m_planeInterp = Context::getSolverProperty<MBool>(
"planeInterp", m_solverId, AT_, &m_planeInterp);
35664 ASSERT(!m_planeInterp,
"m_planeInterp is untested");
35666 MBool noInterp = Context::getSolverProperty<MBool>(
"noInterp", m_solverId, AT_);
35667 if(noInterp && grid().noAzimuthalUnmappedHaloCells())
mTerm(1, AT_
"Grid not symmetric!");
35670 MFloat angle = grid().azimuthalAngle();
35673 MIntScratchSpace sndSize(grid().noAzimuthalNeighborDomains(), AT_,
"sndSize");
35675 MInt sndSizeTotal = 0;
35676 for(
MInt i = 0; i < grid().noAzimuthalUnmappedHaloCells(); i++) {
35677 MInt cellId = grid().azimuthalUnmappedHaloCell(i);
35678 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
35679 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
35680 if(a_bndryId(cellId) < 0)
continue;
35681 MInt dom = grid().azimuthalDomainIndex(grid().azimuthalUnmappedHaloDomain(i));
35686 MIntScratchSpace rcvSize(grid().noAzimuthalNeighborDomains(), AT_,
"rcvSize");
35689 sndReq.fill(MPI_REQUEST_NULL);
35690 rcvReq.fill(MPI_REQUEST_NULL);
35692 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35693 MPI_Isend(&sndSize[i], 1, MPI_INT, grid().azimuthalNeighborDomain(i), 9, mpiComm(), &sndReq[i], AT_,
"sndSize[i]");
35695 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35696 MPI_Recv(&rcvSize[i], 1, MPI_INT, grid().azimuthalNeighborDomain(i), 9, mpiComm(), MPI_STATUS_IGNORE, AT_,
35699 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35700 MPI_Wait(&sndReq[i], MPI_STATUSES_IGNORE, AT_);
35703 MInt rcvSizeTotal = 0;
35704 MIntScratchSpace sndOffsets(grid().noAzimuthalNeighborDomains() + 1, AT_,
"sndOffsets");
35705 MIntScratchSpace rcvOffsets(grid().noAzimuthalNeighborDomains() + 1, AT_,
"rcvOffsets");
35708 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35709 rcvSizeTotal += rcvSize[i];
35710 rcvOffsets[i + 1] = rcvOffsets[i] + rcvSize[i];
35712 sndOffsets[i + 1] = sndOffsets[i] + sndSize[i];
35719 for(
MInt i = 0; i < grid().noAzimuthalUnmappedHaloCells(); i++) {
35720 MInt cellId = grid().azimuthalUnmappedHaloCell(i);
35721 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
35722 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
35723 if(a_bndryId(cellId) < 0)
continue;
35725 if(a_bndryId(cellId) < 0) {
35726 cerr <<
"D:" << domainId() <<
" " <<
cellId <<
"/" << c_globalId(cellId) <<
" "
35727 << grid().azimuthalUnmappedHaloDomain(i) <<
" " << grid().tree().solver2grid(cellId) <<
"/"
35728 << c_globalId(grid().tree().solver2grid(cellId));
35729 if(c_parentId(cellId) > -1) {
35730 cerr <<
" " << grid().tree().solver2grid(c_parentId(cellId)) <<
"/"
35731 << c_globalId(grid().tree().solver2grid(c_parentId(cellId)));
35733 cerr <<
" " << a_coordinate(cellId, 0) <<
" " << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, 2) <<
" "
35734 << a_hasProperty(cellId, SolverCell::IsInactive) <<
" level: " << a_level(cellId) << endl;
35735 mTerm(1, AT_,
"Unmapped halo which is not bndryCell?");
35738 MInt dom = grid().azimuthalDomainIndex(grid().azimuthalUnmappedHaloDomain(i));
35740 MInt side = grid().determineAzimuthalBoundarySide(&a_coordinate(cellId, 0));
35742 for(
MInt d = 0; d < nDim; d++) {
35743 recCoord[d] = a_coordinate(cellId, d);
35745 grid().rotateCartesianCoordinates(recCoord, (side * angle));
35747 for(
MInt d = 0; d < nDim; d++) {
35748 sndBuff[sndOffsets[dom] * (nDim + 1) + sndSize[dom] * (nDim + 1) + d] = recCoord[d];
35750 sndBuff[sndOffsets[dom] * (nDim + 1) + sndSize[dom] * (nDim + 1) + nDim] = (
MFloat)side;
35755 sndReq.fill(MPI_REQUEST_NULL);
35756 rcvReq.fill(MPI_REQUEST_NULL);
35758 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35759 if(sndSize[i] <= 0)
continue;
35761 grid().azimuthalNeighborDomain(i), 13, mpiComm(), &sndReq[i], AT_,
"sndBuff[sndOffsets[i]*(nDim+1)]");
35764 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35765 if(rcvSize[i] <= 0)
continue;
35767 grid().azimuthalNeighborDomain(i), 13, mpiComm(), MPI_STATUS_IGNORE, AT_,
35768 "rcvBuff[rcvOffsets[i]*(nDim+1)]");
35771 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35772 if(sndSize[i] <= 0)
continue;
35773 MPI_Wait(&sndReq[i], MPI_STATUSES_IGNORE, AT_);
35778 set<MInt> nearBndryCells;
35779 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
35780 for(
MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
35781 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
35782 if(!a_isHalo(cellId)) {
35783 nearBndryCells.insert(cellId);
35785 MInt counter = grid().getAdjacentGridCells(cellId, 1, nghbrList, a_level(cellId), 0);
35786 for(
MInt n = 0; n < counter; n++) {
35787 MInt nghbrId = nghbrList[n];
35788 if(!a_isHalo(nghbrId)) {
35789 nearBndryCells.insert(nghbrId);
35796 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35797 for(
MInt j = 0; j < rcvSize[i]; j++) {
35798 for(
MInt d = 0; d < nDim; d++) {
35799 recCoord[d] = rcvBuff[rcvCnt++];
35801 MInt side = (
MInt)rcvBuff[rcvCnt++];
35803 MInt actualDom = domainId();
35807 for(
MInt e = -12; e < 0; e++) {
35808 MFloat eps = F1 + pow(10, e);
35809 for(
auto it = nearBndryCells.begin(); it != nearBndryCells.end(); ++it) {
35810 MInt bndryCell = *it;
35812 if(this->inCell(bndryCell, recCoord, eps)) {
35821 for(
MInt n = 0; n < noNeighborDomains(); n++) {
35822 for(
MInt c = 0; c < noHaloCells(n); c++) {
35823 if(!c_isLeafCell(haloCellId(n, c)))
continue;
35824 if(this->inCell(haloCellId(n, c), recCoord, eps)) {
35825 cellId = haloCellId(n, c);
35826 actualDom = neighborDomain(n);
35832 if(cellId > -1)
break;
35837 std::copy_n(&recCoord[0], nDim, &dummyCoord[0]);
35838 grid().rotateCartesianCoordinates(dummyCoord, (-side * angle));
35839 cerr <<
"D:" << domainId() <<
" " << grid().azimuthalNeighborDomain(i) <<
" " << j <<
" " << recCoord[0] <<
" "
35840 << recCoord[1] <<
" " << recCoord[nDim - 1] <<
" " << dummyCoord[0] <<
" " << dummyCoord[1] <<
" "
35841 << dummyCoord[nDim - 1] << endl;
35842 mTerm(1, AT_,
"No containing window found!");
35845 rcvBuff[rcvOffsets[i] + j] = actualDom;
35849 sndReq.fill(MPI_REQUEST_NULL);
35850 rcvReq.fill(MPI_REQUEST_NULL);
35852 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35853 if(rcvSize[i] <= 0)
continue;
35855 grid().azimuthalNeighborDomain(i), 13, mpiComm(), &sndReq[i], AT_,
"rcvBuff[rcvOffsets[i]]");
35858 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35859 if(sndSize[i] <= 0)
continue;
35861 grid().azimuthalNeighborDomain(i), 13, mpiComm(), MPI_STATUS_IGNORE, AT_,
"sndBuff[sndOffsets[i]]");
35864 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35865 if(rcvSize[i] <= 0)
continue;
35866 MPI_Wait(&sndReq[i], MPI_STATUSES_IGNORE, AT_);
35870 MInt sndSizeTotalG = 0;
35873 MIntScratchSpace azimuthalUnmappedDomains(grid().noAzimuthalUnmappedHaloCells(), AT_,
"azimuthalUnmappedDomains");
35874 azimuthalUnmappedDomains.fill(-1);
35876 for(
MInt i = 0; i < grid().noAzimuthalUnmappedHaloCells(); i++) {
35877 MInt cellId = grid().azimuthalUnmappedHaloCell(i);
35878 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
35879 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
35880 if(a_bndryId(cellId) < 0)
continue;
35882 MInt assumedDomainIndex = grid().azimuthalDomainIndex(grid().azimuthalUnmappedHaloDomain(i));
35883 MInt actualDomain = sndBuff[sndOffsets[assumedDomainIndex] + sndSize[assumedDomainIndex]];
35884 sndSize[assumedDomainIndex]++;
35886 sndSizeG[actualDomain]++;
35889 azimuthalUnmappedDomains[i] = actualDomain;
35896 sndReqG.fill(MPI_REQUEST_NULL);
35897 rcvReqG.fill(MPI_REQUEST_NULL);
35899 for(
MInt i = 0; i < noDomains(); i++) {
35900 MPI_Isend(&sndSizeG[i], 1, MPI_INT, i, 9, mpiComm(), &sndReqG[i], AT_,
"sndSizeG[i]");
35902 for(
MInt i = 0; i < grid().noDomains(); i++) {
35903 MPI_Recv(&rcvSizeG[i], 1, MPI_INT, i, 9, mpiComm(), MPI_STATUS_IGNORE, AT_,
"rcvSizeG[i]");
35905 MPI_Waitall(noDomains(), &sndReqG[0], MPI_STATUSES_IGNORE, AT_);
35907 MInt noAzimuthalRemappedNeighborDoms = 0;
35908 MInt rcvSizeTotalG = 0;
35909 for(
MInt i = 0; i < noDomains(); i++) {
35910 rcvSizeTotalG += rcvSizeG[i];
35911 if(rcvSizeG[i] > 0 || sndSizeG[i] > 0) noAzimuthalRemappedNeighborDoms++;
35914 m_azimuthalRemappedNeighborDomains.resize(noAzimuthalRemappedNeighborDoms);
35915 m_azimuthalRemappedNeighborsDomainIndex.assign(noDomains(), -1);
35916 m_azimuthalRemappedWindowCells.resize(noAzimuthalRemappedNeighborDoms);
35917 m_azimuthalRemappedHaloCells.resize(noAzimuthalRemappedNeighborDoms);
35918 MIntScratchSpace sndOffsetsG(noAzimuthalRemappedNeighborDoms + 1, AT_,
"sndOffsetsG");
35919 MIntScratchSpace rcvOffsetsG(noAzimuthalRemappedNeighborDoms + 1, AT_,
"rcvOffsetsG");
35920 sndOffsetsG[0] = 0;
35921 rcvOffsetsG[0] = 0;
35923 for(
MInt i = 0; i < noDomains(); i++) {
35924 if(rcvSizeG[i] > 0 || sndSizeG[i] > 0) {
35925 m_azimuthalRemappedNeighborDomains[cnt] = i;
35926 m_azimuthalRemappedNeighborsDomainIndex[i] = cnt;
35927 m_azimuthalRemappedHaloCells[cnt].resize(sndSizeG[i]);
35928 m_azimuthalRemappedWindowCells[cnt].resize(rcvSizeG[i]);
35929 rcvOffsetsG[cnt + 1] = rcvOffsetsG[cnt] + rcvSizeG[i];
35930 sndOffsetsG[cnt + 1] = sndOffsetsG[cnt] + sndSizeG[i];
35932 rcvSizeG[cnt] = rcvSizeG[i];
35941 sndCnt += sndSizeTotalG;
35945 rcvCnt += rcvSizeTotalG;
35947 windowBuff.fill(0);
35949 m_noAzimuthalReconstNghbrs.clear();
35950 m_noAzimuthalReconstNghbrs.assign(rcvCnt, 0);
35951 m_azimuthalCutRecCoord.clear();
35952 m_azimuthalCutRecCoord.assign(rcvCnt * nDim, F0);
35953 m_azimuthalRecConsts.clear();
35954 m_azimuthalRecConsts.assign(rcvCnt * m_maxNoAzimuthalRecConst, F0);
35955 m_azimuthalReconstNghbrIds.clear();
35956 m_azimuthalReconstNghbrIds.assign(rcvCnt * m_maxNoAzimuthalRecConst, -1);
35957 m_azimuthalBndrySide.assign(rcvCnt, 0);
35961 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
35962 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
35963 MInt cellId = grid().azimuthalHaloCell(i, j);
35964 ASSERT(a_isPeriodic(cellId),
"azimuthal halo is not isPeriodic!");
35965 ASSERT(!cellOutside(cellId),
"Halo outside!");
35967 MInt side = grid().determineAzimuthalBoundarySide(&a_coordinate(cellId, 0));
35969 for(
MInt d = 0; d < nDim; d++) {
35970 recCoord[d] = a_coordinate(cellId, d);
35973 if(!(!m_geometry->pointIsInside(recCoord) || c_noChildren(cellId) > 0
35974 || a_hasProperty(cellId, SolverCell::IsInactive))) {
35975 cerr <<
"O:" << domainId() <<
" " <<
cellId <<
"/" << c_globalId(cellId) <<
" " << c_coordinate(cellId, 0)
35976 <<
" " << c_coordinate(cellId, 1) <<
" " << c_coordinate(cellId, 2) <<
" " << a_coordinate(cellId, 0)
35977 <<
" " << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, 2) <<
" " << a_level(cellId) <<
" "
35978 << m_geometry->pointIsInside(recCoord) <<
" " << c_noChildren(cellId) <<
" "
35979 << a_hasProperty(cellId, SolverCell::IsInactive) <<
" " << recCoord[0] <<
" " << recCoord[1] <<
" "
35980 << recCoord[nDim - 1] << endl;
35985 grid().rotateCartesianCoordinates(recCoord, (side * angle));
35987 for(
MInt d = 0; d < nDim; d++) {
35988 haloBuff[sndCnt++] = recCoord[d];
35990 haloBuff[sndCnt++] = (
MFloat)side;
35994 if(grid().noAzimuthalNeighborDomains() > 0) {
35996 grid().azimuthalHaloCells(), mpiComm(), haloBuff.getPointer(), windowBuff.getPointer(),
36002 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36003 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
36004 for(
MInt d = 0; d < nDim; d++) {
36005 recCoord[d] = windowBuff[rcvCnt++];
36008 for(
MInt d = 0; d < nDim; d++) {
36009 m_azimuthalCutRecCoord[offset * nDim + d] = recCoord[d];
36012 MInt side = (
MInt)windowBuff[rcvCnt++];
36013 m_azimuthalBndrySide[offset] = side;
36022 for(
MInt i = 0; i < grid().noAzimuthalUnmappedHaloCells(); i++) {
36023 MInt cellId = grid().azimuthalUnmappedHaloCell(i);
36024 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
continue;
36025 if(a_hasProperty(cellId, SolverCell::IsInactive))
continue;
36026 if(a_bndryId(cellId) < 0)
continue;
36028 MInt actualDomain = azimuthalUnmappedDomains[i];
36029 MInt dom = m_azimuthalRemappedNeighborsDomainIndex[actualDomain];
36030 m_azimuthalRemappedHaloCells[dom][sndSizeG[dom]] =
cellId;
36032 MInt side = grid().determineAzimuthalBoundarySide(&a_coordinate(cellId, 0));
36034 for(
MInt d = 0; d < nDim; d++) {
36035 recCoord[d] = a_coordinate(cellId, d);
36037 grid().rotateCartesianCoordinates(recCoord, (side * angle));
36039 for(
MInt d = 0; d < nDim; d++) {
36040 sndBuffG[sndOffsetsG[dom] * (nDim + 1) + sndSizeG[dom] * (nDim + 1) + d] = recCoord[d];
36042 sndBuffG[sndOffsetsG[dom] * (nDim + 1) + sndSizeG[dom] * (nDim + 1) + nDim] = (
MFloat)side;
36046 sndReqG.fill(MPI_REQUEST_NULL);
36047 rcvReqG.fill(MPI_REQUEST_NULL);
36049 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36050 if(sndSizeG[i] <= 0)
continue;
36052 m_azimuthalRemappedNeighborDomains[i], 13, mpiComm(), &sndReqG[i], AT_,
36053 "sndBuffG[sndOffsetsG[i]*(nDim+1)]");
36056 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36057 if(rcvSizeG[i] <= 0)
continue;
36059 m_azimuthalRemappedNeighborDomains[i], 13, mpiComm(), MPI_STATUS_IGNORE, AT_,
36060 "rcvBuffG[rcvOffsetsG[i]*(nDim+1)]");
36063 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36064 if(sndSizeG[i] <= 0)
continue;
36065 MPI_Wait(&sndReqG[i], MPI_STATUSES_IGNORE, AT_);
36071 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36072 for(
MInt j = 0; j < rcvSizeG[i]; j++) {
36073 for(
MInt d = 0; d < nDim; d++) {
36074 recCoord[d] = rcvBuffG[rcvCnt++];
36076 MInt side = (
MInt)rcvBuffG[rcvCnt++];
36080 for(
MInt e = -12; e < 0; e++) {
36081 MFloat eps = F1 + pow(10, e);
36082 for(
auto it = nearBndryCells.begin(); it != nearBndryCells.end(); ++it) {
36083 MInt bndryCell = *it;
36085 if(this->inCell(bndryCell, recCoord, eps)) {
36091 if(cellId > -1)
break;
36095 std::copy_n(&recCoord[0], nDim, &dummyCoord[0]);
36096 grid().rotateCartesianCoordinates(dummyCoord, (-side * angle));
36097 cerr <<
"D:" << domainId() <<
" " << m_azimuthalRemappedNeighborDomains[i] <<
" " << j <<
" " << rcvSizeG[i]
36098 <<
" " << recCoord[0] <<
" " << recCoord[1] <<
" " << recCoord[nDim - 1] <<
" " << dummyCoord[0] <<
" "
36099 << dummyCoord[1] <<
" " << dummyCoord[nDim - 1] << endl;
36100 mTerm(1, AT_,
"No containing window found!");
36103 m_azimuthalRemappedWindowCells[i][j] =
cellId;
36105 for(
MInt d = 0; d < nDim; d++) {
36106 m_azimuthalCutRecCoord[offset * nDim + d] = recCoord[d];
36108 m_azimuthalBndrySide[offset] = side;
36114 m_azimuthalRecConstSet =
true;
36116 if(domainId() == 0) {
36117 cerr <<
" done" << endl;
36125template <MInt nDim,
class SysEqn>
36132 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36133 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
36134 MInt cellId = grid().azimuthalWindowCell(i, j);
36136 std::copy_n(&m_azimuthalCutRecCoord[offset * nDim], nDim, &recCoord[0]);
36138 rebuildAzimuthalReconstructionConstants(cellId, offset, recCoord, mode);
36144 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36145 for(
MUint j = 0; j < m_azimuthalRemappedWindowCells[i].size(); j++) {
36146 MInt cellId = m_azimuthalRemappedWindowCells[i][j];
36148 std::copy_n(&m_azimuthalCutRecCoord[offset * nDim], nDim, &recCoord[0]);
36150 rebuildAzimuthalReconstructionConstants(cellId, offset, recCoord, mode);
36157template <MInt nDim,
class SysEqn>
36162 const MInt maxNoNghbrs = m_maxNoAzimuthalRecConst;
36165 m_noAzimuthalReconstNghbrs[offset] = 0;
36167 if(m_geometry->pointIsInside(recCoord)) {
36168 if(a_bndryId(cellId) < 0) {
36170 m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst] =
cellId;
36171 m_noAzimuthalReconstNghbrs[offset] = 1;
36172 m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst] = F1;
36173 if(a_level(cellId) == maxRefinementLevel())
mTerm(1, AT_,
"");
36176 std::vector<MFloat> ghostCoord{F0, F0, F0};
36177 for(
MInt srfc = 0; srfc < m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs; srfc++) {
36178 MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcVariables[srfc]->m_ghostCellId;
36179 std::copy_n(&a_coordinate(ghostCellId, 0), nDim, &ghostCoord[0]);
36181 if(a_level(cellId) == maxLevel()) {
36182 cerr <<
"cut cell and stl issue"
36183 <<
" D:" << domainId() <<
" " <<
cellId <<
"/" << c_globalId(cellId) <<
" (" << a_coordinate(cellId, 0)
36184 <<
", " << a_coordinate(cellId, 1) <<
", " << a_coordinate(cellId, 2) <<
") | "
36185 <<
"GC: (" << ghostCoord[0] <<
", " << ghostCoord[1] <<
", " << ghostCoord[2] <<
") | "
36186 <<
"RC: (" << recCoord[0] <<
", " << recCoord[1] <<
", " << recCoord[2] <<
")" << endl;
36194 if((abs(a_coordinate(cellId, 0) - recCoord[0]) > c_cellLengthAtLevel(a_level(cellId))
36195 || abs(a_coordinate(cellId, 1) - recCoord[1]) > c_cellLengthAtLevel(a_level(cellId))
36196 || abs(a_coordinate(cellId, nDim - 1) - recCoord[nDim - 1]) > c_cellLengthAtLevel(a_level(cellId)))
36197 && !a_hasProperty(cellId, SolverCell::IsInactive)) {
36198 MInt side = m_azimuthalBndrySide[offset];
36200 MFloat angle = grid().azimuthalAngle();
36201 cerr <<
"Rec coord " << domainId() <<
" " <<
cellId <<
"/" << c_globalId(cellId) <<
" " << recCoord[0] <<
" "
36202 << recCoord[1] <<
" " << recCoord[nDim - 1] <<
" / Window G " << c_coordinate(cellId, 0) <<
" "
36203 << c_coordinate(cellId, 1) <<
" " << c_coordinate(cellId, nDim - 1) <<
" FV " << a_coordinate(cellId, 0) <<
" "
36204 << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, nDim - 1) <<
" / " << a_level(cellId) <<
" "
36205 << c_cellLengthAtLevel(a_level(cellId)) <<
" " << side;
36207 std::copy_n(&recCoord[0], nDim, &dummyCoord[0]);
36208 grid().rotateCartesianCoordinates(dummyCoord, (-side * angle));
36209 cerr <<
" / Halo " << dummyCoord[0] <<
" " << dummyCoord[1] <<
" " << dummyCoord[nDim - 1] << endl;
36213 MInt contCell = -1;
36214 if(this->inCell(cellId, recCoord)) {
36217 MInt counter = grid().getAdjacentGridCells(cellId, 1, nghbrList, (a_level(cellId) - 1), 2);
36218 for(
MInt n = 0; n < counter; n++) {
36219 MInt nghbrId = nghbrList[n];
36220 if(this->inCell(nghbrId, recCoord)) {
36221 contCell = nghbrId;
36228 MInt counter = grid().getAdjacentGridCells(cellId, 1, nghbrList, (a_level(cellId) - 1), 2);
36229 cerr << domainId() <<
" No contCell"
36230 <<
" " <<
cellId <<
"/" << c_globalId(cellId) <<
" " << a_level(cellId) <<
" G " << c_coordinate(cellId, 0)
36231 <<
" " << c_coordinate(cellId, 1) <<
" " << c_coordinate(cellId, nDim - 1) <<
" S " << a_coordinate(cellId, 0)
36232 <<
" " << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, nDim - 1) <<
" R " << recCoord[0] <<
" "
36233 << recCoord[1] <<
" " << recCoord[2] << endl;
36234 for(
MInt n = 0; n < counter; n++) {
36235 MInt nghbrId = nghbrList[n];
36236 cerr <<
"Nghbr: " << n <<
"/" << (counter - 1) <<
" " << nghbrId <<
"/" << c_globalId(nghbrId) <<
" "
36237 << a_coordinate(nghbrId, 0) <<
" " << a_coordinate(nghbrId, 1) <<
" " << a_coordinate(nghbrId, nDim - 1)
36240 mTerm(1, AT_,
"No containing cell found?");
36243 MInt contCellLC = contCell;
36244 contCellLC = grid().findContainingLeafCell(recCoord, contCell);
36246 if(c_noChildren(cellId) > 0) {
36247 if(this->inCell(cellId, recCoord)) {
36248 cellIdLC = grid().findContainingLeafCell(recCoord, cellId);
36252 for(
MInt l = 0; l < (maxLevel() - a_level(cellId)); l++) {
36253 MFloat minDist = numeric_limits<MFloat>::max();
36254 MInt closestChild = -1;
36255 for(
MInt child = 0; child < grid().m_maxNoChilds; child++) {
36256 const MInt childId = c_childId(nextId, child);
36261 for(
MInt d = 0; d < nDim; d++) {
36262 dist += pow(recCoord[d] - c_coordinate(childId, d), F2);
36264 if(
dist < minDist) {
36265 closestChild = childId;
36268 nextId = closestChild;
36274 if(a_isPeriodic(contCellLC)) {
36275 mTerm(1,
"azimuthal window cell is isPeriodic!");
36279 MBool noInterp = Context::getSolverProperty<MBool>(
"noInterp", m_solverId, AT_);
36281 m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst] = contCellLC;
36282 m_noAzimuthalReconstNghbrs[offset]++;
36283 m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst] = F1;
36288 if(a_hasProperty(contCellLC, SolverCell::IsOnCurrentMGLevel)) {
36289 m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + m_noAzimuthalReconstNghbrs[offset]] = contCellLC;
36290 m_noAzimuthalReconstNghbrs[offset]++;
36292 if(cellIdLC != contCellLC && a_hasProperty(cellIdLC, SolverCell::IsOnCurrentMGLevel)) {
36293 m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + m_noAzimuthalReconstNghbrs[offset]] = cellIdLC;
36294 m_noAzimuthalReconstNghbrs[offset]++;
36298 if(mode == 0 && a_bndryId(contCellLC) > -1) {
36299 for(
MInt srfc = 0; srfc < m_bndryCells->a[a_bndryId(contCellLC)].m_noSrfcs; srfc++) {
36300 MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[a_bndryId(contCellLC)].m_srfcVariables[srfc]->m_ghostCellId;
36301 if(ghostCellId < 0)
mTerm(1, AT_,
"ghostCellId not set!");
36302 m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + m_noAzimuthalReconstNghbrs[offset]] = ghostCellId;
36303 m_noAzimuthalReconstNghbrs[offset]++;
36307 MInt axDir = grid().raw().m_azimuthalAxialDir;
36308 const MInt counter = grid().getAdjacentGridCells(cellIdLC, 2, nghbrList, a_level(cellIdLC), 2);
36309 MInt nghbrTmpCnt = 0;
36311 for(
MInt k = 0; k < counter; k++) {
36312 MInt nghbrId = nghbrList[k];
36313 if(nghbrId < 0)
continue;
36314 if(a_isPeriodic(nghbrId))
mTerm(1,
"azimuthal recNghbr is periodic! Increase cutOffNmbrLayers");
36315 if(!a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel))
continue;
36316 if(nghbrId == contCellLC) {
36319 if(nghbrId == cellIdLC) {
36323 && abs(a_coordinate(nghbrId, axDir) - recCoord[axDir]) / c_cellLengthAtLevel(a_level(contCellLC)) > F1B2) {
36328 if(m_noAzimuthalReconstNghbrs[offset] >= m_maxNoAzimuthalRecConst) {
36329 cerr <<
"too many rec nghbrs " << contCellLC <<
"/" << c_globalId(contCellLC) <<
" " << dbgCnt <<
" "
36330 << m_maxNoAzimuthalRecConst <<
" " << c_coordinate(contCellLC, 0) <<
" " << c_coordinate(contCellLC, 1)
36331 <<
" " << c_coordinate(contCellLC, 2) << endl;
36335 m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + m_noAzimuthalReconstNghbrs[offset]] = nghbrId;
36336 m_noAzimuthalReconstNghbrs[offset]++;
36341 if(nghbrTmpCnt == 0 && !a_hasProperty(contCellLC, SolverCell::IsNotGradient)) {
36342 m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst] = cellIdLC;
36343 m_noAzimuthalReconstNghbrs[offset] = 1;
36344 m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst] = F1;
36348 if(nghbrTmpCnt == 0) {
36349 cerr <<
"D:" << domainId() <<
" " <<
cellId <<
"/" << c_globalId(cellId) <<
" " << contCell <<
"/"
36350 << c_globalId(contCell) <<
" " << c_level(contCell) <<
" " << c_noChildren(contCell) <<
" "
36351 << c_coordinate(contCell, 0) <<
" " << c_coordinate(contCell, 1) <<
" " << c_coordinate(contCell, nDim - 1)
36352 <<
" " << contCellLC <<
"/" << c_globalId(contCellLC) <<
" " << c_level(contCellLC) <<
" "
36353 << c_coordinate(contCellLC, 0) <<
" " << c_coordinate(contCellLC, 1) <<
" "
36354 << c_coordinate(contCellLC, nDim - 1) << endl;
36355 mTerm(1,
"Cell without neighbors?");
36358 const MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
36361 MBool nonlinear =
true;
36362 MInt recDim = nDim + 1;
36364 if(m_planeInterp) {
36367 recDim = 3 * nDim + 1;
36374 const MFloat normalizationFactor =
FPOW2(a_level(contCellLC)) / c_cellLengthAtLevel(0);
36378 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36379 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
36385 if(!a_isBndryGhostCell(recId) && a_isBndryCell(recId)) {
36386 const MFloat vf = a_cellVolume(recId) / c_cellVolumeAtLevel(a_level(recId));
36390 tmpA(nghbr, dimCnt) = F1;
36395 if(m_planeInterp) {
36396 for(
MInt i = 0; i < (nDim - 1); i++) {
36397 MInt perDir1 = grid().azimuthalDir(i);
36398 dx[i] = (a_coordinate(recId, perDir1) - recCoord[perDir1]) * normalizationFactor;
36399 dxdx +=
POW2(a_coordinate(recId, perDir1) - recCoord[perDir1]);
36401 for(
MInt i = 0; i < (nDim - 1); i++) {
36402 tmpA(nghbr, dimCnt) = dx[i];
36406 for(
MInt i = 0; i < nDim; i++) {
36407 dx[i] = (a_coordinate(recId, i) - recCoord[i]) * normalizationFactor;
36408 dxdx +=
POW2(a_coordinate(recId, i) - recCoord[i]);
36410 for(
MInt i = 0; i < nDim; i++) {
36411 tmpA(nghbr, dimCnt) = dx[i];
36419 if(m_planeInterp) {
36420 for(
MInt i = 0; i < (nDim - 1); i++) {
36421 MInt perDir1 = grid().azimuthalDir(i);
36422 tmpA(nghbr, dimCnt) = 0.5 *
POW2((a_coordinate(recId, perDir1) - recCoord[perDir1]) * normalizationFactor);
36425 for(
MInt i = 0; i < (nDim - 1); i++) {
36426 MInt perDir1 = grid().azimuthalDir(i);
36427 for(
MInt j = i + 1; j < (nDim - 1); j++) {
36428 MInt perDir2 = grid().azimuthalDir(j);
36429 tmpA(nghbr, dimCnt) = (a_coordinate(recId, perDir2) - recCoord[perDir2])
36430 * (a_coordinate(recId, perDir1) - recCoord[perDir1]) *
POW2(normalizationFactor);
36435 for(
MInt i = 0; i < nDim; i++) {
36436 tmpA(nghbr, dimCnt) = 0.5 *
POW2((a_coordinate(recId, i) - recCoord[i]) * normalizationFactor);
36439 for(
MInt i = 0; i < nDim; i++) {
36440 for(
MInt j = i + 1; j < nDim; j++) {
36441 tmpA(nghbr, dimCnt) = (a_coordinate(recId, j) - recCoord[j]) * (a_coordinate(recId, i) - recCoord[i])
36442 *
POW2(normalizationFactor);
36448 ASSERT(dimCnt == recDim,
"");
36452 if(rank < min(noNghbrIds, recDim)) {
36453 cerr << domainId() <<
": QRD failed for azimuthal periodic cell " <<
cellId <<
"(" << c_globalId(cellId) <<
") "
36454 << a_isHalo(cellId) <<
" " << a_level(cellId) <<
" " << c_noChildren(cellId) <<
" " << noNghbrIds << endl;
36455 cerr <<
"G: (" << a_coordinate(cellId, 0) <<
", " << a_coordinate(cellId, 1) <<
", "
36456 << a_coordinate(cellId, nDim - 1) <<
") " << endl;
36457 cerr <<
"R: (" << recCoord[0] <<
", " << recCoord[1] <<
", " << recCoord[2] <<
"), "
36458 << m_geometry->pointIsInside(recCoord) <<
" " << a_hasProperty(cellId, SolverCell::IsInactive) << endl;
36459 MFloat angle = grid().azimuthalAngle();
36460 MInt side = grid().determineAzimuthalBoundarySide(recCoord);
36461 grid().rotateCartesianCoordinates(recCoord, (side * angle));
36462 cerr <<
" M " << contCellLC <<
"(" << c_globalId(contCellLC) <<
")"
36463 <<
" " << a_bndryId(contCellLC) <<
" " << a_coordinate(contCellLC, 0) <<
" " << a_coordinate(contCellLC, 1)
36464 <<
" " << a_coordinate(contCellLC, nDim - 1) <<
" H " << recCoord[0] <<
" " << recCoord[1] <<
" "
36465 << recCoord[nDim - 1] << endl;
36467 for(
MInt i = 0; i < noNghbrIds; i++) {
36468 for(
MInt j = 0; j < recDim; j++) {
36469 cerr <<
" " << tmpA(i, j);
36473 mTerm(1, AT_,
"Error in matrix inverse!");
36476 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36477 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
36478 ASSERT(!a_isPeriodic(recId),
"ERROR");
36481 m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst + nghbr] = tmpC(0, nghbr);
36485 if(condNum < F0 || condNum > 1e7 || std::isnan(condNum)) {
36486 cerr << domainId() <<
" SVD decomposition for azimuthal periodic windowCell " << contCell <<
"/"
36487 << c_globalId(contCell) <<
" level " << a_level(contCell) <<
" with large condition number: " << condNum <<
" "
36488 << noNghbrIds <<
"x" << recDim <<
" "
36489 << a_cellVolume(contCell) / pow(c_cellLengthAtCell(contCell), (
MFloat)nDim) <<
" coords "
36490 << a_coordinate(contCell, 0) <<
", " << a_coordinate(contCell, 1) <<
", " << a_coordinate(contCell, 2)
36491 <<
" bndryId " << a_bndryId(contCell) << endl;
36498template <MInt nDim,
class SysEqn>
36504 windowData.fill(0);
36509 m_fvBndryCnd->m_azimuthalNearBoundaryWindowCells.resize(grid().noAzimuthalNeighborDomains());
36510 m_fvBndryCnd->m_azimuthalNearBoundaryWindowMap.resize(grid().noAzimuthalNeighborDomains());
36511 m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells.resize(grid().noAzimuthalNeighborDomains());
36513 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36514 m_fvBndryCnd->m_azimuthalNearBoundaryWindowCells[i].clear();
36515 m_fvBndryCnd->m_azimuthalNearBoundaryWindowMap[i].clear();
36516 m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i].clear();
36519 if(grid().noAzimuthalNeighborDomains() > 0) {
36521 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36522 for(
MUint j = 0; j < m_azimuthalMaxLevelHaloCells[i].size(); j++) {
36523 MInt cellId = m_azimuthalMaxLevelHaloCells[i][j];
36524 if(activeFlag[cellId] > 0) {
36525 ASSERT(a_isPeriodic(cellId),
"");
36526 m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i].push_back(cellId);
36527 haloData[sndCnt] = 1;
36535 m_azimuthalMaxLevelHaloCells, mpiComm(), haloData.getPointer(), windowData.getPointer(),
36539 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36540 for(
MUint j = 0; j < m_azimuthalMaxLevelWindowCells[i].size(); j++) {
36541 MInt cellId = m_azimuthalMaxLevelWindowCells[i][j];
36542 MInt offset = m_azimuthalMaxLevelWindowMap[i][j];
36543 if(windowData[rcvCnt] > 0) {
36544 m_fvBndryCnd->m_azimuthalNearBoundaryWindowCells[i].push_back(cellId);
36545 m_fvBndryCnd->m_azimuthalNearBoundaryWindowMap[i].push_back(offset);
36547 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
36548 for(
MInt n = 0; n < noNghbrIds; n++) {
36549 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + n];
36550 activeFlag[recId] = 1;
36559 if(m_azimuthalRemappedNeighborDomains.size() > 0) {
36561 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36562 for(
MUint j = 0; j < m_azimuthalRemappedWindowCells[i].size(); j++) {
36563 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
36564 for(
MInt n = 0; n < noNghbrIds; n++) {
36565 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + n];
36566 activeFlag[recId] = 1;
36573 m_azimuthalNearBndryInit =
true;
36580template <MInt nDim,
class SysEqn>
36584 if(!m_azimuthalRecConstSet)
mTerm(1, AT_,
"Azimuthal reconstruction constants not initialized!");
36586 MInt noVars = m_sysEqn.CV->noVariables;
36591 windowData.fill(0);
36599 if(grid().noAzimuthalNeighborDomains() > 0) {
36600 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36601 for(
MUint j = 0; j < m_fvBndryCnd->m_azimuthalNearBoundaryWindowCells[i].size(); j++) {
36602 MInt cellId = m_fvBndryCnd->m_azimuthalNearBoundaryWindowCells[i][j];
36603 MInt offset = m_fvBndryCnd->m_azimuthalNearBoundaryWindowMap[i][j];
36604 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
36605 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36606 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
36607 if(a_isBndryGhostCell(recId)) {
36608 setConservativeVariables(recId);
36611 checkAzimuthalRecNghbrConsistency(recId);
36616 interpolateAzimuthalData(&windowData[sndCnt * noVars], offset, noVars, &a_variable(0, 0));
36618 MInt side = m_azimuthalBndrySide[offset];
36619 rotateVectorAzimuthal(side, &windowData[sndCnt * noVars], noVars, m_rotIndVarsCV);
36621 if(windowData[sndCnt * noVars + m_sysEqn.CV->RHO] < F0
36622 && (a_cellVolume(cellId) / pow(c_cellLengthAtLevel(a_level(cellId)), 3) > m_fvBndryCnd->m_volumeLimitWall)) {
36623 cerr <<
globalTimeStep <<
"/" << m_RKStep <<
" Window data CV " << domainId() <<
" " <<
cellId <<
"/"
36624 << c_globalId(cellId) <<
" " << c_level(cellId) <<
" " << side <<
" "
36625 << a_hasProperty(cellId, SolverCell::IsSplitChild) <<
" " << a_coordinate(cellId, 0) <<
" "
36626 << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, nDim - 1);
36627 for(
MInt v = 0; v < noVars; v++) {
36628 cerr <<
" /" << v <<
" " << windowData[sndCnt * noVars + v] <<
" " << a_variable(cellId, v);
36632 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36633 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
36634 cerr <<
"Window nghbr " << domainId() <<
" " << recId <<
"/";
36635 if(a_isBndryGhostCell(recId)) {
36638 cerr << c_globalId(recId) <<
" " << a_level(recId);
36640 cerr <<
" " << a_coordinate(recId, 0) <<
" " << a_coordinate(recId, 1) <<
" "
36641 << a_coordinate(recId, nDim - 1) <<
" "
36642 << m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst + nghbr] <<
" "
36643 << a_variable(recId, m_sysEqn.CV->RHO) <<
" " << a_isHalo(recId) <<
" " << a_isPeriodic(recId) <<
" "
36644 << (a_cellVolume(cellId) / pow(c_cellLengthAtLevel(a_level(cellId)), 3)
36645 > m_fvBndryCnd->m_volumeLimitWall)
36656 m_fvBndryCnd->m_azimuthalNearBoundaryWindowCells, mpiComm(), windowData.getPointer(),
36657 haloData.getPointer(), noVars);
36660 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36661 for(
MUint j = 0; j < m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i].size(); j++) {
36662 MInt cellId = m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i][j];
36663 for(
MInt v = 0; v < noVars; v++) {
36664 a_variable(cellId, v) = haloData[rcvCnt + v];
36666 if(a_variable(cellId, m_sysEqn.CV->RHO) < F0) {
36667 cerr << domainId() <<
": EXC Halo CV " <<
cellId <<
"/" << c_globalId(cellId) <<
" " << a_bndryId(cellId)
36668 <<
" " << a_level(cellId) <<
" /r " << a_variable(cellId, m_sysEqn.CV->RHO) <<
" "
36669 << a_coordinate(cellId, 0) <<
" " << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, nDim - 1)
36670 <<
" " << a_hasProperty(cellId, SolverCell::IsSplitChild) <<
" "
36671 << a_hasProperty(cellId, SolverCell::IsSplitCell) << endl;
36681 if(m_azimuthalRemappedNeighborDomains.size() > 0) {
36682 windowData.fill(F0);
36686 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36687 for(
MUint j = 0; j < m_azimuthalRemappedWindowCells[i].size(); j++) {
36688 MInt cellId = m_azimuthalRemappedWindowCells[i][j];
36690 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
36691 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36692 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
36693 if(a_isBndryGhostCell(recId)) {
36694 setConservativeVariables(recId);
36697 checkAzimuthalRecNghbrConsistency(recId);
36701 interpolateAzimuthalData(&windowData[sndCnt * noVars], offset, noVars, &a_variable(0, 0));
36703 MInt side = m_azimuthalBndrySide[offset];
36704 rotateVectorAzimuthal(side, &windowData[sndCnt * noVars], noVars, m_rotIndVarsCV);
36706 if(windowData[sndCnt * noVars + m_sysEqn.CV->RHO] < F0
36707 && (a_cellVolume(cellId) / pow(c_cellLengthAtLevel(a_level(cellId)), 3) > m_fvBndryCnd->m_volumeLimitWall)) {
36708 cerr <<
"Window data CV Rem " << domainId() <<
" " <<
cellId <<
"/" << c_globalId(cellId) <<
" "
36709 << c_level(cellId) <<
" " << a_hasProperty(cellId, SolverCell::IsSplitChild) <<
" "
36710 << a_coordinate(cellId, 0) <<
" " << a_coordinate(cellId, 1) <<
" " << a_coordinate(cellId, nDim - 1);
36711 for(
MInt v = 0; v < noVars; v++) {
36712 cerr <<
" /" << v <<
" " << windowData[sndCnt * noVars + v] <<
" " << a_variable(cellId, v);
36716 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36717 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
36718 cerr <<
"Window nghbr " << domainId() <<
" " << recId <<
"/";
36719 if(a_isBndryGhostCell(recId)) {
36722 cerr << c_globalId(recId) <<
" " << a_level(recId);
36724 cerr <<
" " << a_coordinate(recId, 0) <<
" " << a_coordinate(recId, 1) <<
" "
36725 << a_coordinate(recId, nDim - 1) <<
" "
36726 << m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst + nghbr] <<
" "
36727 << a_variable(recId, m_sysEqn.CV->RHO) <<
" " << a_isHalo(recId) <<
" " << a_isPeriodic(recId) <<
" "
36728 << (a_cellVolume(cellId) / pow(c_cellLengthAtLevel(a_level(cellId)), 3)
36729 > m_fvBndryCnd->m_volumeLimitWall)
36741 m_azimuthalRemappedWindowCells, mpiComm(), windowData.getPointer(), haloData.getPointer(),
36746 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36747 for(
MUint j = 0; j < m_azimuthalRemappedHaloCells[i].size(); j++) {
36748 MInt cellId = m_azimuthalRemappedHaloCells[i][j];
36749 for(
MInt v = 0; v < noVars; v++) {
36750 a_variable(cellId, v) = haloData[rcvCnt + v];
36761template <MInt nDim,
class SysEqn>
36765 MInt noVars = m_sysEqn.CV->noVariables;
36770 windowData.fill(0);
36779 if(grid().noAzimuthalNeighborDomains() > 0) {
36780 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36781 for(
MUint j = 0; j < m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i].size(); j++) {
36782 MInt cellId = m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells[i][j];
36783 for(
MInt v = 0; v < noVars; v++) {
36784 haloData[sndCnt + v] = a_variable(cellId, v);
36792 m_fvBndryCnd->m_azimuthalNearBoundaryHaloCells, mpiComm(), haloData.getPointer(),
36793 windowData.getPointer(), noVars);
36796 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36797 for(
MUint j = 0; j < m_fvBndryCnd->m_azimuthalNearBoundaryWindowCells[i].size(); j++) {
36798 MInt offset = m_fvBndryCnd->m_azimuthalNearBoundaryWindowMap[i][j];
36800 MInt side = -1 * m_azimuthalBndrySide[offset];
36801 rotateVectorAzimuthal(side, &windowData[rcvCnt * noVars], noVars, m_rotIndVarsCV);
36803 interpolateAzimuthalDataReverse(&a_variable(0, 0), offset, noVars, &windowData[rcvCnt * noVars]);
36811 if(m_azimuthalRemappedNeighborDomains.size() > 0) {
36812 windowData.fill(F0);
36815 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36816 for(
MUint j = 0; j < m_azimuthalRemappedHaloCells[i].size(); j++) {
36817 MInt cellId = m_azimuthalRemappedHaloCells[i][j];
36818 for(
MInt v = 0; v < noVars; v++) {
36819 haloData[sndCnt + v] = a_variable(cellId, v);
36827 m_azimuthalRemappedHaloCells, mpiComm(), haloData.getPointer(), windowData.getPointer(),
36833 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36834 for(
MUint j = 0; j < m_azimuthalRemappedWindowCells[i].size(); j++) {
36836 MInt side = -1 * m_azimuthalBndrySide[offset];
36837 rotateVectorAzimuthal(side, &windowData[rcvCnt * noVars], noVars, m_rotIndVarsCV);
36839 interpolateAzimuthalDataReverse(&a_variable(0, 0), offset, noVars, &windowData[rcvCnt * noVars]);
36851template <MInt nDim,
class SysEqn>
36852template <MBool exchangeAll_>
36854 const vector<MInt>& rotIndices) {
36857 if(grid().noAzimuthalNeighborDomains() > 0) {
36861 windowData.fill(0);
36868 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36870 (exchangeAll_) ? grid().noAzimuthalWindowCells(i) : (signed)m_azimuthalMaxLevelWindowCells[i].size();
36871 for(
MInt j = 0; j < noWindows; j++) {
36872 MInt cellId = (exchangeAll_) ? grid().azimuthalWindowCell(i, j) : m_azimuthalMaxLevelWindowCells[i][j];
36873 MInt offset = (exchangeAll_) ? sndCnt : m_azimuthalMaxLevelWindowMap[i][j];
36874 fillExcBufferAzimuthal(cellId, offset, &windowData[sndCnt * noVars], data, noVars, rotIndices);
36882 grid().azimuthalWindowCells(), mpiComm(), windowData.getPointer(),
36883 haloData.getPointer(), noVars);
36886 m_azimuthalMaxLevelWindowCells, mpiComm(), windowData.getPointer(),
36887 haloData.getPointer(), noVars);
36892 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36893 MInt noHalos = (exchangeAll_) ? grid().noAzimuthalHaloCells(i) : (signed)m_azimuthalMaxLevelHaloCells[i].size();
36894 for(
MInt j = 0; j < noHalos; j++) {
36895 MInt cellId = (exchangeAll_) ? grid().azimuthalHaloCell(i, j) : m_azimuthalMaxLevelHaloCells[i][j];
36896 for(
MInt v = 0; v < noVars; v++) {
36897 data[
cellId * noVars + v] = haloData[rcvCnt + v];
36905 exchangeAzimuthalRemappedHaloCells();
36908 for(
MInt i = 0; i < grid().noAzimuthalUnmappedHaloCells(); i++) {
36909 MInt cellId = grid().azimuthalUnmappedHaloCell(i);
36910 reduceData(cellId, data, noVars);
36918template <MInt nDim,
class SysEqn>
36922 if(m_azimuthalRemappedNeighborDomains.size() == 0)
return;
36924 MInt noVars = PV->noVariables;
36927 windowData.fill(0);
36934 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36935 for(
MUint j = 0; j < m_azimuthalRemappedWindowCells[i].size(); j++) {
36936 MInt cellId = m_azimuthalRemappedWindowCells[i][j];
36937 fillExcBufferAzimuthal(cellId, offset, &windowData[sndCnt * noVars], &a_pvariable(0, 0), noVars, m_rotIndVarsCV);
36945 m_azimuthalRemappedWindowCells, mpiComm(), windowData.getPointer(), haloData.getPointer(),
36950 for(
MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36951 for(
MUint j = 0; j < m_azimuthalRemappedHaloCells[i].size(); j++) {
36952 MInt cellId = m_azimuthalRemappedHaloCells[i][j];
36954 for(
MInt v = 0; v < noVars; v++) {
36955 a_pvariable(cellId, v) = haloData[rcvCnt + v];
36966template <MInt nDim,
class SysEqn>
36970 if(grid().noAzimuthalNeighborDomains() == 0)
return;
36972 m_azimuthalMaxLevelHaloCells.resize(grid().noAzimuthalNeighborDomains());
36973 m_azimuthalMaxLevelWindowCells.resize(grid().noAzimuthalNeighborDomains());
36974 m_azimuthalMaxLevelWindowMap.resize(grid().noAzimuthalNeighborDomains());
36976 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36977 m_azimuthalMaxLevelHaloCells[i].clear();
36978 m_azimuthalMaxLevelWindowCells[i].clear();
36979 m_azimuthalMaxLevelWindowMap[i].clear();
36984 windowData.fill(0);
36989 m_azimuthalHaloActive.clear();
36990 m_azimuthalHaloActive.assign(rcvSize, 0);
36993 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36994 m_azimuthalMaxLevelHaloCells[i].reserve(grid().noAzimuthalHaloCells(i));
36996 for(
MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
36997 MInt cellId = grid().azimuthalHaloCell(i, j);
36998 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
36999 ASSERT(a_isPeriodic(cellId),
"");
37000 m_azimuthalMaxLevelHaloCells[i].push_back(cellId);
37001 haloData[sndCnt] = 1;
37008 if(grid().noAzimuthalNeighborDomains() > 0) {
37010 grid().azimuthalHaloCells(), mpiComm(), haloData.getPointer(), windowData.getPointer());
37014 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
37015 m_azimuthalMaxLevelWindowCells[i].reserve(grid().noAzimuthalWindowCells(i));
37017 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
37018 MInt cellId = grid().azimuthalWindowCell(i, j);
37019 ASSERT(m_noAzimuthalReconstNghbrs[rcvCnt] >= 1,
"");
37020 if(windowData[rcvCnt] > 0) {
37021 m_azimuthalMaxLevelWindowCells[i].push_back(cellId);
37022 m_azimuthalMaxLevelWindowMap[i].push_back(rcvCnt);
37034template <MInt nDim,
class SysEqn>
37039 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
37040 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
37041 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
37042 for(
MInt v = 0; v < noVars; v++) {
37043 data[v] += m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst + nghbr] * vars[recId * noVars + v];
37052template <MInt nDim,
class SysEqn>
37057 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
37059 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
37060 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
37062 if(a_isBndryGhostCell(recId)) {
37065 MInt baseId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst];
37069 for(
MInt v = 0; v < noVars; v++) {
37070 data[recId * noVars + v] += m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst + nghbr] * vars[v];
37078template <MInt nDim,
class SysEqn>
37080 const std::vector<MInt>& indices) {
37083 MFloat phi = grid().azimuthalAngle();
37088 for(
MInt d = 0; d < noData; d++) {
37089 if(indices[d] > 0) {
37100 mTerm(1, AT_,
"Vector is only rotated along one axis.");
37104 for(
MInt d = 0; d < noData; d++) {
37108 data[dir1] =
cos(phi) * vTmp[dir1] + side * sin(phi) * vTmp[dir2];
37109 data[dir2] = -side * sin(phi) * vTmp[dir1] +
cos(phi) * vTmp[dir2];
37116template <MInt nDim,
class SysEqn>
37120 if(!a_isBndryGhostCell(cellId) && a_isHalo(cellId)) {
37121 MBool isNearBndry =
false;
37122 for(
MInt n = 0; n < noNeighborDomains(); n++) {
37123 for(
MUint m = 0; m < m_fvBndryCnd->m_nearBoundaryHaloCells[n].size(); m++) {
37124 MInt bndryId = m_fvBndryCnd->m_nearBoundaryHaloCells[n][m];
37125 if(a_hasProperty(bndryId, SolverCell::IsSplitChild)) bndryId = getAssociatedInternalCell(bndryId);
37126 if(c_globalId(bndryId) == c_globalId(cellId)) {
37127 isNearBndry =
true;
37132 cerr <<
"Not near bndry! " << domainId() <<
" " <<
cellId <<
"/" << c_globalId(cellId) <<
" "
37133 << c_coordinate(cellId, 0) <<
" " << c_coordinate(cellId, 1) <<
" " << c_coordinate(cellId, nDim - 1) <<
" "
37134 << c_level(cellId);
37135 for(
MInt n = 0; n < noNeighborDomains(); n++) {
37136 for(
MInt m = 0; m < m_noMaxLevelHaloCells[n]; m++) {
37137 MInt bndryId = m_maxLevelHaloCells[n][m];
37138 if(c_globalId(bndryId) == c_globalId(cellId)) {
37139 cerr <<
" Is maxLevel!";
37144 mTerm(1, AT_,
"Not near bndry");
37152template <MInt nDim,
class SysEqn>
37155 if(grid().noAzimuthalNeighborDomains() == 0)
return;
37158 for(
MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
37159 for(
MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
37160 const MInt noNghbrIds = m_noAzimuthalReconstNghbrs[sndCnt];
37161 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
37162 MInt recId = m_azimuthalReconstNghbrIds[sndCnt * m_maxNoAzimuthalRecConst + nghbr];
37163 setConservativeVariables(recId);
37178template <MInt nDim,
class SysEqn>
37182 const MInt noSmallCells = (signed)m_fvBndryCnd->m_smallCutCells.size();
37183 const MInt noFVars = FV->noVariables;
37184 const MInt noCVars = CV->noVariables;
37185 const MInt noPVars = PV->noVariables;
37201 sendReq.fill(MPI_REQUEST_NULL);
37202 recvReq.fill(MPI_REQUEST_NULL);
37203 sendBufferCnts.fill(0);
37204 recvBufferCnts.fill(0);
37205 for(
MInt i = 0; i < noNeighborDomains(); i++) {
37206 sendBufferCnts(i) = noFVars * (signed)m_fvBndryCnd->m_nearBoundaryWindowCells[i].size();
37207 recvBufferCnts(i) = noFVars * (signed)m_fvBndryCnd->m_nearBoundaryHaloCells[i].size();
37208 if(m_fvBndryCnd->m_nearBoundaryWindowCells[i].empty()) {
37211 MInt sendBufferCounter = 0;
37212 for(
MUint j = 0; j < m_fvBndryCnd->m_nearBoundaryWindowCells[i].size(); j++) {
37213 MInt cellId = m_fvBndryCnd->m_nearBoundaryWindowCells[i][j];
37214 for(
MInt v = 0; v < noFVars; v++) {
37215 m_sendBuffers[i][sendBufferCounter] = a_rightHandSide(cellId, v);
37216 sendBufferCounter++;
37222 if(m_nonBlockingComm) {
37223 for(
MInt i = 0; i < noNeighborDomains(); i++) {
37224 if(sendBufferCnts(i) == 0) {
37227 ASSERT(sendBufferCnts(i) <= m_noMaxLevelWindowCells[i] * noFVars,
"");
37228 MPI_Isend(m_sendBuffers[i], sendBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 12, mpiComm(), &sendReq[sendCnt],
37229 AT_,
"m_sendBuffers[i]");
37232 for(
MInt i = 0; i < noNeighborDomains(); i++) {
37233 if(recvBufferCnts(i) == 0) {
37236 ASSERT(recvBufferCnts(i) <= m_noMaxLevelHaloCells[i] * noFVars,
"");
37237 MPI_Irecv(m_receiveBuffers[i], recvBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 12, mpiComm(),
37238 &recvReq[recvCnt], AT_,
"m_receiveBuffers[i]");
37242 MPI_Waitall(recvCnt, &recvReq[0], MPI_STATUSES_IGNORE, AT_);
37245 for(
MInt i = 0; i < noNeighborDomains(); i++) {
37246 if(sendBufferCnts(i) == 0) {
37249 ASSERT(sendBufferCnts(i) <= m_noMaxLevelWindowCells[i] * noFVars,
"");
37250 MPI_Issend(m_sendBuffers[i], sendBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 12, mpiComm(), &sendReq[sendCnt],
37251 AT_,
"m_sendBuffers[i]");
37254 for(
MInt i = 0; i < noNeighborDomains(); i++) {
37255 if(recvBufferCnts(i) == 0) {
37258 ASSERT(recvBufferCnts(i) <= m_noMaxLevelHaloCells[i] * noFVars,
"");
37259 MPI_Recv(m_receiveBuffers[i], recvBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 12, mpiComm(),
37260 MPI_STATUS_IGNORE, AT_,
"m_receiveBuffers[i]");
37264 for(
MInt i = 0; i < noNeighborDomains(); i++) {
37265 if(m_fvBndryCnd->m_nearBoundaryHaloCells[i].empty()) {
37268 MInt recvBufferCounter = 0;
37269 for(
MUint j = 0; j < m_fvBndryCnd->m_nearBoundaryHaloCells[i].size(); j++) {
37270 MInt cellId = m_fvBndryCnd->m_nearBoundaryHaloCells[i][j];
37271 for(
MInt v = 0; v < noFVars; v++) {
37272 a_rightHandSide(cellId, v) = m_receiveBuffers[i][recvBufferCounter];
37273 recvBufferCounter++;
37278 MPI_Waitall(sendCnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
37286#if !defined NDEBUG || defined _MB_DEBUG_
37293 for(
MInt smallc = 0; smallc < noSmallCells; smallc++) {
37294 const MInt bndryId = m_fvBndryCnd->m_smallCutCells[smallc];
37295 ASSERT(std::count(m_fvBndryCnd->m_smallCutCells.begin(), m_fvBndryCnd->m_smallCutCells.end(), bndryId) == 1,
"");
37296 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
37297 if(a_isPeriodic(cellId)) {
37300 if(a_isHalo(cellId)) {
37303 if(a_hasProperty(cellId, SolverCell::IsPeriodicWithRot)) {
37306 if(a_hasProperty(cellId, SolverCell::IsCutOff) && !m_fvBndryCnd->m_cbcCutOff) {
37310 const MInt noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
37311 const MInt noRecNghbrs = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size();
37312 if(noRecNghbrs == 0) {
37313 cerr << domainId() <<
": Warning: no reconstruction posible in small cell " <<
cellId << endl;
37317 for(
MInt v = 0; v < noFVars; v++) {
37321 for(
MInt n = noSrfcs + 1; n < noRecNghbrs; n++) {
37322 if(fabs(m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n]) > m_eps) {
37323 const MInt recNId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
37324 rhsNB[v] += m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n] * a_FcellVolume(recNId)
37325 * a_rightHandSide(recNId, v);
37328#if !defined NDEBUG || defined _MB_DEBUG_
37330 && (std::isnan(m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n])
37331 || std::isnan(a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], v)))) {
37332 cerr << domainId() <<
": "
37333 <<
" nan detected in smallCellCorrection " <<
globalTimeStep <<
"/" << m_RKStep <<
" "
37334 <<
" " <<
cellId <<
"(" << c_globalId(cellId) <<
") " << n <<
"/" << noRecNghbrs <<
" " << v <<
" "
37335 << m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n] <<
"("
37336 << c_globalId(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n]) <<
")"
37337 <<
" " << m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[
IPOW2(noSrfcs) * n] <<
" "
37338 << a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], v) << endl;
37340 if(nanCnt == 100) {
37341 cerr << domainId() <<
": More than 100 nan's, not reporting any more." << endl;
37346 rhsUpdate[smallc * noFVars + v] = rhsNB[v];
37351 for(
MInt smallc = 0; smallc < noSmallCells; smallc++) {
37352 const MInt bndryId = m_fvBndryCnd->m_smallCutCells[(unsigned)smallc];
37353 ASSERT(std::count(m_fvBndryCnd->m_smallCutCells.begin(), m_fvBndryCnd->m_smallCutCells.end(), bndryId) == 1,
"");
37354 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
37355 if(a_isPeriodic(cellId)) {
37358 if(a_isHalo(cellId)) {
37361 if(a_hasProperty(cellId, SolverCell::IsPeriodicWithRot)) {
37365 if(a_hasProperty(cellId, SolverCell::IsCutOff) && !m_fvBndryCnd->m_cbcCutOff) {
37368 ASSERT(maxLevel() >= maxUniformRefinementLevel() && maxLevel() <= maxRefinementLevel(),
"");
37370 MFloat vfrac = a_cellVolume(cellId) / c_cellVolumeAtLevel(maxLevel());
37372 vfrac = a_cellVolume(cellId) / c_cellVolumeAtLevel(a_level(cellId));
37374 const MFloat volumeLimit = m_fvBndryCnd->m_volumeLimitWall;
37378 const MFloat volumeLimitSponge = 0.6 * m_fvBndryCnd->m_volumeLimitWall;
37383 const MFloat limitValue = 0.000047872 * 1.5 / m_cfl;
37384 MFloat spongeFactor = 2;
37385 if(fac < limitValue) {
37387 spongeFactor = 20.0;
37392 setPrimitiveVariables(cellId);
37394 const MInt noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
37397 MFloat combSurfArea = 0;
37398 for(
MInt srfc = 0; srfc < noSrfcs; srfc++) {
37399 combSurfArea += m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
37400 if(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId == 3007) {
37401 mTerm(1, AT_,
"Not presribed for 3007 bc yet!");
37403 for(
MInt var = 0; var < noPVars; var++) {
37404 if(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[var] ==
BC_DIRICHLET) {
37405 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
37406 const MFloat imageVar = F2 * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[var]
37407 - a_pvariable(ghostCellId, var);
37408 const MFloat imageDist =
37409 mMax(F0, (
mMax(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance,
37410 F1B2 * c_cellLengthAtLevel(a_level(cellId)))
37411 - m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance));
37412 const MFloat distSum = imageDist + m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
37414 pvars(var) += (m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area / distSum
37415 * (m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[var] * imageDist
37416 + imageVar * m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance));
37417 }
else if(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[var] ==
BC_ROBIN) {
37419 for(
MInt s = 0; s < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; s++) {
37422 imageVar += m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[var]
37423 * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[s];
37425 for(
MUint n = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
37426 n < m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size();
37428 const MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
37429 imageVar += m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n]
37430 * a_pvariable(nghbrId, var);
37432 const MFloat imageDist =
37433 mMax(F0, (
mMax(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance,
37434 F1B2 * c_cellLengthAtLevel(a_level(cellId)))
37435 - m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance));
37436 const MFloat distSum = imageDist + m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
37437 pvars(var) += (m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area / distSum
37438 * (m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[var] * imageDist
37439 + imageVar * m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance));
37442 pvars(var) += m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area * a_pvariable(cellId, var);
37452 for(
MInt var = 0; var < noPVars; var++) {
37453 pvars(var) /= combSurfArea;
37459 MFloat* avars = hasAV ? &a_avariable(cellId, 0) : nullptr;
37460 sysEqn().computeConservativeVariables(&pvars(0), &cvars(0), avars);
37463 rhsSponge[CV->RHO] = 3 * spongeFactor * (a_variable(cellId, CV->RHO) - cvars(CV->RHO));
37464 for(
MInt i = 0; i < nDim; i++) {
37465 rhsSponge[CV->RHO_VV[i]] = spongeFactor * (a_variable(cellId, CV->RHO_VV[i]) - cvars[CV->RHO_VV[i]]);
37467 rhsSponge[CV->RHO_E] = spongeFactor * (a_variable(cellId, CV->RHO_E) - cvars[CV->RHO_E]);
37468 for(
MInt v = 0; v < noFVars; v++) {
37469 a_rightHandSide(cellId, v) = fac * a_rightHandSide(cellId, v) + facSponge * rhsSponge[v] * a_cellVolume(cellId)
37470 + (F1 - fac - facSponge) * rhsUpdate[smallc * noFVars + v] / a_FcellVolume(cellId);
37478template <MInt nDim,
class SysEqn>
37481 const std::vector<MInt>& rotIndex) {
37484 if(m_azimuthalRecConstSet) {
37486 interpolateAzimuthalData(&dataDest[0], offset, noData, &dataSrc[0]);
37488 if(rotIndex.size() >= (
unsigned)1) {
37489 MInt side = m_azimuthalBndrySide[offset];
37490 rotateVectorAzimuthal(side, &dataDest[0], noData, rotIndex);
37494 for(
MInt v = 0; v < noData; v++) {
37495 dataDest[v] = dataSrc[
cellId * noData + v];
37501 for(
MInt v = 0; v < noData; v++) {
37502 if(!(dataDest[v] >= F0 || dataDest[v] < F0) || std::isnan(dataDest[v])) {
37503 cerr <<
globalTimeStep <<
"/" << m_RKStep <<
" Window data:" << domainId() <<
" " << offset <<
" " <<
cellId
37504 <<
"/" << c_globalId(cellId) <<
" " << c_level(cellId) <<
" " << c_coordinate(cellId, 0) <<
" "
37505 << c_coordinate(cellId, 1) <<
" " << c_coordinate(cellId, nDim - 1) <<
" "
37506 << (m_levelSetMb ? a_levelSetValuesMb(cellId, 0) : -1) <<
" // " << v <<
" " << dataDest[v] <<
" "
37507 << dataSrc[
cellId * noData + v] << endl;
37509 if(m_azimuthalRecConstSet) {
37510 const MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
37511 for(
MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
37512 MInt recId = m_azimuthalReconstNghbrIds[offset * m_maxNoAzimuthalRecConst + nghbr];
37513 if(!(dataSrc[recId * noData + v] >= F0 || dataSrc[recId * noData + v] < F0)
37514 || std::isnan(dataSrc[recId * noData + v])) {
37515 cerr <<
"Rec " << nghbr <<
"/" << (noNghbrIds - 1) <<
" " << recId <<
"/";
37516 if(!a_isBndryGhostCell(recId)) {
37517 cerr << c_globalId(recId) <<
" " << c_level(recId) <<
" " << c_parentId(recId);
37521 cerr <<
" " << a_isHalo(recId) <<
" " << a_hasProperty(recId, SolverCell::IsCutOff) <<
" "
37522 << a_hasProperty(recId, SolverCell::IsOnCurrentMGLevel) <<
" " << a_coordinate(recId, 0) <<
" "
37523 << a_coordinate(recId, 1) <<
" " << a_coordinate(recId, nDim - 1) <<
" // " << v <<
" "
37524 << dataSrc[recId * noData + v] <<
" "
37525 << m_azimuthalRecConsts[offset * m_maxNoAzimuthalRecConst + nghbr] << endl;
37539template <MInt nDim,
class SysEqn>
37541 MFloat minCoord = std::numeric_limits<MFloat>::max();
37542 MFloat maxCoord = std::numeric_limits<MFloat>::lowest();
37544 minCoord =
mMin(minCoord, a_coordinate(cellId, direction) - F1B2 * c_cellLengthAtLevel(maxRefinementLevel()));
37545 maxCoord =
mMax(maxCoord, a_coordinate(cellId, direction) + F1B2 * c_cellLengthAtLevel(maxRefinementLevel()));
37547 MPI_Allreduce(MPI_IN_PLACE, &minCoord, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_,
"MPI_IN_PLACE",
"minCoord");
37548 MPI_Allreduce(MPI_IN_PLACE, &maxCoord, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"maxCoord");
37549 return maxCoord - minCoord;
37556template <MInt nDim,
class SysEqn>
37578 IF_CONSTEXPR(isDetChem<SysEqn>) {
37600template <MInt nDim_,
class SysEqn>
37604 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
37607 sort(m_LESAverageCells.begin(), m_LESAverageCells.end());
37609 mAlloc(m_LESVarAverage, m_LESNoVarAverage,
"m_LESVarAverage", AT_);
37611 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
37612 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37613 m_LESVarAverage[var].push_back(F0);
37617 if(m_calcLESAverage && m_restartLESAverage
37621 for(
MInt var = 0; var < noVariables(); var++) {
37622 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37623 MInt cellId = m_LESAverageCells[c];
37624 ASSERT(c < (
MInt)m_LESVarAverage[var].size(),
37625 "Trying to access data [" + to_string(var) +
"][" + to_string(c) +
"] in m_LESVarAverage with length "
37626 + to_string(m_LESVarAverage[var].size()));
37628 m_LESVarAverage[var][c] = a_pvariable(cellId, var);
37634 for(
MInt i = 0; i < nDim; i++) {
37635 for(
MInt j = count; j < nDim; j++) {
37636 MInt indexAvg = index + noVariables();
37637 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37638 MInt cellId = m_LESAverageCells[c];
37640 ASSERT(c < (
MInt)m_LESVarAverage[indexAvg].size(),
37641 "Trying to access data [" + to_string(indexAvg) +
"][" + to_string(c)
37642 +
"] in m_LESVarAverage with length " + to_string(m_LESVarAverage[indexAvg].size()));
37644 m_LESVarAverage[indexAvg][c] = a_pvariable(cellId, i) * a_pvariable(cellId, j);
37653template <MInt nDim_,
class SysEqn>
37657 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
37659 MFloat avgFactor = getAveragingFactor();
37661 for(
MInt var = 0; var < noVariables(); var++) {
37662 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37663 MInt cellId = m_LESAverageCells[c];
37665 ASSERT(c < (
MInt)m_LESVarAverage[var].size(),
37666 "Trying to access data [" + to_string(var) +
"][" + to_string(c) +
"] in m_LESVarAverage with length "
37667 + to_string(m_LESVarAverage[var].size()) +
", domainId: " + to_string(domainId()));
37669 m_LESVarAverage[var][c] = avgFactor * a_pvariable(cellId, var) + (1 - avgFactor) * m_LESVarAverage[var][c];
37675 for(
MInt i = 0; i < nDim; i++) {
37676 for(
MInt j = count; j < nDim; j++) {
37677 MInt indexAvg = index + noVariables() + m_averageReconstructNut[0];
37678 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37679 MInt cellId = m_LESAverageCells[c];
37681 ASSERT(c < (
MInt)m_LESVarAverage[indexAvg].size(),
37682 "Trying to access data [" + to_string(indexAvg) +
"][" + to_string(c)
37683 +
"] in m_LESVarAverage with length " + to_string(m_LESVarAverage[indexAvg].size()));
37685 m_LESVarAverage[indexAvg][c] = avgFactor * a_pvariable(cellId, i) * a_pvariable(cellId, j)
37686 + (1 - avgFactor) * m_LESVarAverage[indexAvg][c];
37694template <MInt nDim_,
class SysEqn>
37698 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
37702 if(m_useNonSpecifiedRestartFile) {
37703 fn << restartDir() <<
"restartLESAverage" << m_solverId;
37705 fn << restartDir() <<
"restartLESAverage" << m_solverId <<
"_" <<
globalTimeStep;
37707 fn << ParallelIo::fileExt();
37711 if(domainId() == 0) {
37712 cerr <<
"loading LES average restart file " << fn.str() <<
"...";
37716 ParallelIo parallelIo(fileName, PIO_READ, mpiComm());
37718 ParallelIo::size_type size = 0;
37719 ParallelIo::size_type start = 0;
37720 ParallelIo::size_type count = 0;
37722 size = parallelIo.getArraySize(
"avgCellIds");
37727 vector<MLong> avgCellIds((
MInt)size, -1);
37730 parallelIo.setOffset(count, start);
37731 parallelIo.readArray(&avgCellIds[0],
"avgCellIds");
37733 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
37734 MString s =
"LESAverageVar" + to_string(var);
37735 parallelIo.readArray(&LESVar[0], s);
37737 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37738 MInt cellId = m_LESAverageCells[c];
37740 if(a_isBndryGhostCell(cellId))
continue;
37743 vector<MLong>::iterator findLESGlobalId = find(avgCellIds.begin(), avgCellIds.end(), gCellId);
37744 if(findLESGlobalId != avgCellIds.end()) {
37745 MInt dist = std::distance(avgCellIds.begin(), findLESGlobalId);
37746 m_LESVarAverage[var][c] = LESVar[
dist];
37752 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37753 MInt cellId = m_LESAverageCells[c];
37754 if(a_isBndryCell(cellId)) {
37756 for(
MInt nghbr = 0; nghbr < a_noReconstructionNeighbors(cellId); nghbr++) {
37757 const MInt recNghbrId = a_reconstructionNeighborId(cellId, nghbr);
37758 if(a_isBndryGhostCell(recNghbrId)) {
37759 vector<MInt>::iterator findBndryGhostId =
37760 find(m_LESAverageCells.begin(), m_LESAverageCells.end(), recNghbrId);
37761 if(findBndryGhostId != m_LESAverageCells.end()) {
37762 MInt index = std::distance(m_LESAverageCells.begin(), findBndryGhostId);
37765 for(
MInt var = 0; var < noVariables(); var++) {
37766 m_LESVarAverage[var][index] = -m_LESVarAverage[var][c];
37768 for(
MInt var = noVariables(); var < m_LESNoVarAverage; var++) {
37769 m_LESVarAverage[var][index] = m_LESVarAverage[var][c];
37777 if(domainId() == 0) {
37778 cerr <<
"done" << endl;
37783template <MInt nDim_,
class SysEqn>
37787 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
37789 if(domainId() == 0) {
37790 cerr <<
"Writing LES average restart file at " <<
globalTimeStep <<
"...";
37793 MLong noAvgCells = 0;
37794 vector<pair<MInt, MInt>> LESCellsGlobalId;
37795 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37796 MInt cellId = m_LESAverageCells[c];
37797 if(a_isHalo(cellId))
continue;
37798 if(a_isPeriodic(cellId))
continue;
37799 if(a_isBndryGhostCell(cellId))
continue;
37802 MInt globalLESId = c_globalId(cellId);
37803 LESCellsGlobalId.emplace_back(make_pair(globalLESId, c));
37807 MLong noAvgCellsGlobal = noAvgCells;
37810 if(noDomains() > 1) {
37811 offsets(domainId() + 1) = (MPI_Offset)noAvgCells;
37813 MPI_Allgather(&noAvgCells, 1, MPI_LONG, &offsets[1], 1, MPI_LONG, mpiComm(), AT_,
"noAvgCells",
"offsets[1]");
37815 for(
MInt d = 0; d < noDomains(); d++) {
37816 offsets(d + 1) += offsets(d);
37818 noAvgCellsGlobal = noAvgCells;
37820 MPI_Allreduce(MPI_IN_PLACE, &noAvgCellsGlobal, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
37821 "noAvgCellsGlobal");
37823 if(noAvgCellsGlobal != offsets(noDomains())) {
37824 mTerm(1, AT_,
"Dimension mismatch.");
37828 offsets(noDomains()) = (MPI_Offset)noAvgCellsGlobal;
37832 if(m_useNonSpecifiedRestartFile) {
37833 fn << outputDir() <<
"restartLESAverage" << m_solverId;
37835 fn << outputDir() <<
"restartLESAverage" << m_solverId <<
"_" <<
globalTimeStep;
37837 fn << ParallelIo::fileExt();
37841 for(
MInt i = 0; i < noAvgCells; i++) {
37842 avgCellIds[i] = LESCellsGlobalId[i].first;
37845 ParallelIo::size_type start = 0;
37846 ParallelIo::size_type count = 0;
37849 ParallelIo parallelIo(fileName, PIO_REPLACE, mpiComm());
37851 count = noAvgCellsGlobal;
37852 parallelIo.defineArray(PIO_LONG,
"avgCellIds", count);
37853 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
37854 MString s =
"LESAverageVar" + to_string(var);
37855 parallelIo.defineArray(PIO_FLOAT, s, count);
37858 start = offsets(domainId());
37859 count = noAvgCells;
37860 parallelIo.setOffset(count, start);
37862 parallelIo.writeArray(avgCellIds.
begin(),
"avgCellIds");
37865 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
37866 MString s =
"LESAverageVar" + to_string(var);
37867 for(
MInt i = 0; i < noAvgCells; i++) {
37868 LESVar[i] = m_LESVarAverage[var][LESCellsGlobalId[i].second];
37870 parallelIo.writeArray(LESVar.
begin(), s);
37873 if(domainId() == 0) cerr <<
"ok" << endl;
37880template <MInt nDim_,
class SysEqn>
37884 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
37886 mAlloc(m_STGSpongeFactor, nDim + 3,
"m_STGSpongeFactor", AT_);
37887 for(
MInt i = 0; i < nDim + 3; i++) {
37888 m_STGSpongeFactor[i].clear();
37891 for(
MInt varId = 0; varId < nDim + 3; varId++) {
37892 m_STGSpongeFactor[varId].resize(c_noCells());
37893 for(
MInt c = 0; c < c_noCells(); c++) {
37894 ASSERT(c < (
MInt)m_STGSpongeFactor[varId].size(),
37895 "Trying to access data [" + to_string(varId) +
"][" + to_string(c) +
"] in m_STGSpongeFactor with length "
37896 + to_string(m_STGSpongeFactor[varId].size()));
37898 m_STGSpongeFactor[varId][c] = F0;
37903template <MInt nDim_,
class SysEqn>
37907 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
37909 m_spongeLocations.clear();
37910 m_spongeCells.clear();
37912 MInt noSpongeCells = 0;
37913 MInt noSpongeLocations = 0;
37919 MBool first =
true;
37921 for(
MInt c = 0; c < (
MInt)m_LESAverageCells.size(); c++) {
37922 MInt cellId = m_LESAverageCells[c];
37923 if(!c_isLeafCell(cellId))
continue;
37924 MInt averageDir = abs(m_7901wallDir + m_7901periodicDir - nDim);
37925 MFloat pos = a_coordinate(cellId, averageDir);
37926 MFloat halfCellLength = grid().halfCellLength(cellId);
37928 if(
approx(m_7901Position, pos, halfCellLength) && !a_isInactive(cellId)) {
37930 periodicL = a_coordinate(cellId, m_7901periodicDir) - F1B3 * halfCellLength;
37933 if(abs(a_coordinate(cellId, m_7901periodicDir) + halfCellLength - 1e-16 - periodicL) < halfCellLength) {
37934 m_spongeLocations.push_back(a_coordinate(cellId, m_7901wallDir));
37935 m_spongeLocations.push_back(a_coordinate(cellId, m_7901periodicDir));
37936 noSpongeLocations++;
37937 noSpongeLocations++;
37939 m_spongeCells.push_back(cellId);
37944 m_noSpongeCells = noSpongeCells;
37950 MPI_Comm_size(mpiComm(), &comm_size);
37951 std::vector<MInt> spongeCellsperDomain(comm_size);
37953 if(noDomains() > 1) {
37954 MPI_Allgather(&noSpongeCells, 1, MPI_INT, &spongeCellsperDomain[0], 1, MPI_INT, mpiComm(), AT_,
"noSpongeCells ",
37955 "spongeCellsperDomain");
37958 MInt noInvolvedRanks = 0;
37959 std::vector<MInt> involvedRanks(comm_size);
37960 for(
MInt i = 0; i < comm_size; i++) {
37961 if(spongeCellsperDomain[i]) {
37962 involvedRanks[noInvolvedRanks] = i;
37967 MPI_Comm commSponge;
37969 MPI_Group groupSponge;
37971 MPI_Group_incl(group, noInvolvedRanks, &involvedRanks[0], &groupSponge, AT_);
37972 MPI_Comm_create(mpiComm(), groupSponge, &commSponge, AT_,
"commStg");
37974 m_spongeComm = commSponge;
37975 m_spongeCommSize = noInvolvedRanks;
37978 if(m_noSpongeCells > 0) {
37979 for(
MInt i = 0; i < noInvolvedRanks; i++) {
37980 if(involvedRanks[i] == domainId()) {
37986 m_spongeRoot = involvedRanks[0];
37991 MInt globalNoBcStgLocations = 0;
37992 MInt globalNoBcStgCells = 0;
37993 MPI_Allreduce(&noSpongeLocations, &globalNoBcStgLocations, 1, MPI_INT, MPI_SUM, m_spongeComm, AT_,
37994 "noSpongeLocations",
"globalNoBcStgLocations");
37996 MPI_Allreduce(&noSpongeCells, &globalNoBcStgCells, 1, MPI_INT, MPI_SUM, m_spongeComm, AT_,
"noSpongeCells",
37997 "globalNoBcStgCells");
38000 mAlloc(m_globalBcStgLocationsG, globalNoBcStgLocations,
"m_globalBcStgLocationsG", AT_);
38001 if(m_spongeCommSize > 0) {
38005 MPI_Gather(&noSpongeLocations, 1, MPI_INT, &recvbuf[0], 1, MPI_INT, 0, m_spongeComm, AT_,
"noSpongeLocations",
38009 if(domainId() == m_spongeRoot) {
38011 for(
MInt dom = 0; dom < comm_size; dom++) {
38012 displs[dom] = offset;
38013 offset += recvbuf[dom];
38017 MPI_Gatherv(&m_spongeLocations[0], noSpongeLocations, MPI_DOUBLE, &m_globalBcStgLocationsG[0],
38018 &recvbuf[m_spongeRank], &displs[m_spongeRank], MPI_DOUBLE, 0, m_spongeComm, AT_,
"m_spongeLocations",
38019 "globalBcStgLocations");
38021 MPI_Bcast(&m_globalBcStgLocationsG[0], globalNoBcStgLocations, MPI_DOUBLE, 0, m_spongeComm, AT_,
38022 "m_globalBcStgLocationsG");
38025 m_globalNoSpongeLocations = globalNoBcStgLocations;
38036 MPI_Allreduce(MPI_IN_PLACE, &m_spongeRoot, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
"m_spongeRoot");
38039 MInt globalNoBcStgLocationsG = 0;
38040 if(m_noSpongeCells > 0) {
38041 globalNoBcStgLocationsG = m_globalNoSpongeLocations;
38043 MPI_Allreduce(MPI_IN_PLACE, &globalNoBcStgLocationsG, 1, MPI_INT, MPI_MAX, mpiComm(), AT_,
"MPI_IN_PLACE",
38044 "globalNoBcStgLocationsG");
38046 if(m_noSpongeCells == 0) {
38047 mAlloc(m_globalBcStgLocationsG, globalNoBcStgLocationsG,
"m_globalBcStgLocationsG", AT_);
38049 MPI_Bcast(&m_globalBcStgLocationsG[0], globalNoBcStgLocationsG, MPI_DOUBLE, m_spongeRoot, mpiComm(), AT_,
38050 "m_globalBcStgLocationsG");
38052 m_globalSpongeLocations.clear();
38053 m_globalNoSpongeLocations = 0;
38055 for(
MInt i = 0; i < globalNoBcStgLocationsG / 2; i++) {
38056 MFloat L1 = m_globalBcStgLocationsG[2 * i + 0];
38057 MFloat L2 = m_globalBcStgLocationsG[2 * i + 1];
38059 std::find_if(m_globalSpongeLocations.begin(), m_globalSpongeLocations.end(),
38060 [&L1](
const std::pair<MFloat, MFloat>&
element) { return approx(element.first, L1, 1e-16); });
38061 if(it == m_globalSpongeLocations.end()) {
38062 m_globalSpongeLocations.push_back(make_pair(L1, L2));
38063 m_globalNoSpongeLocations++;
38067 sort(m_globalSpongeLocations.begin(), m_globalSpongeLocations.end());
38072 if(m_noSpongeCells > 0) {
38073 mAlloc(m_spongeAverageCellId, m_globalNoSpongeLocations,
"m_spongeAverageCellId", FUN_);
38074 mAlloc(m_globalNoPeriodicExchangeCells, m_globalNoSpongeLocations,
"m_globalNoPeriodicExchangeCells", 0, FUN_);
38076 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38077 m_spongeAverageCellId[i].clear();
38080 vector<MInt> noPeriodicExchangeCells(m_globalNoSpongeLocations, F0);
38082 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38083 for(
MInt c = 0; c < m_noSpongeCells; c++) {
38084 MInt cellId = m_spongeCells[c];
38085 if(abs(a_coordinate(cellId, m_7901wallDir) - m_globalSpongeLocations[i].first) < 1e-16) {
38086 if(!a_isHalo(cellId)) {
38087 m_spongeAverageCellId[i].push_back(cellId);
38088 ++noPeriodicExchangeCells[i];
38094 if(m_spongeCommSize > 0) {
38095 MPI_Allreduce(&noPeriodicExchangeCells[0], &m_globalNoPeriodicExchangeCells[0], m_globalNoSpongeLocations,
38096 MPI_INT, MPI_SUM, m_spongeComm, AT_,
"noPeriodicExchangeCells",
"m_globalNoPeriodicExchangeCells");
38100 mAlloc(m_LESPeriodicAverage, m_LESNoVarAverage, m_globalNoSpongeLocations,
"m_LESPeriodicAverage", F0, FUN_);
38101 mAlloc(m_uvErr, m_globalNoSpongeLocations,
"m_uvErr", F0, FUN_);
38102 mAlloc(m_uvRans, m_globalNoSpongeLocations,
"m_uvRans", F0, FUN_);
38103 mAlloc(m_uvInt, m_globalNoSpongeLocations,
"m_uvInt", F0, FUN_);
38106template <MInt nDim_,
class SysEqn>
38110 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
38115 MString fname = Context::getSolverProperty<MString>(
"preliminarySpongeDataFile", m_solverId, AT_, &fname);
38116 if(m_spongeRank == 0) cerr <<
"loading STG preliminary sponge data from " << fname <<
"...";
38118 ifstream preliminarySpongeData;
38119 preliminarySpongeData.open(fname);
38121 vector<MFloat> data;
38125 while(preliminarySpongeData >> num) {
38126 data.push_back(num);
38130 MInt preliminarySpongeDataVarCount = Context::getSolverProperty<MInt>(
"preliminarySpongeDataVarCount", m_solverId,
38131 AT_, &preliminarySpongeDataVarCount);
38132 MInt uvIndex = Context::getSolverProperty<MInt>(
"preliminarySpongeDataUVIndex", m_solverId, AT_, &uvIndex);
38133 MInt dataCount = data.size() / preliminarySpongeDataVarCount;
38135 vector<vector<MFloat>> preData(dataCount, vector<MFloat>(preliminarySpongeDataVarCount, 0));
38138 for(
MInt d = 0; d < dataCount; d++) {
38139 for(
MInt dd = 0; dd < preliminarySpongeDataVarCount; dd++) {
38140 index = preliminarySpongeDataVarCount * d + dd;
38141 preData[d][dd] = data[index];
38145 preliminarySpongeData.close();
38147 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38148 MFloat pos = m_globalSpongeLocations[i].first;
38149 for(
MInt d = 0; d < dataCount - 1; d++) {
38151 if(preData[d][0] < pos && preData[d + 1][0] > pos) {
38152 m_uvRans[i] = preData[d][uvIndex]
38153 + (preData[d + 1][uvIndex] - preData[d][uvIndex]) / (preData[d + 1][0] - preData[d][0])
38154 * (pos - preData[d][0]);
38159 if(m_spongeRank == 0) cerr <<
"ok" << endl;
38162template <MInt nDim_,
class SysEqn>
38166 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
38168 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38169 if(m_zonal) m_uvRans[i] = F0;
38170 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
38171 m_LESPeriodicAverage[var][i] = F0;
38175 if(m_spongeRank > -1) {
38176 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38177 for(
MInt p = 0; p < (
MInt)m_spongeAverageCellId[i].size(); p++) {
38178 MInt cellId = m_spongeAverageCellId[i][p];
38180 vector<MInt>::iterator findAvgId = find(m_LESAverageCells.begin(), m_LESAverageCells.end(), cellId);
38181 if(findAvgId != m_LESAverageCells.end()) {
38182 MInt avgId = distance(m_LESAverageCells.begin(), findAvgId);
38183 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
38184 m_LESPeriodicAverage[var][i] += m_LESVarAverage[var][avgId] / m_globalNoPeriodicExchangeCells[i];
38187 m_uvRans[i] += m_RANSValues[m_noRANSVariables - 1][cellId] / m_globalNoPeriodicExchangeCells[i];
38193 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
38194 MPI_Allreduce(MPI_IN_PLACE, m_LESPeriodicAverage[var], m_globalNoSpongeLocations, MPI_DOUBLE, MPI_SUM,
38195 m_spongeComm, AT_,
"MPI_IN_PLACE",
"m_LESPeriodicAverage[var]");
38199 MPI_Allreduce(MPI_IN_PLACE, &m_uvRans[0], m_globalNoSpongeLocations, MPI_DOUBLE, MPI_SUM, m_spongeComm, AT_,
38200 "MPI_IN_PLACE",
"m_uvRans");
38204 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38206 m_LESPeriodicAverage[noVariables() + 1][i] - m_LESPeriodicAverage[0][i] * m_LESPeriodicAverage[1][i];
38207 m_uvErr[i] = m_uvRans[i] - uv_LES;
38208 if(abs(m_uvInt[i]) < m_spongeLimitFactor * abs(m_uvRans[i]) ||
38210 m_uvErr[i] * m_uvInt[i] < 1e-16) {
38211 m_uvInt[i] += timeStep() * m_uvErr[i];
38217 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
38218 MPI_Bcast(&m_LESPeriodicAverage[var][0], m_globalNoSpongeLocations, MPI_DOUBLE, m_spongeRoot, mpiComm(), AT_,
38219 "m_LESPeriodicAverage");
38221 MPI_Bcast(&m_uvInt[0], m_globalNoSpongeLocations, MPI_DOUBLE, m_spongeRoot, mpiComm(), AT_,
"m_uvInt");
38222 MPI_Bcast(&m_uvErr[0], m_globalNoSpongeLocations, MPI_DOUBLE, m_spongeRoot, mpiComm(), AT_,
"m_uvErr");
38228 for(
MInt cellId = 0; cellId < c_noCells(); cellId++) {
38229 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38231 m_LESPeriodicAverage[noVariables() + 1][i] - m_LESPeriodicAverage[0][i] * m_LESPeriodicAverage[1][i];
38232 MFloat pos = m_globalSpongeLocations[i].first;
38233 if(
approx(pos, a_coordinate(cellId, m_7901wallDir), 1e-16)) {
38234 for(
MInt d = 0; d < nDim; d++) {
38236 m_STGSpongeFactor[d][cellId] = a_pvariable(cellId, d) - m_LESPeriodicAverage[d][i];
38238 m_STGSpongeFactor[nDim - 1][cellId] = m_uvRans[i];
38240 m_STGSpongeFactor[nDim][cellId] = m_uvErr[i];
38242 m_STGSpongeFactor[nDim + 1][cellId] = alpha * m_uvErr[i] + beta * m_uvInt[i];
38244 m_STGSpongeFactor[nDim + 2][cellId] = uv_LES;
38255template <MInt nDim_,
class SysEqn>
38259 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
38261 for(
MInt var = 0; var < m_LESNoVarAverage; var++) {
38262 m_LESVarAverage[var].clear();
38263 for(
auto it = std::begin(m_LESAverageCells); it != std::end(m_LESAverageCells); ++it) {
38264 m_LESVarAverage[var].push_back(F0);
38270template <MInt nDim_,
class SysEqn>
38274 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
38276 m_LESAverageCells.clear();
38278 if(!grid().isActive())
return;
38281 m_LESNoVarAverage = noVariables() + (nDim - 1) * 3;
38283 MFloat averagePos = m_7901Position;
38284 MInt averageDir = abs(m_7901wallDir + m_7901periodicDir - nDim);
38287 if(!std::isinf(m_7901Position)) {
38289 m_averagePos.push_back(averagePos);
38290 m_averageDir.push_back(averageDir);
38291 m_averageReconstructNut.push_back(
false);
38295 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) {
38296 for(
MInt p = 0; p < (
MInt)m_averagePos.size(); p++) {
38297 MInt noLESAverageCells = 0;
38298 for(
MInt cellId = 0; cellId < c_noCells(); cellId++) {
38299 MFloat halfCellLength = grid().halfCellLength(cellId);
38300 MFloat pos = a_coordinate(cellId, m_averageDir[p]);
38301 if(
approx(m_averagePos[p], pos, halfCellLength)) {
38302 m_LESAverageCells.push_back(cellId);
38303 noLESAverageCells++;
38308 if(m_averageReconstructNut[p]) {
38309 for(
MInt l = 0; l < noLESAverageCells; l++) {
38310 MInt cellId = m_LESAverageCells[l];
38311 for(
MInt nghbr = 0; nghbr < a_noReconstructionNeighbors(cellId); nghbr++) {
38312 const MInt recNghbrId = a_reconstructionNeighborId(cellId, nghbr);
38314 vector<MInt>::iterator findRecNghbrId =
38315 find(m_LESAverageCells.begin(), m_LESAverageCells.end(), recNghbrId);
38317 if(findRecNghbrId == m_LESAverageCells.end()) {
38318 m_LESAverageCells.push_back(recNghbrId);
38324 MInt noAvgCellsGlobal = 0;
38325 MInt size = (
MInt)m_LESAverageCells.size();
38326 MPI_Allreduce(&size, &noAvgCellsGlobal, 1, MPI_INT, MPI_SUM, mpiComm(), AT_,
"size",
"noAvgCellsGlobal");
38328 if(domainId() == 0) {
38329 cerr <<
"m_noLESAverageCells: " << noAvgCellsGlobal << endl;
38336template <MInt nDim_,
class SysEqn>
38340 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
38341 for(
MInt var = 0; var < m_noLESVariables; var++) {
38342 m_LESValues[var].resize(c_noCells());
38346 for(
MInt var = 0; var < m_noRANSVariables; var++) {
38347 m_RANSValues[var].resize(c_noCells());
38353template <MInt nDim_,
class SysEqn>
38357 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
38359 if(m_spongeRank > -1 && domainId() == m_spongeRoot) {
38362 if(m_useNonSpecifiedRestartFile) {
38363 fn << outputDir() <<
"stgSpongeData";
38371 cerr <<
"Writing STG sponge data at " <<
globalTimeStep <<
" ..";
38373 MString header =
"#x1 x2 m_uvInt";
38375 ofstream spongeData;
38376 spongeData.precision(16);
38378 spongeData.open(fname);
38379 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38381 line.append(to_string(m_globalSpongeLocations[i].first) +
";" + to_string(m_globalSpongeLocations[i].second) +
";"
38382 + to_string(m_uvInt[i]) +
";");
38384 spongeData << line << endl;
38386 spongeData.close();
38388 cerr <<
"ok" << endl;
38392template <MInt nDim_,
class SysEqn>
38396 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0)
return;
38398 if(m_spongeRank > -1 && domainId() == m_spongeRoot) {
38401 if(m_useNonSpecifiedRestartFile) {
38402 fn << restartDir() <<
"stgSpongeData";
38410 cerr <<
"Loading STG sponge data at " <<
globalTimeStep <<
" ..";
38412 ifstream spongeData;
38413 spongeData.open(fname);
38415 vector<double> data(3);
38419 while(spongeData >> num) {
38420 data.push_back(num);
38425 if(m_globalSpongeLocations.size() == 0) {
38426 cerr <<
"ERROR in loading sponge data" << endl;
38429 MInt dataCount = 0;
38430 for(
MInt i = 0; i < m_globalNoSpongeLocations; i++) {
38431 for(
unsigned int d = 0; d < data.size() - 3; d++) {
38435 if((data[d] <= m_globalSpongeLocations[i].first ||
approx(data[d], m_globalSpongeLocations[i].first, 1e-8))
38436 && (data[d + 3] >= m_globalSpongeLocations[i].first
38437 ||
approx(data[d + 3], m_globalSpongeLocations[i].first, 1e-8))) {
38440 + (data[d + 5] - data[d + 2]) / (data[d + 3] - data[d]) * (m_globalSpongeLocations[i].first - data[d]);
38448 if(dataCount != m_globalNoSpongeLocations) {
38449 cerr <<
"not all data was correctly read" << endl;
38450 cerr <<
"read data count: " << dataCount <<
", should be: " << m_globalNoSpongeLocations << endl;
38453 spongeData.close();
38455 cerr <<
"ok" << endl;
38459 if(m_spongeRank > -1 && m_spongeCommSize > 0) {
38460 MPI_Allreduce(MPI_IN_PLACE, &m_uvInt[0], m_globalNoSpongeLocations, MPI_DOUBLE, MPI_SUM, m_spongeComm, AT_,
38461 "MPI_IN_PLACE",
"m_uvInt");
38466template <MInt nDim_,
class SysEqn>
38471 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) {
38474 for(
MInt p = 0; p < (
MInt)m_averagePos.size(); p++) {
38475 for(
MInt cellId = 0; cellId < c_noCells(); cellId++) {
38476 MFloat halfCellLength = grid().halfCellLength(cellId);
38477 MFloat pos = a_coordinate(cellId, m_averageDir[p]);
38478 if(
approx(m_averagePos[p], pos, halfCellLength) && a_isHalo(cellId)) {
38479 m_LESAverageCells.push_back(cellId);
38480 for(
MInt v = 0; v < m_LESNoVarAverage; v++) {
38481 m_LESVarAverage[v].push_back(F0);
38487 if(m_averageReconstructNut[p]) {
38488 for(
auto it = std::begin(m_LESAverageCells); it != std::end(m_LESAverageCells); ++it) {
38491 if(a_isHalo(cellId)) {
38492 for(
MInt nghbr = 0; nghbr < a_noReconstructionNeighbors(cellId); nghbr++) {
38493 const MInt recNghbrId = a_reconstructionNeighborId(cellId, nghbr);
38498 vector<MInt>::iterator findRecNghbrId =
38499 find(m_LESAverageCells.begin(), m_LESAverageCells.end(), recNghbrId);
38501 if(findRecNghbrId == m_LESAverageCells.end()) {
38502 m_LESAverageCells.push_back(recNghbrId);
38503 for(
MInt v = 0; v < m_LESNoVarAverage; v++) {
38504 m_LESVarAverage[v].push_back(F0);
38515 for(
MInt v = 0; v < m_LESNoVarAverage; v++) {
38517 exchangeLESVarAverage.
fill(F0);
38518 for(
MInt cellId = 0; cellId < c_noCells(); cellId++) {
38519 vector<MInt>::iterator findAverageId = find(m_LESAverageCells.begin(), m_LESAverageCells.end(), cellId);
38520 if(findAverageId != m_LESAverageCells.end()) {
38521 MInt LESAvgId = distance(m_LESAverageCells.begin(), findAverageId);
38522 if(!a_isHalo(cellId)) {
38524 exchangeLESVarAverage[cellId] = m_LESVarAverage[v][LESAvgId];
38529 exchangeData(&exchangeLESVarAverage[0], 1);
38531 for(
MInt LESAvgId = 0; LESAvgId < (
MInt)m_LESAverageCells.size(); LESAvgId++) {
38532 MInt cellId = m_LESAverageCells[LESAvgId];
38533 if(a_isHalo(cellId)) {
38534 m_LESVarAverage[v][LESAvgId] = exchangeLESVarAverage[cellId];
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'
define the names of all variables and attributes in the netcdf file
const MChar * globalTimeStep
const MChar * physicalTime
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.
void computeSrfcs(MInt, MInt, MInt, MInt)
virtual void computeConservativeVariables()
Dispatches the computation of the conservative variables for different number of species.
void resetSolver() override
Reset the solver prior to load balancing.
virtual void LSReconstructCellCenter()
Dispatch the reconstruction computation to the appropiate loop.
virtual MFloat & vorticityAtCell(const MInt cellId, const MInt dir)
void computeRecConstPeriodic_()
void computeQCriterion(MFloatScratchSpace &qCriterion)
virtual void viscousFlux_Gequ_Pv_Plenum()
Computes the viscous flux using a central difference scheme, modified version for flame plenum comput...
virtual void computePrimitiveVariablesCoarseGrid()
Computes the primitive variables: velocity, density, and pressure from the conservative variables and...
MFloat cv_p(MInt cellId) const noexcept
Returns the pressure computed from the conservative variables of the cell cellId.
virtual void initNearBoundaryExchange(const MInt mode=0, const MInt offset=0)
Setup the near-boundary communicator needed for the flux-redistribution method.
virtual void loadGridFlowVarsPar(const MChar *fileName)
This function loads the flow information of the cells such as variables and attributes like u_velocit...
void exchangeFloatDataAzimuthal(MFloat *data, MInt noVars, const std::vector< MInt > &rotIndices)
MFloat computeTimeStepApeDirectional(MInt cellId) const noexcept
MFloat computeWMViscositySpalding(MInt)
void computeSpeciesReactionRates()
Dispatches the species reaction rate computation at each cell by calling the relevant method from the...
void setAndAllocateCombustionGequPvProperties()
reads in the combustion properties
void viscousFluxCompact_(F &viscousFluxFct)
Computes the viscous fluxes using a compact stencil with increased stability for flows with dominatin...
void getSolverTimings(std::vector< std::pair< MString, MFloat > > &solverTimings, const MBool allTimings) override
Get solver timings.
void resizeGridMap() override
Swap the given cells.
virtual void determineLESAverageCells()
virtual void calcSamplingVariables(const std::vector< MInt > &varIds, const MBool exchange) override
Calculate sampling variables.
MBool requiresTimeStepUpdate() const
Returns true if the time-step should be updated on this step.
virtual void nonReflectingBCAfterTreatmentCutOff()
void setAndAllocateSpongeLayerProperties()
Reads and initializes properties associated with sponge boundary conditions.
MInt cellDataSizeDlb(const MInt dataId, const MInt gridCellId) override
Return data size to be communicated during DLB for a grid cell and given data id.
virtual MInt getAdjacentLeafCells_d2_c(const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
MFloat reduceData(const MInt cellId, MFloat *data, const MInt dataBlockSize=1, const MBool average=true)
determines the value of 'data' in the given cell by recusively volumetric averaging among all its off...
void deleteSrfcs()
Deletes all surfaces existing.
void balance(const MInt *const noCellsToReceiveByDomain, const MInt *const noCellsToSendByDomain, const MInt *const targetDomainsByCell, const MInt oldNoCells) override
Balance the solver.
void setMeanMolarWeight_PV(MInt cellId)
FvCartesianSolverXD()=delete
void computeCoarseGridCorrection(MInt)
void computeConservativeVariablesCoarseGrid()
Computes the primitive variables: velocity, density, and pressure from the conservative variables and...
void getGlobalSolverVars(std::vector< MFloat > &globalFloatVars, std::vector< MInt > &globalIdVars) override
Get/set global solver variables during DLB.
virtual void smallCellRHSCorrection(const MInt timerId=-1)
void reInitActiveCellIdsMemory()
Allocate memory to arrays according to the current number of cells.
std::vector< MInt > findWallNormalNeighbors(MInt pointId)
MFloat computeWMViscositySpalding3D(MInt)
virtual void writeListOfActiveFlowCells()
void rotateVectorAzimuthal(MInt side, MFloat *data, MInt noData, const std::vector< MInt > &indices)
void sensorEntropyQuot(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
void setAndAllocateJetProperties()
reads in the jet properties
void copyGridProperties()
void resetExternalSources()
Reset external sources.
virtual void setConservativeVariables(MInt cellId)
computes conservative from primitive variables for given cell id
void LSReconstructCellCenterCons(const MUint noSpecies)
virtual void copyRHSIntoGhostCells()
virtual MInt getAdjacentLeafCells_d0_c(const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
void tripForceCoefficients(MFloat *, MFloat *, MFloat *, MInt, MInt)
virtual void computeSurfaceValuesLOCD(MInt timerId=-1)
virtual MFloat getBoundaryHeatFlux(const MInt cellId) const
calculates heat flux of boundary cells
virtual void computeSurfaceValuesLimitedSlopes(MInt timerId=-1)
void getInterpolatedVariablesInCell(const MInt cellId, const MFloat *position, MFloat *vars)
calculates interpolated variables for a given position in a given cell
MInt setUpBndryInterpolationStencil(const MInt, MInt *, const MFloat *)
void removeCell(const MInt) override
Remove the given cell.
void getDefaultWeights(MFloat *weights, std::vector< MString > &names) const
Return the default weights for all load quantities.
void getInterpolatedVariables(const MInt cellId, const MFloat *position, MFloat *vars) override
calculates interpolated variables for a given position in a given cell
void checkForSrfcsMGC_2()
virtual void computeReconstructionConstants()
void computeMeanMolarWeights_PV()
Dispatches the mean molar weight computation at the cell center from the primitive variables by calli...
void findNeighborHood(MInt cellId, MInt layer, std::vector< MInt > &nghbrList)
Obtain list of neighbors for the given extend.
void computeRecConstPeriodic()
void setAndAllocateAdaptationProperties()
This function reads the properties required for adaptive mesh refinement.
void initAzimuthalReconstruction()
void resetSponge()
reset sponge properties
virtual void cutOffBoundaryCondition()
virtual void resetRHSNonInternalCells()
void checkGhostCellIntegrity()
Checks whether cells' isGhost and the boundary Id coincede. Cells' isGhost is is used to tell the gri...
void saveSolverSolution(const MBool forceOutput=false, const MBool finalTimeStep=false) override
Manages solver-specific output.
void finalizeAdaptation() override
void swapCells(const MInt, const MInt) override
void linearInterpolation(MInt, MInt, MInt *)
virtual void initInterpolationForCell(const MInt cellId)
Init the interpolation for points inside a given cell (based on interpolateVariables())
virtual void findNghbrIds()
virtual void resetBoundaryCells(const MInt offset=0)
void loadRestartTime(const MChar *fileName, MInt &globalTimeStepInput, MFloat &timeInput, MFloat &physicalTimeInput)
This function loads the flow information of the cells such as variables and attributes like u_velocit...
void extendStencil(const MInt)
extend the reconstruction sencil towards all diagonal cells on the first layer
virtual void resetSolverFull()
MBool useTimeStepFromRestartFile() const
Returns true if the time-step from a restart file should be reused.
virtual MInt getAdjacentLeafCells_d2(const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
void prepareAdaptation() override
void calculateHeatRelease()
calculates heatRelease, currently used for postprocessing (average_in)
void setAndAllocateZonalProperties()
std::array< MFloat, nDim_+2 > computeSpongeDeltas(MInt cellId, std::array< MFloat, 6 >)
void setCombustionGequPvVariables()
reads in the combustion properties
void computeWallNormalPointCoords()
void exchangeAzimuthalRemappedHaloCells()
void loadSampleVariables(MInt timeStep)
load variables for the specified timeStep
MFloat time() const override
returns the time
MFloat crankAngle(const MFloat, const MInt)
help-function for engine calculations which returns the crank-angle for a given time mode = 0: return...
void setUpwindCoefficient()
void setSamplingProperties()
Reads properties associated with variable sampling.
void applySandpaperTrip()
void buildLeastSquaresStencilSimple()
Determine the least squares stencil.
void bilinearInterpolation(MInt, MInt, MInt *)
void computeGamma()
Dispatches the gamma computation at each cell by calling the relevant function from the detChemSysEqn...
void computeCellSurfaceDistanceVectors()
void getWallNormalPointVars()
void writeCutCellsToGridFile()
Writes cut cell information to an existing grid file in order to visualize it in ParaView.
void initSpanAvgSrfcProbes()
void setRestartFileOutputTimeStep()
std::array< MFloat, 6 > computeTargetValues()
virtual void viscousFlux_Gequ_Pv()
Computes the viscous flux using a central difference scheme.
void initWMSurfaceProbes()
void writeSpanAvgSrfcProbes()
void setMeanMolarWeight_CV(MInt cellId)
Computes the mean molar weight at the given cell ID from the primitive variables. The mean molar weig...
virtual void getDimensionalizationParams(std::vector< std::pair< MFloat, MString > > &dimParams) const
get dimensionalization parameters
void setInputOutputProperties()
Reads properties and initializes variables associated with input/output.
void reInitSmallCellIdsMemory()
Reallocate memory to small and master cell id arrays according to the current number of cells.
MBool prepareRestart(MBool, MBool &) override
Prepare the solvers for a grid-restart.
void send(const MBool exchangeAll=false)
Send window cell data to corresponding neighbors.
void computeAndSetTimeStep()
void saveDebugRestartFile()
Saves the solver restart file and the grid restartFile NOTE: for debugging purposes only!...
virtual void initSolutionStep(MInt)
Initializes the solver.
void initSTGSpongeExchange()
virtual void exchangePeriodic()
virtual void correctBoundarySurfaces_()
virtual void saveRestartFile(const MBool)
virtual void viscousFlux()
MFloat computeTimeStep(MInt cellId) const noexcept
void finalizeBalance() override
Reinitialize solver after all data structures have been recreated.
void sensorVorticity(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
void computeDomainAndSpongeDimensions()
Extracts the minimum and maximum coordinates of all cells in the grid.
void setRungeKuttaProperties()
This function reads the properties required for Runge Kutta time stepping.
virtual void initializeRungeKutta()
Reads the Runge-Kutta properties and initializes the variables required for Runge Kutta time stepping...
void finalizeMpiExchange()
Finalize non-blocking MPI communication (cancel open requests, free all requests)
void startMpiExchange()
Begin non-blocking communication by posting new send requests.
void saveGridFlowVarsPar(const MChar *fileName, MInt noTotalCells, MLong noInternalCells, MFloatScratchSpace &variables, std::vector< MString > &dbVariablesName, MInt, MIntScratchSpace &idVariables, std::vector< MString > &idVariablesName, MInt, MFloatScratchSpace &dbParameters, std::vector< MString > &dbParametersName, MIntScratchSpace &idParameters, std::vector< MString > &idParametersName, const MInt *recalcIds)
This function stores the massivley parallel flow information of the cells.
virtual MBool maxResidual(MInt mode=0)
Computes the global root-mean-square residual. The residual is defined as time derivative of conserva...
virtual void Ausm()
Dispatches the AUSM flux computation for different number of species.
MBool cellOutside(const MInt)
void setNumericalProperties()
Reads and initializes properties associated with the numerical method.
void computeGridCellCoordinates(MFloat *)
computes the coordinates of the grid cell centers and stores them into a one-dimensional array
void computeVorticity2D(MFloat *const vorticity)
void computeVorticity3D(MFloat *const vorticity)
void createBoundaryCells()
identifies bndry cells (Sets a_isInterface for the solver!)
void writeCenterLineVel()
MBool bubblePathDispersion
MFloat setAndAllocateSpongeDomainProperties(MFloat)
reads in the sponge properties for the domain boundaries
void getSampleVariables(MInt cellId, const MFloat *&vars)
read only access to primitive variables of a single cell
virtual void filterConservativeVariablesAtFineToCoarseGridInterfaces()
void initAzimuthalMaxLevelExchange()
void setConservativeVarsOnAzimuthalRecCells()
void sensorInterfaceLs(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
virtual void correctMasterCells()
adds the right hand side of small cells to their corresponding master cells and sets the small cell R...
void addSpeciesReactionRatesAndHeatRelease()
MInt getAdjacentLeafCells(const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
retrieves the first 'noLayers' layers of direct and(or diagonal neighbors to the given cell
void fillExcBufferAzimuthal(MInt cellId, MInt offset, MFloat *dataDest, MFloat *dataSrc, MInt noData, const std::vector< MInt > &rotIndex=std::vector< MInt >())
void finalizeLESAverage()
void computeForceCoefficients(MFloat *)
void cellSurfaceMapping()
void azimuthalNearBoundaryReverseExchange()
MFloat cv_a(MInt cellId) const noexcept
Returns the speed-of-sound computed from the conservative variables of the cell cellId.
virtual MInt getAdjacentLeafCells_d1_c(const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
void readWallModelProperties()
void computeSlopesByCentralDifferences()
virtual void Muscl(MInt=-1)
Reconstructs the flux on the surfaces.
void sensorInterface(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
void identPeriodicCells()
virtual void convertPrimitiveRestartVariables()
converts the primitive restart variables to a new Mach Number
virtual void getSolverSamplingProperties(std::vector< MInt > &samplingVars, std::vector< MInt > &noSamplingVars, std::vector< std::vector< MString > > &samplingVarNames, const MString featureName="") override
Read sampling related properties.
void bilinearInterpolationAtBnd(MInt, MInt, MInt *)
void loadRestartFile() override
void scatter()
Scatter received data of all neighbors to the corresponding halo cells.
virtual void initSolverSamplingVariables(const std::vector< MInt > &varIds, const std::vector< MInt > &noSamplingVars) override
Initialize sampling variables/allocate memory.
void sensorCutOff(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
void allocateAndInitSolverMemory()
Allocates the resources of the FV solver. Mostly arrays of size maxNoCells used in the main part of t...
void interpolateVariablesInCell(const MInt cellId, const MFloat *position, std::function< MFloat(MInt, MInt)> variables, MFloat *result)
Interpolate the given variable field inside a cell at a given position (based on interpolateVariables...
void swapProxy(const MInt, const MInt) override
void setAndAllocateDetailedChemistryProperties()
void azimuthalNearBoundaryExchange()
void interpolateAzimuthalDataReverse(MFloat *data, MInt offset, MInt noVars, const MFloat *vars)
void sensorPatch(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
void prepareMpiExchange()
void setSensors(std::vector< std::vector< MFloat > > &sensors, std::vector< MFloat > &sensorWeight, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MInt > &sensorSolverId) override
set the sensors for the adaptation (i.e. which cell should be refined/removed?)
void setTestcaseProperties()
Reads and initializes properties associated with the physics of the simulation and allocates small ar...
virtual void initializeMaxLevelExchange()
parallel: Store all necessary data in send buffer
MFloat cv_T(MInt cellId) const noexcept
Returns the temperature computed from the conservative variables of the cell cellId.
virtual void smallCellCorrection(const MInt timerId=-1)
Flux-redistribution method Apply a stable correction to small-cells and redistribute the defective fl...
MInt determineRestartTimeStep() const override
Determine the restart time step from the restart file (for useNonSpecifiedRestartFile = true)
void computeReconstructionConstantsSVD()
Compute the reconstruction constants using a weighted least squares approached solved via singular va...
void calcPeriodicSpongeAverage()
void computeSourceTerms()
void sensorInterfaceLsMb(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
void exchangeGapInfo()
exchanges the Gap-Information with the solver-own communicators!
virtual void resetImplicitCoefficients()
void interpolateVariables(const MInt cellId, const MFloat *position, MFloat *result)
calculates interpolated variables (in the range a, b) for a given position in a given cell
void limitWeights(MFloat *) override
Limit Weight types to avoid large memory disbalance between ranks for DLB.
void correctMajorSpeciesMassFraction()
Corrects the mass fraction of the predominant species to ensure conservation due to numerical or appr...
virtual void resetSurfaces()
void determineStructuredCells()
void interpolateAzimuthalData(MFloat *data, MInt offset, MInt noVars, const MFloat *vars)
void refineCell(const MInt) override
void computeSamplingTimeStep_()
computes the time step according to the sample variables
void getPrimitiveVariables(MInt, MFloat *, MFloat *, MInt)
void initSolver() override
Initializes the fv-solver.
void finishMpiExchange()
Finish non-blocking communication by waiting for receive requests.
void initCutOffBoundaryCondition()
void gather()
Gather data of all window cells for all neighbors in the send buffers.
void initAzimuthalCartesianHaloInterpolation()
void lhsBnd()
Apply lhsBnd.
void sensorDerivative(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
computes the sensor values for a derivative sensor
MInt noLoadTypes() const override
void balancePost() override
Reinitialize solver after setting solution data in DLB.
virtual void updateSpongeLayer()
computes the additional rhs of all cells lying inside the sponge layer to dissipate outgoing waves.
void getHeatRelease(MFloat *&heatRelease)
returns
void getLoadQuantities(MInt *const loadQuantities) const override
Return the cumulative load quantities on this domain.
void removeChilds(const MInt) override
void initViscousFluxComputation()
virtual void nonReflectingBCCutOff()
MFloat getCellLoad(const MInt cellId, const MFloat *const weights) const override
Return the load of a single cell (given computational weights).
void computeInitialPressureLossForChannelFlow()
Computes pressure loss for the initial condition of channel flow testcases as . Requires property ReT...
void applyCoarseLevelCorrection()
Apply coarse-level correction to RHS.
virtual void getVorticity(MFloat *const vorticity)
wrapper for vorticity computation
void implicitTimeStep() override
void identPeriodicCells_()
virtual void applyInitialCondition()
Initializes the entire flow field.
void setGlobalSolverVars(std::vector< MFloat > &globalFloatVars, std::vector< MInt > &globalIdVars) override
Set global solver variables (see getGlobalSolverVars())
void generateBndryCells()
virtual MInt getAdjacentLeafCells_d1(const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
MFloat computeTimeStepEulerDirectional(MInt cellId) const noexcept
void cancelMpiRequests() override
Cancel open MPI (receive) requests.
virtual void loadOldVariables(const MString &fileName)
This function loads oldVariable data from a restartFile-type file.
virtual void computePrimitiveVariables()
Dispatches the computation of the primitive variables for different number of species.
void initCanteraObjects()
Allocates the Cantera objects that define a thermodynamic phase, reaction kinetics and transport prop...
void lhsBndFinish()
Finish the split MPI communication and perform the left out part from lhsBnd().
void computeVorticity3DT(MFloat *const vorticity)
Compute vorticity and store in vorticity pointer (transposed version)
virtual void calcSamplingVarAtPoint(const MFloat *point, const MInt id, const MInt sampleVarId, MFloat *state, const MBool interpolate=false) override
Calculate the sampling variables at a given point in a cell.
void updateSpongeLayerRhs(MInt, std::array< MFloat, nDim_+2 >)
virtual MInt getAdjacentLeafCells_d0(const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
virtual void distributeFluxToCells()
Distributes the surface fluxes to the cell RHS.
void writeWMTimersASCII()
MInt noVariables() const override
Return the number of primitive variables.
void initializeFvCartesianSolver(const MBool *propertiesGroups)
FV Constructor: reads and allocate properties/variables:
virtual void applyBoundaryCondition()
handles the application of boundary conditions to the ghost cells
virtual void computeLimitedSurfaceValues(MInt timerId=-1)
void tripFourierCoefficients(MFloat *, MInt, MFloat, MFloat)
void computeMeanMolarWeights_CV()
Dispatches the mean molar weight computation at the cell center from the conservative variables by ca...
void sensorParticle(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
void writeWMSurfaceProbes()
void computeVolumeForcesRANS()
virtual void resetZonalLESAverage()
Initializes zonal exchange arrays.
void setInfinityState()
Computes/defines the infinity values/state once and for all Ideally the infinity variables should not...
virtual void computeSurfaceValuesLimitedSlopesMan(MInt timerId=-1)
aaplies the slope limiter to the slopes before calling computeSurfaceValues_
void exchangeZonalAverageCells()
MFloat interpolateWallNormalPointVars(MInt var, MFloat coords[], MInt localId, std::vector< MInt > neighborList)
void viscousFlux_(F &viscousFluxFct)
Computes the viscous flux using a central difference scheme to approximate the slopes at the surface ...
void setPrimitiveVariables(MInt cellId)
computes primitive from primitive variables for given cell id. This is the version for all SysEqn.
virtual void resetRHSCutOffCells()
void sensorSpecies(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
void initializeTimers()
Initializes the communication timers.
void computeSurfaceCoefficients()
Dispatches the transport coefficients computation at each surfaces by calling the relevant function f...
void saveSandpaperTripVars()
virtual void setCellProperties()
void computeAcousticSourceTermQe(MFloatScratchSpace &, MFloatScratchSpace &, MFloatScratchSpace &, MFloatScratchSpace &)
MInt getNghbrLeafCells(const MInt cellId, MInt refCell, MInt layer, MInt *nghbrs, MInt dir, MInt dir1=-1, MInt dir2=-1) const
returns the neighbor leaf cells in the specified direction 'dir' (dir1 and dir2 are used to identify ...
void setAndAllocateCombustionTFProperties()
Reads and initializes properties associated with combustion simulations.
void writeRestartFile(const MBool, const MBool, const MString, MInt *) override
void postAdaptation() override
virtual void reIntAfterRestart(MBool)
void computeCellVolumes()
virtual void applyExternalSource()
Add external sources to the RHS.
void checkForSrfcsMGC()
Check all existing cells if surfaces have to be created member function with the task to check all ex...
void exchangeExternalSources()
Exchange external sources.
virtual void getVorticityT(MFloat *const vorticity)
wrapper for vorticity computation (transposed version)
void oldPressure(MFloat *const p)
This function computes the pressure from the oldVariables.
void findDirectNghbrs(MInt cellId, std::vector< MInt > &nghbrList)
Obtain list of direct neighbors of given cell.
virtual void initComputeSurfaceValuesLimitedSlopesMan1()
initializes the limiter at cells, that are in the vicinity of a given stl-geometry
void sensorInterfaceDelta(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
void setActiveFlag(MIntScratchSpace &, const MInt mode, const MInt offset)
Set the flag for the cells needed for near bndry exchange.
void computeDetailedChemistryVariables()
virtual void copyVarsToSmallCells()
MBool cellParticipatesInTimeStep(MInt cellId) const noexcept
Does the cell cellId participate in the time-step computation?
void initDepthCorrection()
void allocateCommunicationMemory()
Allocates and initializes send/receive buffers for multiSolver computations.
void checkInfinityVarsConsistency()
Check that all infinity (or other global) variables are equal on all ranks.
void initAzimuthalNearBoundaryExchange(MIntScratchSpace &activeFlag)
void exchangeProperties()
exchanges isInactive and isOnCurrentMGLevel
virtual void correctBoundarySurfaces()
void resetCutOffCells()
resets all Cut-Off Information should only be called before the adaptation and balance!
MFloat computeTimeStepMethod(MInt cellId) const noexcept
Computes the time-step of the cell cellId.
void interpolateSurfaceDiffusionFluxOnCellCenter(MFloat *const, MFloat *const)
void findWallNormalCellIds()
void checkCellSurfaces()
checks if the surfaces for a cell are correct and balanced The accumulated cell surfaces in +x direct...
virtual void resetZonalSolverData()
virtual bool rungeKuttaStep()
Dispatches the RungeKutta method for different number of species.
void getDomainDecompositionInformation(std::vector< std::pair< MString, MInt > > &domainInfo) override
Return decomposition information, i.e. number of local elements,...
MBool solutionStep() override
Performs one Runge-Kutta step of the FV solver, returns true if the time step is completed.
void setAndAllocateSpongeBoundaryProperties()
reads in the sponge properties for specific boundaries
void checkForSrfcsMGC_2_()
Check all existing cells if surfaces have to be created member function with the task to check all ex...
virtual void updateMultiSolverInformation(MBool fullReset=false)
virtual MBool gridPointIsInside(MInt, MInt)
void computeVolumeForces()
void checkAzimuthalRecNghbrConsistency(MInt cellId)
void rebuildAzimuthalReconstructionConstants(MInt cellId, MInt offset, MFloat *recCoord, MInt mode=0)
void reduceVariables()
Check whether any of the extracted cells lie below the halo cell level and interpolate their variable...
void postTimeStep() override
: Performs the post time step
void receive(const MBool exchangeAll=false)
Receive halo cell data from corresponding neighbors.
MFloat computeDomainLength(MInt direction)
void computeSamplingTimeStep()
void sensorEntropyGrad(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
void finalizeInitSolver() override
Initializes the solver afer the initialRefinement!
virtual void initComputeSurfaceValuesLimitedSlopesMan2()
can be used to apply the slope limiter at certain positions such as refinement interfaces,...
virtual void initSTGSponge()
Initializes zonal exchange arrays.
void dumpCellData(const MString name)
Dump cell data of each rank to a separate file for debugging purposes.
void tagCellsNeededForSurfaceFlux()
virtual void computeAzimuthalReconstructionConstants(MInt mode=0)
void setCellWeights(MFloat *) override
void initHeatReleaseDamp()
MFloat computeRecConstSVD(const MInt cellId, const MInt offset, MFloatScratchSpace &tmpA, MFloatScratchSpace &tmpC, MFloatScratchSpace &weights, const MInt recDim, const MInt, const MInt, const std::array< MBool, nDim > dirs={}, const MBool relocateCenter=false)
compute the reconstruction constants of the given cell by a weighted least-squares approach via singu...
void balancePre() override
Reinitialize solver for DLB prior to setting solution data.
virtual void getSampleVarsDerivatives(const MInt cellId, const MFloat *&vars)
Access derivatives of primitive variables of a given cell.
MFloat computeTimeStepDiffusionNS(MFloat density, MFloat temperature, MFloat Re, MFloat C, MFloat dx) const noexcept
void readPreliminarySTGSpongeData()
void getSampleVariableNames(std::vector< MString > &varNames) override
Return the sample variable names (primitive variables)
virtual void LSReconstructCellCenter_Boundary()
Computes the slopes at the cell centers of only the boundary cells.
virtual void getBoundaryDistance(MFloatScratchSpace &)
Get distance to boundary, currently bc 3003. Should be replaced by more precise distance using STL in...
MBool isOnGeometry(const MFloat, const MFloat *, MString)
static MString printSelfReport()
Returns a shortened string summing up the scratch space state information.
static MString printSelf()
Returns a string summing up the scratch state information and all scratch space elements information.
This class is a ScratchSpace.
T * getPointer() const
Deprecated: use begin() instead!
void fill(T val)
fill the scratch with a given value
pointer p
Deprecated: use [] instead!
void writeVtkXmlOutput(const MChar *fileName)
Copy of parallel single-file VTU output using MPI I/O.
Checks if the primitive variable C exists.
void set(const T &value)
Initializes tensor to constant value.
size_type size() const
Returns the size of the array as product of all five dimensions (i.e. not the actual array size but t...
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
@ HOCD_LIMITED_SLOPES_MAN
void mTerm(const MInt errorCode, const MString &location, const MString &message)
const MString const MString & message
constexpr Real POW3(const Real x)
constexpr Real POW2(const Real x)
MBool approx(const T &, const U &, const T)
constexpr T mMin(const T &x, const T &y)
constexpr T mMax(const T &x, const T &y)
@ IsSplitChild
cell is a split child
@ IsSplitClone
cell is an older-version of a splitchild
ATTRIBUTES1(ATTRIBUTE_NO_AUTOVEC) void FvCartesianSolverXD< nDim_
resets the solver
void printAllocatedMemory(const MLong oldAllocatedBytes, const MString &solverName, const MPI_Comm comm)
Prints currently allocated memory.
MInt globalNoDomains()
Return global number of domains.
MInt globalDomainId()
Return global domain id.
constexpr MLong IPOW2(MInt x)
constexpr MFloat FPOW2(MInt x)
constexpr MFloat FFPOW2(MInt x)
std::basic_string< char > MString
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status, const MString &name, const MString &varname)
same as MPI_Recv
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_Send_init(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_Send_init
int MPI_Barrier(MPI_Comm comm, const MString &name)
same as MPI_Barrier
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_File_seek(MPI_File mpi_fh, MPI_Offset offset, int whence, const MString &name)
same as MPI_File_seek
int MPI_Waitsome(int incount, MPI_Request array_of_requests[], int *outcount, int array_of_indices[], MPI_Status array_of_statuses[], const MString &name)
same as MPI_Waitsome
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_Recv_init(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_Recv_init
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_Issend(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_Issend
int MPI_File_open(MPI_Comm comm, const char *filename, int amode, MPI_Info info, MPI_File *mpi_fh, const MString &name)
same as MPI_File_open
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_Cancel(MPI_Request *request, const MString &name)
same as MPI_cancel
int MPI_Wait(MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Wait
int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gatherv
int MPI_Exscan(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_Exscan
int MPI_Waitall(int count, MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Waitall
int MPI_Iallreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Iallreduce
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_File_close(MPI_File *mpi_fh, const MString &name)
same as MPI_File_close
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_Alltoall(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_Alltoall
int MPI_Request_free(MPI_Request *request, const MString &name)
same as MPI_Request_free
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm, const MString &name, const MString &varname)
same as MPI_Comm_split, but updates the number of MPI communicators
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_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gather
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
int MPI_Alltoallv(const void *sendbuf, const int sendcounts[], const int sdispls[], MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int rdispls[], MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Alltoallv
int MPI_Startall(int count, MPI_Request array_of_requests[], const MString &name)
same as MPI_Startall
int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Send
void const MInt const MInt const MInt const MInt maxNoCells
constexpr std::underlying_type< FcCell >::type p(const FcCell property)
Converts property name to underlying integer value.
T cos(const T a, const T b, const T x)
Cosine slope filter.
constexpr std::underlying_type< FvCell >::type p(const FvCell property)
Converts property name to underlying integer value.
void cross(const T *const u, const T *const v, T *const c)
MFloat RBF(const MFloat R, const MFloat R0)
radial base function
MFloat distance(const MFloat *a, const MFloat *b)
void invert(MFloat *A, const MInt m, const MInt n)
MFloat frobeniusMatrixNormSquared(MFloatScratchSpace &m, MInt dim1, MInt dim2)
MFloat deltaFun(const MFloat r, const MFloat r0, const MFloat r1)
void initFft(fftw_complex *uPhysField, fftw_complex *vPhysField, fftw_complex *wPhysField, MInt lx, MInt ly, MInt lz, MInt noPeakModes, const MFloat Ma)
Generates a velocity field from Fourier-modes using FFTW.
MFloat crankAngle(const MFloat time, const MFloat Strouhal, const MFloat offset, const MInt mode)
help-function for engine calculations which returns the crank-angle for a given time,...
MInt inverse(MFloat **a, MFloat **ainv, MInt n, const MFloat epsilon)
MInt getGlobalPosFFTW(MInt i0, MInt i1, MInt i2, MInt ny, MInt nz)
MInt invertR(T &A, T &weights, T &AInv, const MInt m, const MInt n)
MUint getBufferSize(const std::vector< std::vector< MInt > > &exchangeCells)
Generic exchange of data.
void communicateData(const DataType *const data, const MInt noCells, const MInt *const sortedCellId, const MInt noDomains, const MInt domainId, const MPI_Comm mpiComm, const MInt *const noCellsToSendByDomain, const MInt *const noCellsToReceiveByDomain, const MInt dataBlockSize, DataType *const buffer)
Assemble given data in send buffer and communicate.
void exchangeBuffer(const MInt noExDomains, const MInt *const exDomainId, const MInt *const recvSize, const MInt *const sendSize, const MPI_Comm comm, U *const receiveBuffer, const U *const sendBuffer, const MInt noDat=1)
Generic exchange of data.
void reverseExchangeAddData(const std::vector< MInt > &nghbrDomains, const std::vector< std::vector< MInt > > &haloCellVec, const std::vector< std::vector< MInt > > &windowCellVec, const MPI_Comm comm, U **const data, const MInt noDat=1)
Generic exchange from halo to window cells, however in this case the value in the halo-cell is added ...
void reverseExchangeData(const MInt noNghbrDomains, const MInt *const nghbrDomains, const MInt *const noHaloCells, const MInt **const haloCells, const MInt *const noWindowCells, const MInt **const, const MPI_Comm comm, const U *const data, U *const windowBuffer, const MInt noDat=1)
Generic reverse exchange of data.
void exchangeBitset(const std::vector< MInt > &nghbrDomains, const std::vector< std::vector< MInt > > &haloCellVec, const std::vector< std::vector< MInt > > &windowCellVec, const MPI_Comm comm, std::bitset< N > *const data, const MInt noCells, const MInt noDat=1)
Generic exchange of data.
const MInt PIO_CREATE
< File mode to create a new file. Aborts if file already exists
Namespace for auxiliary functions/classes.
PARALLELIO_DEFAULT_BACKEND ParallelIo
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)
MInt nearest(Point< DIM > pt, MFloat &dist)