================================================================= Domain Creation ================================================================= **Last update:** |today| ---- Introduction ============ One of the more challenging tasks in an EHRATM simulation can be the creation of the computational domain - the outer WRF nest (frequently referred to as the Mother of all Domains, or MOAD), inner WRF nests, as well as the Flexpart OUTGRID and, optionally, OUTGRID_NEST.  Getting them all arranged in a valid way can be tedious and, once that’s done, one still needs to consider issues related to positioning of nest boundaries over complex terrain.  Once defined, the specifications go into a domain definition namelist and become part of the worfklow definition.   The *domaincheck* tool was developed for this project to aid the user in checking a domain definition namelist for issues that might cause problems during a simulation.  Although it won’t detect all problems (such as nest boundaries crossing complex terrain), it provides the means to view the entire domain in both the native and latlon map projections, as well as running the domain parameters through several constraint checks so that the user can find and correct them early, rather than finding out deep into a simulation workflow.   There are also a couple of tools available for creating domains through a GUI.  These tools both have limitations and problems, but they have been valuable at times, and so they are discussed briefly here. Verifying a domain namelist with domaincheck ============================================ The ``domaincheck.py`` tool is available in the repository at ``misc/domaincheck/``.  The program depends on two internal modules, **Domain/wpsnest** and **Domain/fpoutgrid**, as well as external modules *f90nml*, and *cartopy* and its dependencies.  The external modules are available within the *ehratmv1.0* conda environment, with a definition file for creating such an environment in ``misc/conda/ehratmv1.0.yml``.   Access to the internal modules requires having them in your PYTHONPATH, e.g.  .. code-block:: bash $ export PYTHONPATH=/dvlscratch/ATM/morton/git/high-res-atm/misc/domaincheck:$PYTHONPATH A fairly comprehensive set of tests is available for this in subdirectory ``test/``.  For example, the **wpsnest** and **fpoutgrid** modules have unit tests built for them (these are currently somewhat simple, but were included as prototypes for future developers who want to develop a more robust set of tests).   In the following example, the warnings that are issued come from the *cartopy* module and its underlying dependencies.  Running from the directory ``misc/domaincheck/`` .. code-block:: bash $ pytest ============================= test session starts ============================== platform linux -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 rootdir: /dvlscratch/ATM/morton/git/high-res-atm/misc/domaincheck plugins: anyio-2.2.0 collected 11 items                                                             test/unit/test_domain_fpoutgrid.py ..                                    [ 18%] test/unit/test_domain_wpsnest.py .........                               [100%] =============================== warnings summary =============================== test/unit/test_domain_wpsnest.py::TestWpsNest::test_ak_polar_d02_correct_lr_corner_lat . . . Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations     b = np.float(self.globe.semiminor_axis or WGS84_SEMIMINOR_AXIS) -- Docs: https://docs.pytest.org/en/stable/warnings.html ======================== 11 passed, 8 warnings in 0.33s ======================== Also available in the ``test/`` subdirectory is a ``driver/wpsfpplot3.py``, which I used for initial development, containing hard-coded domain parameters for low-level testing and debugging.  In the ``test/comptest/`` subdirectory is a Python program, ``comptest.py``, that iterates through a series of test cases (defined within the program), calling ``domaincheck.py`` to plot each test domain in both native and latlon projections, typically over potential problem areas like the International Dateline and Prime Meridian.  The plots are copied into a directory with an *index.html* that allows for quick scrutiny with a web browser. The primary program, ``domaincheck.py`` expects a domain definition namelist as input .. code-block:: bash $ ./domaincheck.py --help usage: domaincheck.py [-h] [-s] [-o OUTPUTPNG] [-v] [-m] [-c] [-l LOGLEVEL] namelist positional arguments: namelist path to domain defn namelist optional arguments: -h, --help show this help message and exit -s, --noscreenplot suppress default plotting to screen (default: False) -o OUTPUTPNG, --outputpng OUTPUTPNG full path to optional plot PNG file (default: None) -v, --nativeproj Plot the native projection only (default: False) -m, --latlonproj Plot the latlon projection only (default: False) -c, --checkwpsoverlap Test whether a WPS nest has immediate children with overlapping boundaries. Only necessary if using 2-way (nest feedbacks) WRF nesting (default: False) -l LOGLEVEL, --loglevel LOGLEVEL Log level - 30=WARNING, 20=INFO, 10=DEBUG (default: 30) The various options allow for flexibility, depending on whether the user wants to plot to a file, or plot one or both projections to the display, or simply run the test domain through a constraint check without producing any plots. Some examples of usage (run from within the ``misc/domaincheck/`` directory) .. code-block:: bash $ ./domaincheck.py test/data/AK5Nest/domaindef.nml Setting LOGGER to: WARNING CLI argument settings --------------------- namelist: test/data/AK5Nest/domaindef.nml noscreenplot: False outputpng: None nativeprojonly: False latlonprojonly: False checkwpsoverlap: False WPS MOAD nest (d01) created WPS Nest d02 created WPS Nest d03 created WPS Nest d04 created WPS Nest d05 created OUTGRID created OUTGRID_NEST created ========================================= EXTENT FOR METEOROLOGY (Lat, Lon) MOAD buffer:  2.0 degrees ---------------------------------- LL (  39.46,  153.18) LR (  39.46,  -89.90) UR (  76.63,  -89.90) UL (  76.63,  153.18) ========================================= .. |AK5NestBoth| image:: AK5NestBoth.png :scale: 90 % |AK5NestBoth| .. code-block:: bash $ ./domaincheck.py -m test/data/EULambert3Nests/domaindef.nml . . . ========================================= EXTENT FOR METEOROLOGY (Lat, Lon) MOAD buffer:  2.0 degrees ---------------------------------- LL (  27.14,  -46.35) LR (  27.14,   61.06) UR (  67.13,   61.06) UL (  67.13,  -46.35) ========================================= .. |EULambert3NestsLatLon| image:: EULambert3NestsLatLon.png :scale: 70 % |EULambert3NestsLatLon| .. code-block:: bash $ ./domaincheck.py -m test/data/ParentGridRatioViolation/domaindef.nml Setting LOGGER to: WARNING CLI argument settings --------------------- namelist: test/data/ParentGridRatioViolation/domaindef.nml noscreenplot: False outputpng: None nativeprojonly: False latlonprojonly: True checkwpsoverlap: False WPS MOAD nest (d01) created WPS Nest d02 created ERROR - wpsnest.py:valid_npts_wrt_pgridratio:278 --> d03: Invalid e_sn with respect to parent grid ratio Traceback (most recent call last):   File "./domaincheck.py", line 1121, in     main()   File "./domaincheck.py", line 1097, in main     setup_dict = domain_setup(   File "./domaincheck.py", line 423, in domain_setup     wpsnest_obj = wpsnest.WpsNest(nestnum=nestnum,   File "/home/ctbtuser/git/high-res-atm/misc/domaincheck/Domain/wpsnest.py", line 152, in __init__     raise ValueError('Num child points not conformed to pgrid ratio') ValueError: Num child points not conformed to pgrid ratio .. code-block:: bash $ ./domaincheck.py test/data/BoundaryPointsViolation/domaindef.nml Setting LOGGER to: WARNING CLI argument settings --------------------- namelist: test/data/BoundaryPointsViolation/domaindef.nml noscreenplot: False outputpng: None nativeprojonly: False latlonprojonly: False checkwpsoverlap: False WPS MOAD nest (d01) created WPS Nest d02 created WARNING - wpsnest.py:valid_child_parent_boundaries:211 --> Left boundary too close to parent boundary -- Min pts: 10 WARNING - wpsnest.py:__init__:163 --> Failed child/parent boundary test WPS Nest d03 created OUTGRID created OUTGRID_NEST created ========================================= EXTENT FOR METEOROLOGY (Lat, Lon) MOAD buffer:  2.0 degrees ---------------------------------- LL (  27.14,  -46.35) LR (  27.14,   61.06) UR (  67.13,   61.06) UL (  67.13,  -46.35) ========================================= .. |BoundaryPointsViolation| image:: BoundaryPointsViolation.png :scale: 80 % |BoundaryPointsViolation| ---- Creating a Domain Namelist ========================== For those who have worked with WPS and WRF, and Flexpart, choosing domains is at least slightly intuitive, and typically takes some trial and error.  The domain definition namelist is structured almost exactly like the geogrid entry in a WPS *namelist.wps*, so in fact, one can copy/paste the appropriate domain and nest components into a *domaindef.nml*.  The FLEXPART outgrid entries would be added in after the fact.  For example .. |NamelistTable| image:: NamelistTable.png :scale: 100 % |NamelistTable| There are public domain tools that can substantially ease the task of creating a complicated domain interactively through a GUI.  WRF Domain Wizard has been around for many years, and the latest update is from 2022.  Although a couple of us have had problems running it on devlan, it is Java-based and installs easily on an Ubuntu 18.02 workstation, and presumably works well on Windows and MacOS, too.  The program is designed to serve as a front-end for defining a domain and even running a WPS workflow.   WRF Domain Wizard ----------------- Although WRF Domain Wizard was available for years at https://esrl.noaa.gov/gsd/wrfportal/DomainWizard.html, sometime in late Autumn 2023 it became unavailable.  In fact, nothing under the **gsd/** directory is available any more.  I managed to save a copy of the .zip file, however, and have placed it in the high-res-atm repository under ``misc/WRFDomainWizard.zip`` in case it doesn’t appear back on the web again.  Here, we briefly discuss its installation, potential use, and caveats. Installation is as simple as unzipping the distribution file and directly running the ``run_DomainWizard`` application that gets unpacked .. |wizardinstall| image:: wizardinstall.png :scale: 70 % |wizardinstall| Upon running for the first time, the user is presented with a directory configuration screen.  Keeping in mind that this tool is used not only for generating domain parameters, but for running WPS components, also.  Since our only interest is in the domain generation it is safe to enter arbitrary paths for **WPS Programs** and **Geography**, but they need to be paths of existing directories (the tool checks for this).   The **Domains** entry is where output for the generated domain is going to be stored, so it must be an existing writable directory .. |wizardconfig| image:: wizardconfig.png :scale: 70 % |wizardconfig| After this, one chooses to load an already-created domain or a new domain, and then the interactive defining can begin .. |wizardedit| image:: wizardedit.png :scale: 70 % |wizardedit| When domain definition has been completed, it can be viewed in text format, but what you see is the *namelist.input*, not *namelist.wps*.  That’s OK, however, see below. .. |wizardnamelist| image:: wizardnamelist.png :scale: 70 % |wizardnamelist| **WARNING** - at this point if you hit the **Next >** button, you will be taken into a set of screens for running WPS and, since you probably entered arbitrary directories in the initial setup, you will get many error messages about non-existing WPS components, and it will be hard to get out of this. You have gone as far as you need to, however. In addition to the *namelist.input* information on the screen, the tool will create files *namelist.input*, *namelist.wps*, as well as a graphic, *projection.jpg*. With the *namelist.wps* **geogrid** section, you have what you need to copy/paste into a domain definition namelist. **WARNING** - if you have played around with setting up the ideal projection, it’s possible that what’s in the output directory does not fully conform to what you were last editing. There is some kind of synchronization issue, so when you’re done it’s important that you check the graphic in the directory, as well as the *namelist.wps*. Do not blindly assume that what you see in the output directory corresponds exactly to what you were last editing. Other than these caveats, I have found this to be a great time-saving tool for quickly generating the domain definition parameters that I need. An Online WRF Domain Wizard --------------------------- One other tool that has been recently discovered is also called *WRF Domain Wizard*, but it is available for online usage.  It is not quite as complete as the original *WRF Domain Wizard*, showing all projections in a latlon framework, and only supporting Lambert and Mercator.  I have also encountered difficulties when zooming out, as the longitudes repeat over and over and if you’re not careful you will end up with longitudes that are correct, but are several multiples of the standard [-180, 180] .. |OtherDomainWizard| image:: OtherDomainWizard.png :scale: 90 % |OtherDomainWizard| Although interesting, and perhaps useful to others, I have found the original *WRF Domain Wizard* to be more useful for quick generation of multi-nested domains.  The online interface to the tool is available at https://jiririchter.github.io/WRFDomainWizard/     and the github root page for the project is at https://github.com/JiriRichter/WRFDomainWizard  .. toctree::