72 const T*
const NOALIAS QL,
73 const T*
const NOALIAS QR,
74 const tarch::la::Vector<DIMENSIONS, double>& x,
75 const tarch::la::Vector<DIMENSIONS, double>& h,
84 T horizontalVelocitiesLeft[2] = {
85 QL[Shortcuts::hu] * QL[Shortcuts::h] * std::sqrt(2)
86 / std::sqrt(std::pow(QL[Shortcuts::h], 4) + std::pow(std::fmax(QL[Shortcuts::h], hThreshold), 4)),
87 QL[Shortcuts::hv] * QL[Shortcuts::h] * std::sqrt(2)
88 / std::sqrt(std::pow(QL[Shortcuts::h], 4) + std::pow(std::fmax(QL[Shortcuts::h], hThreshold), 4))
91 T horizontalVelocitiesRight[2] = {
92 QR[Shortcuts::hu] * QR[Shortcuts::h] * std::sqrt(2)
93 / std::sqrt(std::pow(QR[Shortcuts::h], 4) + std::pow(std::fmax(QR[Shortcuts::h], hThreshold), 4)),
94 QR[Shortcuts::hv] * QR[Shortcuts::h] * std::sqrt(2)
95 / std::sqrt(std::pow(QR[Shortcuts::h], 4) + std::pow(std::fmax(QR[Shortcuts::h], hThreshold), 4))
99 const T zMax = std::fmax(QL[Shortcuts::z], QR[Shortcuts::z]);
100 const T hLeft = std::fmax(0.0, QL[Shortcuts::h] + QL[Shortcuts::z] - zMax);
101 const T hRight = std::fmax(0.0, QR[Shortcuts::h] + QR[Shortcuts::z] - zMax);
106 const bool leftWet = tarch::la::greater(hLeft, hThreshold);
107 const bool rightWet = tarch::la::greater(hRight, hThreshold);
108 const bool leftDry = not leftWet;
109 const bool rightDry = not rightWet;
111 for (
int i = 0; i < 3; ++i) {
117 if (leftDry and rightDry) {
123 const T huLeft = hLeft * horizontalVelocitiesLeft[0];
124 const T hvLeft = hLeft * horizontalVelocitiesLeft[1];
125 const T huRight = hRight * horizontalVelocitiesRight[0];
126 const T hvRight = hRight * horizontalVelocitiesRight[1];
131 T celerityLeft = std::sqrt(g * hLeft);
132 T celerityRight = std::sqrt(g * hRight);
133 T hStarEstimate = 0.0;
140 constexpr bool UseTwoRarefactionsEstimate =
true;
141 if constexpr (UseTwoRarefactionsEstimate) {
143 T celerityEstimate = 0.5 * (celerityLeft + celerityRight)
144 - 0.25 * (horizontalVelocitiesRight[normal] - horizontalVelocitiesLeft[normal]);
146 hStarEstimate = std::pow(celerityEstimate, 2) / g;
156 horizontalVelocitiesLeft[normal],
157 horizontalVelocitiesRight[normal]
173 if (hLeft > hThreshold) {
174 if (hRight > hThreshold) {
175 qLeft = (hStarEstimate > hLeft)
176 ? std::sqrt(0.5 * ((hStarEstimate + hLeft) * hStarEstimate) / (std::pow(hLeft, 2)))
178 sLeft = horizontalVelocitiesLeft[normal] - qLeft * celerityLeft;
181 sLeft = horizontalVelocitiesLeft[normal] - 1.0 * celerityLeft;
185 sLeft = horizontalVelocitiesRight[normal] - 2 * celerityRight;
188 if (hRight > hThreshold) {
189 if (hLeft > hThreshold) {
190 qRight = (hStarEstimate > hRight)
191 ? std::sqrt(0.5 * ((hStarEstimate + hRight) * hStarEstimate) / (std::pow(hRight, 2)))
193 sRight = horizontalVelocitiesRight[normal] + qRight * celerityRight;
196 sRight = horizontalVelocitiesRight[normal] + 1.0 * celerityRight;
200 sRight = horizontalVelocitiesLeft[normal] + 2 * celerityLeft;
208 if (hLeft <= hThreshold) {
210 }
else if (hRight <= hThreshold) {
214 = (sLeft * hRight * (horizontalVelocitiesRight[normal] - sRight)
215 - sRight * hLeft * (horizontalVelocitiesLeft[normal] - sLeft))
216 / (hRight * (horizontalVelocitiesRight[normal] - sRight) - hLeft * (horizontalVelocitiesLeft[normal] - sLeft));
221 sStar = std::max(sLeft, sStar);
222 sStar = std::min(sRight, sStar);
232 if (hLeft > hThreshold) {
233 hStarLeft = hLeft * ((sLeft - horizontalVelocitiesLeft[normal]) / (sLeft - sStar));
236 if (hRight <= hThreshold) {
237 hStarLeft = (1 / 3) * hLeft;
239 qStarLeft[0] = hStarLeft;
240 qStarLeft[1] = (normal == 0) ? (hStarLeft * sStar) : (hStarLeft * horizontalVelocitiesLeft[0]);
241 qStarLeft[2] = (normal == 0) ? (hStarLeft * horizontalVelocitiesLeft[1]) : (hStarLeft * sStar);
248 if (hRight > hThreshold) {
249 if (hLeft <= hThreshold) {
250 hStarRight = (1 / 3) * hRight;
252 hStarRight = hRight * ((sRight - horizontalVelocitiesRight[normal]) / (sRight - sStar));
253 qStarRight[0] = hStarRight;
254 qStarRight[1] = (normal == 0) ? (hStarRight * sStar) : (hStarRight * horizontalVelocitiesRight[0]);
255 qStarRight[2] = (normal == 0) ? (hStarRight * horizontalVelocitiesRight[1]) : (hStarRight * sStar);
263 double fluxLeft[3] = {
264 normal == 0 ? (hLeft * horizontalVelocitiesLeft[0]) : (hLeft * horizontalVelocitiesLeft[1]),
266 ? (hLeft * horizontalVelocitiesLeft[0] * horizontalVelocitiesLeft[0] + 0.5 * g * std::pow(hLeft, 2))
267 : (hLeft * horizontalVelocitiesLeft[1] * horizontalVelocitiesLeft[0]),
269 ? (hLeft * horizontalVelocitiesLeft[0] * horizontalVelocitiesLeft[1])
270 : (hLeft * horizontalVelocitiesLeft[1] * horizontalVelocitiesLeft[1] + 0.5 * g * std::pow(hLeft, 2))
273 double fluxRight[3] = {
274 normal == 0 ? (hRight * horizontalVelocitiesRight[0]) : (hRight * horizontalVelocitiesRight[1]),
276 ? (hRight * horizontalVelocitiesRight[0] * horizontalVelocitiesRight[0] + 0.5 * g * std::pow(hRight, 2))
277 : (hRight * horizontalVelocitiesRight[1] * horizontalVelocitiesRight[0]),
279 ? (hRight * horizontalVelocitiesRight[0] * horizontalVelocitiesRight[1])
280 : (hRight * horizontalVelocitiesRight[1] * horizontalVelocitiesRight[1] + 0.5 * g * std::pow(hRight, 2))
285 if (hLeft > hThreshold && hRight > hThreshold) {
287 hllcFlux[0] = fluxLeft[0];
288 hllcFlux[1] = fluxLeft[1];
289 hllcFlux[2] = fluxLeft[2];
290 }
else if (sStar >= 0) {
291 hllcFlux[0] = fluxLeft[0] + sLeft * (qStarLeft[0] - hLeft);
292 hllcFlux[1] = fluxLeft[1] + sLeft * (qStarLeft[1] - (hLeft * horizontalVelocitiesLeft[0]));
293 hllcFlux[2] = fluxLeft[2] + sLeft * (qStarLeft[2] - (hLeft * horizontalVelocitiesLeft[1]));
294 }
else if (sRight >= 0) {
295 hllcFlux[0] = fluxRight[0] + sRight * (qStarRight[0] - hRight);
296 hllcFlux[1] = fluxRight[1] + sRight * (qStarRight[1] - (hRight * horizontalVelocitiesRight[0]));
297 hllcFlux[2] = fluxRight[2] + sRight * (qStarRight[2] - (hRight * horizontalVelocitiesRight[1]));
299 hllcFlux[0] = fluxRight[0];
300 hllcFlux[1] = fluxRight[1];
301 hllcFlux[2] = fluxRight[2];
303 }
else if (hLeft <= hThreshold) {
305 hllcFlux[0] = fluxLeft[0];
306 hllcFlux[1] = fluxLeft[1];
307 hllcFlux[2] = fluxLeft[2];
308 }
else if (sRight >= 0) {
309 hllcFlux[0] = fluxRight[0] + sRight * (qStarRight[0] - hRight);
310 hllcFlux[1] = fluxRight[1] + sRight * (qStarRight[1] - (hRight * horizontalVelocitiesRight[0]));
311 hllcFlux[2] = fluxRight[2] + sRight * (qStarRight[2] - (hRight * horizontalVelocitiesRight[1]));
313 hllcFlux[0] = fluxRight[0];
314 hllcFlux[1] = fluxRight[1];
315 hllcFlux[2] = fluxRight[2];
317 }
else if (hRight <= hThreshold) {
319 hllcFlux[0] = fluxLeft[0];
320 hllcFlux[1] = fluxLeft[1];
321 hllcFlux[2] = fluxLeft[2];
322 }
else if (sRight >= 0) {
323 hllcFlux[0] = fluxLeft[0] + sLeft * (qStarLeft[0] - hLeft);
324 hllcFlux[1] = fluxLeft[1] + sLeft * (qStarLeft[1] - (hLeft * horizontalVelocitiesLeft[0]));
325 hllcFlux[2] = fluxLeft[2] + sLeft * (qStarLeft[2] - (hLeft * horizontalVelocitiesLeft[1]));
327 hllcFlux[0] = fluxRight[0];
328 hllcFlux[1] = fluxRight[1];
329 hllcFlux[2] = fluxRight[2];
336 double sourceLeft[3] = {
338 normal == 0 ? g * 0.5 * ((QL[Shortcuts::h] * QL[Shortcuts::h]) - (hLeft * hLeft)) : 0.0,
339 normal == 0 ? 0.0 : g * 0.5 * ((QL[Shortcuts::h] * QL[Shortcuts::h]) - (hLeft * hLeft))
342 double sourceRight[3] = {
344 normal == 0 ? g * 0.5 * ((QR[Shortcuts::h] * QR[Shortcuts::h]) - (hRight * hRight)) : 0.0,
345 normal == 0 ? 0.0 : g * 0.5 * ((QR[Shortcuts::h] * QR[Shortcuts::h]) - (hRight * hRight))
349 for (
int i = 0; i < 3; ++i) {
350 FL[i] = hllcFlux[i] + sourceLeft[i];
351 FR[i] = hllcFlux[i] + sourceRight[i];
354 return (std::max(std::abs(sLeft), std::abs(sRight)));