E3SM-Project / scream

Fork of E3SM used to develop exascale global atmosphere model written in C++
https://e3sm-project.github.io/scream/
Other
80 stars 55 forks source link

Enable regional nudging #2419

Open PeterCaldwell opened 1 year ago

PeterCaldwell commented 1 year ago

In regionally refined runs we often want to nudge the coarse region to reanalysis while we let the fine-resolution region evolve naturally. This is how we turn the RRM into a computationally affordable regional model without needing to build the infrastructure for actually supporting a regional model. It is also sometimes illuminating to nudge one area of the globe (e.g. tropics) while letting other regions evolve on their own.

Our plan for enabling regional nudging in EAMxx is to just read in an array of the same dimensions as the grid we're running on which is 1 where nudging is to be fully applied, 0 where nudging should be ignored, and a real between 0 or 1 if a transition region is desired. This array will be multiplied by the computed nudging tendencies before they are used to update any state variables.

I think the steps for implementing this will be:

  1. write a python code that takes in some output variable on the physics grid for the desired simulation, then uses its lat and lon attributes to create our weighting array (e.g. if lat>-20 and lat<20 and lon>120 and lon<160 then nudging_weights=0, else nudging_weights=1). Write that weighting array out to a netcdf file. Save that python code in the scream_docs repo and write confluence documentation for using it.
  2. start from Aaron's PR #2378 and its aarondonahue/nudging branch (unless it is already merged, which will hopefully be the case). This PR is the place to start because it cleans up our nudging implementation.
  3. Add a namelist entry for reading in a nudging_weights file. If this entry is empty, assume nudging is global and create a nudging_weights array which is 1 everywhere.
  4. Add code for reading in nudging_weights array assuming a nudging_weights file is specified. This array only needs to be read in 1x at init because we will apply these weights equally at each timestep. We will also assume the weights are defined on the grid the model is running on, so there's no need to do horizontal interpolation. The array won't include a vertical dimension because we will assume all levels are weighted equally (though try to code things so we could extend the code later to handle arrays with a vertical dimension - sometimes people like nudging differently in the stratosphere).
  5. Multiply the nudging tendency calculated online by nudging_weights. I think this should happen on this line, but I don't fully understand what the line is doing: https://github.com/E3SM-Project/scream/blob/af26a9a0cec980f6aaff2c9677dd87f69e0578e0/components/eamxx/src/physics/nudging/eamxx_nudging_process_interface.cpp#L73 . You will probably need to resize nudging_weights to have vertical extent (by just copying the value for a given latitude across all levels for that latitude).
  6. Add tests that if nudging_weights is zero everywhere we get the same solution as if no nudging was going on and if nudging_weights is 1, we get the same answer as we got with nudging prior to this addition. Also add assert statements that max(nudging_weights)<=1 and min(nudging_weights)>=0. Add a test where nudging is only applied in some latitude/longitude band and ensure that the nudging tendencies from output are zero and nonzero where we expect.

Pinging @paullric, @tangq, @bogensch since I think they have been using regional nudging and might have opinions about whether my approach is dumb. Pinging @AaronDonahue and @rebassoo since they created the nudging code and might be able to correct my mistaken assumptions.

tangq commented 1 year ago

@PeterCaldwell , since you mentioned the nudging application for stratosphere, it is worth noting the QBO nudging experiments E3SM participated, which requires a function than a real between 0 or 1 for the transition region. This function is available in the Fortran nudging code, so it is straightforward to configure such QBOi simulations. Would be nice to have a similar capability in EAMxx, e.g., having the option to specify a transition function.

The QBOi nudging protocol:

Screen Shot 2023-07-08 at 12 13 06 AM Screen Shot 2023-07-08 at 12 13 27 AM
PeterCaldwell commented 1 year ago

In the face of a concrete example where different nudging strength is needed in the vertical, I propose we just always insist that users supply a 3d weight array. This will simplify the c++ code and maximize generality. @xyuan