Skip to content

Issue1088 slab ocean bug - #1105

Merged
einola merged 28 commits into
developfrom
issue1088_slab_ocean_bug
Aug 26, 2026
Merged

Issue1088 slab ocean bug#1105
einola merged 28 commits into
developfrom
issue1088_slab_ocean_bug

Conversation

@einola

@einola einola commented Aug 10, 2026

Copy link
Copy Markdown
Member

Fix salinity calculation in slab ocean

Fixes #1088

Task List

  • Linked an issue above that captures the requirements of this PR
  • Defined the tests that specify a complete and functioning change
  • Implemented the source code change that satisfies the tests
  • Commented all code so that it can be understood without additional context
  • No new warnings are generated or they are mentioned below
  • The documentation has been updated (or an issue has been created to do so)
  • Relevant labels (e.g., enhancement, bug) have been applied to this PR
  • This change conforms to the conventions described in the README

Change Description

The code wasn't using the salt flux calculated by IOCeanBoundary::mergeFluxes. This may be causing problems in the spring. Not fully tested yet!


Test Description

It doesn't crash immediately, but I need @Thanduriel's help to test it on his setup.


Documentation Impact

None


Other Details

None

einola added 3 commits August 10, 2026 12:55
The salt flux is already calculated in mergeFluxes of IOceanBoundary. In
this PR I use this in SlabOcean to calculate the change in SSS, instead
of the salt flux derived from freshwater flux.
We have to define a local relaxation timescale anyway, so we might as
well use its reciprocal and do repeated multiplications instead of
divisions. This is probably an inperceptible speedup, but it's nice that
we don't have local variables shaddowing global ones.
It's not needed unless the cell fluxes out in a single time step and if
that happens, the problem is somewhere else!
@einola einola added the bug Something isn't working label Aug 10, 2026
@einola
einola requested a review from Thanduriel August 10, 2026 11:02
einola added 21 commits August 14, 2026 08:54
Change era5_topaz4_maker.py so that ocean velocities are zero on land
(as we have always done before).
Just follow suggestions by ruff. Nothing fancy, but it does give better
looking code.
Remove an unused variable.
We remove all ice in the grid cell when it falls below the minima, cMin
or hMin. Doing this, we also have to reset newice to zero - otherwise it
may be erroneously used by other routines, e.g.
IOceanBoundary::mergeFluxes to calculate freshwater flux.
Adds several const statements and renames variables to use camel case.
Clearer program flow w.r.t. updates of snow, concentration, and volume.
It is a tunable parameter in the old neXtSIM, but that doesn't really
make sense. In Hibler's paper it's just 2, and it should be a constant.
sFlux is in kg/m^2/s, but we need PSU/m^2/s
Also report index, not just [i,j], when we encounter out-of-bounds
values.
These values may be unphysical, but they appear in the first few time
steps when the model is "settling". Stopping at those makes the error
checking unusable.
We should record the ice and snow volume lost when everything melts away
because we're below the cMin or hMin values. Also, be less agressive
with using _ft.
Doesn't really belong here ... but it should be done.
Take advantage of the fact that cIce >= cMin if there is ice and that
deltaCMelt == 0 if there is no melt.
Assign proper values to deltaHi, botMelt (diagnostic), topMelt
(diagnostic), and snowMelt. First and last are used later in the code to
compute freshwater fluxes.
For some reason I can't use std::max(cMin, cIce[i]) on my GPU machine.
The reason seems to be that cMin and cIce[i] are of different types, but
I've tried casting cIce[i] to FloatType and that doesn't help.
Left in some debug code that I didn't want to commit. I've removed it
now.
They were the changes in slab thickness, but everything should be
volumetric - it makes things easier.
Just use a salt flux to nudge in the numerator of the sssSlab equation.
Not doing so was just a silly mistake.
That involved fixing the tests and fixing bugs.
Kokkos doesn't like std, so use Utils. One use of _ft to prevent
promotion to float.
@einola
einola marked this pull request as draft August 21, 2026 06:53
einola added 3 commits August 21, 2026 09:16
The default in old nextsim was 30 days, but that seems to be too long
here. The reason is probably that in the Lagrangian version, the slab
ocean is advected with the ice, so excessively saline waters created in
polynyas will be transported away from the coast. I could probably try
to find a more nuanced value than one week, but it's good enough for a
default.
@einola
einola marked this pull request as ready for review August 24, 2026 05:41
I don't need an `if (cice[i] > 0)` any more when setting things to zero
for too little ice. This is because there is no division by cice[i] now,
 after I changed the meaning of deltaHi.
@einola

einola commented Aug 24, 2026

Copy link
Copy Markdown
Member Author

It now runs for a full year with ok looking results (since we don't have snow cover or precipitation).

The only thing to note is that I can get it to work with DG1 only. With DG2, I get a crash in the dynamics. This should be a different issue.

@Thanduriel Thanduriel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Works for me. In fact, DG2 looks ok as well. I am still running with a time-step of 5min and 120 BBM sub-steps.

Image

A closer look at the solutions in december:
Image

@einola
einola merged commit fcfe561 into develop Aug 26, 2026
9 checks passed
@einola

einola commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

@Thanduriel Thanks for confirming it works. I'll try DG2 again, but I'm confused as to why it didn't work for me. Can you add the config file you used to this PR?

@Thanduriel

Thanduriel commented Aug 26, 2026

Copy link
Copy Markdown
Member
[model]
init_file = init_6.25km_NH_open.nc
start = 2010-01-01T00:00:00Z
stop = 2010-12-31T00:00:00Z
time_step = P0-0T00:05:00


[Modules]
DiagnosticOutputModule = Nextsim::ConfigOutput
DynamicsModule = Nextsim::BBMDynamics
IceThermodynamicsModule = Nextsim::ThermoWinton
AtmosphereBoundaryModule = Nextsim::ERA5Atmosphere
OceanBoundaryModule = Nextsim::TOPAZOcean

[ConfigOutput]
period = P0-8T00:00:00
start = 2010-01-01T00:00:00Z
field_names = hsnow,hice,tice,cice,tsurf,damage,u,v
filename = realistic_6.25km_bbm_dg2_oceanfix.nc

[ERA5Atmosphere]
file = 6.25km_NH.ERA5_2010-01-01_2010-12-31.nc

[TOPAZOcean]
file = 6.25km_NH.TOPAZ4_2010-01-01_2010-12-31.nc

[debug]
check_fields = true

Build options:

  "-DWITH_THREADS=ON",
  "-DWITH_KOKKOS=ON",
  "-DKokkos_ENABLE_CUDA=ON",
  "-DDynamicsType=DG2",
  "-DBUILD_TESTS=OFF",
  "-DENABLE_MPI=OFF",
  "-DUSE_SINGLE_PRECISION=OFF",

@einola

einola commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

DG2 works for me now as well. Don't know what I did wrong before, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Instability related to SlabOcean

2 participants