Skip to content

refactor nudging code to use cdeps on line remapping and interpolation#243

Open
mvertens wants to merge 23 commits intoNorESMhub:noresm_developfrom
mvertens:feature/refactor_nudging
Open

refactor nudging code to use cdeps on line remapping and interpolation#243
mvertens wants to merge 23 commits intoNorESMhub:noresm_developfrom
mvertens:feature/refactor_nudging

Conversation

@mvertens
Copy link

@mvertens mvertens commented Oct 30, 2025

Summary: refactor nudging code to use cdeps on line remapping and interpolation

Contributors: @gold2718

Reviewers: @gold2718

Purpose of changes:
The current nudging code (nudging.F90) requires a single file for every time sample - and often this is every 6 hours. In addition it does not do any mapping from the forcing data to the model grid. Using the CDEPS inline functionality along with its capability to do online horizontal regridding (including for multiple vertical levels) and time interpolation the nudging code has been completely refactored. With this new code - monthly nudging data can be read at just one resolution and the model vertical levels and used with any model grid.
The one change that comes with this is if there is missing data. In the original scheme, if missing data was encountered then the model 'coasted' through the forcing interval and was not nudged. In the new scheme, the time interpolation (linear or upper) is used with the actual data that is available.

To see more details of the inline functionality from CDEPS used here see: https://escomp.github.io/CDEPS/versions/master/html/index.html and in particular https://escomp.github.io/CDEPS/versions/master/html/streams.html#data-model-stream-inline-api

Changes made to build system: None

Changes made to the namelist: The following new namelist variables were introduced:
Nudge_Filenames, Nudge_Meshfile, Nugde_beg_day, Nudge_beg_month, Nudge_beg_year, Nudge_end_day, Nudge_end_month, Nudge_end_year, Nudge_file_times_per_day, Model_update_times_per_day

Changes to the defaults for the boundary datasets: None

Substantial timing or memory changes: TODO - the expectation is that the new code should be faster than the old one since a new file does not have to be opened and closed at every nudging time step. This needs to be confirmed.

Validation:
The following validation was run. using a noresm3_0_beta09 sandbox with this PR and the CDEPS PR NorESMhub/CDEPS#26. Two simulations were done - a reference simulation and a nudging to the reference simulation.

Reference Simulation:

/create_newcase --case /cluster/home/mvertens/noresm/NF1850_ne16pg3_ne16pg3_mtn14_b09_ref --compset 1850_CAM70%LT%NORESM%CAMoslo_CLM60%SP_CICE%PRES_DOCN%DOM_MOSART_DGLC%NOEVOLVE_SWAV_SESP --res ne16pg3_ne16pg3_mtn14 --project nn9560
k --run-unsupported --mach betzy

with the following user_nl_cam

empty_htapes=.true.
nhtfrq = 0, -6, -1,
mfilt  = 1,  28, 168,
ndens  = 2,  2,  2,
fincl2 = 'PS:I','U:I','V:I','T:I','Q:I'
fincl3 = 'PS:I','U:I','V:I','T:I','Q:I','U850:I','V850:I','T850:I','Z500:I'
fincl3lonlat = '11e_60n'

zmconv_c0_lnd             = 0.0075D0
zmconv_c0_ocn             = 0.0075D0
zmconv_ke                 =  5.0E-6
zmconv_ke_lnd             =  1.0E-5
dust_emis_fact            = 6.1D0
clim_modal_aero_top_press = 1.D-4
micro_mg_dcs              = 700.D-6
clubb_c8                  =  5.0D0

Nudging Simulation:

./create_newcase --case /cluster/home/mvertens/noresm/NF1850_ne16pg3_ne16pg3_mtn14_b09_nudging --compset 1850_CAM70%LT%NORESM%CAMoslo_CLM60%SP_CICE%PRES_DOCN%DOM_MOSART_DGLC%NOEVOLVE_SWAV_SESP --res ne16pg3_ne16pg3_mtn14 --project nn
9560k --run-unsupported --mach betzy

The following was set in user_nl_cam:

&nudging_nl
Nudge_Model         = .true.
Nudge_Datapath      = '/cluster/work/users/mvertens/archive/NF1850_ne16pg3_ne16pg3_mtn14_b09_ref/atm/hist'
Nudge_Filenames     = 'NF1850_ne16pg3_ne16pg3_mtn14_b09_ref.cam.h1i.0001-01-01-21600.nc',
                      'NF1850_ne16pg3_ne16pg3_mtn14_b09_ref.cam.h1i.0001-01-08-21600.nc',
                      'NF1850_ne16pg3_ne16pg3_mtn14_b09_ref.cam.h1i.0001-01-15-21600.nc'
Nudge_Meshfile      = '/cluster/shared/noresm/inputdata/share/meshes/ne16pg3_ESMFmesh_cdf5_c20211018.nc'
Nudge_TimeScale_Opt = 0
Nudge_Force_Opt     = 1
Nudge_Uprof         = 1
Nudge_Ucoef         = 1.0
Nudge_Vprof         = 1
Nudge_Vcoef         = 1.0
Nudge_Tprof         = 0
Nudge_Tcoef         = 0.0
Nudge_PSprof        = 0
Nudge_PScoef        = 0.0
Nudge_Qprof         = 0
Nudge_Qcoef         = 0.0
Nudge_beg_year      = 1
Nudge_beg_month     = 1
Nudge_beg_day       = 2
Nudge_end_day       = 14
Nudge_end_month     = 1
Nudge_end_year      = 1
Nudge_taxmode       = 'limit'
Model_update_times_per_day = 48
!
empty_htapes       =.true.
nhtfrq             = 0, -6, -1,
mfilt            = 1,  28, 168,
!mfilt             = 1,   1,   1
ndens              = 2,  2,  2,
fincl2             = 'PS:I','U:I','V:I','T:I','Q:I','Target_U','Target_V','Nudge_U','Nudge_V'
fincl3             = 'PS:I','U:I','V:I','T:I','Q:I','U850:I','V850:I','T850:I','Z500:I',
                     'Target_U','Target_V','Nudge_U','Nudge_V'
fincl3lonlat       = '11e_60n'
!
zmconv_c0_lnd             = 0.0075D0
zmconv_c0_ocn             = 0.0075D0
zmconv_ke                 =  5.0E-6
zmconv_ke_lnd             =  1.0E-5
dust_emis_fact            = 6.1D0
clim_modal_aero_top_press = 1.D-4

Following is the nudging validation:

Screenshot 2025-12-25 at 12 27 27 PM

[ List each test suite run. For each suite, include machine, compiler, and any test failures.
For each failure, include the contents of TestStatus or the output from cs.status.testid for that test ]

Issues addressed by this PR: [ For each issue include a GitHub issue entry, one per line. ]

@mvertens mvertens force-pushed the feature/refactor_nudging branch from 40ad302 to 875a455 Compare December 20, 2025 22:21
@mvertens mvertens marked this pull request as ready for review December 30, 2025 16:52
@Ovewh
Copy link
Collaborator

Ovewh commented Jan 12, 2026

Plot for the same nudged and reference simulation, but of surface pressure:

image

Copy link

@gold2718 gold2718 left a comment

Choose a reason for hiding this comment

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

This work will be a great improvement to NorESM/CAM!

  • I have a few questions and a bunch of (hopefully easy) change requests.
  • I have included a set of change requests to refactor how the model is aligned with the nudging data. This is to allow nudging to be turned on and off during a model run while independently choosing which nudging data to use.
  • Consider moving the cnst_get_ind call in timestep_init to init and make the Q index a module variable. Then, you can remove the call in nudging_timestep_tend (it is not the cheapest function).

Comment on lines +241 to +245
<entry id="Nudge_lev_dimname" type="char*256" category="nudging"
group="nudging_nl" valid_values="" >
Name of vertical dimension in file.
Default: none
</entry>

Choose a reason for hiding this comment

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

Do we need this if we have Nudge_levname (introduced below)? You can easily find the dimension name from the variable name if needed (they should be the same for a coordinate variable).
In addition, it is not used anywhere in the code.
Please remove.

use spmd_utils, only: mpi_integer, mpi_real8, mpi_logical, mpi_character
use cam_logfile, only: iulog
use zonal_mean_mod, only: ZonalMean_t
use ESMF

Choose a reason for hiding this comment

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

Please dress this naked use statement.

use ESMF , only : ESMF_DistGrid, ESMF_DistGridCreate
use ESMF , only : ESMF_Mesh, ESMF_MeshCreate, ESMF_MeshGet, ESMF_FILEFORMAT_ESMFMESH
use ESMF , only : ESMF_Clock, ESMF_ClockGet, ESMF_ClockSet, ESMF_ClockGetNextTime, ESMF_ClockAdvance
use ESMF , only : ESMF_CLockCreate

Choose a reason for hiding this comment

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

This is not used anymore, please remove

! Nudging will never occur, so switch it off
Nudge_Model = .false.
write(iulog,*) ' '
write(iulog,*) 'NUDGING: WARNING - Nudging has been requested by it will'
Copy link

Choose a reason for hiding this comment

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

Typo?

Suggested change
write(iulog,*) 'NUDGING: WARNING - Nudging has been requested by it will'
write(iulog,*) 'NUDGING: WARNING - Nudging has been requested but it will'

allocate(Nudge_PStau(pcols,begchunk:endchunk),stat=istat)
call alloc_err(istat,'nudging_init','Nudge_PStau',pcols*((endchunk-begchunk)+1))
allocate(Nudge_Utau0(pcols,pver,begchunk:endchunk),stat=istat)
call alloc_err(istat,subname,'Nudge_Utau',size3d)
Copy link

Choose a reason for hiding this comment

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

Please correct the error strings here and below?

Suggested change
call alloc_err(istat,subname,'Nudge_Utau',size3d)
call alloc_err(istat,subname,'Nudge_Utau0',size3d)

Copy link

Choose a reason for hiding this comment

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

I think that since the Nudge_begin and Nudge_end variables are model times, we need begin and end variables that are specific to the nudging dataset being used (similar to other uses of CDEPS stream info):

<entry id="nudge_data_year_first" type="integer" category="nudging"
       group="nudging_nl" valid_values="" >
First year to use in Nudge_Filenames dataset.
Default: none

<entry id="nudge_data_year_last" type="integer" category="nudging"
       group="nudging_nl" valid_values="" >
Last year to use in Nudge_Filenames dataset.
Default: none
</entry>

Nudge_Force_Opt, Nudge_TimeScale_Opt, &
Nudge_Beg_Year, Nudge_Beg_Month, Nudge_Beg_Day, &
Nudge_End_Year, Nudge_End_Month, Nudge_End_Day, &
Nudge_Align_Year, Nudge_Mapalgo, Nudge_Taxmode, &
Copy link

Choose a reason for hiding this comment

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

Based on my comments in namelist_definition.xml, I think this should be:

Suggested change
Nudge_Align_Year, Nudge_Mapalgo, Nudge_Taxmode, &
Nudge_Year_Align, nudge_data_year_first, nudge_data_year_last, Nudge_Mapalgo, Nudge_Taxmode, &

Also, nudge_data_year_first and nudge_data_year_last have to be declared above, and initialized and broadcast below.``


<entry id="Nudge_Align_Year" type="integer" category="nudging"
group="nudging_nl" valid_values="" >
Model year to align with Nudge_Beg_Year.
Copy link

Choose a reason for hiding this comment

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

Based on comments above, I think this could be clarified:

Suggested change
Model year to align with Nudge_Beg_Year.
Model (simulation) year to align with nudge_data_year_first.
If this is set to Nudge_Beg_Year, then nudging will begin with the beginning of the dataset.
If this is set to some other year, there will be an offset between the model year and the year in the nudging data currently being used.

Comment on lines +1596 to +1597
stream_yearFirst = nudge_year_first, &
stream_yearLast = nudge_year_last, &
Copy link

Choose a reason for hiding this comment

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

Based on comments above, I think this should be:

Suggested change
stream_yearFirst = nudge_year_first, &
stream_yearLast = nudge_year_last, &
stream_yearFirst = nudge_data_year_first, &
stream_yearLast = nudge_data_year_first, &

Comment on lines +1619 to +1620
stream_yearFirst = nudge_year_first, &
stream_yearLast = nudge_year_last, &
Copy link

Choose a reason for hiding this comment

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

Based on comments above, I think this should be:

Suggested change
stream_yearFirst = nudge_year_first, &
stream_yearLast = nudge_year_last, &
stream_yearFirst = nudge_data_year_first, &
stream_yearLast = nudge_data_year_first, &

@github-project-automation github-project-automation bot moved this from Todo to In Progress in NorESM Development Feb 6, 2026
Copy link

@gold2718 gold2718 left a comment

Choose a reason for hiding this comment

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

This work will be a great improvement to NorESM/CAM!

  • I have a few questions and a bunch of (hopefully easy) change requests.
  • I have included a set of change requests to refactor how the model is aligned with the nudging data. This is to allow nudging to be turned on and off during a model run while independently choosing which nudging data to use.
  • Consider moving the cnst_get_ind call in timestep_init to init and make the Q index a module variable. Then, you can remove the call in nudging_timestep_tend (it is not the cheapest function).

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

Labels

enhancement New feature or request

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

3 participants