Skip to content

moved the Forcing to its own IO#443

Open
alicebarthel wants to merge 4 commits into
E3SM-Project:developfrom
alicebarthel:omega/add-forcing-io
Open

moved the Forcing to its own IO#443
alicebarthel wants to merge 4 commits into
E3SM-Project:developfrom
alicebarthel:omega/add-forcing-io

Conversation

@alicebarthel

@alicebarthel alicebarthel commented Jun 24, 2026

Copy link
Copy Markdown

This PR updates the code to expect the forcing from a dedicated forcing IO (by Default forcing.nc)

A polaris PR is required to update the tests to read forcing from forcing.nc instead of the init.nc, under development at https://github.com/alicebarthel/polaris/tree/update-forcing-io

Checklist

  • Linting
  • Building
    • CMake build does not produce any new warnings from changes in this PR
  • Testing
    • CTest unit tests - all pass on pm-cpu (gnu) - see below re. additional files
    • The Polaris omega_pr test suite
      has passed, using the Polaris e3sm_submodules/Omega baseline
      • Polaris tests updates TBD
  • Stealth Features
    • If any stealth features are included in the PR, please confirm that they have been documented.

@alicebarthel

Copy link
Copy Markdown
Author

The following tests FAILED:
19 - IOSTREAM_TEST (Failed)
23 - FORCING_PLANE_TEST (Failed)
24 - FORCING_SPHERE_TEST (Failed)
25 - TENDENCIES_TEST (Failed)
27 - STATE_TEST (Failed)
35 - DRIVER_TEST (Failed)
Errors while running CTest

but the omega.log only shows expected errors. I'll investigate more tomorrow.

void Forcing::readStreamIntoArrays() {
Error Err;

Real FillValueReal = -999._Real;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should we be doing anything here to make it consistent with #428 or is the change best made after #428 is merged?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yes, I am aware of the overlap/conflict with #428.
My thought was to get that one in first and then update asap for #428. Or vice versa if #428 gets merged first.
I am not sure how to make this section consistent with #428 and test it without the whole #428 change.


std::string StreamName = "Forcing";

// Attempt to read stream; if unavailable, log and fall back to zero forcing.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Does it fall back to zero forcing because all forcing tendencies will be computed and applied with zeros?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yes, if the tendency flag is on but the forcing stream is missing, it defaults the forcing to zero and calculates the tendencies. If the tendency flag is off, then it skips the tendency calculation.
We can change that behavior later if we want a visible fail, the idea here was to write it in the log and proceed without failing.

@andrewdnolan andrewdnolan Jun 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@cbegeman I suggested this; in order to produce as few breaking changes as possible. With us staring down the coupling deadline, I figure this might be worth it (though in generally it's not the best practice).

I think if we are OK with this for now, we should open up a linked issue about "failing fast" here. We can circle back to this after delivering a first pass at the coupled model.

I don't want to speak for @alicebarthel, but I don't think we are that tied to this approach. We are just trying to mindful of the work left and timeline. If people feel very strongly against defaulting to zeros, then I'd think we are okay with dropping this and just failing if the read is unsuccessful.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is there a check for whether any forcing tendency is on before we attempt to load the forcing stream? I.e., if we leave off the default-to-zero feature and the forcing stream is not provided, will the simulation always fail?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

There isn't a check on the tendency flag before the Forcing::init() or read from file.
Because the tendency flags are per forcing type, I didn't think of that since I expect most longer cases to have some forcing, but for the spin-down ones, we may be able to skip this altogether?
A check on whether at least one forcing flag exists is worth considering...

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't feel strongly that we need to run through all forcing flags before trying to read from the forcing stream. My concern with default-to-fill-value right now is that we may be introducing a requirement to provide a forcing file for all cases.

It could be good in the long run to have: if SfcStressForcingTendencyEnable is True, throw a critical error if SfcStressZonal and SfcStressMeridional are not included in the forcing stream (and do the same for other forcing fields and their corresponding flags).

I'm fine with default-to-zero for now as long as we open an issue that this needs to be fixed later.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed! I'll open an issue.
The key point of default to zero was indeed to avoid introducing a forcing file requirement for now.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Great. Glad we're on the same page

@alicebarthel

alicebarthel commented Jun 26, 2026

Copy link
Copy Markdown
Author

OK, here is an update:

  • because we added forcing into the yml file, IOStreams validateAll() now needed the forcing fields to be registered and a forcing file to be present --> i added these inits for the dependencies in IOStreams and StateTest.
  • to keep the coverage of the computeStress test, I had shifted the forcing test to have a SPHERE and a PLANE test at run time (based on existing tests). Thus this requires forcing files with the corresponding nCells dimensions. I have made these files manually and now call a different name for each forcing test (mirroring the treatment of the mesh at run time).

The ctests now all pass on pm-cpu (gnu).
They require the 3 new forcing files available on perlmutter at:
/global/homes/a/abarthel/pscratch/omega_scratch

I typically copy these in my base directory the run in each case directory:

cd test
ln -sf  ../../forcing_nCells_7153.nc forcing.nc
ln -sf  ../../forcing_nCells_2304.nc forcingPlanar.nc
ln -sf  ../../forcing_nCells_2562.nc forcingSphere.nc
cd ..

At this stage, anyone testing this PR with ctests should also fetch these.
Ultimately, these will be moved to be with the meshes if we keep this structure.

# and the surface restoring target files (if appl.).
Forcing:
UsePointerFile: false
Filename: forcing.nc

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

not saying we should do this, but could we set this to init.nc to delay the need for a polaris PR?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think this could be helpful for the tests that do not have any forcing. It would be weird to me to create an (empty?) forcing file for cases that wouldn't otherwise need one.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think it would be better to alter the logic so the forcing stream isn't read if it's not needed. Pointing to an unrelated file by default seems like a messy solution to me.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Or to comment out the forcing stream by default.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We could change the FreqUnits to never for now. And manually change to OnStartup for the few test we actually need it?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yes, I think that's the right solution.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

That sounds ideal. @alicebarthel Could you use this approach in a companion Polaris PR and check that it works as expected?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, I like this approach. I'll look into it and check its behavior.

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.

5 participants