Program Listing for File roeMHD.hpp

Return to documentation for file (hydro/MHDsolvers/roeMHD.hpp)

// ***********************************************************************************
// Idefix MHD astrophysical code
// Copyright(C) 2020-2022 Geoffroy R. J. Lesur <geoffroy.lesur@univ-grenoble-alpes.fr>
// and other code contributors
// Licensed under CeCILL 2.1 License, see COPYING for more information
// ***********************************************************************************

#ifndef HYDRO_MHDSOLVERS_ROEMHD_HPP_
#define HYDRO_MHDSOLVERS_ROEMHD_HPP_

#include "../idefix.hpp"
#include "slopeLimiter.hpp"
#include "fluxMHD.hpp"
#include "convertConsToPrimMHD.hpp"
#include "storeFlux.hpp"
#include "electroMotiveForce.hpp"

#define ROE_AVERAGE 0

#define KFASTM 0
#define KFASTP 1
#define KDIVB  2

#if HAVE_ENERGY

#define KENTRP 3
#define KSLOWM 4
#define KSLOWP 5
#define KALFVM 6
#define KALFVP 7

#define NMODES 8

#else

#define KSLOWM 3
#define KSLOWP 4
#define KALFVM 5
#define KALFVP 6

#define NMODES 7

#endif


#define DSIGN(x) ( (x) >= 0.0 ? (1.0) : (-1.0))

// Compute Riemann fluxes from states using ROE solver
template<const int DIR>
void Hydro::RoeMHD() {
  idfx::pushRegion("Hydro::ROE_MHD");

  constexpr int ioffset = (DIR==IDIR) ? 1 : 0;
  constexpr int joffset = (DIR==JDIR) ? 1 : 0;
  constexpr int koffset = (DIR==KDIR) ? 1 : 0;

  // extension in perp to the direction of integration, as required by CT.
  constexpr int iextend = (DIR==IDIR) ? 0 : 1;
  #if DIMENSIONS > 1
    constexpr int jextend = (DIR==JDIR) ? 0 : 1;
  #else
    constexpr int jextend = 0;
  #endif
  #if DIMENSIONS > 2
    constexpr int kextend = (DIR==KDIR) ? 0 : 1;
  #else
    constexpr int kextend = 0;
  #endif

  IdefixArray4D<real> Vc = this->Vc;
  IdefixArray4D<real> Vs = this->Vs;
  IdefixArray4D<real> Flux = this->FluxRiemann;
  IdefixArray3D<real> cMax = this->cMax;
  IdefixArray3D<real> csIsoArr = this->isoSoundSpeedArray;

  // Required for high order interpolations
  IdefixArray1D<real> dx = this->data->dx[DIR];

  // References to required emf components
  IdefixArray3D<real> Eb;
  IdefixArray3D<real> Et;

  const ElectroMotiveForce::AveragingType emfAverage = emf.averaging;


  // Required by UCT_Contact
  IdefixArray3D<real> SV;

  // Required by UCT_HLLX
  IdefixArray3D<real> aL;
  IdefixArray3D<real> aR;
  IdefixArray3D<real> dL;
  IdefixArray3D<real> dR;

  real gamma = this->gamma;
  [[maybe_unused]] real gamma_m1=gamma-ONE_F;
  [[maybe_unused]] real csIso = this->isoSoundSpeed;
  [[maybe_unused]] HydroModuleStatus haveIsoCs = this->haveIsoSoundSpeed;

  // TODO(baghdads) what is this delta?
  real delta    = 1.e-6;

  // Define normal, tangent and bi-tanget indices
  // st and sb will be useful only when Hall is included
  real st = ONE_F, sb = ONE_F;

  SlopeLimiter<DIR,NVAR> slopeLim(Vc,data->dx[DIR],shockFlattening);

  switch(DIR) {
    case(IDIR):
      D_EXPAND(
                st = -ONE_F;  ,
                  ,

                sb = +ONE_F;  )

      Et = this->emf.ezi;
      Eb = this->emf.eyi;

      SV = this->emf.svx;

      aL = this->emf.axL;
      aR = this->emf.axR;

      dL = this->emf.dxL;
      dR = this->emf.dxR;

      break;
#if DIMENSIONS >= 2
    case(JDIR):
      D_EXPAND(
                st = +ONE_F;  ,
                              ,

                sb = -ONE_F;  )

      Et = this->emf.ezj;
      Eb = this->emf.exj;

      SV = this->emf.svy;

      aL = this->emf.ayL;
      aR = this->emf.ayR;

      dL = this->emf.dyL;
      dR = this->emf.dyR;

      break;
#endif
#if DIMENSIONS == 3
    case(KDIR):

      D_EXPAND(

                st = -ONE_F;  ,
                  ,
                sb = +ONE_F;  )

      Et = this->emf.eyk;
      Eb = this->emf.exk;

      SV = this->emf.svz;

      aL = this->emf.azL;
      aR = this->emf.azR;

      dL = this->emf.dzL;
      dR = this->emf.dzR;
      break;
#endif
    default:
      IDEFIX_ERROR("Wrong direction");
  }

  idefix_for("CalcRiemannFlux",
             data->beg[KDIR]-kextend,data->end[KDIR]+koffset+kextend,
             data->beg[JDIR]-jextend,data->end[JDIR]+joffset+jextend,
             data->beg[IDIR]-iextend,data->end[IDIR]+ioffset+iextend,
    KOKKOS_LAMBDA (int k, int j, int i) {
      // Init the directions (should be in the kernel for proper optimisation by the compilers)
      EXPAND( const int Xn = DIR+MX1;                    ,
              const int Xt = (DIR == IDIR ? MX2 : MX1);  ,
              const int Xb = (DIR == KDIR ? MX2 : MX3);  )

      EXPAND( const int BXn = DIR+BX1;                    ,
              const int BXt = (DIR == IDIR ? BX2 : BX1);  ,
              const int BXb = (DIR == KDIR ? BX2 : BX3);   )

      // Primitive variables
      real vL[NVAR];
      real vR[NVAR];
      real dV[NVAR];

      // Conservative variables
      real uL[NVAR];
      real uR[NVAR];
      [[maybe_unused]] real dU[NVAR];

      // Flux (left and right)
      real fluxL[NVAR];
      real fluxR[NVAR];

      // Roe
      real Rc[NVAR][NVAR];


      // 1-- Store the primitive variables on the left, right, and averaged states
      slopeLim.ExtrapolatePrimVar(i, j, k, vL, vR);
      vL[BXn] = Vs(DIR,k,j,i);
      vR[BXn] = vL[BXn];

#pragma unroll
      for(int nv = 0 ; nv < NVAR; nv++) {
        dV[nv] = vR[nv] - vL[nv];
      }

      // 2-- Compute the conservative variables
      K_PrimToCons(uL, vL, gamma_m1);
      K_PrimToCons(uR, vR, gamma_m1);

      // --- Compute the square of the sound speed
      real a, a2, a2L, a2R;
      #if HAVE_ENERGY
        // These are actually not used, but are initialised to avoid warnings
        a2L = ONE_F;
        a2R = ONE_F;
      #else
        if(haveIsoCs == UserDefFunction) {
          a2L = HALF_F*(csIsoArr(k,j,i)+csIsoArr(k-koffset,j-joffset,i-ioffset));
      } else {
          a2L = csIso;
      }
      a2L = a2L*a2L;
      a2R = a2L;
      #endif

      // 3-- Compute the left and right fluxes
#pragma unroll
      for(int nv = 0 ; nv < NVAR; nv++) {
        fluxL[nv] = uL[nv];
        fluxR[nv] = uR[nv];
        dU[nv] = uR[nv] - uL[nv];
      }
      K_Flux(fluxL, vL, fluxL, a2L, ARG_EXPAND(Xn, Xt, Xb), ARG_EXPAND(BXn, BXt, BXb));
      K_Flux(fluxR, vR, fluxR, a2R, ARG_EXPAND(Xn, Xt, Xb), ARG_EXPAND(BXn, BXt, BXb));

      // 5. Set eigenvectors components Rc = 0 initially
#pragma unroll
      for(int nv1 = 0 ; nv1 < NVAR; nv1++) {
#pragma unroll
        for(int nv2 = 0 ; nv2 < NVAR; nv2++) {
          Rc[nv1][nv2] = 0;
        }
      }

      real sqr_rho_L, sqr_rho_R, sl, sr, rho, sqrt_rho;

      // 6c. Compute Roe averages
      sqr_rho_L = std::sqrt(vL[RHO]);
      sqr_rho_R = std::sqrt(vR[RHO]);

      sl = sqr_rho_L/(sqr_rho_L + sqr_rho_R);
      sr = sqr_rho_R/(sqr_rho_L + sqr_rho_R);

      // sl = sr = 0.5;

      rho = sr*vL[RHO] + sl*vR[RHO];

      sqrt_rho = std::sqrt(rho);

      [[maybe_unused]] real u, v, w, Bx, By, Bz, sBx, bx, by, bz, bt2, b2, Btmag;

      EXPAND ( u = sl*vL[Xn] + sr*vR[Xn];  ,
               v = sl*vL[Xt] + sr*vR[Xt];  ,
               w = sl*vL[Xb] + sr*vR[Xb];  )

      EXPAND ( Bx = sr*vL[BXn] + sl*vR[BXn];  ,
               By = sr*vL[BXt] + sl*vR[BXt];  ,
               Bz = sr*vL[BXb] + sl*vR[BXb];  )

      sBx = (Bx >= 0.0 ? 1.0 : -1.0);

      EXPAND( bx = Bx/sqrt_rho;  ,
              by = By/sqrt_rho;  ,
              bz = Bz/sqrt_rho;  )

      bt2   = EXPAND(0.0  , + by*by, + bz*bz);
      b2    = bx*bx + bt2;
      Btmag = std::sqrt(bt2*rho);

      real X  = EXPAND(dV[BXn]*dV[BXn], + dV[BXt]*dV[BXt], + dV[BXb]*dV[BXb]);
      X /= (sqr_rho_L + sqr_rho_R)*(sqr_rho_L + sqr_rho_R)*2.0;


      [[maybe_unused]] real Bmag2L, Bmag2R, pL, pR;
      Bmag2L = EXPAND(vL[BX1]*vL[BX1] , + vL[BX2]*vL[BX2], + vL[BX3]*vL[BX3]);
      Bmag2R = EXPAND(vR[BX1]*vR[BX1] , + vR[BX2]*vR[BX2], + vR[BX3]*vR[BX3]);
#if HAVE_ENERGY
      pL  = vL[PRS] + HALF_F*Bmag2L;
      pR  = vR[PRS] + HALF_F*Bmag2R;
#else
      pL  = a2L*vL[RHO] + HALF_F*Bmag2L;
      pR  = a2R*vR[RHO] + HALF_F*Bmag2R;
#endif

      // 6d. Compute enthalpy and sound speed.
#if HAVE_ENERGY
      real vel2, HL, HR, H, Hgas;
      real vdm, BdB;

      vdm = EXPAND(u*dU[Xn],  + v*dU[Xt],  + w*dU[Xb]);
      BdB = EXPAND(Bx*dU[BXn], + By*dU[BXt], + Bz*dU[BXb]);

      vel2    = EXPAND(u*u, + v*v, + w*w);
      dV[PRS] = gamma_m1*((0.5*vel2 - X)*dV[RHO] - vdm + dU[ENG] - BdB);

      HL   = (uL[ENG] + pL)/vL[RHO];
      HR   = (uR[ENG] + pR)/vR[RHO];
      H    = sl*HL + sr*HR;   // total enthalpy

      Hgas = H - b2;         // gas enthalpy

      a2 = (2.0 - gamma)*X + gamma_m1*(Hgas - 0.5*vel2);
      if (a2 < 0.0) {
          //IDEFIX_ERROR("! Roe_Solver(): a2 < 0.0 !! \n");
      }
#else
      // in most cases a2L = a2R for isothermal MHD
      a2 = 0.5*(a2L + a2R) + X;
#endif

      /* ------------------------------------------------------------
      6e. Compute fast and slow magnetosonic speeds.

      The following expression appearing in the definitions
      of the fast magnetosonic speed

      (a^2 - b^2)^2 + 4*a^2*bt^2 = (a^2 + b^2)^2 - 4*a^2*bx^2

      is always positive and avoids round-off errors.

      Note that we always use the total field to compute the
      characteristic speeds.
      ------------------------------------------------------------ */

      [[maybe_unused]] real scrh, ca, cf, cs, ca2, cf2, cs2, alpha_f, alpha_s, beta_y, beta_z;
      scrh = a2 - b2;
      ca2  = bx*bx;
      scrh = scrh*scrh + 4.0*bt2*a2;
      scrh = std::sqrt(scrh);

      cf2 = 0.5*(a2 + b2 + scrh);
      cs2 = a2*ca2/cf2;   // -- same as 0.5*(a2 + b2 - scrh)

      cf = std::sqrt(cf2);
      cs = std::sqrt(cs2);
      ca = std::sqrt(ca2);
      a  = std::sqrt(a2);

      if (cf == cs) {
        alpha_f = 1.0;
        alpha_s = 0.0;
      } else if (a <= cs) {
        alpha_f = 0.0;
        alpha_s = 1.0;
      } else if (cf <= a) {
        alpha_f = 1.0;
        alpha_s = 0.0;
      } else {
        scrh    = 1.0/(cf2 - cs2);
        alpha_f = (a2  - cs2)*scrh;
        alpha_s = (cf2 -  a2)*scrh;
        alpha_f = FMAX(0.0, alpha_f);
        alpha_s = FMAX(0.0, alpha_s);
        alpha_f = std::sqrt(alpha_f);
        alpha_s = std::sqrt(alpha_s);
      }

      if (Btmag > 1.e-9) {
        SELECT(                      ,
                beta_y = DSIGN(By);  ,
                beta_y = By/Btmag;
                beta_z = Bz/Btmag;   )
      } else {
        SELECT(                         ,
                beta_y = 1.0;           ,
                beta_z = beta_y = 1.0;  )
      }

      /* -------------------------------------------------------------------
      6f. Compute non-zero entries of conservative eigenvectors (Rc),
          wave strength L*dU (=eta) for all 8 (or 7) waves using the
          expressions given by Eq. [4.18]--[4.21].
          Fast and slow eigenvectors are multiplied by a^2 while
          jumps are divided by a^2.

          Notes:
          - the expression on the paper has a typo in the very last term
          of the energy component: it should be + and not - !
          - with background field splitting: additional terms must be
          added to the energy component for fast, slow and Alfven waves.
          To obtain energy element, conservative eigenvector (with
          total field) must be multiplied by | 0 0 0 0 -B0y -B0z 1 |.
          Also, H - b2 does not give gas enthalpy. A term b0*btot must
          be added and eta (wave strength) should contain total field
          and deviation's delta.
      ------------------------------------------------------------------- */

      // Fast wave:  u - c_f
      real lambda[NMODES], alambda[NMODES], eta[NMODES];
      [[maybe_unused]] real beta_dv, beta_dB, beta_v;

      int kk = KFASTM;
      lambda[kk] = u - cf;

      scrh    = alpha_s*cs*sBx;
      beta_dv = EXPAND(0.0, + beta_y*dV[Xt], + beta_z*dV[Xb]);
      beta_dB = EXPAND(0.0, + beta_y*dV[BXt], + beta_z*dV[BXb]);

      Rc[RHO][kk] = alpha_f;
      EXPAND( Rc[Xn][kk] = alpha_f*lambda[kk];       ,
              Rc[Xt][kk] = alpha_f*v + scrh*beta_y;  ,
              Rc[Xb][kk] = alpha_f*w + scrh*beta_z;  )

      EXPAND(                                           ,
              Rc[BXt][kk] = alpha_s*a*beta_y/sqrt_rho;  ,
              Rc[BXb][kk] = alpha_s*a*beta_z/sqrt_rho;  )

#if HAVE_ENERGY
      beta_v  = EXPAND(0.0, + beta_y*v,       + beta_z*w);
      Rc[ENG][kk] =   alpha_f*(Hgas - u*cf) + scrh*beta_v
                  + alpha_s*a*Btmag/sqrt_rho;

      eta[kk] =   alpha_f*(X*dV[RHO] + dV[PRS]);
#else
      // eta[kk] =   alpha_f*(0.0*X + a2)*dV[RHO] + rho*scrh*beta_dv
      //        - rho*alpha_f*cf*dV[Xn] + sqrt_rho*alpha_s*a*beta_dB;
      eta[kk] =   alpha_f*a2*dV[RHO];
#endif
      eta[kk] += rho*scrh*beta_dv - rho*alpha_f*cf*dV[Xn] + sqrt_rho*alpha_s*a*beta_dB;
      eta[kk] *= 0.5/a2;

      // Fast wave:  u + c_f

      kk = KFASTP;
      lambda[kk] = u + cf;

      Rc[RHO][kk] = alpha_f;
      EXPAND( Rc[Xn][kk] = alpha_f*lambda[kk];       ,
              Rc[Xt][kk] = alpha_f*v - scrh*beta_y;  ,
              Rc[Xb][kk] = alpha_f*w - scrh*beta_z;  )
      EXPAND(                                 ,
              Rc[BXt][kk] = Rc[BXt][KFASTM];  ,
              Rc[BXb][kk] = Rc[BXb][KFASTM];  )

#if HAVE_ENERGY
      Rc[ENG][kk] =   alpha_f*(Hgas + u*cf) - scrh*beta_v
                  + alpha_s*a*Btmag/sqrt_rho;

      eta[kk] =   alpha_f*(X*dV[RHO] + dV[PRS]) - rho*scrh*beta_dv
              + rho*alpha_f*cf*dV[Xn]        + sqrt_rho*alpha_s*a*beta_dB;
#else
      eta[kk] =   alpha_f*(0.*X + a2)*dV[RHO] - rho*scrh*beta_dv
              + rho*alpha_f*cf*dV[Xn]      + sqrt_rho*alpha_s*a*beta_dB;
#endif

      eta[kk] *= 0.5/a2;

      // Entropy wave:  u

#if HAVE_ENERGY
      kk = KENTRP;
      lambda[kk] = u;

      Rc[RHO][kk] = 1.0;
      EXPAND( Rc[Xn][kk] = u;  ,
              Rc[Xt][kk] = v;  ,
              Rc[Xb][kk] = w;  )
      Rc[ENG][kk] = 0.5*vel2 + (gamma - 2.0)/gamma_m1*X;

      eta[kk] = ((a2 - X)*dV[RHO] - dV[PRS])/a2;
#endif

      /* -----------------------------------------------------------------
      div.B wave (u): this wave exists when:

      1) 8 wave formulation
      2) CT, since we always have 8 components, but it
          carries zero jump.

      With GLM, KDIVB is replaced by KPSI_GLMM, KPSI_GLMP and these
      two waves should not enter in the Riemann solver (eta = 0.0)
      since the 2x2 linear system formed by (B,psi) has already
      been solved.
      ----------------------------------------------------------------- */

      kk = KDIVB;
      lambda[kk] = u;
      eta[kk] = 0.0;

#if COMPONENTS > 1
      // Slow wave:  u - c_s

      scrh = alpha_f*cf*sBx;

      kk = KSLOWM;
      lambda[kk] = u - cs;

      Rc[RHO][kk] = alpha_s;
      EXPAND( Rc[Xn][kk] = alpha_s*lambda[kk];       ,
              Rc[Xt][kk] = alpha_s*v - scrh*beta_y;  ,
              Rc[Xb][kk] = alpha_s*w - scrh*beta_z;  )
      EXPAND(                                             ,
              Rc[BXt][kk] = - alpha_f*a*beta_y/sqrt_rho;  ,
              Rc[BXb][kk] = - alpha_f*a*beta_z/sqrt_rho;  )

  #if HAVE_ENERGY
      Rc[ENG][kk] =   alpha_s*(Hgas - u*cs) - scrh*beta_v
                  - alpha_f*a*Btmag/sqrt_rho;

      eta[kk] =   alpha_s*(X*dV[RHO] + dV[PRS]) - rho*scrh*beta_dv
              - rho*alpha_s*cs*dV[Xn]        - sqrt_rho*alpha_f*a*beta_dB;
  #else
      eta[kk] =   alpha_s*(0.*X + a2)*dV[RHO] - rho*scrh*beta_dv
              - rho*alpha_s*cs*dV[Xn]      - sqrt_rho*alpha_f*a*beta_dB;
  #endif

      eta[kk] *= 0.5/a2;

      // Slow wave:  u + c_s

      kk = KSLOWP;
      lambda[kk] = u + cs;

      Rc[RHO][kk] = alpha_s;
      EXPAND( Rc[Xn][kk] = alpha_s*lambda[kk];       ,
              Rc[Xt][kk] = alpha_s*v + scrh*beta_y;  ,
              Rc[Xb][kk] = alpha_s*w + scrh*beta_z;  )
      EXPAND(                                 ,
              Rc[BXt][kk] = Rc[BXt][KSLOWM];  ,
              Rc[BXb][kk] = Rc[BXb][KSLOWM];  )

  #if HAVE_ENERGY
      Rc[ENG][kk] =   alpha_s*(Hgas + u*cs) + scrh*beta_v
                  - alpha_f*a*Btmag/sqrt_rho;

      eta[kk] =   alpha_s*(X*dV[RHO] + dV[PRS]) + rho*scrh*beta_dv
              + rho*alpha_s*cs*dV[Xn]        - sqrt_rho*alpha_f*a*beta_dB;
  #else
      eta[kk] =   alpha_s*(0.*X + a2)*dV[RHO] + rho*scrh*beta_dv
              + rho*alpha_s*cs*dV[Xn]      - sqrt_rho*alpha_f*a*beta_dB;
  #endif

      eta[kk] *= 0.5/a2;

#endif // COMPONENTS > 1

#if COMPONENTS == 3

      // Alfven wave:  u - c_a

      kk = KALFVM;
      lambda[kk] = u - ca;

      Rc[Xt][kk] = - rho*beta_z;
      Rc[Xb][kk] = + rho*beta_y;
      Rc[BXt][kk] = - sBx*sqrt_rho*beta_z;
      Rc[BXb][kk] =   sBx*sqrt_rho*beta_y;
  #if HAVE_ENERGY
      Rc[ENG][kk] = - rho*(v*beta_z - w*beta_y);
  #endif

      eta[kk] = + beta_y*dV[Xb]               - beta_z*dV[Xt]
              + sBx/sqrt_rho*(beta_y*dV[BXb] - beta_z*dV[BXt]);

      eta[kk] *= 0.5;

      // Alfven wave:  u + c_a

      kk = KALFVP;
      lambda[kk] = u + ca;

      Rc[Xt][kk] = - Rc[Xt][KALFVM];
      Rc[Xb][kk] = - Rc[Xb][KALFVM];
      Rc[BXt][kk] =   Rc[BXt][KALFVM];
      Rc[BXb][kk] =   Rc[BXb][KALFVM];
  #if HAVE_ENERGY
      Rc[ENG][kk] = - Rc[ENG][KALFVM];
  #endif

      eta[kk] = - beta_y*dV[Xb]               + beta_z*dV[Xt]
              + sBx/sqrt_rho*(beta_y*dV[BXb] - beta_z*dV[BXt]);

      eta[kk] *= 0.5;
#endif // COMPONENTS == 3

      // 6g. Compute maximum signal velocity

      real cmax = std::fabs(u) + cf;

      // 6h. Save max and min Riemann fan speeds for EMF computation.
      sl = lambda[KFASTM];
      sr = lambda[KFASTP];

#pragma unroll
      for(int nv = 0 ; nv < NVAR; nv++) {
          alambda[nv] = fabs(lambda[nv]);
      }

      // 6i. Entropy Fix

      if (alambda[KFASTM] < 0.5*delta) {
        alambda[KFASTM] = lambda[KFASTM]*lambda[KFASTM]/delta + 0.25*delta;
      }
      if (alambda[KFASTP] < 0.5*delta) {
        alambda[KFASTP] = lambda[KFASTP]*lambda[KFASTP]/delta + 0.25*delta;
      }
#if COMPONENTS > 1
      if (alambda[KSLOWM] < 0.5*delta) {
        alambda[KSLOWM] = lambda[KSLOWM]*lambda[KSLOWM]/delta + 0.25*delta;
      }
      if (alambda[KSLOWP] < 0.5*delta) {
        alambda[KSLOWP] = lambda[KSLOWP]*lambda[KSLOWP]/delta + 0.25*delta;
      }
#endif

      // 6j. Compute Roe numerical flux
#pragma unroll
      for(int nv1 = 0 ; nv1 < NFLX; nv1++) {
        scrh = 0.0;
#pragma unroll
        for(int nv2 = 0 ; nv2 < NFLX; nv2++) {
          scrh += alambda[nv2]*eta[nv2]*Rc[nv1][nv2];
        }
        Flux(nv1,k,j,i) = 0.5*(fluxL[nv1] + fluxR[nv1] - scrh);
      }

      // save maximum wave speed for this sweep
      cMax(k,j,i) = cmax;

      // 7-- Store the flux in the emf components
      if (emfAverage==ElectroMotiveForce::arithmetic
                || emfAverage==ElectroMotiveForce::uct0) {
        K_StoreEMF<DIR>(i,j,k,st,sb,Flux,Et,Eb);
      } else if (emfAverage==ElectroMotiveForce::uct_contact) {
        K_StoreContact<DIR>(i,j,k,st,sb,Flux,Et,Eb,SV);
      } else if (emfAverage==ElectroMotiveForce::uct_hll) {
        K_StoreHLL<DIR>(i,j,k,st,sb,sl,sr,vL,vR,Et,Eb,aL,aR,dL,dR);
      } else if (emfAverage==ElectroMotiveForce::uct_hlld) {
        K_StoreHLLD<DIR>(i,j,k,st,sb,a2L,sl,sr,
                         vL,vR,uL,uR,Et,Eb,aL,aR,dL,dR);
      }
  });

  idfx::popRegion();
}
#endif // HYDRO_MHDSOLVERS_ROEMHD_HPP_