Optimise neutral_mixed flux limiter implementation - #605
Conversation
New default (0.5) equivalent to old (0.2). This is important for comparing to other codes and to flux limits elsewhere, e.g. electron conduction.
Now a softFloor instead of addition. Previous implementation was offsetting collisionality everywhere even though it was meant to act as a floor. The floor was also non-smooth.
Now differentiable, and avoids full gradient. This is perpendicular transport so only the perpendicular gradient should be used. The abs(grad) used before had a kink, new floor is smooth. Neutral_lmax now used only as collisionality floor for better consistency and separation of concern.
diffusion_limit now caps Dmax.
SOLPS-style. Defaults to original behaviour.
Improves robustness to initial transients.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #605 +/- ##
==========================================
+ Coverage 56.92% 58.61% +1.68%
==========================================
Files 97 98 +1
Lines 10092 10274 +182
Branches 1462 1471 +9
==========================================
+ Hits 5745 6022 +277
+ Misses 3757 3640 -117
- Partials 590 612 +22 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I've been using the |
|
Hi @mikekryjak , I'll try to test this in the next few days but do you think we should split the flux limiters into parallel and perp? I don't have any strong opinion. |
Yes, we should, but I wanted that in a separate PR. This one keeps the same limiter form as master. |
They test how Dnn changes in different regimes.
AFN collisions mode is what would be expected from what other codes do. A higher gradient floor can improve performance with a small impact on the profiles, and it's still more accurate than old regularisation. neutral_lmax is now only used for collisionality floor and so is set to a physically informed 1m.
New improvements in neutral flux limiter robustness have a small effect on the profiles in default conditions, so the test was reran from scratch for 200ms. I also found that the pump recycling fraction was not updated when the all-wall pump was implemented, so it wasn't consistent with my simulations. This has now been corrected.
Unit test was comparing unlimited D with D but the flux_limit value was not high enough for the chosen tolerance.
Previously the inputs were in normalised units and actual application of regularisations was normalisation dependent.
|
I realised that leaving |
Limiter floor and ceiling were only normalising the default value. The previous, normalised defaults for those were almost round numbers - I made them round numbers in SI, which caused 2D-production to fail by a tiny amount. I have set the floor and celing values to the exact previous defaults and left a note. The loose flux limit Dn unit test was failing because the floor and ceiling were tuned to physical conditions and completely control the answer in the arbitrary conditions in the test. The floor and ceiling were set to very low/high values to deactivate them for these tests.
Purpose
I have been trying to merge the separated flux limiters for several years (see #556, #451, mikekryjak#15 and mikekryjak#6). My efforts were hampered by extreme performance degradation which I couldn't understand.
I have recently been conferring with LLMs to try and understand how a code could slow down by 100x just because we limit conduction separately. I found that the code is extremely sensitive to regularisation issues (e.g. denominators going to zero, non-differentiable things, etc). There a lot of small things in our existing implementation and my implementation of the separate limiters which caused problems.
I decided to separate the PRs and implement the regularisation first as well as the new limiter features apart from parallel and split limiters (so smooth SOLPS like limiter form and new Vth definition).
The new changes give robustness improvements a scan of
flux_limitervalues, while being much closer to the unregularised results. They will change the physics result to be more accurate. Previous profiles can be recovered by tuning the flux limiter.Change Summary
flux_limit. The new default of 0.5 is equivalent to the old default of 0.2. If you have simulations whereflux_limitis not set to default, your results will be affected.neutral_lmaxis now user-settable and only controls the collisionality floor for separation of concern.diffusion_limitnow capsDmaxeven ifflux_limitis used, as opposed to replacing the flux limitation with a D limitation.softFloorinstead of addition. Nu is no longer always higher byRnneverywhere and there is no longer a kink at the floor.Rnnis now callednu_pseudo_mfp.AFNas the more accurate model.Dmaxdenominator now correctly uses the perpendicular instead of total gradient.abs(Grad_perp(logPnlim))inDmaxdenominator creates a non-differentiable kink. Replaced with smoothsqrt(abs(Grad_perp(logPnlim))^2 + gradient_floor^2) and removed the now redundant1/neutral_lmax` floor.Validation
I've ran comprehensive test on my low-res ST40 case and performed a second verification on a MAST-U case. I did a scan in each of the normalisation parameters to figure out sensible defaults.
Results of the runs:
neutral_lmaxset to physical 1m. It now only floors collisionality. Increasing it doesn't change the answer much.limiter_gradient_ceilingis at 0.1: only mildly activated in steady state, but prevents crashes at initial transients when the flux is heavily limited.limiter_gradient_flooris at 0.01: prevented huge slowdowns due to shallow gradient regions when separate limiters are used (next PR).My low res case scan
Profiles:

Performance:

I found that a lot of the speed variability I've been getting is due to the slope limiter choice. Here are the scans repeated with the Van Albada slope limiter which shows that the new changes now have very consistent performance and are still better than master:

AI Assistance
Documentation
The
neutral_mixedsection was rewritten to include the new changes.Review Notes
Vthdefinition means that e.g. a flux limiter value of 0.5 is equivalent to the old 0.2. I have kept the defaults to be equivalent to old behaviour. Secondly, the regularisation is now less impactful on the simulation, so the profiles will change, generally towards less limitation. This can be compensated for with a different flux limiter setting.