Program Listing for File storeFlux.hpp
↰ Return to documentation for file (hydro/MHDsolvers/storeFlux.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_STOREFLUX_HPP_
#define HYDRO_MHDSOLVERS_STOREFLUX_HPP_
#include "idefix.hpp"
#include "hydro.hpp"
template <const int DIR>
KOKKOS_FORCEINLINE_FUNCTION void K_StoreEMF( const int i, const int j, const int k,
const real st, const real sb,
const IdefixArray4D<real> &Flux,
const IdefixArray3D<real> &Et,
const IdefixArray3D<real> &Eb ) {
EXPAND( ,
constexpr int BXt = (DIR == IDIR ? BX2 : BX1); ,
[[maybe_unused]] constexpr int BXb = (DIR == KDIR ? BX2 : BX3); )
#if COMPONENTS > 1
D_EXPAND( Et(k,j,i) = st*Flux(BXt,k,j,i); ,
,
Eb(k,j,i) = sb*Flux(BXb,k,j,i); )
#endif
}
template <const int DIR>
KOKKOS_FORCEINLINE_FUNCTION void K_StoreContact( const int i, const int j, const int k,
const real st, const real sb,
const IdefixArray4D<real> &Flux,
const IdefixArray3D<real> &Et,
const IdefixArray3D<real> &Eb,
const IdefixArray3D<real> &SV) {
K_StoreEMF<DIR>(i,j,k,st,sb,Flux,Et,Eb);
real s = HALF_F;
if (Flux(RHO,k,j,i) > eps_UCT_CONTACT) s = ONE_F;
if (Flux(RHO,k,j,i) < -eps_UCT_CONTACT) s = ZERO_F;
SV(k,j,i) = s;
}
template <const int DIR>
KOKKOS_FORCEINLINE_FUNCTION void K_StoreHLL( const int i, const int j, const int k,
const real st, const real sb,
const real sl, const real sr,
real vL[], real vR[],
const IdefixArray3D<real> &Et,
const IdefixArray3D<real> &Eb,
const IdefixArray3D<real> &aL,
const IdefixArray3D<real> &aR,
const IdefixArray3D<real> &dL,
const IdefixArray3D<real> &dR) {
EXPAND( ,
constexpr int Xt = (DIR == IDIR ? MX2 : MX1); ,
constexpr int Xb = (DIR == KDIR ? MX2 : MX3); )
real ar = std::fmax(ZERO_F, sr);
real al = std::fmin(ZERO_F, sl);
real scrh = ONE_F/(ar - al);
#if COMPONENTS > 1
EXPAND( Et(k,j,i) = -st*(ar*vL[Xt] - al*vR[Xt])*scrh; ,
,
Eb(k,j,i) = -sb*(ar*vL[Xb] - al*vR[Xb])*scrh; );
#endif
aL(k,j,i) = ar*scrh;
aR(k,j,i) = -al*scrh;
dR(k,j,i) = -al*ar*scrh;
dL(k,j,i) = dR(k,j,i);
}
template <const int DIR>
KOKKOS_FORCEINLINE_FUNCTION void K_StoreHLLD( const int i, const int j, const int k,
const real st, const real sb,
const real c2Iso,
const real sl, const real sr,
real vL[], real vR[],
real uL[], real uR[],
const IdefixArray3D<real> &Et,
const IdefixArray3D<real> &Eb,
const IdefixArray3D<real> &aL,
const IdefixArray3D<real> &aR,
const IdefixArray3D<real> &dL,
const IdefixArray3D<real> &dR) {
EXPAND( const int Xn = DIR+MX1; ,
const int Xt = (DIR == IDIR ? MX2 : MX1); ,
const int Xb = (DIR == KDIR ? MX2 : MX3); )
// Compute magnetic pressure
[[maybe_unused]] real ptR, ptL;
#if HAVE_ENERGY
ptL = vL[PRS] + HALF_F* ( EXPAND(vL[BX1]*vL[BX1] ,
+ vL[BX2]*vL[BX2] ,
+ vL[BX3]*vL[BX3]) );
ptR = vR[PRS] + HALF_F* ( EXPAND(vR[BX1]*vR[BX1] ,
+ vR[BX2]*vR[BX2] ,
+ vR[BX3]*vR[BX3]) );
#else
ptL = c2Iso*vL[RHO] + HALF_F* (EXPAND(vL[BX1]*vL[BX1] ,
+ vL[BX2]*vL[BX2] ,
+ vL[BX3]*vL[BX3]) );
ptR = c2Iso*vR[RHO] + HALF_F* (EXPAND(vR[BX1]*vR[BX1] ,
+ vR[BX2]*vR[BX2] ,
+ vR[BX3]*vR[BX3]) );
#endif
int revert_to_hll = 0;
const int BXn = DIR+BX1;
real Bn = (sr*vR[BXn] - sl*vL[BXn])/(sr - sl);
real chiL, chiR, nuLR, nuL, nuR, SaL, SaR;
real Sc;
real eps = 1.e-12*(fabs(sl) + fabs(sr));
real duL = sl - vL[Xn];
real duR = sr - vR[Xn];
#if HAVE_ENERGY
// Recompute speeds
real sqrL, sqrR, usLRHO, usRRHO;
real scrh = ONE_F/(duR*uR[RHO] - duL*uL[RHO]);
Sc = (duR*uR[Xn] - duL*uL[Xn] - ptR + ptL)*scrh;
usLRHO = uL[RHO]*duL/(sl - Sc);
usRRHO = uR[RHO]*duR/(sr - Sc);
sqrL = sqrt(usLRHO);
sqrR = sqrt(usRRHO);
SaL = Sc - fabs(Bn)/sqrL;
SaR = Sc + fabs(Bn)/sqrR;
if((SaL - sl) < 1e-4*(Sc-sl)) revert_to_hll = 1;
if((SaR - sr) > -1e-4*(sr-Sc)) revert_to_hll = 1;
chiL = (vL[Xn] - Sc)*(sl - Sc)/(SaL + sl - TWO_F*Sc);
chiR = (vR[Xn] - Sc)*(sr - Sc)/(SaR + sr - TWO_F*Sc);
#else
real scrh = ONE_F/(sr - sl);
real rho_h = (uR[RHO]*duR - uL[RHO]*duL)*scrh;
Sc = (sl*uR[RHO]*duR - sr*uL[RHO]*duL)*scrh/rho_h;
// Recompute speeds
real sqrho_h = sqrt(rho_h);
SaL = Sc - fabs(Bn)/sqrho_h;
SaR = Sc + fabs(Bn)/sqrho_h;
if((SaL - sl) < 1e-4*(Sc-sl)) revert_to_hll = 1;
if((SaR - sr) > -1e-4*(sr-Sc)) revert_to_hll = 1;
chiL = (vL[Xn] - Sc)*(sl - Sc)/(SaL + sl - TWO_F*Sc);
chiR = (vR[Xn] - Sc)*(sr - Sc)/(SaR + sr - TWO_F*Sc);
#endif
nuL = (SaL + sl)/(fabs(SaL) + fabs(sl));
nuR = (SaR + sr)/(fabs(SaR) + fabs(sr));
nuLR = (SaL + SaR)/(fabs(SaL) + fabs(SaR));
if (fabs(SaR - SaL) > 1.e-9*fabs(sr-sl)) {
dL(k,j,i) = HALF_F*(chiL*nuL - chiL*nuLR)
+ HALF_F*(fabs(SaL) - nuLR*SaL);
dR(k,j,i) = HALF_F*(chiR*nuR - chiR*nuLR)
+ HALF_F*(fabs(SaR) - nuLR*SaR);
aL(k,j,i) = HALF_F*(ONE_F + nuLR);
aR(k,j,i) = HALF_F*(ONE_F - nuLR);
} else { // HLLC, degenerate limit Bx -> 0
dL(k,j,i) = HALF_F*chiL*nuL + HALF_F*fabs(SaL);
dR(k,j,i) = HALF_F*chiR*nuR + HALF_F*fabs(SaR);
aL(k,j,i) = HALF_F;
aR(k,j,i) = HALF_F;
}
real ar = std::fmax(ZERO_F, sr);
real al = std::fmin(ZERO_F, sl);
scrh = ONE_F/(ar - al);
// HLL diffusion coefficients
if (revert_to_hll) {
aL(k,j,i) = ar*scrh;
aR(k,j,i) = -al*scrh;
dR(k,j,i) = -al*ar*scrh;
dL(k,j,i) = dR(k,j,i);
}
// Lax-Friedrichs diffusion coefficients
if(0) {
real lambda = std::fmax(sr,sl);
aL(k,j,i) = HALF_F;
aR(k,j,i) = HALF_F;
dR(k,j,i) = HALF_F*lambda;
dL(k,j,i) = HALF_F*lambda;
}
#if COMPONENTS > 1
EXPAND( Et(k,j,i) = -st*(ar*vL[Xt] - al*vR[Xt])*scrh; ,
,
Eb(k,j,i) = -sb*(ar*vL[Xb] - al*vR[Xb])*scrh; );
#endif
}
#endif //HYDRO_MHDSOLVERS_STOREFLUX_HPP_