Program Listing for File calcCurrent.cpp
↰ Return to documentation for file (hydro/calcCurrent.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 the electrical current on faces
void Hydro::CalcCurrent() {
idfx::pushRegion("Hydro::CalcCurrent");
IdefixArray4D<real> Vc = this->Vc;
IdefixArray4D<real> Vs = this->Vs;
IdefixArray4D<real> J = this->J;
IdefixArray1D<real> dx1 = data->dx[IDIR];
IdefixArray1D<real> dx2 = data->dx[JDIR];
IdefixArray1D<real> dx3 = data->dx[KDIR];
IdefixArray1D<real> r = data->x[IDIR];
IdefixArray1D<real> rm = data->xl[IDIR];
IdefixArray1D<real> th = data->x[JDIR];
#if GEOMETRY == SPHERICAL
IdefixArray1D<real> sinx2 = data->sinx2;
IdefixArray1D<real> sinx2m = data->sinx2m;
#endif
idefix_for("CalcCurrent",
KOFFSET,data->np_tot[KDIR],
JOFFSET,data->np_tot[JDIR],
IOFFSET,data->np_tot[IDIR],
KOKKOS_LAMBDA (int k, int j, int i) {
[[maybe_unused]] real Bx1_000 = ZERO_F, Bx1_0m0 = ZERO_F, Bx1_00m = ZERO_F;
[[maybe_unused]] real Bx2_000 = ZERO_F, Bx2_m00 = ZERO_F, Bx2_00m = ZERO_F;
[[maybe_unused]] real Bx3_000 = ZERO_F, Bx3_m00 = ZERO_F, Bx3_0m0 = ZERO_F;
[[maybe_unused]] real d12 = ZERO_F, d13 = ZERO_F,
d21 = ZERO_F, d23 = ZERO_F,
d31 = ZERO_F, d32 = ZERO_F;
[[maybe_unused]] real Jx = ZERO_F, Jy = ZERO_F, Jz = ZERO_F;
Bx1_000 = Vs(BX1s,k,j,i);
#if DIMENSIONS >= 2
Bx1_0m0 = Vs(BX1s,k,j-1,i);
Bx2_000 = Vs(BX2s,k,j,i);
Bx2_m00 = Vs(BX2s,k,j,i-1);
#elif COMPONENTS >= 2 // DIMENSIONS == 1 here!
Bx2_000 = Vc(BX2,k,j,i);
Bx2_m00 = Vc(BX2,k,j,i-1);
#if COMPONENTS == 3
Bx3_000 = Vc(BX3,k,j,i);
Bx3_m00 = Vc(BX3,k,j,i-1);
#endif
#endif
#if DIMENSIONS == 3
Bx1_00m = Vs(BX1s,k-1,j,i);
Bx2_00m = Vs(BX2s,k-1,j,i);
Bx3_000 = Vs(BX3s,k,j,i);
Bx3_m00 = Vs(BX3s,k,j,i-1);
Bx3_0m0 = Vs(BX3s,k,j-1,i);
#elif COMPONENTS == 3 && DIMENSIONS == 2 // DIMENSIONS 2 here
Bx3_000 = Vc(BX3,k,j,i);
Bx3_m00 = Vc(BX3,k,j,i-1);
Bx3_0m0 = Vc(BX3,k,j-1,i);
#endif
// define geometrical factors
D_EXPAND( d12 = d13 = TWO_F / (dx1(i-1)+dx1(i)); ,
d21 = d23 = TWO_F / (dx2(j-1)+dx2(j)); ,
d31 = d32 = TWO_F / (dx3(k-1)+dx3(k)); )
[[maybe_unused]] real a13Bx3_000 = Bx3_000;
[[maybe_unused]] real a13Bx3_m00 = Bx3_m00;
[[maybe_unused]] real a23Bx3_000 = Bx3_000;
[[maybe_unused]] real a23Bx3_0m0 = Bx3_0m0;
[[maybe_unused]] real a12Bx2_000 = Bx2_000;
[[maybe_unused]] real a12Bx2_m00 = Bx2_m00;
#if GEOMETRY == CYLINDRICAL
d32 = d31 = ZERO_F;
d13 = TWO_F / (FABS(r(i))*r(i) - FABS(r(i-1))*r(i-1));
#if COMPONENTS == 3
a13Bx3_000 = Bx3_000 * FABS(r(i));
a13Bx3_m00 = Bx3_m00 * FABS(r(i-1));
#endif
#elif GEOMETRY == POLAR
d23 /= r(i);
d21 /= rm(i);
d12 = TWO_F / (FABS(r(i))*r(i) - FABS(r(i-1))*r(i-1));
#if COMPONENTS >= 2
a12Bx2_000 = Bx2_000 * r(i);
a12Bx2_m00 = Bx2_m00 * r(i-1);
#endif
#elif GEOMETRY == SPHERICAL
real s = FABS(sinx2(j));
real sm = 0.5*(FABS(sinx2(j))+FABS(sinx2(j-1)));
D_EXPAND(d12 /= rm(i); d13 /= rm(i); ,
d21 /= rm(i); d23 /= r(i)*sm; ,
d32 /= r(i)*sm; d31 /= rm(i)*s; )
#if COMPONENTS >= 2
a12Bx2_000 = Bx2_000 * r(i);
a12Bx2_m00 = Bx2_m00 * r(i-1);
#endif
#if COMPONENTS == 3
a13Bx3_000 = Bx3_000 * r(i);
a13Bx3_m00 = Bx3_m00 * r(i-1);
#if DIMENSIONS >= 2
a23Bx3_000 = Bx3_000 * s;
a23Bx3_0m0 = Bx3_0m0 * FABS(sinx2(j-1));
#endif
#endif // COMPONENTS
#endif
// Compute actual current
#if COMPONENTS == 3
#if DIMENSIONS == 3
Jx += - (Bx2_000 - Bx2_00m)*d32;
Jy += + (Bx1_000 - Bx1_00m)*d31;
#endif
#if DIMENSIONS >= 2
Jx += + (a23Bx3_000 - a23Bx3_0m0)*d23;
#endif
Jy += - (a13Bx3_000 - a13Bx3_m00)*d13;
#endif
#if COMPONENTS >= 2
Jz += (a12Bx2_000 - a12Bx2_m00)*d12;
#endif
#if DIMENSIONS >= 2
Jz += - (Bx1_000 - Bx1_0m0)*d21;
#endif
// Store the beast
J(IDIR, k, j, i) = Jx;
J(JDIR, k, j, i) = Jy;
J(KDIR, k, j, i) = Jz;
}
);
// Regularize the current along the axis in cases where an axis is present.
// This feature is not yet ready, so it is commented out
//if(this->haveAxis) {
// this->myAxis.RegularizeCurrent();
//}
idfx::popRegion();
}