Program Listing for File addSourceTerms.cpp
↰ Return to documentation for file (hydro/addSourceTerms.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"
#include "fargo.hpp"
// Add source terms
void Hydro::AddSourceTerms(real t, real dt) {
idfx::pushRegion("Hydro::AddSourceTerms");
IdefixArray4D<real> Uc = this->Uc;
IdefixArray4D<real> Vc = this->Vc;
IdefixArray1D<real> x1 = data->x[IDIR];
IdefixArray1D<real> x2 = data->x[JDIR];
IdefixArray2D<real> fargoVelocity = data->fargo.meanVelocity;
#ifdef ISOTHERMAL
IdefixArray3D<real> csIsoArr = this->isoSoundSpeedArray;
#endif
#if GEOMETRY == SPHERICAL
IdefixArray1D<real> sinx2 = data->sinx2;
IdefixArray1D<real> tanx2 = data->tanx2;
IdefixArray1D<real> rt = data->rt;
#endif
#ifdef ISOTHERMAL
[[maybe_unused]] real csIso = this->isoSoundSpeed;
[[maybe_unused]] HydroModuleStatus haveIsoCs = this->haveIsoSoundSpeed;
#endif
bool haveRotation = this->haveRotation;
real OmegaZ = this->OmegaZ;
// Fargo
bool haveFargo = data->haveFargo;
// shearing box (only with fargo&cartesian)
[[maybe_unused]] real sbS = this->sbS;
if(haveUserSourceTerm) userSourceTerm(*data, t, dt);
idefix_for("AddSourceTerms",
data->beg[KDIR],data->end[KDIR],
data->beg[JDIR],data->end[JDIR],
data->beg[IDIR],data->end[IDIR],
KOKKOS_LAMBDA (int k, int j, int i) {
#if GEOMETRY == CARTESIAN
// Manually add Coriolis force in cartesian geometry. Otherwise
// Coriolis is treated as a modification to the fluxes
if(haveRotation) {
Uc(MX1,k,j,i) += TWO_F * dt * Vc(RHO,k,j,i) * OmegaZ * Vc(VX2,k,j,i);
Uc(MX2,k,j,i) += - TWO_F * dt * Vc(RHO,k,j,i) * OmegaZ * Vc(VX1,k,j,i);
}
if(haveFargo) {
Uc(MX1,k,j,i) += TWO_F * dt * Vc(RHO,k,j,i) * OmegaZ * sbS * x1(i);
}
#endif
// fetch fargo velocity when required
[[maybe_unused]] real fargoV = ZERO_F;
if(haveFargo) {
// No source term when CARTESIAN+Fargo
#if GEOMETRY == POLAR
fargoV = fargoVelocity(k,i);
#elif GEOMETRY == SPHERICAL
fargoV = fargoVelocity(j,i);
#endif
}
#if GEOMETRY == CYLINDRICAL
#if COMPONENTS == 3
real vphi,Sm;
vphi = Vc(iVPHI,k,j,i);
if(haveRotation) vphi += OmegaZ*x1(i);
Sm = Vc(RHO,k,j,i) * vphi*vphi; // Centrifugal
// Presure (because pressure is included in the flux, additional source terms arise)
#ifdef ISOTHERMAL
real c2Iso;
if(haveIsoCs == UserDefFunction) {
c2Iso = csIsoArr(k,j,i);
c2Iso = c2Iso*c2Iso;
} else {
c2Iso = csIso*csIso;
}
Sm += Vc(RHO,k,j,i)*c2Iso;
#else
Sm += Vc(PRS,k,j,i);
#endif // ISOTHERMAL
#if MHD==YES
Sm -= Vc(iBPHI,k,j,i)*Vc(iBPHI,k,j,i); // Hoop stress
// Magnetic pressure
Sm += HALF_F*(EXPAND( Vc(BX1,k,j,i)*Vc(BX1,k,j,i) ,
+Vc(BX2,k,j,i)*Vc(BX2,k,j,i) ,
+Vc(BX3,k,j,i)*Vc(BX3,k,j,i) ));
#endif // MHD
Uc(MX1,k,j,i) += dt * Sm / x1(i);
#endif // COMPONENTS
#elif GEOMETRY == POLAR
real vphi,Sm;
vphi = Vc(iVPHI,k,j,i) + fargoV;
if(haveRotation) vphi += OmegaZ*x1(i);
Sm = Vc(RHO,k,j,i) * vphi*vphi; // Centrifugal
// Pressure (because we're including pressure in the flux,
// we need that to get the radial pressure gradient)
#ifdef ISOTHERMAL
real c2Iso;
if(haveIsoCs == UserDefFunction) {
c2Iso = csIsoArr(k,j,i);
c2Iso = c2Iso*c2Iso;
} else {
c2Iso = csIso*csIso;
}
Sm += Vc(RHO,k,j,i)*c2Iso;
#else
Sm += Vc(PRS,k,j,i);
#endif // ISOTHERMAL
#if MHD==YES
Sm -= Vc(iBPHI,k,j,i)*Vc(iBPHI,k,j,i); // Hoop stress
// Magnetic pressus
Sm += HALF_F*(EXPAND( Vc(BX1,k,j,i)*Vc(BX1,k,j,i) ,
+Vc(BX2,k,j,i)*Vc(BX2,k,j,i) ,
+Vc(BX3,k,j,i)*Vc(BX3,k,j,i) ));
#endif // MHD
Uc(MX1,k,j,i) += dt * Sm / x1(i);
#elif GEOMETRY == SPHERICAL
real vphi,Sm,ct;
vphi = SELECT(ZERO_F, ZERO_F, Vc(iVPHI,k,j,i))+fargoV;
if(haveRotation) vphi += OmegaZ*x1(i)*FABS(sinx2(j));
// Centrifugal
Sm = Vc(RHO,k,j,i) * (EXPAND( ZERO_F, + Vc(VX2,k,j,i)*Vc(VX2,k,j,i), + vphi*vphi));
// Pressure curvature
#ifdef ISOTHERMAL
real c2Iso;
if(haveIsoCs == UserDefFunction) {
c2Iso = csIsoArr(k,j,i);
c2Iso = c2Iso*c2Iso;
} else {
c2Iso = csIso*csIso;
}
Sm += 2.0*Vc(RHO,k,j,i)*c2Iso;
#else
Sm += 2.0*Vc(PRS,k,j,i);
#endif // ISOTHERMAL
#if MHD == YES
// Hoop stress
Sm -= EXPAND( ZERO_F ,
+ Vc(iBTH,k,j,i)*Vc(iBTH,k,j,i) ,
+ Vc(iBPHI,k,j,i)*Vc(iBPHI,k,j,i) );
// 2* mag pressure curvature
Sm += EXPAND( Vc(BX1,k,j,i)*Vc(BX1,k,j,i) ,
+Vc(BX2,k,j,i)*Vc(BX2,k,j,i) ,
+Vc(BX3,k,j,i)*Vc(BX3,k,j,i) );
#endif
Uc(MX1,k,j,i) += dt*Sm/x1(i);
#if COMPONENTS >= 2
ct = 1.0/tanx2(j);
// Centrifugal
Sm = Vc(RHO,k,j,i) * (EXPAND( ZERO_F, - Vc(iVTH,k,j,i)*Vc(iVR,k,j,i), + ct*vphi*vphi));
// Pressure curvature
#ifdef ISOTHERMAL
Sm += ct * c2Iso * Vc(RHO,k,j,i);
#else
Sm += ct * Vc(PRS,k,j,i);
#endif
#if MHD == YES
// Hoop stress
Sm += EXPAND( ZERO_F ,
+ Vc(iBTH,k,j,i)*Vc(iBR,k,j,i) ,
- ct*Vc(iBPHI,k,j,i)*Vc(iBPHI,k,j,i) );
// Magnetic pressure
Sm += HALF_F*ct*(EXPAND( Vc(BX1,k,j,i)*Vc(BX1,k,j,i) ,
+Vc(BX2,k,j,i)*Vc(BX2,k,j,i) ,
+Vc(BX3,k,j,i)*Vc(BX3,k,j,i)) );
#endif
Uc(MX2,k,j,i) += dt*Sm / rt(i);
#endif // COMPONENTS
#endif
}
);
idfx::popRegion();
}