Program Listing for File calcCornerEmf.cpp
↰ Return to documentation for file (hydro/electromotiveforce/calcCornerEmf.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 "hydro.hpp"
#include "dataBlock.hpp"
// Compute Corner EMFs from the one stored in the Riemann step
void ElectroMotiveForce::CalcCornerEMF(real t) {
idfx::pushRegion("ElectroMotiveForce::CalcCornerEMF");
#if MHD == YES && DIMENSIONS >= 2
if(averaging==arithmetic) {
CalcArithmeticAverage();
}
if(averaging==uct_contact||averaging==uct0) {
CalcCellCenteredEMF();
if(averaging==uct0) {
CalcUCT0Average();
} else {
CalcContactAverage();
}
}
if(averaging==uct_hll || averaging==uct_hlld) {
CalcRiemannAverage();
}
#endif // MHD
idfx::popRegion();
}
// Compute Corner EMFs from arithmetic averages
void ElectroMotiveForce::CalcArithmeticAverage() {
idfx::pushRegion("ElectroMotiveForce::CalcCornerEMF");
// Corned EMFs
IdefixArray3D<real> ex = this->ex;
IdefixArray3D<real> ey = this->ey;
IdefixArray3D<real> ez = this->ez;
// Face-centered EMFs
IdefixArray3D<real> exj = this->exj;
IdefixArray3D<real> exk = this->exk;
IdefixArray3D<real> eyi = this->eyi;
IdefixArray3D<real> eyk = this->eyk;
IdefixArray3D<real> ezi = this->ezi;
IdefixArray3D<real> ezj = this->ezj;
#if MHD == YES && DIMENSIONS >= 2
idefix_for("CalcArithmeticAverage",
data->beg[KDIR],data->end[KDIR]+KOFFSET,
data->beg[JDIR],data->end[JDIR]+JOFFSET,
data->beg[IDIR],data->end[IDIR]+IOFFSET,
KOKKOS_LAMBDA (int k, int j, int i) {
// CT_EMF_ArithmeticAverage (emf, 0.25);
real w = ONE_FOURTH_F;
#if DIMENSIONS == 3
ex(k,j,i) = w * (exj(k,j,i) + exj(k-1,j,i) + exk(k,j,i) + exk(k,j-1,i));
ey(k,j,i) = w * (eyi(k,j,i) + eyi(k-1,j,i) + eyk(k,j,i) + eyk(k,j,i-1));
#endif
#if DIMENSIONS >= 2
ez(k,j,i) = w * (ezi(k,j,i) + ezi(k,j-1,i) + ezj(k,j,i) + ezj(k,j,i-1));
#else
ez(k,j,i) = w * (TWO_F*ezi(k,j,i) + ezj(k,j,i) + ezj(k,j,i-1));
#endif
});
#endif // MHD
idfx::popRegion();
}
void ElectroMotiveForce::CalcCellCenteredEMF() {
idfx::pushRegion("ElectroMotiveForce::CalcCellCenteredEMF");
IdefixArray4D<real> Vc = hydro->Vc;
// cell-centered EMFs
IdefixArray3D<real> Ex1 = this->Ex1;
IdefixArray3D<real> Ex2 = this->Ex2;
IdefixArray3D<real> Ex3 = this->Ex3;
#if MHD == YES && DIMENSIONS >= 2
idefix_for("CalcCenterEMF",
0,data->np_tot[KDIR],
0,data->np_tot[JDIR],
0,data->np_tot[IDIR],
KOKKOS_LAMBDA (int k, int j, int i) {
[[maybe_unused]] real vx1, vx2, vx3;
[[maybe_unused]] real Bx1, Bx2, Bx3;
vx1 = vx2 = vx3 = ZERO_F;
Bx1 = Bx2 = Bx3 = ZERO_F;
EXPAND( vx1 = Vc(VX1,k,j,i); ,
vx2 = Vc(VX2,k,j,i); ,
vx3 = Vc(VX3,k,j,i); )
EXPAND( Bx1 = Vc(BX1,k,j,i); ,
Bx2 = Vc(BX2,k,j,i); ,
Bx3 = Vc(BX3,k,j,i); )
// -- Compute inductive electric field
#if DIMENSIONS == 3
Ex1(k,j,i) = (vx3*Bx2 - vx2*Bx3);
Ex2(k,j,i) = (vx1*Bx3 - vx3*Bx1);
#endif
Ex3(k,j,i) = (vx2*Bx1 - vx1*Bx2);
}
);
#endif // MHD
idfx::popRegion();
}
void ElectroMotiveForce::CalcUCT0Average() {
idfx::pushRegion("ElectroMotiveForce::CalcUCT0Average");
// Corned EMFs
IdefixArray3D<real> ex = this->ex;
IdefixArray3D<real> ey = this->ey;
IdefixArray3D<real> ez = this->ez;
// Face-centered EMFs
IdefixArray3D<real> exj = this->exj;
IdefixArray3D<real> exk = this->exk;
IdefixArray3D<real> eyi = this->eyi;
IdefixArray3D<real> eyk = this->eyk;
IdefixArray3D<real> ezi = this->ezi;
IdefixArray3D<real> ezj = this->ezj;
// cell-centered EMFs
IdefixArray3D<real> Ex1 = this->Ex1;
IdefixArray3D<real> Ex2 = this->Ex2;
IdefixArray3D<real> Ex3 = this->Ex3;
#if MHD == YES && DIMENSIONS >= 2
idefix_for("CalcUCT0FaceCentered",
data->beg[KDIR]-KOFFSET,data->end[KDIR]+KOFFSET,
data->beg[JDIR]-JOFFSET,data->end[JDIR]+JOFFSET,
data->beg[IDIR]-IOFFSET,data->end[IDIR]+IOFFSET,
KOKKOS_LAMBDA (int k, int j, int i) {
#if DIMENSIONS == 3
exj(k,j,i) *= TWO_F;
exk(k,j,i) *= TWO_F;
eyi(k,j,i) *= TWO_F;
eyk(k,j,i) *= TWO_F;
exj(k,j,i) -= HALF_F*(Ex1(k,j-1,i) + Ex1(k,j,i));
exk(k,j,i) -= HALF_F*(Ex1(k-1,j,i) + Ex1(k,j,i));
eyi(k,j,i) -= HALF_F*(Ex2(k,j,i-1) + Ex2(k,j,i));
eyk(k,j,i) -= HALF_F*(Ex2(k-1,j,i) + Ex2(k,j,i));
#endif
ezi(k,j,i) *= TWO_F;
ezj(k,j,i) *= TWO_F;
ezi(k,j,i) -= HALF_F*(Ex3(k,j,i-1) + Ex3(k,j,i));
ezj(k,j,i) -= HALF_F*(Ex3(k,j-1,i) + Ex3(k,j,i));
}
);
idefix_for("CalcUCT0CornerEMF",
data->beg[KDIR],data->end[KDIR]+KOFFSET,
data->beg[JDIR],data->end[JDIR]+JOFFSET,
data->beg[IDIR],data->end[IDIR]+IOFFSET,
KOKKOS_LAMBDA (int k, int j, int i) {
// CT_EMF_ArithmeticAverage (emf, 0.25);
const real w = ONE_FOURTH_F;
#if DIMENSIONS == 3
ex(k,j,i) = w * (exj(k,j,i) + exj(k-1,j,i) + exk(k,j,i) + exk(k,j-1,i));
ey(k,j,i) = w * (eyi(k,j,i) + eyi(k-1,j,i) + eyk(k,j,i) + eyk(k,j,i-1));
#endif
#if DIMENSIONS >= 2
ez(k,j,i) = w * (ezi(k,j,i) + ezi(k,j-1,i) + ezj(k,j,i) + ezj(k,j,i-1));
#else
ez(k,j,i) = w * (TWO_F*ezi(k,j,i) + ezj(k,j,i) + ezj(k,j,i-1));
#endif
}
);
#endif
idfx::popRegion();
}
void ElectroMotiveForce::CalcContactAverage() {
idfx::pushRegion("ElectroMotiveForce::CalcContactAverage");
// Corned EMFs
IdefixArray3D<real> ex = this->ex;
IdefixArray3D<real> ey = this->ey;
IdefixArray3D<real> ez = this->ez;
// Face-centered EMFs
IdefixArray3D<real> exj = this->exj;
IdefixArray3D<real> exk = this->exk;
IdefixArray3D<real> eyi = this->eyi;
IdefixArray3D<real> eyk = this->eyk;
IdefixArray3D<real> ezi = this->ezi;
IdefixArray3D<real> ezj = this->ezj;
// cell-centered EMFs
IdefixArray3D<real> Ex1 = this->Ex1;
IdefixArray3D<real> Ex2 = this->Ex2;
IdefixArray3D<real> Ex3 = this->Ex3;
// sign of contact discontinuity
IdefixArray3D<real> wsx = this->svx;
IdefixArray3D<real> wsy = this->svy;
IdefixArray3D<real> wsz = this->svz;
#if MHD == YES && DIMENSIONS >= 2
idefix_for("EMF_Integrate_to_Corner",
data->beg[KDIR],data->end[KDIR]+KOFFSET,
data->beg[JDIR],data->end[JDIR]+JOFFSET,
data->beg[IDIR],data->end[IDIR]+IOFFSET,
KOKKOS_LAMBDA (int k, int j, int i) {
real ez_l2 = (1-wsx(k,j-1,i)) * (ezj(k,j,i) - Ex3(k,j-1,i)) +
( wsx(k,j-1,i)) * (ezj(k,j,i-1) - Ex3(k,j-1,i-1));
real ez_r2 = (1-wsx(k,j,i)) * (ezj(k,j,i) - Ex3(k,j,i)) +
( wsx(k,j,i)) * (ezj(k,j,i-1) - Ex3(k,j,i-1));
real ez_l1 = (1-wsy(k,j,i-1)) * (ezi(k,j,i) - Ex3(k,j,i-1)) +
( wsy(k,j,i-1)) * (ezi(k,j-1,i) - Ex3(k,j-1,i-1));
real ez_r1 = (1-wsy(k,j,i)) * (ezi(k,j,i) - Ex3(k,j,i)) +
( wsy(k,j,i)) * (ezi(k,j-1,i) - Ex3(k,j-1,i));
ez(k,j,i) = ONE_FOURTH_F * (ez_l2 + ez_r2 + ez_l1 + ez_r1 +
#if DIMENSIONS >= 2
ezi(k,j,i) + ezi(k,j-1,i) + ezj(k,j,i) + ezj(k,j,i-1)
#else
TWO_F*ezi(k,j,i) + ezj(k,j,i) + ezj(k,j,i-1)
#endif
);
#if DIMENSIONS == 3
real ex_l3 = (1-wsy(k-1,j,i)) * (exk(k,j,i) - Ex1(k-1,j,i)) +
( wsy(k-1,j,i)) * (exk(k,j-1,i) - Ex1(k-1,j-1,i));
real ex_r3 = (1-wsy(k,j,i)) * (exk(k,j,i) - Ex1(k,j,i)) +
( wsy(k,j,i)) * (exk(k,j-1,i) - Ex1(k,j-1,i));
real ex_l2 = (1-wsz(k,j-1,i)) * (exj(k,j,i) - Ex1(k,j-1,i)) +
( wsz(k,j-1,i)) * (exj(k-1,j,i) - Ex1(k-1,j-1,i));
real ex_r2 = (1-wsz(k,j,i)) * (exj(k,j,i) - Ex1(k,j,i)) +
( wsz(k,j,i)) * (exj(k-1,j,i) - Ex1(k-1,j,i));
ex(k,j,i) = ONE_FOURTH_F * (ex_l3 + ex_r3 + ex_l2 + ex_r2 +
exj(k,j,i) + exj(k-1,j,i) + exk(k,j,i) + exk(k,j-1,i) );
real ey_l3 = (1-wsx(k-1,j,i)) * (eyk(k,j,i) - Ex2(k-1,j,i)) +
( wsx(k-1,j,i)) * (eyk(k,j,i-1) - Ex2(k-1,j,i-1));
real ey_r3 = (1-wsx(k,j,i)) * (eyk(k,j,i) - Ex2(k,j,i)) +
( wsx(k,j,i)) * (eyk(k,j,i-1) - Ex2(k,j,i-1));
real ey_l1 = (1-wsz(k,j,i-1)) * (eyi(k,j,i) - Ex2(k,j,i-1)) +
( wsz(k,j,i-1)) * (eyi(k-1,j,i) - Ex2(k-1,j,i-1));
real ey_r1 = (1-wsz(k,j,i)) * (eyi(k,j,i) - Ex2(k,j,i)) +
( wsz(k,j,i)) * (eyi(k-1,j,i) - Ex2(k-1,j,i));
ey(k,j,i) = ONE_FOURTH_F * (ey_l3 + ey_r3 + ey_l1 + ey_r1 +
eyi(k,j,i) + eyi(k-1,j,i) + eyk(k,j,i) + eyk(k,j,i-1));
#endif
});
/*
idefix_for("EMF_Integrate to Corner",
data->beg[KDIR]-KOFFSET,data->end[KDIR]+KOFFSET,
data->beg[JDIR]-JOFFSET,data->end[JDIR]+JOFFSET,
data->beg[IDIR]-IOFFSET,data->end[IDIR]+IOFFSET,
KOKKOS_LAMBDA (int k, int j, int i) {
[[maybe_unused]] int iu, ju, ku;
D_EXPAND( int sx; ,
int sy; ,
int sz; )
D_EXPAND( sx = svx(k,j,i); ,
sy = svy(k,j,i); ,
sz = svz(k,j,i); )
D_EXPAND( iu = sx > 0 ? i-1:i; , // -- upwind index
ju = sy > 0 ? j-1:j; ,
ku = sz > 0 ? k-1:k; )
// Span X - Faces: dEz/dy, dEy/dz
// Reminder:
// - Ez(k,j,i) is centered on (i ,j ,k)
// - svx(k,j,i) is centered on (i-1/2,j ,k)
// - ezj(k,j,i) is centered on (i ,j-1/2,k)
// - ezi(k,j,i) is centered on (i-1/2,j ,k)
// - ez(k,j,i) is centered on (i-1/2,j-1/2,k)
#define DEX_DYP(k,j,i) (exj(k,j+1,i) - Ex1(k,j,i))
#define DEX_DZP(k,j,i) (exk(k+1,j,i) - Ex1(k,j,i))
#define DEY_DXP(k,j,i) (eyi(k,j,i+1) - Ex2(k,j,i))
#define DEY_DZP(k,j,i) (eyk(k+1,j,i) - Ex2(k,j,i))
#define DEZ_DXP(k,j,i) (ezi(k,j,i+1) - Ex3(k,j,i))
#define DEZ_DYP(k,j,i) (ezj(k,j+1,i) - Ex3(k,j,i))
#define DEX_DYM(k,j,i) (Ex1(k,j,i) - exj(k,j,i))
#define DEX_DZM(k,j,i) (Ex1(k,j,i) - exk(k,j,i))
#define DEY_DXM(k,j,i) (Ex2(k,j,i) - eyi(k,j,i))
#define DEY_DZM(k,j,i) (Ex2(k,j,i) - eyk(k,j,i))
#define DEZ_DXM(k,j,i) (Ex3(k,j,i) - ezi(k,j,i))
#define DEZ_DYM(k,j,i) (Ex3(k,j,i) - ezj(k,j,i))
if (sx == 0) {
ezAtomic(k,j+1,i) += HALF_F*(DEZ_DYP(k,j,i-1) + DEZ_DYP(k,j,i));
ezAtomic(k,j ,i) -= HALF_F*(DEZ_DYM(k,j,i-1) + DEZ_DYM(k,j,i));
#if DIMENSIONS == 3
eyAtomic(k+1,j,i) += HALF_F*(DEY_DZP(k,j,i-1) + DEY_DZP(k,j,i));
eyAtomic(k ,j,i) -= HALF_F*(DEY_DZM(k,j,i-1) + DEY_DZM(k,j,i));
#endif
} else {
ezAtomic(k,j+1,i) += DEZ_DYP(k,j,iu);
ezAtomic(k,j, i) -= DEZ_DYM(k,j,iu);
#if DIMENSIONS == 3
eyAtomic(k+1,j,i) += DEY_DZP(k,j,iu);
eyAtomic(k ,j,i) -= DEY_DZM(k,j,iu);
#endif
}
// Span Y - Faces: dEz/dx, dEx/dz
if (sy == 0) {
ezAtomic(k,j,i+1) += HALF_F*(DEZ_DXP(k,j-1,i) + DEZ_DXP(k,j,i));
ezAtomic(k,j,i ) -= HALF_F*(DEZ_DXM(k,j-1,i) + DEZ_DXM(k,j,i));
#if DIMENSIONS == 3
exAtomic(k+1,j,i) += HALF_F*(DEX_DZP(k,j-1,i) + DEX_DZP(k,j,i));
exAtomic(k ,j,i) -= HALF_F*(DEX_DZM(k,j-1,i) + DEX_DZM(k,j,i));
#endif
} else {
ezAtomic(k,j,i+1) += DEZ_DXP(k,ju,i);
ezAtomic(k,j,i ) -= DEZ_DXM(k,ju,i);
#if DIMENSIONS == 3
exAtomic(k+1,j,i) += DEX_DZP(k,ju,i);
exAtomic(k ,j,i) -= DEX_DZM(k,ju,i);
#endif
}
// Span Z - Faces: dEx/dy, dEy/dx
#if DIMENSIONS == 3
if (sz == 0) {
exAtomic(k,j+1,i ) += HALF_F*(DEX_DYP(k-1,j,i) + DEX_DYP(k,j,i));
exAtomic(k,j ,i ) -= HALF_F*(DEX_DYM(k-1,j,i) + DEX_DYM(k,j,i));
eyAtomic(k,j ,i+1) += HALF_F*(DEY_DXP(k-1,j,i) + DEY_DXP(k,j,i));
eyAtomic(k,j ,i ) -= HALF_F*(DEY_DXM(k-1,j,i) + DEY_DXM(k,j,i));
} else {
exAtomic(k,j+1,i ) += DEX_DYP(ku,j,i);
exAtomic(k,j ,i ) -= DEX_DYM(ku,j,i);
eyAtomic(k,j ,i+1) += DEY_DXP(ku,j,i);
eyAtomic(k,j ,i ) -= DEY_DXM(ku,j,i);
}
#endif // DIMENSIONS
});
idefix_for("EMF_Renormalize",
data->beg[KDIR],data->end[KDIR]+KOFFSET,
data->beg[JDIR],data->end[JDIR]+JOFFSET,
data->beg[IDIR],data->end[IDIR]+IOFFSET,
KOKKOS_LAMBDA (int k, int j, int i) {
#if DIMENSIONS == 3
ex(k,j,i) *= ONE_FOURTH_F;
ey(k,j,i) *= ONE_FOURTH_F;
#endif
ez(k,j,i) *= ONE_FOURTH_F;
}
);
#undef DEX_DYP
#undef DEX_DZP
#undef DEY_DXP
#undef DEY_DZP
#undef DEZ_DXP
#undef DEZ_DYP
#undef DEX_DYM
#undef DEX_DZM
#undef DEY_DXM
#undef DEY_DZM
#undef DEZ_DXM
#undef DEZ_DYM
*/
#endif // MHD
idfx::popRegion();
}