12template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
15template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
24template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
26 if(m_alphaConvergenceCheck > 0) {
28 if(m_updateAfterPropagation)
lbSolver().storeOldVariables();
32template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
36 mAlloc(m_depthCorrectionValues,
fvSolver().maxNoGridCells(),
"m_depthCorrectionValues", F0, AT_);
37 initDepthcorrection();
41template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
44 initDepthcorrection();
49template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
52 TERMM(1,
"not implemented for in-coupler depthCorrection!");
56template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
58 std::vector<MBool>& solverCompleted) {
59 static MInt noAlphaIterations = 0;
61 if(m_redistributeAlpha && !m_disableSubstepAlphaRedist
63 correctInvalidAlpha();
66 if(m_redistributeAlpha) correctInvalidAlpha();
68 MBool alphaConverged =
true;
69 if(noAlphaIterations < m_maxNoAlphaIterations) alphaConverged = checkAlphaConverged();
75 if(
fvSolver().domainId() == 0 && m_alphaConvergenceCheck != 0 && noAlphaIterations > 3) {
76 if(noAlphaIterations < m_maxNoAlphaIterations)
77 std::cerr <<
"Globaltimestep: " <<
globalTimeStep <<
" alpha Converged after " << noAlphaIterations
78 <<
" Iterations!" << std::endl;
81 <<
" max number of alphaIterations reached: " << noAlphaIterations << std::endl;
85 noAlphaIterations = 0;
98 transferPressureLb2Fv(
fvSolver().m_RKalpha[
fvSolver().m_RKStep], m_updateFVBC);
107 mTerm(1, AT_,
"Fv Solver cant be completed before Lb Solver is completed in LB-FV-Euler-Euler-Multiphase!");
111template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
113 transferPressureLb2Fv(1.0,
false);
116template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
119template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
121 switch(m_initAlphaMethod) {
125 lbSolver().a_alphaGas(lbCellId) = 0.0;
135 const MFloat alpha = m_initialAlpha;
137 lbSolver().a_alphaGas(lbCellId) = alpha;
148 const MFloat alpha = m_initialAlpha;
153 if(xcoord * xcoord + ycoord * ycoord + zcoord * zcoord < 0.5) {
156 lbSolver().a_alphaGas(i) = m_alphaInf;
163 if(xcoord * xcoord + ycoord * ycoord + zcoord * zcoord < 0.5) {
174 const MFloat alpha = m_initialAlpha;
180 lbSolver().a_alphaGas(i) = m_alphaInf;
197 const MFloat delAlpha = m_initialAlpha - m_alphaInf;
201 lbSolver().a_alphaGas(i) = m_initialAlpha + delAlpha;
202 }
else if(zcoord > 1.0) {
203 lbSolver().a_alphaGas(i) = m_initialAlpha - delAlpha;
205 lbSolver().a_alphaGas(i) = m_initialAlpha - zcoord * delAlpha;
212 }
else if(zcoord > 1.0) {
222 mTerm(1, AT_,
"initAlphaMethod not matching any case!");
229template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
240 m_alphaConvergenceCheck = 0;
242 m_alphaConvergenceCheck = Context::getBasicProperty<MInt>(
"alphaConvergenceCheck", AT_, &m_alphaConvergenceCheck);
252 m_maxNoAlphaIterations = 4;
254 m_maxNoAlphaIterations = Context::getBasicProperty<MInt>(
"maxNoAlphaIterations", AT_, &m_maxNoAlphaIterations);
266 m_epsAlpha = Context::getBasicProperty<MFloat>(
"epsAlpha", AT_, &m_epsAlpha);
277 m_alphaFloor = Context::getBasicProperty<MFloat>(
"alphaFloor", AT_, &m_alphaFloor);
287 m_alphaCeil = Context::getBasicProperty<MFloat>(
"alphaCeil", AT_, &m_alphaCeil);
300 m_initAlphaMethod = 0;
302 m_initAlphaMethod = Context::getBasicProperty<MInt>(
"initAlphaMethod", AT_, &m_initAlphaMethod);
312 m_initialAlpha = 0.0;
314 m_initialAlpha = Context::getBasicProperty<MFloat>(
"initialAlpha", AT_, &m_initialAlpha);
324 m_alphaInf = m_initialAlpha;
325 m_alphaInf = Context::getBasicProperty<MFloat>(
"alphaInf", AT_, &m_alphaInf);
334 m_redistributeAlpha =
true;
335 m_redistributeAlpha = Context::getBasicProperty<MBool>(
"redistributeAlpha", AT_, &m_redistributeAlpha);
344 m_disableSubstepAlphaRedist =
true;
345 m_disableSubstepAlphaRedist =
346 Context::getBasicProperty<MBool>(
"disableSubstepAlphaRedist", AT_, &m_disableSubstepAlphaRedist);
355 m_updateAfterPropagation =
true;
356 m_updateAfterPropagation =
357 Context::getSolverProperty<MBool>(
"updateAfterPropagation", 1, AT_, &m_updateAfterPropagation);
367 m_interpolationFactor = 0.5;
368 m_interpolationFactor =
369 Context::getSolverProperty<MFloat>(
"EEMultiphaseInterpolationFactor", 1, AT_, &m_interpolationFactor);
378 m_updateFVBC =
false;
379 m_updateFVBC = Context::getSolverProperty<MBool>(
"EEMultiphaseUpdateFVBC", 1, AT_, &m_updateFVBC);
382 for(
MInt i = 0; i < 3; i++) {
389 m_gravityRefCoords[i] = Context::getSolverProperty<MFloat>(
"gravityRefCoords", 0, AT_, i);
400 m_depthCorrectionCoefficients[i] = Context::getSolverProperty<MFloat>(
"depthCorrectionCoefficients", 0, AT_, i);
403 mTerm(1, AT_,
"gravityRefCoords and depthCorrectionCoefficients are required for Euler-Euler multiphase!");
407template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
410 if(std::isnan(TInf)) {
416 MFloat depthCorrectionValue = 0.0;
417 for(
MInt i = 0; i < nDim; i++) {
419 depthCorrectionValue +=
422 m_depthCorrectionValues[fvCellId] = depthCorrectionValue;
426template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
428 const MBool update) {
438 m_interpolationFactor > 0.0 ? (rkAlpha * m_interpolationFactor - 1.0 + tsSinceUpdate) *
FFPOW2(lvlDiff) : 0.0;
440 if(fvCellId < 0)
continue;
446 + m_depthCorrectionValues[fvCellId];
453 for(
MInt bndIndex = 0; bndIndex < (
MInt)(
lbBndCnd().m_bndCndIds.size()); bndIndex++) {
458 if(fvCellId < 0)
continue;
459 for(
MInt i = 0; i < 26; i++) {
460 if(!
lbSolver().a_hasNeighbor(lbCellId, i)) {
461 MInt lbOppNId =
lbSolver().c_neighborId(lbCellId, oppositeDirGrid[i]);
462 if(lbOppNId >= 0 && !
lbSolver().a_isBndryCell(lbOppNId)) {
469 - m_depthCorrectionValues[fvOppNId]
470 + m_depthCorrectionValues[fvCellId];
491template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
492template <MBool updateGradients>
494 static MBool firstCall =
true;
510 const MBool interpolate = m_interpolationFactor > 0.0;
513 if(fvCellId < 0)
continue;
518 const MFloat dt = (rkAlpha * m_interpolationFactor - 1.0 + tsSinceUpdate) *
FFPOW2(lvlDiff);
520 for(
MInt i = 0; i < nDim; i++) {
522 IF_CONSTEXPR(updateGradients) {
523 const MFloat dtGrad = (m_interpolationFactor - 1.0 + tsSinceUpdate) *
FFPOW2(lvlDiff);
524 for(
MInt j = 0; j < nDim; j++) {
526 ufactor * dufactor *
lbSolver().calculateInterpolatedDerivative(lbCellId, i, j, dtGrad);
531 for(
MInt i = 0; i < nDim; i++) {
533 IF_CONSTEXPR(updateGradients) {
534 for(
MInt j = 0; j < nDim; j++) {
536 ufactor * dufactor *
lbSolver().calculateDerivative(lbCellId, i, j);
541 IF_CONSTEXPR(updateGradients) {
553 if(fvCellId < 0)
continue;
554 for(
MInt i = 0; i < 3; i++) {
562template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
568 if(lbCellId < 0)
continue;
570 lbSolver().a_uOtherPhase(lbCellId, 0) =
572 lbSolver().a_uOtherPhase(lbCellId, 1) =
574 lbSolver().a_uOtherPhase(lbCellId, 2) =
579template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
585 m_interpolationFactor > 0.0 ? (rkAlpha * m_interpolationFactor - 1.0 + tsSinceUpdate) *
FFPOW2(lvlDiff) : 0.0;
587 if(fvCellId < 0)
continue;
588 if(
fvSolver().a_isBndryGhostCell(fvCellId))
continue;
597template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
601 if(lbCellId < 0)
continue;
607template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
617template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
621 lbSolver().a_oldDistribution(cellId, distr) =
lbSolver().a_previousDistribution(cellId, distr);
626template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
636template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
638 if(m_alphaConvergenceCheck <= 0) {
639 mTerm(1, AT_,
"Didn't store the variables to revert the LB solver!");
642 revertLbDistributions();
643 if(m_updateAfterPropagation) revertLbOldVariables();
646 lbSolver().exchangeOldDistributions();
650template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
660template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
667template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
669 MBool converged =
false;
670 switch(m_alphaConvergenceCheck) {
678 if(
fv2lbId(cellId) < 0)
continue;
685 AT_,
"MPI_IN_PLACE",
"converged");
689 mTerm(1, AT_,
"not a valid alphaConvergenceCheck!");
700template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
714 sendReq.
fill(MPI_REQUEST_NULL);
715 recvReq.
fill(MPI_REQUEST_NULL);
716 sendBufferCnts.
fill(0);
717 recvBufferCnts.
fill(0);
721 MInt sendBufferCounter = 0;
724 for(
MInt v = 0; v < noCVars; v++) {
734 if(sendBufferCnts(i) == 0)
continue;
735 ASSERT(sendBufferCnts(i) <=
fvSolver().m_noMaxLevelWindowCells[i] *
fvSolver().m_dataBlockSize,
"");
737 fvSolver().mpiComm(), &sendReq[sendCnt], AT_,
"m_sendBuffers[" + std::to_string(i) +
"],0");
741 if(recvBufferCnts(i) == 0)
continue;
742 ASSERT(recvBufferCnts(i) <=
fvSolver().m_noMaxLevelHaloCells[i] *
fvSolver().m_dataBlockSize,
"");
744 fvSolver().mpiComm(), &recvReq[recvCnt], AT_,
"m_receiveBuffers[" + std::to_string(i) +
"],0");
747 if(recvCnt > 0)
MPI_Waitall(recvCnt, &recvReq[0], MPI_STATUSES_IGNORE, AT_);
750 if(sendBufferCnts(i) == 0)
continue;
751 ASSERT(sendBufferCnts(i) <=
fvSolver().m_noMaxLevelWindowCells[i] *
fvSolver().m_dataBlockSize,
"");
753 fvSolver().mpiComm(), &sendReq[sendCnt], AT_,
"m_sendBuffers[" + std::to_string(i) +
"],0");
757 if(recvBufferCnts(i) == 0)
continue;
758 ASSERT(recvBufferCnts(i) <=
fvSolver().m_noMaxLevelHaloCells[i] *
fvSolver().m_dataBlockSize,
"");
760 fvSolver().mpiComm(), MPI_STATUS_IGNORE, AT_,
"m_receiveBuffers[" + std::to_string(i) +
"],0");
765 MInt recvBufferCounter = 0;
768 for(
MInt v = 0; v < noCVars; v++) {
774 if(sendCnt > 0)
MPI_Waitall(sendCnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
785 constexpr MInt noTransferCV = 4;
786 std::map<MInt, transferCV>
788 for(
MInt cellId = 0; cellId < fvSolver().m_bndryGhostCellsOffset; cellId++) {
789 if(fvSolver().a_isHalo(cellId))
continue;
790 if(!fvSolver().c_isLeafCell(cellId))
continue;
792 const MFloat origAlpha = fvSolver().a_pvariable(cellId, fvSolver().PV->A);
794 if(origAlpha < (m_alphaFloor - 1.0e-8)) {
795 const MFloat origMass = fvSolver().a_variable(cellId, fvSolver().CV->A_RHO) * fvSolver().a_cellVolume(cellId);
796 const MFloat deltaMass = 0.0 - origMass;
797 const std::vector<MInt> neighbors = findRedistCells(cellId,
true, 0.0);
798 std::vector<MInt> redistNeighbors = neighbors;
799 MInt noRedistNbs = 0;
800 MFloat massNeedPerCell = 0.0;
802 MBool change =
false;
803 noRedistNbs = redistNeighbors.size();
804 massNeedPerCell = deltaMass / noRedistNbs;
805 for(
auto it = redistNeighbors.begin(); it != redistNeighbors.end(); ++it) {
806 const MInt candidateId = *it;
807 if(fvSolver().a_variable(candidateId, fvSolver().CV->A_RHO) * fvSolver().a_cellVolume(candidateId)
810 redistNeighbors.erase(it);
817 MFloat momentumTransfer[3] = {0.0, 0.0, 0.0};
818 if(!redistNeighbors.empty()) {
819 for(
auto redistId : redistNeighbors) {
820 const MFloat delRho = massNeedPerCell / fvSolver().a_cellVolume(redistId);
821 const MFloat delRhoVV[3] = {delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[0]),
822 delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[1]),
823 delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[2])};
824 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO) -= delRho;
825 for(
MInt dir = 0; dir < 3; dir++) {
826 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO_VV[dir]) -= delRhoVV[dir];
827 momentumTransfer[dir] += delRhoVV[dir] * fvSolver().a_cellVolume(redistId);
829 fvSolver().setPrimitiveVariables(redistId);
831 if(fvSolver().a_isHalo(redistId)) {
832 const transferCV delCV = {
838 auto success = haloCorrections.insert(std::pair<MInt, transferCV>(redistId, delCV));
839 if(!success.second) {
840 success.first->second.rhoAlpha += delCV.rhoAlpha;
841 success.first->second.rhoUAlpha += delCV.rhoUAlpha;
842 success.first->second.rhoVAlpha += delCV.rhoVAlpha;
843 success.first->second.rhoWAlpha += delCV.rhoWAlpha;
847 fvSolver().a_variable(cellId, fvSolver().CV->A_RHO) +=
848 massNeedPerCell * noRedistNbs / fvSolver().a_cellVolume(cellId);
849 for(
MInt dir = 0; dir < 3; dir++) {
850 fvSolver().a_variable(cellId, fvSolver().CV->A_RHO_VV[dir]) +=
851 momentumTransfer[dir] / fvSolver().a_cellVolume(cellId);
853 fvSolver().setPrimitiveVariables(cellId);
856 redistNeighbors = neighbors;
858 MFloat massTransfer = 0.0;
859 for(
auto redistId : redistNeighbors) {
861 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO) * fvSolver().a_cellVolume(redistId);
862 const MFloat delRho = massAvail / fvSolver().a_cellVolume(redistId);
863 const MFloat delRhoVV[3] = {delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[0]),
864 delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[1]),
865 delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[2])};
866 massTransfer += massAvail;
867 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO) -= delRho;
868 for(
MInt dir = 0; dir < 3; dir++) {
869 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO_VV[dir]) -= delRhoVV[dir];
870 momentumTransfer[dir] += delRhoVV[dir] * fvSolver().a_cellVolume(redistId);
872 fvSolver().setPrimitiveVariables(redistId);
874 if(fvSolver().a_isHalo(redistId)) {
875 const transferCV delCV = {
881 auto success = haloCorrections.insert(std::pair<MInt, transferCV>(redistId, delCV));
882 if(!success.second) {
883 success.first->second.rhoAlpha += delCV.rhoAlpha;
884 success.first->second.rhoUAlpha += delCV.rhoUAlpha;
885 success.first->second.rhoVAlpha += delCV.rhoVAlpha;
886 success.first->second.rhoWAlpha += delCV.rhoWAlpha;
890 fvSolver().a_variable(cellId, fvSolver().CV->A_RHO) += massTransfer / fvSolver().a_cellVolume(cellId);
891 for(
MInt dir = 0; dir < 3; dir++) {
892 fvSolver().a_variable(cellId, fvSolver().CV->A_RHO_VV[dir]) +=
893 momentumTransfer[dir] / fvSolver().a_cellVolume(cellId);
895 fvSolver().setPrimitiveVariables(cellId);
897 }
else if(origAlpha > (m_alphaCeil + 1.0e-8)) {
898 const MFloat origMass = fvSolver().a_variable(cellId, fvSolver().CV->A_RHO) * fvSolver().a_cellVolume(cellId);
900 m_alphaCeil * fvSolver().a_pvariable(cellId, fvSolver().PV->RHO) * fvSolver().a_cellVolume(cellId) - origMass;
901 std::vector<MInt> neighbors = findRedistCells(cellId,
false, m_alphaCeil);
902 MBool isOutlet =
false;
904 if(fvSolver().a_bndryId(cellId) >= 0) {
905 const MInt bndryId = fvSolver().a_bndryId(cellId);
906 for(
MInt srfc = 0; srfc < fvSolver().m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
907 const MInt bndrCndId = fvSolver().m_fvBndryCnd->m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId;
908 if(bndrCndId == 1002) {
915 for(
MUint dir = 0; dir < 26; dir++) {
916 const MInt neighborId = fvSolver().grid().neighborList(cellId, dir);
917 if(fvSolver().a_isBndryGhostCell(neighborId)) {
918 neighbors.push_back(neighborId);
922 std::vector<MInt> redistNeighbors = neighbors;
924 MInt noRedistNbs = 0;
925 MFloat massExcessPerCell = 0.0;
927 MBool change =
false;
928 noRedistNbs = redistNeighbors.size();
929 massExcessPerCell = -deltaMass / noRedistNbs;
930 for(
auto it = redistNeighbors.begin(); it != redistNeighbors.end(); ++it) {
931 const MInt candidateId = *it;
932 if(!fvSolver().a_isBndryGhostCell(candidateId)
933 && ((fvSolver().a_variable(candidateId, fvSolver().CV->A_RHO)
934 + massExcessPerCell / fvSolver().a_cellVolume(candidateId))
935 > fvSolver().a_pvariable(candidateId, fvSolver().PV->RHO) * m_alphaCeil)) {
937 redistNeighbors.erase(it);
944 MFloat momentumTransfer[3] = {0.0, 0.0, 0.0};
945 if(!redistNeighbors.empty() || isOutlet) {
946 if(redistNeighbors.empty()) {
948 massExcessPerCell = -deltaMass / noRedistNbs;
949 for(
MInt dir = 0; dir < 3; dir++) {
950 momentumTransfer[dir] += massExcessPerCell * fvSolver().a_pvariable(cellId, fvSolver().PV->VV[dir]);
953 for(
auto redistId : redistNeighbors) {
954 if(fvSolver().a_isBndryGhostCell(redistId))
continue;
955 const MFloat delRho = massExcessPerCell / fvSolver().a_cellVolume(redistId);
956 const MFloat delRhoVV[3] = {delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[0]),
957 delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[1]),
958 delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[2])};
959 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO) += delRho;
960 for(
MInt dir = 0; dir < 3; dir++) {
961 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO_VV[dir]) += delRhoVV[dir];
962 momentumTransfer[dir] += delRhoVV[dir] * fvSolver().a_cellVolume(redistId);
964 fvSolver().setPrimitiveVariables(redistId);
966 if(fvSolver().a_isHalo(redistId)) {
967 const transferCV delCV = {
973 auto success = haloCorrections.insert(std::pair<MInt, transferCV>(redistId, delCV));
974 if(!success.second) {
975 success.first->second.rhoAlpha += delCV.rhoAlpha;
976 success.first->second.rhoUAlpha += delCV.rhoUAlpha;
977 success.first->second.rhoVAlpha += delCV.rhoVAlpha;
978 success.first->second.rhoWAlpha += delCV.rhoWAlpha;
982 fvSolver().a_variable(cellId, fvSolver().CV->A_RHO) -=
983 massExcessPerCell / fvSolver().a_cellVolume(cellId) * noRedistNbs;
984 for(
MInt dir = 0; dir < 3; dir++) {
985 fvSolver().a_variable(cellId, fvSolver().CV->A_RHO_VV[dir]) -=
986 momentumTransfer[dir] / fvSolver().a_cellVolume(cellId);
988 fvSolver().setPrimitiveVariables(cellId);
991 redistNeighbors = neighbors;
992 if(redistNeighbors.empty()) {
993 redistNeighbors = findRedistCells(cellId,
false, std::numeric_limits<MFloat>::max());
995 MFloat massTransfer = 0.0;
996 for(
auto redistId : redistNeighbors) {
997 const MFloat massCapacityAvail = (fvSolver().a_pvariable(redistId, fvSolver().PV->RHO) * m_alphaCeil
998 - fvSolver().a_variable(redistId, fvSolver().CV->A_RHO))
999 * fvSolver().a_cellVolume(redistId);
1000 if(massCapacityAvail < 0.0)
continue;
1001 const MFloat delRho = massCapacityAvail / fvSolver().a_cellVolume(redistId);
1002 const MFloat delRhoVV[3] = {delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[0]),
1003 delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[1]),
1004 delRho * fvSolver().a_pvariable(redistId, fvSolver().PV->VV[2])};
1005 massTransfer += massCapacityAvail;
1006 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO) += delRho;
1007 for(
MInt dir = 0; dir < 3; dir++) {
1008 fvSolver().a_variable(redistId, fvSolver().CV->A_RHO_VV[dir]) += delRhoVV[dir];
1009 momentumTransfer[dir] += delRhoVV[dir] * fvSolver().a_cellVolume(redistId);
1011 fvSolver().setPrimitiveVariables(redistId);
1013 if(fvSolver().a_isHalo(redistId)) {
1014 const transferCV delCV = {
1020 auto success = haloCorrections.insert(std::pair<MInt, transferCV>(redistId, delCV));
1021 if(!success.second) {
1022 success.first->second.rhoAlpha += delCV.rhoAlpha;
1023 success.first->second.rhoUAlpha += delCV.rhoUAlpha;
1024 success.first->second.rhoVAlpha += delCV.rhoVAlpha;
1025 success.first->second.rhoWAlpha += delCV.rhoWAlpha;
1029 fvSolver().a_variable(cellId, fvSolver().CV->A_RHO) -= massTransfer / fvSolver().a_cellVolume(cellId);
1030 for(
MInt dir = 0; dir < 3; dir++) {
1031 fvSolver().a_variable(cellId, fvSolver().CV->A_RHO_VV[dir]) -=
1032 momentumTransfer[dir] / fvSolver().a_cellVolume(cellId);
1034 fvSolver().setPrimitiveVariables(cellId);
1042 if(noTransferCV > fvSolver().m_dataBlockSize)
1043 mTerm(1, AT_,
"The send- and receive Buffers are too small for this communication!");
1045 for(
MInt i = 0; i < fvSolver().noNeighborDomains(); i++) {
1046 MInt receiveBufferCounter = 0;
1047 for(
MInt j = 0; j < fvSolver().m_noMaxLevelHaloCells[i]; j++) {
1048 auto it = haloCorrections.find(fvSolver().m_maxLevelHaloCells[i][j]);
1049 if(it != haloCorrections.end()) {
1050 fvSolver().m_receiveBuffers[i][receiveBufferCounter + fvSolver().CV->A_RHO] = it->second.rhoAlpha;
1051 fvSolver().m_receiveBuffers[i][receiveBufferCounter + fvSolver().CV->A_RHO_U] = it->second.rhoUAlpha;
1052 fvSolver().m_receiveBuffers[i][receiveBufferCounter + fvSolver().CV->A_RHO_V] = it->second.rhoVAlpha;
1053 fvSolver().m_receiveBuffers[i][receiveBufferCounter + fvSolver().CV->A_RHO_W] = it->second.rhoWAlpha;
1055 fvSolver().m_receiveBuffers[i][receiveBufferCounter + fvSolver().CV->A_RHO] = 0.0;
1056 fvSolver().m_receiveBuffers[i][receiveBufferCounter + fvSolver().CV->A_RHO_U] = 0.0;
1057 fvSolver().m_receiveBuffers[i][receiveBufferCounter + fvSolver().CV->A_RHO_V] = 0.0;
1058 fvSolver().m_receiveBuffers[i][receiveBufferCounter + fvSolver().CV->A_RHO_W] = 0.0;
1060 receiveBufferCounter += noTransferCV;
1066 for(
MInt i = 0; i < fvSolver().noNeighborDomains(); i++) {
1067 bufSize = fvSolver().m_noMaxLevelHaloCells[i] * noTransferCV;
1068 MPI_Issend(fvSolver().m_receiveBuffers[i], bufSize, MPI_DOUBLE, fvSolver().neighborDomain(i), 0,
1069 fvSolver().mpiComm(), &fvSolver().m_mpi_request[i], AT_,
1070 "m_receiveBuffers[" + std::to_string(i) +
"],1");
1075 for(
MInt i = 0; i < fvSolver().noNeighborDomains(); i++) {
1076 bufSize = fvSolver().m_noMaxLevelWindowCells[i] * noTransferCV;
1077 MPI_Recv(fvSolver().m_sendBuffers[i], bufSize, MPI_DOUBLE, fvSolver().neighborDomain(i), 0, fvSolver().mpiComm(),
1078 &status, AT_,
"m_sendBuffers[" + std::to_string(i) +
"],1");
1080 for(
MInt i = 0; i < fvSolver().noNeighborDomains(); i++) {
1081 MPI_Wait(&fvSolver().m_mpi_request[i], &status, AT_);
1085 MInt sendBufferCounter = 0;
1086 for(
MInt i = 0; i < fvSolver().noNeighborDomains(); i++) {
1087 sendBufferCounter = 0;
1088 for(
MInt j = 0; j < fvSolver().m_noMaxLevelWindowCells[i]; j++) {
1089 fvSolver().a_variable(fvSolver().m_maxLevelWindowCells[i][j], fvSolver().CV->A_RHO) +=
1090 fvSolver().m_sendBuffers[i][sendBufferCounter + fvSolver().CV->A_RHO];
1091 for(
MInt dir = 0; dir < nDim; dir++) {
1092 fvSolver().a_variable(fvSolver().m_maxLevelWindowCells[i][j], fvSolver().CV->A_RHO_VV[dir]) +=
1093 fvSolver().m_sendBuffers[i][sendBufferCounter + fvSolver().CV->A_RHO_VV[dir]];
1095 sendBufferCounter += noTransferCV;
1099 fvSolver().computePV();
1100 fvSolver().exchange();
1112template <MInt nDim, MInt nDist,
class SysEqnLb,
class SysEqnFv>
1114 const MBool searchUp,
1116 std::vector<MInt> redistNeighbors;
1117 redistNeighbors.reserve(56);
1121 const MInt noLeafCells = fvSolver().getAdjacentLeafCells_d2(cellId, 1, adjacentLeafCells, layers);
1123 for(
MInt i = 0; i < noLeafCells; i++) {
1124 const MInt neighborId = adjacentLeafCells[i];
1125 const MFloat alpha = fvSolver().a_pvariable(neighborId, fvSolver().PV->A);
1126 if(searchUp && alpha < limit)
continue;
1127 if(!searchUp && alpha > limit)
continue;
1128 redistNeighbors.push_back(neighborId);
1130 return redistNeighbors;
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
void subCouple(MInt, MInt, std::vector< MBool > &solverCompleted) override
CouplerLbFvEEMultiphase(const MInt couplerId, LbSolver *lb, FvCartesianSolver *fv)
MBool checkAlphaConverged()
void transferAlphaFv2Lb()
void transferNuLb2Fv(const MFloat rkAlpha)
std::vector< MInt > findRedistCells(const MInt cellId, const MBool searchUp, const MFloat limit)
find neighbor Cells to cellId, that are candidates for alpha corrections
void finalizeCouplerInit() override
void revertLbDistributions()
void revertLbOldVariables()
void correctInvalidAlpha()
find cells with invalid alpha values and redistribute mass from/to neighboring cells to raise/lower a...
void transferULb2Fv(const MFloat rkAlpha)
void initDepthcorrection()
void transferPressureLb2Fv(const MFloat rkAlpha, const MBool update)
void preCouple(MInt) override
void finalizeSubCoupleInit(MInt) override
void balancePre() override
Load balancing.
virtual void initConversionFactors()
MInt a_lbSolverId() const
MInt lb2fvId(const MInt lbId) const
ConversionFactors conversionLbFv
ConversionFactors conversionFvLb
MInt a_fvSolverId() const
MInt fv2lbId(const MInt fvId) const
solverType & fvSolver(const MInt solverId=0) const
solverType & lbSolver(const MInt solverId=0) const
LbBndCnd & lbBndCnd(const MInt id=0)
MInt a_noLbCells(const MInt id=0) const
void updateGhostCellVariables()
void applyNeumannBoundaryCondition()
MInt * m_noMaxLevelWindowCells
MInt ** m_maxLevelHaloCells
MFloat a_nuEffOtherPhase(const MInt cellId) const
FvBndryCndXD< nDim_, SysEqn > * m_fvBndryCnd
struct FvCartesianSolverXD::@8 m_EEGas
MFloat & a_oldVariable(const MInt cellId, const MInt varId)
Returns oldVariablesv of the cell cellId variables varId.
MFloat & a_variable(const MInt cellId, const MInt varId)
Returns conservative variable v of the cell cellId for variables varId.
SysEqn::ConservativeVariables * CV
MInt ** m_maxLevelWindowCells
MFloat a_alphaGas(const MInt cellId) const
MFloat a_gradUOtherPhase(const MInt cellId, const MInt uDir, const MInt gradDir) const
MFloat & a_coordinate(const MInt cellId, const MInt dir)
Returns the coordinate of the cell from the fvcellcollector cellId for dimension dir.
MFloat a_vortOtherPhase(const MInt cellId, const MInt dir) const
MInt noVariables() const override
Return the number of primitive variables.
MFloat a_nuTOtherPhase(const MInt cellId) const
MFloat ** m_receiveBuffers
MFloat a_uOtherPhase(const MInt cellId, const MInt dir) const
MFloat & a_pvariable(const MInt cellId, const MInt varId)
Returns primitive variable v of the cell cellId for variables varId.
MInt * m_noMaxLevelHaloCells
MFloat a_uOtherPhaseOld(const MInt cellId, const MInt dir) const
std::vector< LbGridBoundaryCell< nDim > > m_bndCells
std::vector< MInt > m_bndCndOffsets
This class represents all LB models.
static constexpr MInt m_noDistributions
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
MFloat m_Ma
the Mach number
MInt noNeighborDomains() const
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW2(const Real x)
constexpr T mMax(const T &x, const T &y)
constexpr MLong IPOW2(MInt x)
constexpr MFloat FFPOW2(MInt x)
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_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_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_Wait(MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Wait
int MPI_Waitall(int count, MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Waitall
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