Program Listing for File shockFlattening.cpp
↰ Return to documentation for file (hydro/shockFlattening.cpp
)
// ***********************************************************************************
// 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
// ***********************************************************************************
#include "dataBlock.hpp"
#include "hydro.hpp"
#include "shockFlattening.hpp"
ShockFlattening::ShockFlattening(Hydro *h, real smoothing) {
hydro = h;
flagArray = IdefixArray3D<FlagShock>("flagArray",h->data->np_tot[KDIR],
h->data->np_tot[JDIR],
h->data->np_tot[IDIR]);
this->isActive = true;
this->smoothing = smoothing;
}
void ShockFlattening::FindShock() {
idfx::pushRegion("ShockFlattening::FindShock");
auto flags = flagArray;
auto Vc = hydro->Vc;
real smoothing = this->smoothing;
#if GEOMETRY == CARTESIAN
auto dx1 = hydro->data->dx[IDIR];
auto dx2 = hydro->data->dx[JDIR];
auto dx3 = hydro->data->dx[KDIR];
#else
auto Ax1 = hydro->data->A[IDIR];
auto Ax2 = hydro->data->A[JDIR];
auto Ax3 = hydro->data->A[KDIR];
auto dV = hydro->data->dV;
#endif
#ifdef ISOTHERMAL
auto cs = hydro->isoSoundSpeedArray;
HydroModuleStatus haveIsoCs = hydro->haveIsoSoundSpeed;
real csIso = hydro->isoSoundSpeed;
#endif
auto beg = hydro->data->beg;
auto end = hydro->data->end;
idefix_for("findshocks",
beg[KDIR]-KOFFSET, end[KDIR]+KOFFSET,
beg[JDIR]-JOFFSET, end[JDIR]+JOFFSET,
beg[IDIR]-IOFFSET, end[IDIR]+IOFFSET,
KOKKOS_LAMBDA(int k, int j, int i) {
flags(k,j,i) = FlagShock::None;
#if GEOMETRY == CARTESIAN
real divV = D_EXPAND( (Vc(VX1,k,j,i+1) - Vc(VX1,k,j,i-1))/(2*dx1(i)) ,
+ (Vc(VX2,k,j+1,i) - Vc(VX2,k,j-1,i))/(2*dx2(j)) ,
+ (Vc(VX3,k+1,j,i) - Vc(VX3,k-1,j,i))/(2*dx3(k)) );
#else
real divV = D_EXPAND( (Vc(VX1,k,j,i+1) + Vc(VX1,k,j,i))*Ax1(k,j,i+1) -
(Vc(VX1,k,j,i-1) + Vc(VX1,k,j,i))*Ax1(k,j,i) ,
+ (Vc(VX2,k,j+1,i) + Vc(VX2,k,j,i))*Ax2(k,j+1,i) -
(Vc(VX2,k,j-1,i) + Vc(VX2,k,j,i))*Ax2(k,j,i) ,
+ (Vc(VX3,k+1,j,i) + Vc(VX3,k,j,i))*Ax3(k+1,j,i) -
(Vc(VX3,k-1,j,i) + Vc(VX3,k,j,i))*Ax3(k,j,i) );
divV = 0.5*divV/dV(k,j,i);
#endif
if(divV<ZERO_F) {
#ifdef ISOTHERMAL
real pmin, gradP;
if(haveIsoCs == UserDefFunction) {
pmin = Vc(RHO,k,j,i)*cs(k,j,i)*cs(k,j,i);
pmin = FMIN(pmin,Vc(RHO,k,j,i+1)*cs(k,j,i+1)*cs(k,j,i+1));
pmin = FMIN(pmin,Vc(RHO,k,j,i-1)*cs(k,j,i-1)*cs(k,j,i-1));
gradP = FABS(Vc(RHO,k,j,i+1)*cs(k,j,i+1)*cs(k,j,i+1) -
Vc(RHO,k,j,i-1)*cs(k,j,i-1)*cs(k,j,i-1));
#if DIMENSIONS >= 2
pmin = FMIN(pmin,Vc(RHO,k,j+1,i)*cs(k,j+1,i)*cs(k,j+1,i));
pmin = FMIN(pmin,Vc(RHO,k,j-1,i)*cs(k,j-1,i)*cs(k,j-1,i));
gradP += FABS(Vc(RHO,k,j+1,i)*cs(k,j+1,i)*cs(k,j+1,i) -
Vc(RHO,k,j-1,i)*cs(k,j-1,i)*cs(k,j-1,i));
#endif
#if DIMENSIONS == 3
pmin = FMIN(pmin,Vc(RHO,k+1,j,i)*cs(k+1,j,i)*cs(k+1,j,i));
pmin = FMIN(pmin,Vc(RHO,k-1,j,i)*cs(k-1,j,i)*cs(k-1,j,i));
gradP += FABS(Vc(RHO,k+1,j,i)*cs(k+1,j,i)*cs(k+1,j,i) -
Vc(RHO,k-1,j,i)*cs(k-1,j,i)*cs(k-1,j,i));
#endif
} else {
pmin = Vc(RHO,k,j,i)*csIso*csIso;
pmin = FMIN(pmin,Vc(RHO,k,j,i+1)*csIso*csIso);
pmin = FMIN(pmin,Vc(RHO,k,j,i-1)*csIso*csIso);
gradP = FABS(Vc(RHO,k,j,i+1)*csIso*csIso -
Vc(RHO,k,j,i-1)*csIso*csIso);
#if DIMENSIONS >= 2
pmin = FMIN(pmin,Vc(RHO,k,j+1,i)*csIso*csIso);
pmin = FMIN(pmin,Vc(RHO,k,j-1,i)*csIso*csIso);
gradP += FABS(Vc(RHO,k,j+1,i)*csIso*csIso -
Vc(RHO,k,j-1,i)*csIso*csIso);
#endif
#if DIMENSIONS == 3
pmin = FMIN(pmin,Vc(RHO,k+1,j,i)*csIso*csIso);
pmin = FMIN(pmin,Vc(RHO,k-1,j,i)*csIso*csIso);
gradP += FABS(Vc(RHO,k+1,j,i)*csIso*csIso -
Vc(RHO,k-1,j,i)*csIso*csIso);
#endif
}
#else // ISOTHERMAL
real pmin = Vc(PRS,k,j,i);
pmin = FMIN(pmin,Vc(PRS,k,j,i+1));
pmin = FMIN(pmin,Vc(PRS,k,j,i-1));
real gradP = FABS(Vc(PRS,k,j,i+1) - Vc(PRS,k,j,i-1));
#if DIMENSIONS >= 2
pmin = FMIN(pmin,Vc(PRS,k,j+1,i));
pmin = FMIN(pmin,Vc(PRS,k,j-1,i));
gradP += FABS(Vc(PRS,k,j+1,i) - Vc(PRS,k,j-1,i));
#endif
#if DIMENSIONS == 3
pmin = FMIN(pmin,Vc(PRS,k+1,j,i));
pmin = FMIN(pmin,Vc(PRS,k-1,j,i));
gradP += FABS(Vc(PRS,k+1,j,i) - Vc(PRS,k-1,j,i));
#endif
#endif // ISOTHERMAL
if(gradP > smoothing*pmin) {
flags(k,j,i) = FlagShock::Shock;
}
}
});
idfx::popRegion();
}