Skip to content

Conversation

@simone-silvestri
Copy link
Collaborator

This is an exploratory PR to use ClimaOcean to force a veros setup.

This exercise is also usefull to make sure that ClimaOcean does not necessarily assume that the ocean model comes from Oceananigans but it is flexible enough to handle different ocean configurations.

@simone-silvestri simone-silvestri added the build docs Add this label to built the docs in a PR label Nov 11, 2025
@glwagner
Copy link
Member

glwagner commented Dec 4, 2025

@simone-silvestri looks like this is a bit stale, is there a possibility of refreshing it?

The interesting exercise here is to couple veros and SpeedyWeather I think now that we have the SpeedyWeather extension.

v :: CF
T :: CC
S :: CC
end
Copy link
Member

Choose a reason for hiding this comment

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

is it not possible to use a general exchanger? Do we need special exchangers for each component?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think we can use a general exchanger. We need to add "ocean" fields that point to the already existing fields in case of an OceananigansSimulation, or more generally, in case of an ocean simulation which matches the exchanger grid.


s = []
tx = []
ty = []
Copy link
Member

@glwagner glwagner Dec 4, 2025

Choose a reason for hiding this comment

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

why can't you use a regular JLD2Writer? I think that would be preferred, to illustrate the user interface which is important.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah, I meant to change it, this was an initial validation case where is just simpler and faster to code it up like this.

Copy link
Member

Choose a reason for hiding this comment

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

ok, makes sense

taux = view(parent(net_ocean_fluxes.u), 1:nx, 1:ny, 1) .* ρₒ
tauy = view(parent(net_ocean_fluxes.v), 1:nx, 1:ny, 1) .* ρₒ

# TODO: Do not do this 12 thingy when we can make sure
Copy link
Member

Choose a reason for hiding this comment

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

what is the "12 thingy"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this veros setup hardcodes a linear interpolation between climatology (for momentum stress) defined as an array with of Nx, Ny, Nt where Nt is 12. To make sure we have the correct momentum flux we need to substitute all 12 time-indices of the climatology. I wanted to have only one forcing array which we can substitute into, but it looks like the interpolation is embedded into the rhs-forcing. I forgot to follow up on the veros issue, asking for this change 😅 .

Copy link
Member

Choose a reason for hiding this comment

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

Is that only a feature of this particular setup (eg other veros setups are more flexible)?

Copy link
Member

Choose a reason for hiding this comment

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

@meteorologytoday maybe has advice on more flexible veros setups

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Is that only a feature of this particular setup (eg other veros setups are more flexible)?

actually I am not necessarily sure about veros' API. It seems that there are preconfigured setups that can be used by defining custom initial condition functions, boundary conditions and so on... so that part looks a bit more oceananigans-like. On the other hand, there seems to be options which require namelist inputs, a bit more a-la-fortran per se. The lines I am referring at are these ones: https://github.com/team-ocean/veros/blob/a6b526f0e648f9fd12bc7d385d9aed7ca46afb78/veros/setups/global_4deg/global_4deg.py#L171-L194
So it seems that these taux and tauy objects, belong to the setup rather than the actual veros class
https://github.com/team-ocean/veros/blob/a6b526f0e648f9fd12bc7d385d9aed7ca46afb78/veros/setups/global_4deg/global_4deg.py#L92-L99

Copy link
Member

Choose a reason for hiding this comment

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

Copy link

@meteorologytoday meteorologytoday Dec 6, 2025

Choose a reason for hiding this comment

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

I am not sure what would be the best way, but I can share my thought from jax-gcm's perspective, hopefully it is relatable.

Jax-gcm used to have this "365 thingy". I believe this is because they were initially thinking about one-way forcing, meaning this annual cycle is not part of the jitted parameters, i.e., a fixed annual cycle. Once the model-advancing function is jitted, the non-jitted variables are frozen and cannot be changed. Therefore, the jitted function needs to know the entire annual cycle during the first invocation. Otherwise, the model has to jit all possible forcing, which is 365 times in their case.

In the recent update, jax-gcm team made the forcing part of the jitted parameter (see https://github.com/climate-analytics-lab/jax-gcm/blob/aae23a0e0ccf689d2c19f4a2d3b206276fc57a0e/jcm/model.py#L423-L430), and allowed the forcing to be 2- or 3-dimensional (see https://github.com/climate-analytics-lab/jax-gcm/blob/aae23a0e0ccf689d2c19f4a2d3b206276fc57a0e/jcm/physics/speedy/speedy_physics.py#L123 and https://github.com/climate-analytics-lab/jax-gcm/blob/aae23a0e0ccf689d2c19f4a2d3b206276fc57a0e/jcm/utils.py#L113). Therefore, user can feed in real-time forcing, and reuse the jitted function.

If that is what is happening here, I believe what makes the most sense is to ask Veros team to allow their design to be more flexible, just as jax-gcm does. But for the purpose of a workable version, yes, it will inevitably look a bit ugly at the moment.

setup = @eval $setups.$setup_name()

# instantiate the setup
setup.setup()
Copy link
Member

Choose a reason for hiding this comment

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

is setup the best name for this object, given that it has a method called setup()? Perhaps the function setup() should be something like instantiate() so it's out of our control...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed, setup() is the veros method, so we cannot change it. We can change the first setup although I agree with you that I tend to think as a setup as something concrete (like a type) rather than a method.
We can maybe name it configuration?

Copy link
Member

Choose a reason for hiding this comment

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

configuration seems good to me. Then "set up" is a verb.

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

Labels

build docs Add this label to built the docs in a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants