astro-turing / Integrating-diagenetic-equations-using-Python

Attempt to reproduce the plots shown at the kickoff by Niklas Hohmann, from his Matlab scripts. See if we can do that using corresponding Python scripts.
Apache License 2.0
0 stars 1 forks source link

Investigate the differences between marlpde and rhytmite when the same solver and initial settings are used #40

Open EmiliaJarochowska opened 4 weeks ago

EmiliaJarochowska commented 4 weeks ago

We want to understand why marlpde and rhytmite give different results for runs longer than 1 dt when the same solver settings are used.

This can be done by fixing the solver and the parameters and focusing on why the results still differ. I suggest focusing on Euler using a fixed time time step of 1e-6. But if needed, a comparison of RK23, RK45 or adaptive could also be done. Important is to do one comparison at a time.

This should be done with the corrected typo as in #39 so using the Oscillations_like_Fortran branch. Additional adjustment can be made, either to marlpde or to rhytmite, e.g. the clipping of values, to pinpoint the causes of differences.

Here is a comparison using the Euler solver after 100 dt, made by Charlotte (email from 13 June):

image

EmiliaJarochowska commented 4 weeks ago

The differences are small but you can use the code for plotting residues in https://github.com/MindTheGap-ERC/Cross-comparison to investigate them

HannoSpreeuw commented 4 weeks ago

Okay, I guess this committed comparison plot, from the day before, i.e. June 12 was also made using the main marlpde branch, i.e. with the correct formula for the porosity diffusion coefficient instead of the restored typo.

Including the default solver settings from the main marlpde branch.

I will use new folders to upload comparisons coming from anything different from the main marlpde branch.

HannoSpreeuw commented 3 weeks ago

res_t_1_py_pde

Better resemblance now near the surface and away from the ADZ.

See these two commits for some background.

HannoSpreeuw commented 3 weeks ago

comp_Tstar_1_py_pde

This is also informative.

EmiliaJarochowska commented 3 weeks ago

That is indeed very good, considering that we are interested in what is exported from the system, some discrepancy in the ADZ is probably acceptable, as long as the values converge in the lower part of the system. Any ideas what the causes of the remaining differences might be?

HannoSpreeuw commented 3 weeks ago

I guess the remaining differences can be explained by either:

I can continue investigating this in a week from now.

HannoSpreeuw commented 2 weeks ago

In order to resolve the remaining differences the simplest approach would be to align the rhythmite and marlpde grids, since they are half a cell apart. Aligning the grids would likely result in a closer resemblance than the linear interpolation added to the comparison code through this commit.

Aligning the grids is impossible without changing the way rhythmite effectuates the boundary conditions, since these are imposed at cell centers, not at cell edges.

HannoSpreeuw commented 2 weeks ago

The easiest way to "resolve" the differences is to revert to a much higher spatial resolution, e.g. a grid of 1000 instead of 200 depths, and check if the differences in the above figure diminish.

HannoSpreeuw commented 2 weeks ago

However, nnx >= 400 will make rhythmite exit with nan encountered, exiting.

HannoSpreeuw commented 2 weeks ago

Tried a different approach. No ADZ ---> No clamping is needed in rhythmite. This makes an integration over T* possible. These are the differences between rhythmite and marlpde.

res_t_1_py_pde

See this commit for the code.

EmiliaJarochowska commented 2 weeks ago

Here's what I received from Charlotte:

Rhythmite can be run at higher resolutions as it is, but the timestep needs to be decreased to keep it stable, I found that with dt=10-7, it can do at least 800 nnx without issue.

HannoSpreeuw commented 2 weeks ago

Okay, thanks, I hadn't changed the time step.

For such a large depth grid one will probably need to run this on a powerful cluster node, if one wants to integrate over an interval appreciably longer than 1e-4 times T*.

EmiliaJarochowska commented 2 weeks ago

Turns out Charlotte has ran the comparison for the steady-state solution (Fig. 3) with different grid sizes (200 to 1000 by 100) and the agreement between rhytmite and marlpde is excellent. There are only very tiny differences at the surface of the system, which is not a problem.

EmiliaJarochowska commented 2 weeks ago

@HannoSpreeuw observed that if clamping of non-physical values is removed from rhytmite, then integration over longer times (as in T*) is not possible, unless one also switches off ADZ. So clamping of unphysical values seems crucial, but is it possible to obtain solutions without it? According to Cedric, if intermittent values are unphysical but the final result is, then they are acceptable as an approximation of the solver. I added @csummers25 here btw :-)

HannoSpreeuw commented 1 week ago

Here is yet another way of assessing differences between marlpde and rhythmite. This time a 250 ka run, with initial and surface porosities of 0.8. In marlpde/parameters.py solver: str = "explicit" scheme: str = "rk"

After some 133978 years one runs into

RuntimeError: Time step below 1e-10 54%|███████████████████████████████████████████▍ | 10.15751/18.953752843062926

Now this time of 133978 years may coincide with the calcite bump prior to oscillations from the slides from @csummers25

What does this mean? marlpde tries to enforce a tolerance=0.0001 but that would yield a time step < 1e-10 when the calcite composition becomes almost 1?

But there is a need to verify that also marlpde's calcite composition at the time of bombing out (~133978 years) is almost 1, i.e. in agreement with rhythmite's value at that same time.

I will try an Eulerian scheme as well.

HannoSpreeuw commented 1 week ago

Same result for scheme: str = "euler", slighty earlier, i.e.

54% --> 53%

10.15751 --> 10.12714
HannoSpreeuw commented 1 week ago

With solver: str = "scipy" in marlpde/parameters.py and method="LSODA", first_step=1e-6, atol=1e-3:

RuntimeError: Encountered Not-A-Number (NaN) in evolution 53%|███████████████████████████████████████████▍ | 10.04276/18.953752843062926

So a similar result.

HannoSpreeuw commented 1 week ago

A possible way out would be to add clamping to physically feasible values to marlpde and see if it can integrate beyond this point.

HannoSpreeuw commented 1 week ago

Clamping does not seem to be needed to integrate over 250,000 years if implicit solvers -with numerically approximated instead of functional Jacobians - in marlpde's updated Use_solve_ivp_without_py-pde_wrapper branch is used.

I find these solutions at 50 cm depth over that time interval - i.e. no oscillations:

At_50_cm_depth_over_250_000_years

HannoSpreeuw commented 1 week ago

With a constant porosity diffusion coefficient and the implicit "BDF" solver, those profiles at 50 cm depth are even flatter. Using that solver from solve_ivp this result can be obtained from the main branch as well as from the Use_solve_ivp_without_py-pde_wrapper branch; the latter has been updated to run with a constant porosity diffusion coefficient.

At_50_cm_depth_over_250_000_years_BDF_no_py-pde_wrapper

HannoSpreeuw commented 1 week ago

Does rhythmite have a varying porosity diffusion coefficient?

EmiliaJarochowska commented 1 week ago

Yes, please see https://github.com/cedrict/rhythmite/blob/257136bec97acc283dbc9e682c7fcf6b8669b387/DiagenesisModel.py#L142-L144

HannoSpreeuw commented 1 week ago

Almost the same link.

csummers25 commented 1 week ago

It doesn't vary during the simulation, the value is just calculated from the other parameters initially

HannoSpreeuw commented 1 week ago

Ah, now I see, sorry for the oversight.