OMS-NetZero / FAIR

Finite-amplitude Impulse Response simple climate model
https://docs.fairmodel.net
Apache License 2.0
120 stars 61 forks source link

Better restart handling #145

Open chrisroadmap opened 8 months ago

chrisroadmap commented 8 months ago

Sometimes we want to run fair one timestep at a time, do something with the output, and run for the next timestep. There's no mechanism in the model right now to do this sensibly.

chrisroadmap commented 7 months ago

One improvement would be to create a "restart dump" as an xarray dataset - the output in the last timebound/timestep - that contains all of the information needed to restart the model, and to read this in and handle in one line of code.

ppolonik2 commented 4 months ago

Just chiming in to say this functionality would be useful for my current application. Is there a timeline or a suggested work-around for now? Thanks!

chrisroadmap commented 4 months ago

there is a workaround. Have a look at cell 45 of this: https://github.com/chrisroadmap/methane-mitigation/blob/main/notebooks/adaptive-removal-1.4.0.ipynb

Look for these lines near the end of the block

        initialise(f_fut[year].concentration, f_fut[year-1].concentration[-1, ...])
        initialise(f_fut[year].forcing, f_fut[year-1].forcing[-1, ...])
        initialise(f_fut[year].temperature, f_fut[year-1].temperature[-1, ...])
        initialise(f_fut[year].airborne_emissions, f_fut[year-1].airborne_emissions[-1, ...])
        initialise(f_fut[year].cumulative_emissions, f_fut[year-1].cumulative_emissions[-1, ...])
        initialise(f_fut[year].alpha_lifetime, f_fut[year-1].alpha_lifetime[-1, ...])
        f_fut[year].gas_partitions=copy.deepcopy(f_fut[year-1].gas_partitions)

Replace f_fut[year] with the name of your new FAIR instance, and f_fut[year-1] with the one you want to take the output of the last timebound for. The full example in this notebook is way more complex than you will likely need - it is iterating many many times per timestep and trying to find an optimal emissions value that limits temperature to a certain level, so is very slow.

What is this doing exactly? It uses the output of the last timebound of the old run to initialise the first timebound of the new run. If you define your timebounds to overlap in the old and the new (say the old run ends with a 2050 timebound with f_old.define_time(2000, 2050, 1), the new run starts with a 2050 timebound with f_new.define_time(2050, 2100, 1)), it will make sense.

The real magic is in the gas_partitions, this is the internal state of the atmospheric GHGs, and the only variable in fair that is only book-kept in the latest timebound (else it's a 5D array, and consumes way too much memory).

To do a complete job, you also need to initialise the ocean heat content

initialise(f_new.ocean_heat_content_change, f_old.ocean_heat_content_change[-1, ...])

though if you forget, it won't affect the temperature computation or anything else.

ppolonik2 commented 4 months ago

That works very well, thank you for the quick and helpful response!