Skip to content

Add FastIsostasy - #183

Merged
matthewhoffman merged 16 commits into
developfrom
matthewhoffman/mali/fastisostasy
Sep 26, 2026
Merged

matthewhoffman merged 16 commits into
developfrom
matthewhoffman/mali/fastisostasy

Conversation

@matthewhoffman

@matthewhoffman matthewhoffman commented Jun 13, 2026 •

Copy link
Copy Markdown

This PR adds FastIsostasy as an alternate GIA model to the existing global 1d Sea Level Model. The implementation makes use of a lot of the existing coupling code and builds off of FastIsostasy documentation on coupling here:
https://github.com/palma-ice/FastIsostasy/blob/main/README.md#coupling-fastisostasy-to-your-favorite-ice-sheet-model

@matthewhoffman

matthewhoffman commented Jun 13, 2026 •

Copy link
Copy Markdown
Author

Status: Code compiles with FASTISOSTASY=true but has not been run or tested in any way. Code was written by Copilot w/ GPT 5.3-Codex using these instructions:

Plan instructions

Plan: Couple MALI with FastIsostasy (Fortran)

TL;DR: Use the Fortran version of FastIsostasy (palma-ice/FastIsostasy) — not the Julia version — and follow the existing SLM coupling pattern already in mpas_li_bedtopo.F. The Fortran library has a clean 4-call API and the SLM code provides a near-complete template for the MPI gather/interpolate/solve/scatter workflow.


Key Discovery: A Fortran version already exists

FastIsostasy includes a pure Fortran implementation specifically designed for coupling with ice-sheet models. Its API is:

call isos_init(isos, path_par, "isos", nx, ny, dx, dy)
call isos_init_ref(isos, z_bed_ref, H_ice_ref)
call isos_init_state(isos, z_bed, H_ice, time, bsl)
! In time loop:
call isos_update(isos, H_ice, time, bsl)
z_bed = isos%out%z_bed

The docs for it include specific guidance for coupling to an ice-sheet model: https://github.com/palma-ice/FastIsostasy#coupling-fastisostasy-to-your-favorite-ice-sheet-model


Why this is tractable

MALI already has a complete coupling template in mpas_li_bedtopo.F via the SLM (sea-level model) coupling. That code handles:

  • Alarm-based coupling intervals
  • MPI gather of ice thickness from all ranks to rank 0
  • Interpolation from unstructured MPAS mesh → regular grid (sparse matrix multiply using weight files)
  • External solver call on rank 0
  • Interpolation back to MPAS mesh
  • MPI scatter of bed topography changes
  • Halo exchange + geometry/mask update

The FastIsostasy coupling would replicate this pattern almost exactly, substituting FastIsostasy's isos_update() for the SLM solver calls.


Phases

Phase 1: Build System

  • Add palma-ice/FastIsostasy as a submodule or vendored source
  • Add USE_FASTISOSTASY conditional compilation flag (mirrors USE_SEALEVELMODEL)
  • Link against libisostasy.a + FFTW dependency

Phase 2: Registry & Config

  • New config_uplift_method = 'fastisostasy' option
  • Config params: coupling interval, namelist path, weight file paths

Phase 3: Core Coupling — most complex, but heavily templated

  • fastisostasy_init(): setup alarm, read weights, MPI layout, call isos_init/isos_init_state
  • fastisostasy_solve(): gather → interpolate → isos_update() → interpolate back → scatter → apply
  • New branch in li_bedtopo_solve() dispatch

Phase 4: Grid/Weight Files

  • Generate ESMF/TempestRemap interpolation weights between MPAS mesh and FastIsostasy's regular Cartesian grid
  • FastIsostasy needs a square domain with ≥512 km padding beyond ice extent

Phase 5: Restart

  • FastIsostasy has built-in isos_restart_write/read; wire into MALI checkpoint

Phase 6: Testing

  • Idealized dome test with known analytic GIA solution
  • MPI correctness (1/4/16 procs)
  • Bit-for-bit restart verification

Relevant Files

  • mpas_li_bedtopo.F — primary file to modify (SLM coupling template is here)
  • Registry.xml — add config options
  • Makefile — build system (has USE_SEALEVELMODEL pattern to copy)
  • mpas_li_time_integration_fe_rk.F — calls li_bedtopo_solve() at line 634 (no changes needed here)

Main Challenge: Grid Interpolation

MALI uses an unstructured MPAS mesh; FastIsostasy uses a regular Cartesian (stereographic) grid. The SLM coupling already solves this exact problem using pre-computed sparse interpolation weight files (generated by ESMF_RegridWeightGen or TempestRemap). The same tooling applies — you just need to generate weights for the FastIsostasy target grid rather than the SLM's Gauss-Legendre grid. This will be done outside of MALI in a separate preprocessing step and does not need to be implemented here. However, the MALI implementation should assume a similar format for mapping files as for the existing SLM.

Build and test loop

  • I want the work divided into logical commits with descriptive commit messages.

  • To get a usable environment for compiling MALI, do:
    source /global/cfs/cdirs/fanssie/users/hoffman2/compass/ismip7-devs//load_compass_pm-cpu_gnu_mpich.sh

  • Before each commit, make sure the code builds:
    cd /global/cfs/cdirs/fanssie/users/hoffman2/compass/ismip7-devs/MALI-Dev/components/mpas-albany-landice; make clean; make -j 4 gnu-cray DEBUG=true

  • If code compiles, you may commit and move on to next step.

  • If you run into any environment problems or have any questions, stop and ask for more instructions. Otherwise continue working through the implementation steps until complete.

I made a cursory review of the implementation. The coupling code looks correct in that it mirrors the coupling code for the SLM heavily, as intended, but I have not done a line by line review. The Makefile/build changes look reasonable, but some cleanup is needed to generalize it to any machine. Note that the FastIsostasy build is really slow for two reasons: 1. it uses config which is generally slow and 2. the FFTW library it depends on is very slow to compile and we may want to support optionally pointing to a pre-build lib of it.

Next steps are to build mapping files, set up a FI namelist, and attempt a run.

@matthewhoffman matthewhoffman added the in progress Still being worked on, don't merge yet! label Jun 13, 2026
@hollyhan

hollyhan commented Jul 16, 2026 •

Copy link
Copy Markdown

Update (09/22/2026): This issue has been resolved with commit da45530edb7f95726ddb73c15738d9b9d2bee5ad

There seems to be an issue in linking the fastisostasy libraries- I am not able to build MALI with FASTISOSTASY=true without running into errors that are sometimes solved and sometimes not by adding
override LIBS += $(FASTISOSTASY_LINK_LIBS) in the build_options.mk file.

Built attempted on Perlmutter (make gnu-cray FASTISOSTASY=true ALBANY=true DEBUG=false)

Currently, the way I make the build work spuriously is by compiling once with override LIBS += $(FASTISOSTASY_LINK_LIBS) removed, then add it back without make clean. This seems to work all the time.

@matthewhoffman matthewhoffman added this to the ISMIP7 milestone Sep 12, 2026
@hollyhan

Copy link
Copy Markdown

Results of the testing can be seen here: MPAS-Dev/compass#970

@hollyhan

Copy link
Copy Markdown

Test results:
Setting up and running coupled MALI-FI simulations with a realistic Antarctic Earth structure (i.e., a 2D field derived by depth-lumping the actual 3D viscosity structure) requires an external NetCDF file. The weak and strong Earth-structure files (Swierczek-Jereczek et al.) can be downloaded from https://zenodo.org/records/21105061. The medium Earth model file can be derived from the other two by taking the mean of log10 effective viscosity and the mean of lithospheric thickness. The three Earth structure profiles look like this:
earth_structures_weak_medium_strong

Coupled simulation has been tested with realistic climate forcing (ISMIP7 Experiment C007: CESM2-WACCM SSP585) and the weak Earth structure. Below results are based on the 2D MALI outputs.

state_diff_2015_2200

The spatial pattern of bedrock response is coherent with changes in ice thickness.

The restart capability has been tested to the extent possible – by code inspection config_do_restart=.true. correctly triggers FastIsostasy to read its own restart files rather than calling isos_init_ref. Based on the MALI outputs, globalStats show smooth curves in the ice state through the restart, and the bedrock elevation change rate also shows no kink at the restart boundary either. Based on this evidence, the restart capability can be judged to be sufficiently verified for production use. However, to fully close this out, more direct testing would help — but since FastIsostasy currently overwrites its restart file every year, that would need a small addition on the MALI coupling side to call FastIsostasy's existing (but currently unused) diagnostic-output routine.

@hollyhan
hollyhan force-pushed the matthewhoffman/mali/fastisostasy branch from fd33a82 to 1580599 Compare September 22, 2026 19:42
@hollyhan hollyhan removed in progress Still being worked on, don't merge yet! testing needed labels Sep 24, 2026
@matthewhoffman
matthewhoffman requested a balanced review from Copilot September 25, 2026 20:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Missing submodule gitlinks, an unguarded module import, and invalid-grid handling currently break supported build or initialization paths.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 High severity · 3 Medium severity

Open (5)
What changed in this PR

Adds FastIsostasy as an alternative MALI glacial-isostatic-adjustment model.

Changes:

  • Adds FastIsostasy coupling, remapping, and restart handling.
  • Integrates FastIsostasy and fesm-utils into the build.
  • Adds related namelist configuration.
File Description
.gitmodules Declares external dependencies.
components/​mpas-framework/​Makefile Isolates PIO test libraries.
components/​mpas-albany-landice/​src/​Registry.xml Registers FastIsostasy options.
components/​mpas-albany-landice/​src/​mode_forward/​mpas_li_core.F Writes coupled restart state.
components/​mpas-albany-landice/​src/​mode_forward/​mpas_li_bedtopo.F Implements coupling and remapping.
components/​mpas-albany-landice/​src/​Makefile Builds external libraries.
components/​mpas-albany-landice/​src/​build_options.mk Adds compile and link options.
components/​mpas-albany-landice/​bld/​namelist_files/​namelist_definition_mali.xml Defines namelist entries.
components/​mpas-albany-landice/​bld/​namelist_files/​namelist_defaults_mali.xml Adds defaults.
components/​mpas-albany-landice/​bld/​build-namelist-section Assembles section defaults.
components/​mpas-albany-landice/​bld/​build-namelist Assembles MALI defaults.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .gitmodules Resolved
matthewhoffman and others added 14 commits September 25, 2026 14:24
Without this, a MALI restart with config_uplift_method='fastisostasy'
aborted outright. Cold-starting FastIsostasy instead (bypassing that
guard) would silently discard its viscous relaxation state and reset
the reference load to "now" at every restart, i.e. it would treat the
solid Earth as already in equilibrium with the current ice/ocean load.

Wires MALI up to FastIsostasy's own restart I/O (isos_restart_write/
read, bsl_restart_write/read) instead: writes a FastIsostasy restart
snapshot every time MALI writes its own restart stream, and on restart
recomputes the elapsed coupling-step count from simulation time
(mirroring find_slm_restart_timestep) to resume FastIsostasy's internal
clock at the correct point.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds config_fastisostasy_grid_resolution (meters) so the real spacing
can be supplied via namelist.landice.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
build_options.mk defined FASTISOSTASY_LINK_LIBS (pointing at FastIsostasy's
and fesm-utils' static libraries) but never added it to LIBS, so the final
landice_model link would have failed to find FastIsostasy symbols. Wires it
in with `override LIBS += $(FASTISOSTASY_LINK_LIBS)`.

That addition, however, causes mpas-framework's generic pio_test target to
inherit those library paths too. pio_test runs early (as a prerequisite of
mpas_main) and links a trivial test program against the full $(LIBS) purely
to detect the installed PIO version -- but FastIsostasy's static libraries
are only built later, by the fastisostasy_lib target (a prerequisite of
core_landice). On a build with FASTISOSTASY=true, this made pio_test's link
fail because those .a files don't exist yet, which the target's own error
handling then misreports as "PIO environment variable not set" -- masking
the real, unrelated cause.

Adds PIO_TEST_LIBS, a snapshot of LIBS taken before any core's
build_options.mk can append core-specific libraries, and uses it in
pio_test instead of the full LIBS. pio_test only needs to check PIO
usability, not link against every library the final executable needs, so
this doesn't change what it actually tests -- it just stops it from
depending on libraries that aren't built yet. The real final executable
link is untouched and still uses the full LIBS.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds RKC integrator option, includes PR #52 bsl restart fix
* add config_fastisostasy_grid_resolution to e3sm namelist assembly
* disable unavailable USE statement when FI is not compiled in

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@matthewhoffman
matthewhoffman force-pushed the matthewhoffman/mali/fastisostasy branch from 78eb7e7 to 31188fb Compare September 25, 2026 21:25
@matthewhoffman

matthewhoffman commented Sep 25, 2026 •

Copy link
Copy Markdown
Author

Testing

Compass full_integration suite on pm:

  • compiled using DEBUG=true FASTISOSTASY=false : All tests pass
  • compiled with DEBUG=true FASTISOSTASY=true : fails to compile

matthewhoffman and others added 2 commits September 25, 2026 17:15
This commit replaces the approach from 9715c1c with a cleaner solution
that requires no changes to mpas-framework/Makefile and no machine-specific
TOML configuration files.

Changes:
1. Remove LIBS pollution in build_options.mk
   - The override LIBS line was causing LIBS to contain paths to .a files
     that don't exist yet during the build
   - These paths were inherited by the FFTW ./configure subprocess, causing
     C compiler cannot create executables errors

2. Bundle FastIsostasy libraries into libdycore.a (src/Makefile)
   - Extract objects from libisostasy.a, libfesmutils.a, and libfftw3.a
   - Add them directly to libdycore.a using ar -ru
   - Follows the same pattern as Sea Level Model (SLM)
   - Framework already links -ldycore, so all symbols are found

3. Inherit MPAS compiler settings for FFTW build (src/Makefile)
   - Pass CC_SERIAL, FC_SERIAL, CFLAGS_OPT, FFLAGS_OPT as environment vars
   - Generic linux/gfortran config picks these up via autotools defaults
   - No machine-specific TOML files needed - works on any MPAS machine

This approach eliminates the need for:
- PIO_TEST_LIBS workaround in mpas-framework/Makefile
- Machine-specific fesm-utils/machines/*.toml configuration files
- Any modifications to the shared mpas-framework code

Commit 9715c1c should be reverted from components/mpas-framework/Makefile.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This reverts the mpas-framework/Makefile changes from commit 9715c1c.

The PIO_TEST_LIBS workaround was needed because LIBS contained paths to
FastIsostasy .a files that didn't exist yet. Now that FastIsostasy libraries
are bundled into libdycore.a instead of being added to LIBS, this workaround
is no longer necessary.

See commit 1c71965 for the new FastIsostasy linking approach.
@matthewhoffman

Copy link
Copy Markdown
Author

Testing

Compass full_integration suite on pm with the two new commits modifying the FI build. Built from a fresh clone.

  • compiled with DEBUG=true FASTISOSTASY=true : Compiles and all tests pass

@matthewhoffman
matthewhoffman merged commit 820ab97 into develop Sep 26, 2026
@matthewhoffman
matthewhoffman deleted the matthewhoffman/mali/fastisostasy branch September 26, 2026 02:02
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.

3 participants