Program Listing for File calcNonidealEMF.cpp
↰ Return to documentation for file (hydro/electromotiveforce/calcNonidealEMF.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 nonideal MHD
void ElectroMotiveForce::CalcNonidealEMF(real t) {
idfx::pushRegion("ElectroMotiveForce::CalcNonidealEMF");
#if MHD == YES
// Corned EMFs
IdefixArray3D<real> ex = this->ex;
IdefixArray3D<real> ey = this->ey;
IdefixArray3D<real> ez = this->ez;
IdefixArray4D<real> J = hydro->J;
IdefixArray4D<real> Vs = hydro->Vs;
IdefixArray4D<real> Vc = hydro->Vc;
// These arrays have been previously computed in calcParabolicFlux
IdefixArray3D<real> etaArr = hydro->etaOhmic;
IdefixArray3D<real> xAmbiArr = hydro->xAmbipolar;
// these two are required to ensure that the type is captured by KOKKOS_LAMBDA
HydroModuleStatus resistivity = hydro->resistivityStatus.status;
HydroModuleStatus ambipolar = hydro->ambipolarStatus.status;
bool haveResistivity{false};
bool haveAmbipolar{false};
if(data->rklCycle) {
haveResistivity = hydro->resistivityStatus.isRKL;
haveAmbipolar = hydro->ambipolarStatus.isRKL;
} else {
haveResistivity = hydro->resistivityStatus.isExplicit;
haveAmbipolar = hydro->ambipolarStatus.isExplicit;
}
real etaConstant = hydro->etaO;
real xAConstant = hydro->xA;
idefix_for("CalcNIEMF",
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 Bx1, Bx2, Bx3;
real Jx1, Jx2, Jx3;
real eta, xA;
// CT_EMF_ArithmeticAverage (emf, 0.25);
if(resistivity == Constant)
eta = etaConstant;
if(ambipolar == Constant)
xA = xAConstant;
#if DIMENSIONS == 3
// -----------------------
// X1 EMF Component
// -----------------------
Jx1 = J(IDIR,k,j,i);
// Ohmic resistivity
if(haveResistivity) {
if(resistivity == UserDefFunction) eta = AVERAGE_3D_YZ(etaArr,k,j,i);
ex(k,j,i) += eta * Jx1;
}
// Ambipolar diffusion
if(haveAmbipolar) {
if(ambipolar == UserDefFunction) xA = AVERAGE_3D_YZ(xAmbiArr,k,j,i);
Bx1 = AVERAGE_4D_XYZ(Vs, BX1s, k,j,i+1);
Bx2 = AVERAGE_4D_Z(Vs, BX2s, k, j, i);
Bx3 = AVERAGE_4D_Y(Vs, BX3s, k, j, i);
// Jx1 is already defined above
Jx2 = AVERAGE_4D_XY(J, JDIR, k, j, i+1);
Jx3 = AVERAGE_4D_XZ(J, KDIR, k, j, i+1);
real JdotB = (Jx1*Bx1 + Jx2*Bx2 + Jx3*Bx3);
real BdotB = (Bx1*Bx1 + Bx2*Bx2 + Bx3*Bx3);
ex(k,j,i) += xA * (BdotB*Jx1 - JdotB * Bx1);
}
// -----------------------
// X2 EMF Component
// -----------------------
Jx2 = J(JDIR,k,j,i);
// Ohmic resistivity
if(haveResistivity) {
if(resistivity == UserDefFunction) eta = AVERAGE_3D_XZ(etaArr,k,j,i);
ey(k,j,i) += eta * Jx2;
}
// Ambipolar diffusion
if(haveAmbipolar) {
if(ambipolar == UserDefFunction) xA = AVERAGE_3D_XZ(xAmbiArr,k,j,i);
Bx1 = AVERAGE_4D_Z(Vs, BX1s, k, j, i);
Bx2 = AVERAGE_4D_XYZ(Vs, BX2s, k, j+1, i);
Bx3 = AVERAGE_4D_X(Vs, BX3s, k, j, i);
// Jx2 is already defined above
Jx1 = AVERAGE_4D_XY(J, IDIR, k, j+1, i);
Jx3 = AVERAGE_4D_YZ(J, KDIR, k, j+1, i);
real JdotB = (Jx1*Bx1 + Jx2*Bx2 + Jx3*Bx3);
real BdotB = (Bx1*Bx1 + Bx2*Bx2 + Bx3*Bx3);
ey(k,j,i) += xA * (BdotB*Jx2 - JdotB * Bx2);
}
#endif
// -----------------------
// X3 EMF Component
// -----------------------
Jx3 = J(KDIR,k,j,i);
// Ohmic resistivity
if(haveResistivity) {
if(resistivity == UserDefFunction) eta = AVERAGE_3D_XY(etaArr,k,j,i);
ez(k,j,i) += eta * Jx3;
}
// Ambipolar diffusion
if(haveAmbipolar) {
if(ambipolar == UserDefFunction) xA = AVERAGE_3D_XY(xAmbiArr,k,j,i);
Bx1 = AVERAGE_4D_Y(Vs, BX1s, k, j, i);
#if DIMENSIONS >= 2
Bx2 = AVERAGE_4D_X(Vs, BX2s, k, j, i);
#else
#if COMPONENTS >= 2
Bx2 = AVERAGE_4D_XY(Vc, BX2, k, j, i);
#else
Bx2 = 0.0;
#endif
#endif
#if DIMENSIONS == 3
Bx3 = AVERAGE_4D_XYZ(Vs, BX3s, k+1, j, i);
#else
#if COMPONENTS == 3
Bx3 = AVERAGE_4D_XY(Vc, BX3, k, j, i);
#else
Bx3 = 0.0;
#endif
#endif
// Jx3 is already defined above
#if DIMENSIONS == 3
Jx1 = AVERAGE_4D_XZ(J, IDIR, k+1, j, i);
Jx2 = AVERAGE_4D_YZ(J, JDIR, k+1, j, i);
#else
Jx1 = AVERAGE_4D_X(J, IDIR, k, j, i);
Jx2 = AVERAGE_4D_Y(J, JDIR, k, j, i);
#endif
real JdotB = (Jx1*Bx1 + Jx2*Bx2 + Jx3*Bx3);
real BdotB = (Bx1*Bx1 + Bx2*Bx2 + Bx3*Bx3);
ez(k,j,i) += xA * (BdotB * Jx3 - JdotB * Bx3);
}
}
);
#endif
idfx::popRegion();
}