Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4f5bb9a
First set of commits for the real case tutorial.
domingom Mar 21, 2025
bc6e5ae
Including accidentally left out cases_real.rst file
domingom Mar 21, 2025
cf40ad3
Fix relative path of files.
domingom Mar 21, 2025
1c11758
A first version of the 3 prepocessing steps
domingom Mar 21, 2025
8f61292
language none
domingom Mar 21, 2025
c23c5b2
First complete version of the real case tutorial.
domingom Apr 1, 2025
4658c12
Small fix to reference documention on build/run FastEddy.
domingom Apr 1, 2025
1895aa0
Remove Z0 and ZNT from the list of auxiliary fields necessary by GenI…
domingom Apr 1, 2025
6ea9c39
Updates to the dispersion tutorial
domingom Apr 7, 2025
53fde5c
update to plots of dispersion tutorial
domingom Apr 7, 2025
478891a
fix source file name in notebook
domingom Apr 7, 2025
eb9e0bd
Turn off 6th-order filter on the SBL/CBL dispersion tutorials
domingom Apr 7, 2025
d027afd
Plot from the real case run
domingom Apr 10, 2025
0532119
JAS review of Real case RTD text.
jsauer-NCAR Apr 10, 2025
55b6e66
Fixed a typo.
jsauer-NCAR Apr 10, 2025
b4636f9
Added a draft snippet on CP & TVCP parameters to section 4.2.
jsauer-NCAR Apr 11, 2025
07979d5
Fixed special formatting for mentioning parameters in text.
jsauer-NCAR Apr 11, 2025
040e610
minor adjustments to the RTD landing page authors section to include …
jsauer-NCAR Apr 11, 2025
29f929c
minor adjustments to landing page formatting
jsauer-NCAR Apr 11, 2025
3c04655
minor adjustments to landing page formatting
jsauer-NCAR Apr 11, 2025
427ab4f
minor adjustments to landing page formatting
jsauer-NCAR Apr 11, 2025
cf6c1ad
Final tweaks to the real case tutorial. Inclusion of the Example08_RE…
domingom Apr 11, 2025
657ceba
Little adjustment to tvcp text
domingom Apr 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions docs/Tutorials/cases/DISPERSION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,12 @@ Execute FastEddy

See :ref:`run_fasteddy` for general instructions on how to build and run FastEddy on NSF NCAR's High Performance Computing machines.

Note that this example requires customization of the initial condition file. Follow the sequence of steps below.

1. Create a working directory to run the FastEddy tutorials and change to that directory.
2. Create a **Example07_DISPERSION_SBL** subdirectory and change to that directory.
3. Copy the **tutorials/examples/Example07_DISPERSION_SBL.in** file into the **Example07_DISPERSION_SBL** subdirectory.
4. Execute the Jupyter notebook provided in **tutorials/notebooks/Dispersion_Prep1.ipynb** to create the topography file *Topography_504x498.dat*, which will be written to the **Example07_DISPERSION_SBL** subdirectory. Users will need to set code:`path_case` in the "Generate the WOA hill terrain file" section to specify the full path to and including the **Example07_DISPERSION_SBL** subdirectory. Be sure to include the trailing slash :code:`/`.
5. The FastEddy code will write its output to an **output** subdirectory. Create an **output** directory, if one does not already exist.
6. Run FastEddy for 1 timestep using the default state of the (*Example07_DISPERSION_SBL.in*) and required binary terrain file generated in the previous step, specified as input through the FastEddy parameter file (:code:`topoFile`). This step creates an output file *FE_DISPERSION.0* that includes the topography and establishes a terrain-following vertical coordinate grid.
7. Create an **initial** subdirectory under **Example07_DISPERSION_SBL**, if one does not already exist. Execute the Jupyter notebook provided in **tutorial/notebooks/Dispersion_Prep2.ipynb** to modify the surface roughness distribution over the hill. Running this Jupyter notebook will create a new *FE_DISPERSION.0* file in the **initial** subdirectory. Users will need to set code:`path_case` in the "Modify z0 after terrain has been incorporated" section to specify the full path to and including the **Example07_DISPERSION_SBL** directory. Be sure to include the trailing slash :code:`/`.
8. Execute the Jupyter notebook provided in **/tutorial/notebooks/Dispersion_Prep3.ipynb** to create the source specification input file. Users will need to set :code:`path_base` in the "Create the input file with AuxScalar information" section to specify the full path to and including the **Example07_DISPERSION_SBL** subdirectory. Be sure to include the trailing slash :code:`/`. Executing this notebook will produce a *Example07_sources.nc* file in the **Example07_DISPERSION_SBL** subdirectory.
9. Adjust the *Example07_DISPERSION_SBL.in* file to specify the targeted initial condition file (:code:`inPath`, :code:`inFile`) by removing the :code:`#` just to the right of the equal sign to uncomment these parameters values. Uncomment the pre-formed passive tracer source file (:code:`srcAuxScFile`). Remove the value of :math:`0` and uncomment the value of :math:`2` for the number of source emissions (:code:`NhydroAuxScalars`). Run FastEddy for :math:`1` h of the simulation by changing :code:`frqOutput`, :code:`Nt`, and :code:`NtBatch` removing the values of :math:`1` for each and the (:code:`#`) to uncomment appropriate full-simulation parameters values. The emissions begin :math:`45` min into the simulation.

Two FastEddy simulation setups are provided for this tutorial, corresponding to weakly stable (*Example07_DISPERSION_SBL.in*) and convective conditions (*Example07_DISPERSION_CBL.in*). The initial condition and terrain preparation steps only need to be carried out once for the stable case, then can be reused directly in the convective stability case. Additionally, the CBL case is set up to demonstrate the use of a rank-wise binary output mode in FastEddy for efficient dumping of the model state to file.
To run the convective case and exercise the binary output functionality, create a **Example07_DISPERSION_CBL** subdirectory and change to that directory. Create an **initial** subdirectory and copy the initial condition file from **Example07_DISPERSION_SBL/initial/** into the **Example07_DISPERSION_CBL/initial/** subdirectory. Create an **output_binary** subdirectory where binary files will be written during the simulation. Then personalize and use the batch submission script **/scripts/batch_jobs/fasteddy_convert_pbs_script_casper.sh** which will invoke a python script (**/scripts//python_utilities/post-processing/FEbinaryToNetCDF.py**) to convert the rank-wise binary files from each output timestep into a single aggregate NetCDF output file per timestep analogous to those resulting from the SBL case.
Note that this example requires creation of a terrain and source specification files. Follow the sequence of steps below.

1. Execute the Jupyter notebook provided in **tutorials/notebooks/Dispersion_PrepTerrain.ipynb** to create the topography file *Topography_504x498.dat* that corresponds to a Witch of Agnesi hill of 15 m height.
2. Execute the Jupyter notebook provided in **/tutorial/notebooks/Dispersion_PrepAuxSrc.ipynb** to create the source specification input file. This example will add two sources at the first vertical grid levels upstream (*x* = 930 m) and downstream (*x* = 1082 m) of the hill. The emissions begin :math:`45` min into the simulation.

Two FastEddy simulation setups are provided for this tutorial, corresponding to weakly stable (*Example07_DISPERSION_SBL.in*) and convective conditions (*Example07_DISPERSION_CBL.in*). The terrain preparation and source input file steps only need to be carried out once. Additionally, the CBL case is set up to demonstrate the use of a rank-wise binary output mode in FastEddy for efficient dumping of the model state to file. Personalize and use the batch submission script **/scripts/batch_jobs/fasteddy_convert_pbs_script_casper.sh** which will invoke a python script (**/scripts//python_utilities/post-processing/FEbinaryToNetCDF.py**) to convert the rank-wise binary files from each output timestep into a single aggregate NetCDF output file per timestep analogous to those resulting from the SBL case.

Visualize the output
--------------------
Expand Down
16 changes: 16 additions & 0 deletions docs/Tutorials/cases_real.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
***************
Real Test Cases
***************

Real cases are performed by dynamically downscaling from a mesoscale model such as WRF that can provide initial and boundary conditions for a one-way nested FastEddy simulation. These mesoscale-LES coupled simulations require the following preprocessing steps:

* Step 1: **GeoSpec**. Georeference specification step. Expectss a NetCDF-formatted file of location-specific, georeferenceed coordinate frame (lat/lon), projected cartesian coordinate frame (x,y), elevation and land cover to establish a new NetCDF file of reference geolocated domain static characteristics specification including mapping of land cover category to roughness length.
* Step 2: **SimGrid**. Simulation grid definition step. Defines a FastEddy gridded domain at a specificed grid spacing, location and extent using the file resulting from ther previous GeoSpec step and a FastEddy input parameters file (with targeted domain configuration parameters) as inputs.
* Step 3: **GenICBCs**. Generate initial conditions/boundary (ICBCs) conditions step. Creates ICBCs for a targeted FastEddy domain (defined in the SimGrid step) from a set of mesoscale model results.

The following tutorial provides a practical example of performing these preprocessing steps followed by a corresponding weather-driven FastEddy simulation for a real-world downscaled scenario.

.. toctree::

cases_real/WRF_coupling_case0.rst
cases_real/WRF_coupling_case0_FE.rst
120 changes: 120 additions & 0 deletions docs/Tutorials/cases_real/WRF_coupling_case0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
=============================================
Setting up a real-world downscaled simulation
=============================================

This is an example of a dynamically downscaled FastEddy simulation over Fort Collins (CO) driven by WRF simulated mesoscale weather conditions. This tutorial introduces the 3 preprocessing steps required to run mesoscale coupled real cases: GeoSpec, SimGrid, and GenICBCs, all of which are implemented using python scripts (**scripts/python_utilities/coupler/**). The required datasets to run this tutorial are provided at this `Zenodo record <https://zenodo.org/records/Blahblah>`_.

GeoSpec
-------
The first preprocessing step is **GeoSpec.py**. The purpose of this step is to create a NetCDF file of standard reference format from which one or more specific-resolution gridded FastEddy domain(s) can be created in the next step. The following variable dimensions and naming conventions are required in the *GeoSpec.py* input NetCDF file (see provided example input NetCDF file: :code:`ftCollins_inputs_gis.nc`).

.. code-block:: none

float x(x) ;
float y(y) ;
float elevation(y, x) ;
double lat(y, x) ;
double lon(y, x) ;
int LandCover(y, x) ;
float cellsize ;

Two required fields from an external GIS source are the terrain topography (:code:`elevation`, in m above seal level) and the categorical land cover (:code:`LandCover`). Note that high-resolution fields are desirable as inputs. Terrain can usually be obtained from lidar data at a few meters resolution, while land cover datasets are typically coarser. For U.S. locations we recommend using NLCD dataset that comes at a high resolution of 30 m. The should also include the corresponding latitude and longitude 2d fields (:code:`lat` and :code:`lon`) provided as double precision due to the high-resolution typically used in these FastEddy simulations. All fields must be projected consistently and discretized in the projected coordinate frame at the same resolution (:code:`cellsize`, in m).

Input parameters to **GeoSpec.py** are specified in the **geospec.json** file. These include the path and file name of the input GIS data (*gis_root* and *gis_file*, respectively), along with other parameters including the output path of the standard format, reference NetCDF output file of this step (*FE_dataset_path*). In order to convert the land cover class into a roughness length value, a look-up table must be provided (*nlcd_name*). In this tutorial, a lookup table is provided based on the 16-class NLCD dataset (:code:`LandCoverMetadata_NLCD16.csv`). Finally, the json file entry *water_cats* needs to list all of the land cover categories that correspond to water bodies, so an appropriate roughness length parameterization can be used by FastEddy. Once all the required input files are ready, **GeoSpec.py** can be executed:

.. code-block:: none

python ./GeoSpec.py -f geospec.json

After successful completion, a NetCDF file (:code:`FortCollinsCO.nc`) with the following fields will be created:

.. code-block:: none

float xPos2d(yIndex, xIndex) ;
float yPos2d(yIndex, xIndex) ;
float topoPos(yIndex, xIndex) ;
int LandCover(yIndex, xIndex) ;
float z0m(yIndex, xIndex) ;
float z0t(yIndex, xIndex) ;
float SeaMask(yIndex, xIndex) ;
float dx_inter ;
float dy_inter ;
double lat(yIndex, xIndex) ;
double lon(yIndex, xIndex) ;

If the json file option *save_plot_opt* is set to 1, then a plot will be produced displaying the terrain elevation, land cover, roughness length, and sea mask (water body) maps.

.. image:: ../images/FortCollinsCO_geospec.png
:width: 900
:alt: Alternative text

.. note::

* All three preprocessing steps make use of functions defined in *couplingUtils.py*. This file either needs to be present in the same directory as the preprocessing python scripts or alternatively the location of *couplingUtils.py* must be included in your PYTHONPATH (e.g. using *sys.path.append*).
* The input GIS data should be projected consistently with the WRF mesoscale data that will be used to provide initial and boundary conditions.
* Optionally (:code:`gis_opt = 1`), the user can point to a WRF restart file, inheriting the WRF domain georeference specification as an alternative to providing the standard GIS-derived input file to **GeoSpec.py**. A WRF output file can also be used, but it needs to include the variable *ZNT* (roughness length) not present by default in WRF output files.

SimGrid
-------
The second preprocessing step is **SimGrid.py**. The purpose of this step is to set up a FastEddy grid over a domain located within the area covered by the GIS file generated with *GeoSpec.py*. The location of the center of the FastEddy domain is specified in the **simgrid.json** file by the parameters *center_lat* and *center_lon*. The number of points in each direction (:code:`Nx`, :code:`Ny`, :code:`Nz`), grid spacings (:code:`d_xi`, :code:`d_eta`, :code:`d_zeta`), and vertical stretching parameters (:code:`verticalDeformFactor`, :code:`verticalDeformQuadCoeff`) required to set up a grid are read in from a FastEddy parameters file (*FE_params_file*). *SimGrid.py* performs decimation or interpolation between the *GeoSpec.py* output reference resolution and the parameter-specified grid spacing of the target FastEddy domain for surface fields, in addition to establishing a terrain following vertical goordinate grid. Once all the required input files are ready, **SimGrid.py** can be executed:

.. code-block:: none

python ./SimGrid.py -f simgrid.json

After successful completion, a NetCDF file (:code:`FortCollinsCO.0`) with the following fields will be created:

.. code-block:: none

float xPos(zIndex, yIndex, xIndex) ;
float yPos(zIndex, yIndex, xIndex) ;
float zPos(zIndex, yIndex, xIndex) ;
float topoPos(yIndex, xIndex) ;
float z0m(yIndex, xIndex) ;
float z0t(yIndex, xIndex) ;
float SeaMask(yIndex, xIndex) ;
int LandCover(yIndex, xIndex) ;
double lat(yIndex, xIndex) ;
double lon(yIndex, xIndex) ;
int xIndex(xIndex) ;
int yIndex(yIndex) ;
int zIndex(zIndex) ;

A binary file containing the terrain elevation information will also be generated (:code:`FortCollinsCO_Topography_448x450.dat`) and to be included as the :code:`topoFile` entry of the FastEddy input parameters file. If the json file option *save_plot_opt* is set to 1, then a plot will be produced displaying the vertical distribution of height and grid spacing at the lowest and highest terrain elevation points in the domain:

.. image:: ../images/FortCollinsCO_simgrid.png
:width: 675
:alt: Alternative text

.. note::

* Keep in mind that the highest elevation locations will exhibit the largest grid compression, resulting in the smallest surface grid spacings. You may need to adjust the vertical stretching parameters in the FastEddy input file and rerun *SimGrid.py* until the minimum desired surface grid spacing is achieved. The standard output logging generated during the execution of *SimGrid.py* can be useful for that purpose.
* Remember to adjust the FastEddy timestep size parameter :code:`dt` commensurately with the minimum grid spacing over the entire domain to ensure numerical stability of the simulation.

GenICBCs
--------
The third preprocessing step is **GenICBCs.py**. The purpose of this step is to create initial and boundary conditions (ICBCs) from the mesoscale WRF simulation results specific to the domain created by *SimGrid.py*. The input parameters are specified in the corresponding **genicbcs.json** file. This step involves three-dimensional interpolation of prognostic equation variables (winds, density, potential temperature and water vapor) and two-dimensional interpolation of surface skin forcings (temperature and water vapor). In order for WRF to provide the required fields to drive a nested FastEddy simulation, a number of additional variables not present in WRF's default output are required. To save the necessary variables at a sufficiently high temporal fidelity in an efficient manner, it is recommended to create WRF auxiliary files. For that purpose, when running WRF, include the following lines in WRF's namelist.input.

.. code-block:: none

&time_control
iofields_filename = "vars_io.txt",
ignore_iofields_warning = .true.,
auxhist14_outname = "wrf_fasteddy_d<domain>_<date>",
auxhist14_interval_m = 5,
frames_per_auxhist14 = 1,
io_form_auxhist14 = 2

And include the file *vars_io.txt* containing the one line below in WRF's run directory.

.. code-block:: none

+:h:14:PH,PHB,U,V,W,T,QVAPOR,QCLOUD,ALT,TSK,Q2,HGT,PSFC,XLAT,XLONG

With these additions, WRF will generate a set of timestamped *wrf_fasteddy_* files that will be utilized as basis for the interpolation to the FastEddy grid. The rest of input parameters are meant to provide the starting date and time of the sequence of ICBCs to be created. Similar to the other preprocessing scripts, **GenICBCs.py** is executed as:

.. code-block:: none

python ./GenICBCs.py -f genicbcs.json

Successful completion will create an initial condition file (*FE_interp_170000UTC.0*) and a set of boundary condition files (*FE_Bndys.**) where the index indicates the number of second increments from the initial time (frequency in seconds is specified by the parameter :code:`secInc` in **genicbcs.json**).
Loading