Skip to content

MHD - #123

Open
adamdempsey90 wants to merge 51 commits into
developfrom
dempsey/mhd
Open

MHD#123
adamdempsey90 wants to merge 51 commits into
developfrom
dempsey/mhd

Conversation

@adamdempsey90

Copy link
Copy Markdown
Collaborator

Background

This adds ideal MHD. It should work with AMR and all coordinate systems. I have tested on the magnetized blast problem in cartesian/cylindrical coordinates with/without AMR (modified the existing pgen), the Orszag-Tang vortex (new pgen), and the Brio-Wu shock tube (new input file).

The outline of new features/changed things:

  • Added current unit scaling parameter and $\mu_0$.
  • LLF/HLLE modified to compute the MHD fluxes.
  • Added HLLD (this is horrible btw) basically from Athena++
  • Two new tasks in the driver to compute the edge EMFs from the magnetic face fluxes and then a task to update the face fields from the edge EMFs.
  • New prolongation/restriction operators for edge and face fields.
  • New PostInitialization hook that sets primitive B from face B. Face B is set in the pgens.
  • New edge geometry quantities.
  • Changes are threaded through dual energy.
  • New documentation

Overall, it's not too many new things and there isn't much in the input file that needed to change.

Some things I'm not too happy with that we might want to change:

  • For speed I choose to just use the Alfven speed in the timestep determination, rather that the max of all the fast magnetosonic speeds one could calculate at all the faces. But obviously, if we take fewer timesteps at the cost of a more expensive EstimateTimeStep kernel, it is probably worth it.
  • HLLD is a mess but I don't know of any other way to do it.
  • I'm sure there are BC things we need to add, but I'm not sure at the moment. It's on the pgen to do what it needs to do.

This was done in concert with GPT.

I haven't tested on GPUs yet or anything high res. Initial testing looks pretty good though, I added a diagnostic div(B) field at that remains at machine epsilon even through AMR in cylindrical/cartesian coordinates.

Description of Changes

Closes #122

Checklist

  • New features are documented
  • Tests added for bug fixes and new features
  • (@lanl.gov employees) Update copyright on changed files
  • Any contribution that was created or modified with the assistance of generative AI must have a comment disclosing this such as // This file was created in part or in whole by generative AI

@adamdempsey90
adamdempsey90 requested a review from pdmullen March 31, 2026 16:02

// Add the "flux source terms"
for (int n = 0; n < nspecies; ++n) {
const bool mhd = (F == Fluid::gas) && do_mhd && (n == 0);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const bool mhd = (F == Fluid::gas) && do_mhd && (n == 0);
const bool mhd = do_mhd && (F == Fluid::gas) && (n == 0);

@adamdempsey90

Copy link
Copy Markdown
Collaborator Author

This is now ready for review @pdmullen

@pdmullen pdmullen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see the linear modes test adapted to MHD and the field loop advection test before this goes in.

@@ -0,0 +1,2050 @@
# Athena++ data at time=8.000000e-02 cycle=1559 variables=prim

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need an Athena++ copyright?

const auto xv = coords.GetCellCenter(vg, b, k, j, i);
const auto &bnds = coords.GetBounds();
const Real bx =
((bnds.x1[1] - xv[0]) * vmesh(b, TE::F1, field::face::B(), k, j, i) +

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should make a helper function for this. Maybe it can be templated on coordinates so that we can just do arithmetic average for cartesian.

vmesh(b, TE::F3, field::face::B(), k + threed, j, i)) /
(bnds.x3[1] - bnds.x3[0]))
: vmesh(b, TE::F3, field::face::B(), k, j, i);
emag = MHD::MagneticEnergyDensity(bx, by, bz, mu0_code);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a helper function for cell-centered fields would be nice too. Would clean up duplicated above with below in this file.

Comment thread src/drag/drag.hpp
// Compute SIE via dual energy formalism and apply floor
Real sieg = ArtemisUtils::DualEnergySIE(vmesh, b, n, k, j, i, de_switch, hx);
const Real emag =
(do_mhd && (n == 0)) ? vmesh(b, field::cell::energy(), k, j, i) : 0.0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why only n==0? I suspect that this is just a placeholder bc not all physics packages respect multiple gas species... but the magnetic field should inform all fields if all are coupled.

// Compute SIE via dual energy formalism and apply floor
Real sie = ArtemisUtils::DualEnergySIE(vmesh, b, n, k, j, i, de_switch, hx);
const Real emag =
(do_mhd && (n == 0)) ? vmesh(b, field::cell::energy(), k, j, i) : 0.0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comments as above.... won't repeat hereafter.

Comment thread src/artemis.cpp
const bool do_moment = do_radiation && pin->DoesBlockExist("radiation/moment");
const bool update_fluxes = pin->GetOrAddBoolean("gas", "update_fluxes", true);

// Check configuration selection compatibility

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't mhd require do_gas and update_fluxes (with the latter so that we can get upwind direction)?

Comment on lines +474 to +479
const Real t1 = SQR(vp_(b, IVX, k, j, i) + rfv[0]) -
(mhd ? SQR(vp_(b, field::cell::B(0), k, j, i)) / mu0 : 0.0);
const Real t2 = SQR(vp_(b, IVY, k, j, i) + rfv[1]) -
(mhd ? SQR(vp_(b, field::cell::B(1), k, j, i)) / mu0 : 0.0);
const Real t3 = SQR(vp_(b, IVZ, k, j, i) + rfv[2]) -
(mhd ? SQR(vp_(b, field::cell::B(2), k, j, i)) / mu0 : 0.0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should these divide out rho since wdt contains rho?

// a = (a < 0.0) ? 0.0 : sqrt(gm1 * a);
// Einfeldt (1988)
const Real ngam = 0.5 * sqrtdl * sqrtdr * SQR(isdlpdr);
Real a =

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused about the dimensionality of this... can you check?

qa is a fast magnetosonic speed and the second term has units of velocity squared?

const Real ke = 0.5 * w_d * (SQR(vel1) + SQR(vel2) + SQR(vel3));
Real me = 0.0;
if (do_mhd && (n == 0)) {
const Real bx = 0.5 * (vmesh(b, TE::F1, field::face::B(), k, j, i) +

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no fancy centroid stuff here?

Comment thread src/mhd/mhd.hpp
coords.template GetScaleFactorsFace<X2DIR>(vg, b, k, j, i - 1);
const Real h3e = coords.template GetEdgeScaleFactor<X3DIR>(vg, b, k, j, i);
Real &emf = v.flux(b, TE::E3, field::face::B(), k, j, i);
emf = h3e * 0.25 *

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

straight averaging? no upwinding a la Gardiner & Stone?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MHD

2 participants