@@ -247,25 +247,37 @@ class GodunovFluxes : public LayoutHolder<GridLayout>
247
247
auto riemann_steps_ (auto const & uL, auto const & ubL, auto const & uR, auto const & ubR,
248
248
auto const & fL , auto const & fbL, auto const & fR , auto const & fbR) const
249
249
{
250
- auto [speeds, speedsb]
251
- = riemann_speeds_<direction>( std::tuple_cat (uL, ubL), std::tuple_cat (uR, ubR));
250
+ // 2 calls separate calls of the riemann solver in case we are in hall-mhd (the second time
251
+ // for B and the total energy with whisler contribution).
252
252
253
- auto [rho, rhoVx, rhoVy, rhoVz] = std::apply (
254
- [&](auto ... args) { return riemann_solver_ (uL, uR, fL , fR , args...); }, speeds);
253
+ if (riemann_ == " rusanov" )
254
+ {
255
+ auto [speeds, speedsb]
256
+ = rusanov_speeds_<direction>(std::tuple_cat (uL, ubL), std::tuple_cat (uR, ubR));
255
257
256
- auto [Bx, By, Bz, Etot ] = std::apply (
257
- [&](auto ... args) { return riemann_solver_ (ubL, ubR, fbL, fbR , args...); }, speedsb );
258
+ auto [rho, rhoVx, rhoVy, rhoVz ] = std::apply (
259
+ [&](auto ... args) { return rusanov_ (uL, uR, fL , fR , args...); }, speeds );
258
260
259
- return std::make_tuple (rho, rhoVx, rhoVy, rhoVz, Bx, By, Bz, Etot);
260
- }
261
+ auto [ Bx, By, Bz, Etot] = std::apply (
262
+ [&]( auto ... args) { return rusanov_ (ubL, ubR, fbL, fbR, args...); }, speedsb);
261
263
262
- template <auto direction>
263
- auto riemann_speeds_ (auto const & uL, auto const & uR) const
264
- {
265
- if (riemann_ == " rusanov" )
266
- return rusanov_speeds_<direction>(uL, uR);
264
+ return std::make_tuple (rho, rhoVx, rhoVy, rhoVz, Bx, By, Bz, Etot);
265
+ }
266
+ else if (riemann_ == " hll" )
267
+ {
268
+ auto [speeds, speedsb]
269
+ = hll_speeds_<direction>(std::tuple_cat (uL, ubL), std::tuple_cat (uR, ubR));
270
+
271
+ auto [rho, rhoVx, rhoVy, rhoVz]
272
+ = std::apply ([&](auto ... args) { return hll_ (uL, uR, fL , fR , args...); }, speeds);
273
+
274
+ auto [Bx, By, Bz, Etot] = std::apply (
275
+ [&](auto ... args) { return hll_ (ubL, ubR, fbL, fbR, args...); }, speedsb);
276
+
277
+ return std::make_tuple (rho, rhoVx, rhoVy, rhoVz, Bx, By, Bz, Etot);
278
+ }
267
279
else
268
- throw std::runtime_error (" Error - Riemann Solver - Unknown Riemann solver" );
280
+ throw std::runtime_error (" Error - GodunovFluxes - Unknown Riemann solver" );
269
281
}
270
282
271
283
template <auto direction>
@@ -301,21 +313,45 @@ class GodunovFluxes : public LayoutHolder<GridLayout>
301
313
return compute_speeds (rhoL, rhoR, PL, PR, BdotBL, BdotBR, VzL, VzR, BzL, BzR);
302
314
}
303
315
304
- template <typename ... Speeds>
305
- auto riemann_solver_ (auto const & uL, auto const & uR, auto const & fL , auto const & fR ,
306
- Speeds... S) const
316
+ template <auto direction>
317
+ auto hll_speeds_ (auto const & uL, auto const & uR) const
307
318
{
308
- if (riemann_ == " rusanov" )
309
- return rusanov_ (uL, uR, fL , fR , S...);
310
- else
311
- throw std::runtime_error (" Error - Riemann Solver - Unknown Riemann solver" );
319
+ auto const & [rhoL, VxL, VyL, VzL, BxL, ByL, BzL, PL] = uL;
320
+ auto const & [rhoR, VxR, VyR, VzR, BxR, ByR, BzR, PR] = uR;
321
+ auto BdotBL = BxL * BxL + ByL * ByL + BzL * BzL;
322
+ auto BdotBR = BxR * BxR + ByR * ByR + BzR * BzR;
323
+
324
+ auto compute_speeds = [&](auto rhoL, auto rhoR, auto PL, auto PR, auto BdotBL, auto BdotBR,
325
+ auto VcompL, auto VcompR, auto BcompL, auto BcompR) {
326
+ auto cfastL = compute_fast_magnetosonic_ (rhoL, BcompL, BdotBL, PL);
327
+ auto cfastR = compute_fast_magnetosonic_ (rhoR, BcompR, BdotBR, PR);
328
+ auto SL = std::min (VcompL - cfastL, VcompR - cfastR);
329
+ auto SR = std::max (VcompL + cfastL, VcompR + cfastR);
330
+ auto SLb = SL;
331
+ auto SRb = SR;
332
+
333
+ if (terms_ == " hall" )
334
+ {
335
+ auto cwL = compute_whistler_ (layout_->inverseMeshSize (direction), rhoL, BdotBL);
336
+ auto cwR = compute_whistler_ (layout_->inverseMeshSize (direction), rhoR, BdotBR);
337
+ SLb = std::min (VcompL - cfastL - cwL, VcompR - cfastR - cwR);
338
+ SRb = std::max (VcompL + cfastL + cwL, VcompR + cfastR + cwR);
339
+ }
340
+
341
+ return std::make_tuple (std::make_tuple (SL, SR), std::make_tuple (SLb, SRb));
342
+ };
343
+
344
+ if constexpr (direction == Direction::X)
345
+ return compute_speeds (rhoL, rhoR, PL, PR, BdotBL, BdotBR, VxL, VxR, BxL, BxR);
346
+ else if constexpr (direction == Direction::Y)
347
+ return compute_speeds (rhoL, rhoR, PL, PR, BdotBL, BdotBR, VyL, VyR, ByL, ByR);
348
+ else if constexpr (direction == Direction::Z)
349
+ return compute_speeds (rhoL, rhoR, PL, PR, BdotBL, BdotBR, VzL, VzR, BzL, BzR);
312
350
}
313
351
314
352
auto rusanov_ (auto const & uL, auto const & uR, auto const & fL , auto const & fR ,
315
353
auto const S) const
316
354
{
317
- // to be used 2 times in hall mhd (the second time for B with whisler contribution).
318
-
319
355
auto constexpr N_elements = std::tuple_size_v<std::decay_t <decltype (uL)>>;
320
356
321
357
return for_N<N_elements, for_N_R_mode::make_tuple>([&](auto i) {
@@ -324,6 +360,25 @@ class GodunovFluxes : public LayoutHolder<GridLayout>
324
360
});
325
361
}
326
362
363
+ auto hll_ (auto const & uL, auto const & uR, auto const & fL , auto const & fR , auto const & SL,
364
+ auto const & SR) const
365
+ {
366
+ auto constexpr N_elements = std::tuple_size_v<std::decay_t <decltype (uL)>>;
367
+
368
+ auto hll = [&](auto const ul, auto const ur, auto const fl, auto const fr) {
369
+ if (SL > 0.0 )
370
+ return fl;
371
+ else if (SR < 0.0 )
372
+ return fr;
373
+ else
374
+ return (SR * fl - SL * fr + SL * SR * (ur - ul)) / (SR - SL);
375
+ };
376
+
377
+ return for_N<N_elements, for_N_R_mode::make_tuple>([&](auto i) {
378
+ return hll (std::get<i>(uL), std::get<i>(uR), std::get<i>(fL ), std::get<i>(fR ));
379
+ });
380
+ }
381
+
327
382
auto compute_fast_magnetosonic_ (auto const & rho, auto const & B, auto const & BdotB,
328
383
auto const & P) const
329
384
{
0 commit comments