92 T hMin = std::min(hLeft, hRight);
93 T hMax = std::max(hLeft, hRight);
94 T uDiff = uRight - uLeft;
102 middleSpeeds[0] = uRight + uLeft - 2.0 * std::sqrt(
g * hRight) + 2.0 * std::sqrt(
g * hLeft);
103 middleSpeeds[1] = uRight + uLeft - 2.0 * std::sqrt(
g * hRight) + 2.0 * std::sqrt(
g * hLeft);
108 const T phiMax = uDiff + (hMax - hMin) * (std::sqrt(0.5 *
g * (hMax + hMin) / (hMax * hMin)));
115 T phiZeroDerivative = 0;
119 hMiddle = std::max(0.0, uLeft - uRight + 2.0 * (std::sqrt(
g * hLeft) + std::sqrt(
g * hRight)));
120 hMiddle = 1.0 / (16.0 *
g) * hMiddle * hMiddle;
122 uMiddle = uLeft + 2.0 * (std::sqrt(
g * hLeft) - std::sqrt(
g * hMiddle));
123 }
else if (hMiddle < 0) {
124 uMiddle = -(uLeft + 2.0 * (std::sqrt(
g * hLeft) - std::sqrt(
g * hMiddle)));
126 middleSpeeds[0] = uLeft + 2.0 * std::sqrt(
g * hLeft) - 3.0 * std::sqrt(
g * hMiddle);
127 middleSpeeds[1] = uRight - 2.0 * std::sqrt(
g * hRight) + 3.0 * std::sqrt(
g * hMiddle);
171 gLeft = std::sqrt(0.5 *
g * (1 / hZero + 1 / hLeft));
172 gRight = std::sqrt(0.5 *
g * (1 / hZero + 1 / hRight));
173 phiZero = uDiff + (hZero - hLeft) * gLeft + (hZero - hRight) * gRight;
177 phiZeroDerivative = gLeft -
g * (hZero - hLeft) / (4.0 * (hZero * hZero) * gLeft) + gRight
178 -
g * (hZero - hRight) / (4.0 * (hZero * hZero) * gRight);
179 slope = 2.0 * std::sqrt(hZero) * phiZeroDerivative;
180 hZero = std::pow((std::sqrt(hZero) - phiZero / slope), 2);
183 T uOneMiddle = uLeft - (hMiddle - hLeft) * std::sqrt((0.5 *
g) * (1 / hMiddle + 1 / hLeft));
184 T uTwoMiddle = uRight + (hMiddle - hRight) * std::sqrt((0.5 *
g) * (1 / hMiddle + 1 / hRight));
185 uMiddle = 0.5 * (uOneMiddle + uTwoMiddle);
186 middleSpeeds[0] = uOneMiddle - std::sqrt(
g * hMiddle);
187 middleSpeeds[1] = uTwoMiddle + std::sqrt(
g * hMiddle);
224 phiZero = uDiff + 2.0 * (std::sqrt(
g * hZero) - std::sqrt(
g * hMax))
225 + (hZero - hMin) * std::sqrt(0.5 *
g * (1 / hZero + 1 / hMin));
226 slope = (phiMax - phiZero) / (hMax - hMin);
227 hZero = hZero - phiZero / slope;
232 if (hLeft > hRight) {
233 uMiddle = uLeft + 2.0 * std::sqrt(
g * hLeft) - 2.0 * std::sqrt(
g * hMiddle);
234 middleSpeeds[0] = uLeft + 2.0 * std::sqrt(
g * hLeft) - 3.0 * std::sqrt(
g * hMiddle);
235 middleSpeeds[1] = uLeft + 2.0 * std::sqrt(
g * hLeft) - std::sqrt(
g * hMiddle);
237 middleSpeeds[1] = uRight - 2.0 * std::sqrt(
g * hRight) + 3.0 * std::sqrt(
g * hMiddle);
238 middleSpeeds[0] = uRight - 2.0 * std::sqrt(
g * hRight) + std::sqrt(
g * hMiddle);
239 uMiddle = uRight - 2.0 * std::sqrt(
g * hRight) + 2.0 * std::sqrt(
g * hMiddle);
357 const T& sqrtGhRight,
368 T characteristicSpeeds[2];
369 characteristicSpeeds[0] = uLeft - sqrtGhLeft;
370 characteristicSpeeds[1] = uRight + sqrtGhRight;
373 T hRoe = 0.5 * (hRight + hLeft);
374 T uRoe = uLeft * sqrthLeft + uRight * sqrthRight;
375 uRoe /= (sqrthLeft + sqrthRight);
379 T sqrtGhRoe = std::sqrt(
g * hRoe);
380 roeSpeeds[0] = uRoe - sqrtGhRoe;
381 roeSpeeds[1] = uRoe + sqrtGhRoe;
387 hMiddle =
computeMiddleState(hLeft, hRight, uLeft, uRight, riemannStructure, middleSpeeds);
398 T lambdaStarHStarMinus = middleSpeeds[0];
399 T lambdaStarHStarPlus = middleSpeeds[1];
401 T extEinfeldtSpeeds[2] = {0, 0};
403 extEinfeldtSpeeds[0] = std::min(characteristicSpeeds[0], roeSpeeds[0]);
404 extEinfeldtSpeeds[0] = std::min(extEinfeldtSpeeds[0], lambdaStarHStarPlus);
405 extEinfeldtSpeeds[1] = std::max(characteristicSpeeds[1], roeSpeeds[1]);
406 extEinfeldtSpeeds[1] = std::max(extEinfeldtSpeeds[1], lambdaStarHStarMinus);
408 extEinfeldtSpeeds[0] = std::min(roeSpeeds[0], lambdaStarHStarPlus);
409 extEinfeldtSpeeds[1] = std::max(characteristicSpeeds[1], roeSpeeds[1]);
411 extEinfeldtSpeeds[0] = std::min(characteristicSpeeds[0], roeSpeeds[0]);
412 extEinfeldtSpeeds[1] = std::max(roeSpeeds[1], lambdaStarHStarMinus);
418 T hLLMiddleHeight = huLeft - huRight + extEinfeldtSpeeds[1] * hRight - extEinfeldtSpeeds[0] * hLeft;
419 hLLMiddleHeight /= (extEinfeldtSpeeds[1] - extEinfeldtSpeeds[0]);
420 hLLMiddleHeight = std::max(hLLMiddleHeight, 0.0);
424 eigenValues[0] = extEinfeldtSpeeds[0];
426 eigenValues[2] = extEinfeldtSpeeds[1];
429 T eigenVectors[3][3];
432 eigenVectors[0][0] = 1;
433 eigenVectors[0][2] = 1;
435 eigenVectors[1][0] = eigenValues[0];
436 eigenVectors[1][2] = eigenValues[2];
438 eigenVectors[2][0] = eigenValues[0] * eigenValues[0];
439 eigenVectors[2][2] = eigenValues[2] * eigenValues[2];
443 bool strongRarefaction =
false;
446 constexpr bool CorrectRarefactions =
true;
447 if constexpr (CorrectRarefactions) {
452 T rareBarrier[2] = {0.5, 0.9};
456 and eigenValues[0] * lambdaStarHStarMinus < 0.0) {
457 rareBarrier[0] = 0.2;
459 and eigenValues[2] * lambdaStarHStarPlus < 0.0) {
460 rareBarrier[0] = 0.2;
463 T sqrtGhMiddle = std::sqrt(
g * hMiddle);
465 T rareFactionSize[2];
466 rareFactionSize[0] = 3.0 * (sqrtGhLeft - sqrtGhMiddle);
467 rareFactionSize[1] = 3.0 * (sqrtGhRight - sqrtGhMiddle);
469 T maxRareFactionSize = std::max(rareFactionSize[0], rareFactionSize[1]);
472 if (maxRareFactionSize > rareBarrier[0] * (eigenValues[2] - eigenValues[0])
473 and maxRareFactionSize < rareBarrier[1] * (eigenValues[2] - eigenValues[0])) {
474 strongRarefaction =
true;
475 if (rareFactionSize[0] > rareFactionSize[1]) {
476 eigenValues[1] = lambdaStarHStarMinus;
477 }
else if (rareFactionSize[1] > rareFactionSize[0]) {
478 eigenValues[1] = lambdaStarHStarPlus;
480 eigenValues[1] = 0.5 * (lambdaStarHStarMinus + lambdaStarHStarPlus);
485 if (hLLMiddleHeight < (std::min(hLeft, hRight) / 5.0)) {
486 strongRarefaction =
false;
491 if (not strongRarefaction) {
492 eigenValues[1] = 0.5 * (eigenValues[0] + eigenValues[2]);
493 eigenVectors[0][1] = 0.0;
494 eigenVectors[1][1] = 0.0;
495 eigenVectors[2][1] = 1.0;
497 eigenVectors[0][1] = 1.0;
498 eigenVectors[1][1] = eigenValues[1];
499 eigenVectors[2][1] = eigenValues[1] * eigenValues[1];
504 rightHandSide[0] = hRight - hLeft;
505 rightHandSide[1] = huRight - huLeft;
506 rightHandSide[2] = (huRight * uRight + 0.5 *
g * hRight * hRight)
507 - (huLeft * uLeft + 0.5 *
g * hLeft * hLeft);
511 T steadyStateWave[2] = {0, 0};
513 T hBar = (hLeft + hRight) * 0.5;
517 T eigenvalueAvgBar = 0;
518 T eigenvalueAvgTilde = 0;
529 constexpr bool SteadyStateWave =
false;
530 if constexpr (SteadyStateWave) {
531 if (bLeft != bRight) {
532 eigenvalueAvgBar = (uLeft + uRight) * (uLeft + uRight) * 0.25 -
g * hBar;
533 eigenvalueAvgTilde = std::max(0.0, uRight * uLeft) -
g * hBar;
535 hAvgTilde = hBar * (eigenvalueAvgTilde / eigenvalueAvgBar);
537 hAvgTilde = std::max(hAvgTilde, std::min(hRight, hLeft));
538 hAvgTilde = std::min(hAvgTilde, std::max(hRight, hLeft));
540 steadyStateWave[0] = (
g * hBar) / eigenvalueAvgBar;
541 steadyStateWave[1] = -
g * hAvgTilde;
544 if (eigenValues[0] < 0.0 and eigenValues[2] > 0.0) {
545 if (bRight > bLeft) {
546 steadyStateWave[0] = std::max(
548 (hLLMiddleHeight / (bRight - bLeft)) * ((eigenValues[2] - eigenValues[0]) / eigenValues[0])
550 }
else if (bRight < bLeft) {
551 steadyStateWave[0] = std::max(
553 (hLLMiddleHeight / (bRight - bLeft)) * ((eigenValues[2] - eigenValues[0]) / eigenValues[2])
556 steadyStateWave[0] = std::min(steadyStateWave[0], -1.0);
561 }
else if ((std::fabs(eigenvalueAvgBar) <=
ZERO_TOL) or (eigenvalueAvgBar * eigenvalueAvgTilde <=
ZERO_TOL)
562 or (eigenvalueAvgBar * eigenValues[0] * eigenValues[2] <=
ZERO_TOL)
563 or (std::min(std::fabs(eigenValues[0]), std::fabs(eigenValues[2])) <
ZERO_TOL)
564 or (eigenValues[0] < 0.0 and lambdaStarHStarMinus > 0.0)
565 or (eigenValues[2] > 0.0 and lambdaStarHStarPlus < 0.0)
566 or ((uLeft + sqrt(
g * hLeft)) * (uRight + sqrt(
g * hRight)) < 0.0)
567 or ((uLeft - sqrt(
g * hLeft)) * (uRight - sqrt(
g * hRight)) < 0.0)) {
568 steadyStateWave[0] = 0;
569 }
else if (eigenValues[0] > 0.0 and eigenValues[2] > 0.0) {
570 steadyStateWave[0] = std::min(
572 (hLLMiddleHeight / (bRight - bLeft)) * ((eigenValues[2] - eigenValues[0]) / eigenValues[0])
574 steadyStateWave[0] = std::max(steadyStateWave[0], (-hLeft / (bRight - bLeft)));
575 }
else if (eigenValues[0] < 0.0 and eigenValues[2] < 0.0) {
576 steadyStateWave[0] = std::min(steadyStateWave[0], (hRight / (bRight - bLeft)));
577 steadyStateWave[0] = std::max(
579 (hLLMiddleHeight / (bRight - bLeft)) * ((eigenValues[2] - eigenValues[0]) / eigenValues[2])
583 steadyStateWave[0] = steadyStateWave[1] = 0.0;
587 rightHandSide[0] -= (bRight - bLeft) * steadyStateWave[0];
589 rightHandSide[2] -= (bRight - bLeft) * steadyStateWave[1];
596 steadyStateWave[0] = -(bRight - bLeft);
597 steadyStateWave[1] = -
g * 0.5 * (hRight + hLeft) * (bRight - bLeft);
601 T hRightIter = hRight;
603 T uRightIter = uRight;
604 T huLeftIter = uLeftIter * hLeftIter;
605 T huRightIter = uRightIter * hRightIter;
606 T deltaNorm = rightHandSide[0] * rightHandSide[0] + rightHandSide[2] * rightHandSide[2];
608 bool sonicFlow =
false;
609 constexpr bool SteadyStateIter =
true;
610 if constexpr (SteadyStateIter) {
612 if (std::min(hLeftIter, hRightIter) <
hThreshold and strongRarefaction) {
613 strongRarefaction =
false;
618 huLeftIter = uLeftIter * hLeftIter;
619 huRightIter = uRightIter * hRightIter;
620 eigenValues[1] = 0.5 * (eigenValues[0] + eigenValues[2]);
621 eigenVectors[0][1] = 0.0;
622 eigenVectors[1][1] = 0.0;
623 eigenVectors[2][1] = 1.0;
626 hBar = std::max(0.0, 0.5 * (hLeftIter + hRightIter));
627 eigenvalueAvgBar = (uLeftIter + uRightIter) * (uLeftIter + uRightIter) * 0.25 -
g * hBar;
629 eigenvalueAvgTilde = std::max(0.0, uRightIter * uLeftIter) -
g * hBar;
632 if ((std::fabs(eigenvalueAvgBar) <=
ZERO_TOL) or (eigenvalueAvgBar * eigenvalueAvgTilde <=
ZERO_TOL)
633 or (eigenvalueAvgBar * eigenValues[0] * eigenValues[2] <=
ZERO_TOL)
634 or (std::min(std::fabs(eigenValues[0]), std::fabs(eigenValues[2])) <
ZERO_TOL)
635 or (eigenValues[0] < 0.0 and lambdaStarHStarMinus > 0.0)
636 or (eigenValues[2] > 0.0 and lambdaStarHStarPlus < 0.0)
637 or ((uLeft + sqrt(
g * hLeft)) * (uRight + sqrt(
g * hRight)) < 0.0)
638 or ((uLeft - sqrt(
g * hLeft)) * (uRight - sqrt(
g * hRight)) < 0.0)) {
645 steadyStateWave[0] = -(bRight - bLeft);
647 steadyStateWave[0] = (bRight - bLeft) *
g * hBar / eigenvalueAvgBar;
651 steadyStateWave[0] = std::min(
653 hLLMiddleHeight * (eigenValues[2] - eigenValues[0]) / eigenValues[2]
655 steadyStateWave[0] = std::max(
657 hLLMiddleHeight * (eigenValues[2] - eigenValues[0]) / eigenValues[0]
659 }
else if (eigenValues[0] >=
ZERO_TOL) {
660 steadyStateWave[0] = std::min(
662 hLLMiddleHeight * (eigenValues[2] - eigenValues[0]) / eigenValues[0]
664 steadyStateWave[0] = std::max(steadyStateWave[0], -hLeft);
665 }
else if (eigenValues[2] <= -
ZERO_TOL) {
666 steadyStateWave[0] = std::min(steadyStateWave[0], hRight);
667 steadyStateWave[0] = std::max(
669 hLLMiddleHeight * (eigenValues[2] - eigenValues[0]) / eigenValues[2]
673 steadyStateWave[1] = -
g * hBar * (bRight - bLeft);
675 steadyStateWave[1] = -(bRight - bLeft) *
g * hBar * eigenvalueAvgTilde / eigenvalueAvgBar;
678 steadyStateWave[1] = std::min(
680 g * std::max(-hLeftIter * (bRight - bLeft), -hRightIter * (bRight - bLeft))
682 steadyStateWave[1] = std::max(
684 g * std::min(-hLeftIter * (bRight - bLeft), -hRightIter * (bRight - bLeft))
688 rightHandSide[0] -= steadyStateWave[0];
690 rightHandSide[2] -= steadyStateWave[1];
696 if (std::fabs(rightHandSide[0] * rightHandSide[0] + rightHandSide[2] * rightHandSide[2] - deltaNorm)
701 deltaNorm = rightHandSide[0] * rightHandSide[0] + rightHandSide[2] * rightHandSide[2];
707 huLeftIter = uLeftIter * hLeftIter;
708 huRightIter = uRightIter * hRightIter;
712 for (
int mw = 0; mw < 3; ++mw) {
713 if (eigenValues[mw] < 0.0) {
714 hLeftIter = hLeftIter + beta[mw] * eigenVectors[0][mw];
715 huLeftIter = huLeftIter + beta[mw] * eigenVectors[1][mw];
718 for (
int mw = 2; mw > 0; --mw) {
719 if (eigenValues[mw] > 0.0) {
720 hRightIter = hRightIter - beta[mw] * eigenVectors[0][mw];
721 huRightIter = huRightIter - beta[mw] * eigenVectors[1][mw];
726 uLeftIter = huLeftIter / hLeftIter;
728 hLeftIter = std::max(hLeftIter, 0.0);
732 uRightIter = huRightIter / hRightIter;
734 hRightIter = std::max(hRightIter, 0.0);
744 fWaves[0][0] = beta[0] * eigenVectors[1][0];
745 fWaves[1][0] = beta[0] * eigenVectors[2][0];
746 fWaves[2][0] = beta[0] * eigenVectors[1][0];
747 fWaves[2][0] = fWaves[2][0] * vLeft;
750 fWaves[0][1] = fWaves[1][1] = fWaves[2][1] = 0.0;
751 fWaves[0][2] = fWaves[1][2] = fWaves[2][2] = 0.0;
753 waveSpeeds[0] = eigenValues[0];
754 waveSpeeds[1] = waveSpeeds[2] = 0.0;
759 fWaves[0][2] = beta[2] * eigenVectors[1][2];
760 fWaves[1][2] = beta[2] * eigenVectors[2][2];
761 fWaves[2][2] = beta[2] * eigenVectors[1][2];
762 fWaves[2][2] = fWaves[2][2] * vRight;
765 fWaves[0][0] = fWaves[1][0] = fWaves[2][0] = 0.0;
766 fWaves[0][1] = fWaves[1][1] = fWaves[2][1] = 0.0;
768 waveSpeeds[2] = eigenValues[2];
769 waveSpeeds[0] = waveSpeeds[1] = 0.0;
774 waveSpeeds[0] = eigenValues[0];
775 waveSpeeds[1] = eigenValues[1];
776 waveSpeeds[2] = eigenValues[2];
778 for (
int waveNumber = 0; waveNumber < 3; waveNumber++) {
779 fWaves[0][waveNumber] = beta[waveNumber] * eigenVectors[1][waveNumber];
780 fWaves[1][waveNumber] = beta[waveNumber] * eigenVectors[2][waveNumber];
782 fWaves[2][waveNumber] = beta[waveNumber] * eigenVectors[1][waveNumber];
786 fWaves[2][0] = fWaves[2][0] * vLeft;
787 fWaves[2][2] = fWaves[2][2] * vRight;
788 fWaves[2][1] = hRight * uRight * vRight - hLeft * uLeft * vLeft - fWaves[2][0] - fWaves[2][2];
795 const T*
const NOALIAS QL,
796 const T*
const NOALIAS QR,
797 const tarch::la::Vector<DIMENSIONS, double>& x,
798 const tarch::la::Vector<DIMENSIONS, double>& h,
805 T hLeft = QL[Shortcuts::h];
806 T hRight = QR[Shortcuts::h];
809 T huLeft = QL[Shortcuts::hu + normal];
810 T huRight = QR[Shortcuts::hu + normal];
811 T hvLeft = QL[Shortcuts::hu + 1 - normal];
812 T hvRight = QR[Shortcuts::hu + 1 - normal];
813 T bLeft = QL[Shortcuts::z];
814 T bRight = QR[Shortcuts::z];
842 for (
int i = 0; i < 3; i++) {
848 if (hLeft > hThreshold) {
849 uLeft = huLeft / hLeft;
850 vLeft = hvLeft / hLeft;
853 hLeft = huLeft = uLeft = 0;
857 if (hRight > hThreshold) {
858 uRight = huRight / hRight;
859 vRight = hvRight / hRight;
862 hRight = huRight = uRight = 0;
863 hvRight = vRight = 0;
885 if (wetDryState == WetDryState::DryDry) {
891 sqrtG = std::sqrt(g);
892 sqrthLeft = std::sqrt(hLeft);
893 sqrthRight = std::sqrt(hRight);
895 sqrtGhLeft = sqrtG * sqrthLeft;
896 sqrtGhRight = sqrtG * sqrthRight;
935 for (
int waveNumber = 0; waveNumber < 3; waveNumber++) {
936 if (waveSpeeds[waveNumber] < 0.0) {
937 FL[Shortcuts::h] += fWaves[0][waveNumber];
938 FL[Shortcuts::hu + normal] += fWaves[1][waveNumber];
939 FL[Shortcuts::hu + 1 - normal] += fWaves[2][waveNumber];
940 }
else if (waveSpeeds[waveNumber] > 0.0) {
941 FR[Shortcuts::h] -= fWaves[0][waveNumber];
942 FR[Shortcuts::hu + normal] -= fWaves[1][waveNumber];
943 FR[Shortcuts::hu + 1 - normal] -= fWaves[2][waveNumber];
945 FL[Shortcuts::h] += 0.5 * fWaves[0][waveNumber];
946 FL[Shortcuts::hu + normal] += 0.5 * fWaves[1][waveNumber];
947 FL[Shortcuts::hu + 1 - normal] += 0.5 * fWaves[2][waveNumber];
948 FR[Shortcuts::h] -= 0.5 * fWaves[0][waveNumber];
949 FR[Shortcuts::hu + normal] -= 0.5 * fWaves[1][waveNumber];
950 FR[Shortcuts::hu + 1 - normal] -= 0.5 * fWaves[2][waveNumber];
955 return std::fmax(std::fabs(waveSpeeds[0]), std::fmax(std::fabs(waveSpeeds[1]), std::fabs(waveSpeeds[2])));