Skip to content

Connect ATM's u/v to WAV's u10m/v10m if ATM doesn't produce u10m/v10m - #706

Merged
billsacks merged 2 commits into
ESCOMP:mainfrom
billsacks:ww3_fill_10m_fields
Oct 2, 2026
Merged

billsacks merged 2 commits into
ESCOMP:mainfrom
billsacks:ww3_fill_10m_fields

Conversation

@billsacks

@billsacks billsacks commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Description of changes

The latest version of WW3 expects Sa_u10m and Sa_v10m. CESM doesn't produce these fields from CAM. So connect CAM's Sa_u and Sa_v to WAV's Sa_u10m and Sa_v10m in this case. This is possibly problematic scientifically, but maintains the original behavior before the recent WW3 update.

This fixes a major bug in the coupling of WW3 within CESM, where WW3 was receiving 0 values for winds and therefore producing no waves.

Specific notes

Contributors other than yourself, if any: @briandobbins @mvertens

CMEPS Issues Fixed (include github issue #):

Are changes expected to change answers? (specify if bfb, different at roundoff, more substantial) - Changes answers for CESM cases with WW3: more substantial! (Fixes a major bug in the coupling of WW3 in CESM.) (Answer changes expected in B compsets, not CW or GW compsets.)

Any User Interface Changes (namelist or namelist defaults changes)? NO

Testing performed

Three sets of tests:

(1) Testing in the context of cesm3_0_beta09, with ww3 updated to the latest (main_0.1.1) and cmeps updated to this branch. Before the changes on this branch, updating ww3 and cmeps to their latest version resulted in extensive unintended answer changes relative to the beta09 baseline.

I ran the subset of prealpha tests that use WW3:

ERS.TL319_t232_wg37.GW_JRA.derecho_intel
ERS.TL319_t233.GW_JRA.derecho_intel
ERS_Ld5.TL319_t201.GW_JRA.derecho_intel
ERS_Ld5.ne30pg3_t232.B1850C_LTso.derecho_intel.allactive-defaultio
ERS_Ld5.ne30pg3_t232.BHISTC_LTso.derecho_intel.allactive-defaultio
ERR_Ld5.ne30pg3_t232.B1850C_LTso.derecho_gnu.allactive-defaultio
ERS_Ld5.ne30pg3_t232.B1850C_LTso.derecho_intel.allactive-decstart
ERS_Ld5.ne30pg3_t232.BHISTC_LTso.derecho_intel.allactive-decstart
ERI.ne30pg3_t232.B1850C_LTso.derecho_intel.allactive-defaultio
SMS_Ld2.ne30pg3_t232.B1850C_LTso.derecho_gnu.allactive-defaultio
SMS_Ld2.ne30pg3_t232.B1850C_MTt4s.derecho_gnu.allactive-defaultio
MCC.ne30pg3_t232.B1850C_MTt4s.derecho_intel.allactive-defaultio
PET_PM.ne30pg3_t232.B1850C_LTso.derecho_gnu.allactive-defaultiomi
PET_PM.ne30pg3_t232.B1850C_LTso.derecho_intel.allactive-defaultiomi
PFS.ne30pg3_t232.B1850C_LTso.derecho_intel.allactive-defaultio
PFS.ne30pg3_t232.B1850C_LTso.derecho_gnu.allactive-defaultio
ERS_D_Ld3.ne30pg3_t232.B1850C_LTso.derecho_intel.allactive-defaultio
ERS_Ld5.ne30pg3_t232.B1850C_LTso.derecho_gnu.allactive-defaultio--drv-asyncio1node

These tests pass (other than expected failures) and are effectively bit-for-bit, though with the following differences that are due to the earlier ww3 and cmeps update (not this PR):

  • ww3 hist file: differs only in field lists
  • cpl.hx.ww3: differs only in time and time_bnds
  • cpl.hi: differs only in field lists

(2) Testing in the context of cesm3_0_beta10 (which already has the updated ww3). Baselines were created with cesm3_0_beta10 but with cmeps at cmeps1.1.72 instead of cmeps1.1.71. Tests were then run with cmeps updated to this branch.

For this testing, I ran the aux_ww3 tests, which are expected to be bit-for-bit with this change:

SMS_Ld1.TL319_t232.CW_JRA.derecho_gnu
SMS_D_Ld1.TL319_t232_wg37.GW_JRA.derecho_intel
ERS.TL319_t232_wg37.GW_JRA.derecho_intel
ERI.TL319_t232.GW_JRA.derecho_intel
SMS.TL319_t232.GW_JRA.derecho_gnu.ww3-legacy_cpl

All of those tests passed and were bit-for-bit with baselines.

(3) Same setup as (2), but introducing a deliberate bug and verifying that baselines fail.

For this, I just ran one test: SMS_Ld1.TL319_t232.CW_JRA.derecho_gnu. I introduced this diff in the JRA forcing mode:

diff --git a/datm/datm_datamode_jra_mod.F90 b/datm/datm_datamode_jra_mod.F90
index 058539f..2de2eb1 100644
--- a/datm/datm_datamode_jra_mod.F90
+++ b/datm/datm_datamode_jra_mod.F90
@@ -285,7 +285,7 @@ contains
        Sa_z(n) = 10.0_R8
 
        ! Set Sa_u10m and Sa_v10m to Sa_u and Sa_v
-       Sa_u10m(n) = Sa_u(n)
+       Sa_u10m(n) = Sa_u(n) * 2._r8
        Sa_v10m(n) = Sa_v(n)
 
        ! density computation for JRA55 forcing

and then, separately, a similar diff where I modified Sa_v10m instead of Sa_u10m.

I verified that, with this change, there were extensive answer changes. Since JRA forcings provide identical Sa_u and Sa_u10m (and similarly for Sa_v / Sa_v10m), I believe that the answer changes in the test with this diff verify that we're properly using Sa_u10m and Sa_v10m when they're available, rather than accidentally connecting to Sa_u and Sa_v in this case.

I also verified that the correct fields were connected via this:

diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90
index 021f11b4..3a99a798 100644
--- a/mediator/esmFldsExchange_cesm_mod.F90
+++ b/mediator/esmFldsExchange_cesm_mod.F90
@@ -3322,12 +3322,14 @@ contains
              ! If possible, connect ATM's Sa_u10m to WAV's Sa_u10m
              call addmap_from(compatm, 'Sa_u10m', compwav, mapbilnr, 'one', atm2wav_map)
              call addmrg_to(compwav, 'Sa_u10m', mrg_from=compatm, mrg_fld='Sa_u10m', mrg_type='copy')
+             if (maintask) write(logunit, '(a)') 'WJS: connecting Sa_u10m to WAV'
           else if (fldchk(is_local%wrap%FBImp(compatm,compatm ), 'Sa_u', rc=rc)) then
              ! ATM doesn't export Sa_u10m. But it exports Sa_u, so connect that to WAV's
              ! Sa_u10m. This is scientifically incorrect, but is how CESM has been set up
              ! to couple WAV.
              call addmap_from(compatm, 'Sa_u', compwav, mapbilnr, 'one', atm2wav_map)
              call addmrg_to(compwav, 'Sa_u10m', mrg_from=compatm, mrg_fld='Sa_u', mrg_type='copy')
+             if (maintask) write(logunit, '(a)') 'WJS: connecting Sa_u to WAV'
           end if
        end if
     end if
@@ -3347,12 +3349,14 @@ contains
              ! If possible, connect ATM's Sa_v10m to WAV's Sa_v10m
              call addmap_from(compatm, 'Sa_v10m', compwav, mapbilnr, 'one', atm2wav_map)
              call addmrg_to(compwav, 'Sa_v10m', mrg_from=compatm, mrg_fld='Sa_v10m', mrg_type='copy')
+             if (maintask) write(logunit, '(a)') 'WJS: connecting Sa_v10m to WAV'
           else if (fldchk(is_local%wrap%FBImp(compatm,compatm ), 'Sa_v', rc=rc)) then
              ! ATM doesn't export Sa_v10m. But it exports Sa_v, so connect that to WAV's
              ! Sa_v10m. This is scientifically incorrect, but is how CESM has been set up
              ! to couple WAV.
              call addmap_from(compatm, 'Sa_v', compwav, mapbilnr, 'one', atm2wav_map)
              call addmrg_to(compwav, 'Sa_v10m', mrg_from=compatm, mrg_fld='Sa_v', mrg_type='copy')
+             if (maintask) write(logunit, '(a)') 'WJS: connecting Sa_v to WAV'
           end if
        end if
     end if

The latest version of WW3 expects Sa_u10m and Sa_v10m. CESM doesn't
produce these fields from CAM. So connect CAM's Sa_u and Sa_v to WAV's
Sa_u10m and Sa_v10m in this case. This is possibly problematic
scientifically, but maintains the original behavior before the recent
WW3 update.
@billsacks

Copy link
Copy Markdown
Member Author

@alperaltuntas - FYI

@billsacks
billsacks requested a review from mvertens October 1, 2026 13:11
@billsacks

Copy link
Copy Markdown
Member Author

@mvertens - in addition to your code review of this change, it would be great if you can run at least one test of this in NorESM to confirm that this doesn't change answers for NorESM cases that use WW3 with the u10m and v10m forcings.

@billsacks

Copy link
Copy Markdown
Member Author

@fischer-ncar - FYI - when this comes into a CESM tag, this will change answers for B compsets and GW compsets.

@billsacks

Copy link
Copy Markdown
Member Author

I have run more testing on this PR: As @alperaltuntas suggested, I have verified that aux_ww3 tests (which use DATM rather than CAM) are bit-for-bit with this change. In addition, I ran a test where I deliberately introduced a bug in the Sa_u10m or Sa_v10m forcing from JRA, to verify that we're properly connecting the atm's Sa_u10m and Sa_v10m to wav rather than incorrectly using Sa_u and Sa_v.

This is documented in detail in the top-level comment in the PR.

@mvertens - I think this covers the type of testing that you were going to do in NorESM - i.e., verifying that, in a configuration with Sa_u10m and Sa_v10m, we're indeed still using Sa_u10m and Sa_v10m with these latest changes. Let me know if you still want us to wait to merge this... depending on timelines here, we may go ahead and merge it if it's needed to move ahead with alpha testing.

@billsacks
billsacks merged commit 869eed8 into ESCOMP:main Oct 2, 2026
1 check passed
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