Skip to content

New Kastaun Recovery#142

Merged
c-prather merged 16 commits intodevfrom
fix/normal-recovery
Sep 18, 2025
Merged

New Kastaun Recovery#142
c-prather merged 16 commits intodevfrom
fix/normal-recovery

Conversation

@c-prather
Copy link
Contributor

@c-prather c-prather commented Sep 12, 2025

The existing dev branch contains an attempt at applying simulation floors within the Kastaun inverter in a way which prevents positive feedback loops.

However, it's a bit ad-hoc. The remedy for low density wasn't really physical (luckily it was almost never triggered in practice!) and the remedy for low internal energy amounted to stealing as much kinetic energy as necessary to satisfy the floored temperature, thus preserving only the total energy and not the momenta, where one might reasonably hope to do the opposite.

Often, the re-partitioning of energy failed. The primary "fixup" option was just to replace the primitive variables with atmosphere, giving up on preserving any of the "conserved" variables at all. It was crude but undeniably effective, and triggered in maybe 1 in 1e3 grid zones, which I think overall would have been fine.
(The other option, averaging neighbors, is really only effective for more forgiving floors -- once zones with high density bordered empty zones with high velocity, problems ensued quickly and it was never terribly stable).

In the interest of doing yet better, and specifically of being able to document the scheme without humiliating myself, this is take two: same stability, more consistent philosophy. Specifically: trust the inverter. Rather than apply floors during inversion, and then mess with the solution before returning it, this PR simplifies the inverter to essentials, preserving exactly the prescription guaranteed to converge, coupled with only the strictly necessary limits for numerical stability (keeping numbers positive and speeds barely liminal).

Three mitigations are then applied after the inversion:

  1. Floors are applied to rho and u in the normal observer frame, just like they are when one sets floors/frame=normal. This application must be in the normal frame, as we still want to conserve momentum if possible (not to mention we only have access to the conserved variables at this point). If the user has selected frame=normal, all floors are applied here -- otherwise, only the minimal floors (rho/u_min_const) are applied here, and the rest are added in the desired frame later, in the usual floor call.

  2. After these floors are added to conserved variables, if the inversion afterward cannot reproduce the momenta, reduce the velocities using the old recovery code. That is, solve for $\mu$ from Kastaun's expression for $\hat{\epsilon}$, setting it equal to our known $\epsilon$ after floors. This amounts more or less to prioritizing the thermal and magnetic energy when partitioning the total $T^0_0$, and only using the remainder of the total for kinetic energy and hence velocity. That is, it dissipates kinetic into thermal energy, which is what the code does all the time anyway. I believe it does not actually conserve $T^0_0$, but we already broke conservation of total energy when we applied the floors in normal frame, so it doesn't really matter.

  3. If two inversions and a solve for new velocities all failed, set the velocities to zero (alternatively, just fall through to setting all primitive vars to atmosphere -- both strategies look nearly identical).

Ideally, very few zones (fewer than before) should hit (3). The combination of strategies here tries to conserve momentum first, and if this proves impossible, to at least do something plausibly physical before giving up and setting atmosphere.

Ben Prather and others added 6 commits August 14, 2024 16:47
The Kastaun inverter is guaranteed to converge with only a tiny
minimum of limits.  This commit restricts the implementation
to apply only these.

Without internal floors, results can be very unstable, especially
for the case that no velocity will satisfy the momentum; for this,
the inverter reconstructs the maximum possible velocity.

Thus we apply an adapted form of Normal Observer floors after
inversion, which are guaranteed to add at least enough
material and energy to satisfy constraints.  We also check that
the new primitives have the correct momentum -- if not, the
velocity is zeroed to avoid myriad problems evolving high speeds.
Most of the momentum in these cells comes from B, not rho,
so I think this is a reasonable choice in practice.
@c-prather
Copy link
Contributor Author

Sigma of a million isn't cool. You know what's cool? Sigma of a billion

log_sigma_poloidal.mp4

@c-prather c-prather changed the title WIP: New Kastaun Recovery New Kastaun Recovery Sep 17, 2025
@c-prather c-prather merged commit bde7e46 into dev Sep 18, 2025
1 check passed
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.

1 participant