From dc3bcdbc05f847ea97e81662ebe43738bb38f9ae Mon Sep 17 00:00:00 2001 From: braczka Date: Mon, 5 Aug 2024 09:21:34 -0600 Subject: [PATCH 01/19] Fix WRF mixing ratio to SH conversion Fixes Q2 to SH2 conversion bug and also improves code comments of when operating on Q2(vapor mixing ratio) and SH2 (specific humidity) --- models/wrf/model_mod.f90 | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/models/wrf/model_mod.f90 b/models/wrf/model_mod.f90 index b29c0dc79..29bc27e7a 100644 --- a/models/wrf/model_mod.f90 +++ b/models/wrf/model_mod.f90 @@ -1890,9 +1890,8 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte if (all(fld == missing_r8)) goto 200 !----------------------------------------------------- - ! 1.f Specific Humidity (SH, SH2) - ! Look at me - ! Convert water vapor mixing ratio to specific humidity: + ! 1.f Specific Humidity (QV,Q2) + ! Water vapor mixing ratio is used to calculate specific humidity: else if( obs_kind == QTY_SPECIFIC_HUMIDITY ) then ! This is for 3D specific humidity -- surface spec humidity later @@ -1910,9 +1909,9 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte call getCorners(i, j, id, wrf%dom(id)%type_t, ll, ul, lr, ur, rc ) ! HK why is this type_t if ( rc .ne. 0 ) & - print*, 'model_mod.f90 :: model_interpolate :: getCorners SH rc = ', rc + print*, 'model_mod.f90 :: model_interpolate :: getCorners QV rc = ', rc - ! Interpolation for SH field at level k + ! Interpolation for QV field at level k ill = get_dart_vector_index(ll(1), ll(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_qv) iul = get_dart_vector_index(ul(1), ul(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_qv) ilr = get_dart_vector_index(lr(1), lr(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_qv) @@ -1926,11 +1925,13 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte do e = 1, ens_size if ( k(e) == uniquek(uk) ) then ! interpolate only if it is the correct k a1 = dym*( dxm*x_ill + dx*x_ilr ) + dy*( dxm*x_iul + dx*x_iur ) ! think this can go outside the k loop + + ! Vapor mixing ratio (QV) to specific humidity conversion fld(1,e) = a1(e) /(1.0_r8 + a1(e)) endif enddo - ! Interpolation for SH field at level k+1 + ! Interpolation for QV field at level k+1 ill = get_dart_vector_index(ll(1), ll(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_qv) iul = get_dart_vector_index(ul(1), ul(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_qv) ilr = get_dart_vector_index(lr(1), lr(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_qv) @@ -1942,8 +1943,10 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte x_iur = get_state(iur, state_handle) do e = 1, ens_size - if ( k(e) == uniquek(uk) ) then ! interpolate only if it is the correct + if ( k(e) == uniquek(uk) ) then ! interpolate only if it is the correct k a1 = dym*( dxm*x_ill + dx*x_ilr ) + dy*( dxm*x_iul + dx*x_iur ) + + ! Vapor mixing ratio (QV) to specific humidity conversion fld(2,e) = a1(e) /(1.0_r8 + a1(e)) endif enddo @@ -1952,7 +1955,7 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte endif - ! This is for surface specific humidity (calculated from Q2) + ! This is for surface specific humidity calculated from vapor mixing ratio (Q2) else ! confirm that field is in the DART state vector @@ -1966,7 +1969,7 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte if ( rc .ne. 0 ) & print*, 'model_mod.f90 :: model_interpolate :: getCorners Q2 rc = ', rc - ! Interpolation for the SH2 field + ! Interpolation for the Q2 field ill = get_dart_vector_index(ll(1), ll(2), 1, domain_id(id), wrf%dom(id)%type_q2) iul = get_dart_vector_index(ul(1), ul(2), 1, domain_id(id), wrf%dom(id)%type_q2) ilr = get_dart_vector_index(lr(1), lr(2), 1, domain_id(id), wrf%dom(id)%type_q2) @@ -1978,6 +1981,8 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte x_ilr = get_state(ilr, state_handle) a1 = dym*( dxm*x_ill + dx*x_ilr ) + dy*( dxm*x_iul + dx*x_iur ) + + ! Vapor mixing ratio (Q2) to specific humidity conversion fld(1,:) = a1 /(1.0_r8 + a1) endif @@ -2002,11 +2007,10 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte endif endif - ! Don't accept negative water vapor amounts (?) + ! Don't accept negative water vapor amounts fld = max(0.0_r8, fld) else if (obs_kind == QTY_2M_SPECIFIC_HUMIDITY ) then - ! FIXME: Q2 is actually a mixing ratio, not a specific humidity if ( wrf%dom(id)%type_q2 >= 0 ) then ! Check to make sure retrieved integer gridpoints are in valid range if ( ( boundsCheck( i, wrf%dom(id)%periodic_x, id, dim=1, type=wrf%dom(id)%type_t ) .and. & @@ -2017,7 +2021,7 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte if ( rc .ne. 0 ) & print*, 'model_mod.f90 :: model_interpolate :: getCorners Q2 rc = ', rc - ! Interpolation for the SH2 field + ! Interpolation for the Q2 field ill = get_dart_vector_index(ll(1), ll(2), 1, domain_id(id), wrf%dom(id)%type_q2) iul = get_dart_vector_index(ul(1), ul(2), 1, domain_id(id), wrf%dom(id)%type_q2) ilr = get_dart_vector_index(lr(1), lr(2), 1, domain_id(id), wrf%dom(id)%type_q2) @@ -2029,7 +2033,10 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte x_ilr = get_state(ilr, state_handle) a1 = dym*( dxm*x_ill + dx*x_ilr ) + dy*( dxm*x_iul + dx*x_iur ) - fld(1,:) = a1 + + ! Vapor mixing ratio (Q2) to specific humidity conversion + fld(1,:) = a1/(1.0_r8 + a1) + endif endif From ff2cc870d1603ef88c97c7cff0620ccc42c9d254 Mon Sep 17 00:00:00 2001 From: braczka Date: Mon, 5 Aug 2024 09:44:43 -0600 Subject: [PATCH 02/19] Fix WRF surface temp interpolation Updating 2M temp obs definition such that it horizontally interpolates on WRF surface output (T2) instead of interpolating on bottom level of WRF 3D temperature (T) --- models/wrf/tutorial/template/input.nml.template | 2 +- observations/forward_operators/obs_def_metar_mod.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/models/wrf/tutorial/template/input.nml.template b/models/wrf/tutorial/template/input.nml.template index 3e2a1c100..d85b10372 100644 --- a/models/wrf/tutorial/template/input.nml.template +++ b/models/wrf/tutorial/template/input.nml.template @@ -130,7 +130,7 @@ 'QNRAIN','QTY_RAIN_NUMBER_CONCENTR','TYPE_QNRAIN','UPDATE','999', 'U10','QTY_U_WIND_COMPONENT','TYPE_U10','UPDATE','999', 'V10','QTY_V_WIND_COMPONENT','TYPE_V10','UPDATE','999', - 'T2','QTY_TEMPERATURE','TYPE_T2','UPDATE','999', + 'T2','QTY_2M_2M_TEMPERATURE','TYPE_T2','UPDATE','999', 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', diff --git a/observations/forward_operators/obs_def_metar_mod.f90 b/observations/forward_operators/obs_def_metar_mod.f90 index f559d0086..969b983e2 100644 --- a/observations/forward_operators/obs_def_metar_mod.f90 +++ b/observations/forward_operators/obs_def_metar_mod.f90 @@ -6,7 +6,7 @@ ! BEGIN DART PREPROCESS TYPE DEFINITIONS ! METAR_U_10_METER_WIND, QTY_U_WIND_COMPONENT, COMMON_CODE ! METAR_V_10_METER_WIND, QTY_V_WIND_COMPONENT, COMMON_CODE -! METAR_TEMPERATURE_2_METER, QTY_TEMPERATURE, COMMON_CODE +! METAR_TEMPERATURE_2_METER, QTY_2M_TEMPERATURE, COMMON_CODE ! METAR_SPECIFIC_HUMIDITY_2_METER, QTY_SPECIFIC_HUMIDITY, COMMON_CODE ! METAR_SURFACE_PRESSURE, QTY_SURFACE_PRESSURE, COMMON_CODE ! METAR_POT_TEMP_2_METER, QTY_POTENTIAL_TEMPERATURE, COMMON_CODE From f00976aa46a1acdaa8608ea4a7fa7adabbcd1ac0 Mon Sep 17 00:00:00 2001 From: braczka Date: Tue, 6 Aug 2024 07:40:09 -0600 Subject: [PATCH 03/19] WRF forward operator tutorial documentation Adding docs to FO bug fixes and also providing description of linkage between observation types and required WRF field outputs --- models/wrf/tutorial/README.rst | 236 ++++++++++++++++++++++++++++++++- 1 file changed, 229 insertions(+), 7 deletions(-) diff --git a/models/wrf/tutorial/README.rst b/models/wrf/tutorial/README.rst index 80cd82c34..89584e769 100644 --- a/models/wrf/tutorial/README.rst +++ b/models/wrf/tutorial/README.rst @@ -600,7 +600,7 @@ also want to modify this script to test running a single member first — just in case you have some debugging to do. However, be warned that to successfully complete the tutorial, including -running the *driver.csh* script in Step 5, using a smaller ensemble +running the *driver.csh* script in Step 6, using a smaller ensemble (e.g. < 20 members) can lead to spurious updates during the analysis step, causing the WRF simulation to fail. @@ -617,7 +617,7 @@ Step 3: Prepare observations [OPTIONAL] The observation sequence files to run this tutorial are already provided for you. If you want to run with the provided tutorial observations, you - can skip to Step 4 right now. If you are interested in using custom + can skip to Step 5 right now. If you are interested in using custom observations for a WRF experiment other than the tutorial you should read on. The remaining instructions provided below in Step 3 are meant as a guideline to converting raw PREPBUFR data files into the required ``obs_seq`` format @@ -807,8 +807,230 @@ you would do the following: namelist options to consider, and you must provide a *wrfinput* file for the program to access the analysis domain information. +Step 4: Overview of forward (observation) operators +--------------------------------------------------- -Step 4: Creating the first set of adaptive inflation files +This section is for informational purposes only and does not include any +instructions to complete the tutorial. It provides a description of +the DART settings thet control the forward operator which +calculates the prior and posterior model estimates for the observations. +An introduction to important namelist variables that control the operation of the forward +operator are located in the `WRF namelist documentation +`__ + + + + +The ``obs_seq.out`` file generated as described in Step 3 includes a total +of 30 observation types. Here we examine an exerpt of that file, focusing +on a single temperature observation to describe the process: + +:: + + obs_sequence + obs_kind_definitions + 30 + 41 METAR_TEMPERATURE_2_METER + .. + .. + num_copies: 1 num_qc: 1 + num_obs: 70585 max_num_obs: 70585 + NCEP BUFR observation + NCEP QC index + first: 1 last: 70585 + OBS 1 + 288.750000000000 + 1.00000000000000 + -1 2 -1 + obdef + loc3d + 4.819552185804497 0.6141813398083548 518.0000000000000 -1 + kind + 41 + 43200 152057 + 3.06250000000000 + .. + .. + .. + + +A critical piece of observation metadata includes the observation type +(``METAR_TEMPERATURE_2_METER``) which is linked to the observation quantity +(``QTY_2M_TEMPERATURE``) through the observation definition file +(``obs_def_metar_mod.f90``). This file is included within the +``&preprocess_nml`` section of the namelist file as: + +:: + + &preprocess_nml + overwrite_output = .true. + input_obs_qty_mod_file = '../../../assimilation_code/modules/observations/DEFAULT_obs_kind_mod.F90' + output_obs_qty_mod_file = '../../../assimilation_code/modules/observations/obs_kind_mod.f90' + input_obs_def_mod_file = '../../../observations/forward_operators/DEFAULT_obs_def_mod.F90' + output_obs_def_mod_file = '../../../observations/forward_operators/obs_def_mod.f90' + quantity_files = '../../../assimilation_code/modules/observations/atmosphere_quantities_mod.f90' + obs_type_files = '../../../observations/forward_operators/obs_def_reanalysis_bufr_mod.f90', + '../../../observations/forward_operators/obs_def_altimeter_mod.f90', + '../../../observations/forward_operators/obs_def_radar_mod.f90', + '../../../observations/forward_operators/obs_def_metar_mod.f90', + .. + .. + .. + +During the DART compilation described within Step 1 this information is +included within the ``obs_def_mod.f90`` which is read during the execution of +``filter``. + +The vertical coordinate type is the 4th column beneath the loc3d header. In this example +the value -1 indicates the vertical coordinate is ``VERTISSURFACE``. It defines the +vertical units of the observation (e.g. pressure, meters above sea level, model levels etc). +This serves two purposes -- foremost it is required during the vertical spatial interpolation +to calculate the precise location of the expected observation. +A second crtical function is that it defines whether it is a surface observation. +Observations with a vertical coordinate of ``VERTISSURFACE`` are defined as surface +observations. All other coordinates are considered non-surface observations +(e.g. profile observations). Of note is that the vertical coordinate ``VERTISSURFACE`` and +``VERTISHEIGHT`` are functionally identical (i.e. meters above sea level), however +only the ``VERTISSURFACE`` is a surface observation. + +For more information on the other metadata see the detailed structure of +an `obs_seq file. `__ + +In order to connect this observation to the appropriate WRF output variables +the ``wrf_state_variables`` within``&model_nml`` defines the *WRF field name* and +the *WRF TYPE* in the 1st and 3rd columns as shown in the tutorial example below: + +:: + + &model_nml + wrf_state_variables = 'T2','QTY_TEMPERATURE','TYPE_T2','UPDATE','999' + + .. + .. + +For more information on the ``&model_nml`` variables see the `WRF documentation page +`__ + + +As described above, the linkage between the observation type and the WRF output field +is defined through the observation quantity, surface variable (observation +vertical coordinate), and WRF TYPE. The current design of the WRF ``model_mod.f90`` +is such that the observation quantity is a general classification (e.g. temperature, wind +specific humidity), whereas the WRF TYPE classification is more precisely +mapped to the WRF output field. Future DART versions may remove the need for the WRF TYPE. +The table below summarizes the dependency between the observation type and the WRF +output field for a select number of observation types within the tutorial. + +.. Note:: + + The number of WRF output fields required to support an observation type can vary. For + observation types where there is a direct analog to a WRF output field, the forward + operator consists of only spatial interpolation, thus requires only a single output + variable (e.g. METAR_TEMPERATURE_2_METER). For observation types that require multiple + WRF output fields, the forward operator is more complex than a simple spatial interpolation. + For more information see the notes below the table. A rule of thumb is a surface + observation should use a surface output field (e.g. T2, U10). WRF surface output fields + are appended by a numeric value indicating surface height in meters. It is possible to use + a non-surface WRF output field (3D field) to estimate a surface observation, however, this + requires a vertical interpolation of the 3D WRF field where the observed surface height does + not coincide with the model levels. This either requires a vertical interpolation or an + extrapolation which can be **inaccurate and is not recommended**. + + + + ++--------------------------------+-----------------------------+-----------------+-----------------+ +| DART Observation Type | DART Observation Quantities | WRF Type | WRF output field| ++================================+=============================+=================+=================+ +| ``METAR_TEMPERATURE_2_METER`` | ``QTY_2M_TEMPERATURE`` | ``TYPE_T2`` | ``T2`` | +| (VERTISSURFACE) | | | | ++--------------------------------+-----------------------------+-----------------+-----------------+ +| ``RADIOSONDE_TEMPERATURE`` |``QTY_POTENTIAL_TEMPERATURE``| ``TYPE_T`` | ``THM`` | +| (VERTISPRESSURE) | ``QTY_VAPOR_MIXING_RATIO`` | ``TYPE_QV`` | ``QVAPOR`` | +| | ``QTY_PRESSURE`` | ``TYPE_MU`` | ``MU`` | +| | ``QTY_GEOPOTENTIAL_HEIGHT``| ``TYPE_GZ`` | ``PH`` | ++--------------------------------+-----------------------------+-----------------+-----------------+ +| ``METAR_U_10_METER_WIND`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U10`` | ``U10`` | +| (VERTISSURFACE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V10`` | ``V10`` | ++--------------------------------+-----------------------------+-----------------+-----------------+ +| ``ACARS_U_WIND_COMPONENT`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U`` | ``U`` | +| (VERTISPRESSURE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V`` | ``V`` | ++--------------------------------+-----------------------------+-----------------+-----------------+ +| ``METAR_DEWPOINT_2_METER`` | ``QTY_DEWPOINT`` | | | +| (VERTISSURFACE) | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_Q2`` | ``Q2`` | +| | ``QTY_PRESSURE`` | ``TYPE_PS`` | ``PSFC`` | ++--------------------------------+-----------------------------+-----------------+-----------------+ +|``RADIOSONDE_SPECIFIC_HUMIDITY``| ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_QV`` | ``QVAPOR`` | +| (VERTISPRESSURE) | | | | ++--------------------------------+-----------------------------+-----------------+-----------------+ + + + +Surface Temperature (e.g. METAR_TEMPERATURE_2_METER) +---------------------------------------------------- + +WRF output includes a direct analog for sensible temperature surface observations (e.g. T2), thus +the forward operator requires only 1 variable to calculate the expected observation. +The calculation includes a horizontal interpolation of the 2D temperature variable (e.g. T2). + + +Non-Surface Temperature (e.g. RADIOSONDE_TEMPERATURE) +----------------------------------------------------- + +In contrast to surface temperature observations, non-surface temperature observations require 4 WRF +output fields. This is because observations are sensible temperature, whereas the 3D WRF +temperature field is provided in perturbation potential temperature. Thus, the forward +operator first requires a physical conversion between perturbation potential temperature to +sensible temperature, followed by a spatial interpolation (this includes horizontal interpolation +on WRF levels k and k+1, followed by vertical interpolation). + +.. Important:: + + There are two different 3D temperature WRF output fields that can work to calculate non- + surface temperature observations (e.g. T or THM, T=THM when use_theta_m=0). However, and of + high importance is the variable THM is required to be within the ``&model_nml`` if the + 3D temperature field is to be updated in the ``filter`` step. **This is because the WRF field *T* + is a diagnostic variable with no impact on the forecast step, whereas the WRF field *THM* is + a prognostic field.** + + +Surface Wind (e.g. METAR_U_10_METER_WIND) +----------------------------------------- + +Surface winds have a direct WRF output analog (e.g. U10) +and requires horizontal interpolation of the 2D zonal wind field. However, the +meridional wind (e.g. V10) is also required in order to convert from modeled *gridded* winds to +*true* wind observations. This requirement is an artifact of winds measured on a sphere being +mapped on a 2D grid. + + +Non-Surface Wind (e.g. ACARS_U_WIND_COMPONENT) +---------------------------------------------- + +This is identical to surface winds as described above, except the spatial interpolation requires +horizontal interpolation on the k and k+1 WRF levels, followed by vertical interpolation. + + +Surface Dewpoint (e.g. METAR_DEWPOINT_2_METER) +---------------------------------------------- + +The calculation of surface dewpoint requires a physical conversion using both surface +pressure (PSFC) and surface vapor mixing ratio (Q2), follwed by horizontal interpolation. + + +Non-Surface Specific Humidity (e.g. RADIOSONDE_SPECIFIC_HUMIDITY) +----------------------------------------------------------------- + +Specific humidity observations require (water) vapor mixing ratio (QVAPOR) for the forward operator. +Although specific humidity and vapor mixing ratio are nearly identical, especially in dry +air, they are actually two distinct physical properties -- the ratio of water mass to total air mass +versus ratio of water vapor mass to dry air mass respectively. Therefore the forward operator +includes this physical conversion followed by a spatial interpolation (i.e. horizontal interpolation of k and +k+1 WRF vertical levels followed by vertical interpolation). + + + +Step 5: Creating the first set of adaptive inflation files ---------------------------------------------------------- In this section we describe how to create initial adaptive inflation @@ -874,7 +1096,7 @@ cycle. -Step 5: Cycled analysis system +Step 6: Cycled analysis system ------------------------------ While the DART system provides executables to perform individual tasks @@ -924,10 +1146,10 @@ continue to cycle until the final analysis time has been reached. -Step 6: Diagnosing the assimilation results +Step 7: Diagnosing the assimilation results ------------------------------------------- -Once you have successfully completed steps 1-5, it is important to +Once you have successfully completed steps 1-6, it is important to check the quality of the assimilation. In order to do this, DART provides analysis system diagnostics in both state and observation space. @@ -989,7 +1211,7 @@ The tools below provide methods to visualize the spatial patterns, statistics an failure mode for all observations. The observation diagnostics use the **obs_epoch*.nc** file as input. This file is -automatically generated by the **obs_diagnostic.csh** script within Step 5 of this +automatically generated by the **obs_diagnostic.csh** script within Step 6 of this tutorial. The **obs_epoch*.nc** file is located in the output directory of each time step. From 7b6e4a9d61d984a86c93afac7b89a8baa1fa01d0 Mon Sep 17 00:00:00 2001 From: braczka Date: Tue, 6 Aug 2024 09:54:06 -0600 Subject: [PATCH 04/19] Improve supporting WRF-DART docs --- models/wrf/readme.rst | 33 +++++++-- models/wrf/tutorial/README.rst | 73 ++++++++++--------- .../wrf/tutorial/template/input.nml.template | 2 +- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index 0f37ad09f..d89fd4046 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -4,23 +4,40 @@ WRF Overview -------- - -DART interface module for the Weather Research and Forecasting +The following is a description of the DART interface module for the +Weather Research and Forecasting model `(WRF) `__ -model. This page documents the details of the -module compiled into DART that interfaces with the WRF data in the state vector. +model. This page provides an overview of the module compiled into DART +that interfaces with the WRF data in the state vector. **The WRF-DART interface is compatible with WRF versions 4 and later, and is no longer backwards compatible with WRFv3.9 and earlier.** For more information on the interface changes required between -different WRF versions see the WRF tutorial link in the next section. +different WRF versions, read through this documentation *and* the +WRF-DART tutorial link in the next section. + +There have been several important updates to the WRF-DART interface starting +with `DARTv11.5.0. `__ +Some important WRF-DART updates include: + +1) Version 11.4.1: Detects use of the Hybrid Vertical Coordinate system + (terrain following at surface) and accounts for this in forward + operator calculations. + +2) Version 11.5.0: Improves compatibility with WRFv4+ versions and later + where prognostic 3D temperature variable is THM. + +It is always recommended that you update your DART version to the `latest tag +`__ -Please work through the tutorial in order to learn how to run WRF and DART. Items of Note ~~~~~~~~~~~~~ diff --git a/models/wrf/tutorial/README.rst b/models/wrf/tutorial/README.rst index 89584e769..b1e99385b 100644 --- a/models/wrf/tutorial/README.rst +++ b/models/wrf/tutorial/README.rst @@ -807,15 +807,15 @@ you would do the following: namelist options to consider, and you must provide a *wrfinput* file for the program to access the analysis domain information. -Step 4: Overview of forward (observation) operators +Step 4: Overview of forward (observation) operators [OPTIONAL] --------------------------------------------------- This section is for informational purposes only and does not include any instructions to complete the tutorial. It provides a description of -the DART settings thet control the forward operator which +the DART settings that control the forward operator which calculates the prior and posterior model estimates for the observations. An introduction to important namelist variables that control the operation of the forward -operator are located in the `WRF namelist documentation +operator are located in the `WRF namelist documentation. `__ @@ -881,8 +881,8 @@ During the DART compilation described within Step 1 this information is included within the ``obs_def_mod.f90`` which is read during the execution of ``filter``. -The vertical coordinate type is the 4th column beneath the loc3d header. In this example -the value -1 indicates the vertical coordinate is ``VERTISSURFACE``. It defines the +The vertical coordinate type is the 4th column beneath the loc3d header within ``obs_seq.out``. +In this example the value -1 indicates the vertical coordinate is ``VERTISSURFACE``. It defines the vertical units of the observation (e.g. pressure, meters above sea level, model levels etc). This serves two purposes -- foremost it is required during the vertical spatial interpolation to calculate the precise location of the expected observation. @@ -893,11 +893,11 @@ observations. All other coordinates are considered non-surface observations ``VERTISHEIGHT`` are functionally identical (i.e. meters above sea level), however only the ``VERTISSURFACE`` is a surface observation. -For more information on the other metadata see the detailed structure of +For more information on the vertical coordinate metadata see the detailed structure of an `obs_seq file. `__ In order to connect this observation to the appropriate WRF output variables -the ``wrf_state_variables`` within``&model_nml`` defines the *WRF field name* and +the ``wrf_state_variables`` within ``&model_nml`` defines the *WRF field name* and the *WRF TYPE* in the 1st and 3rd columns as shown in the tutorial example below: :: @@ -939,30 +939,31 @@ output field for a select number of observation types within the tutorial. -+--------------------------------+-----------------------------+-----------------+-----------------+ -| DART Observation Type | DART Observation Quantities | WRF Type | WRF output field| -+================================+=============================+=================+=================+ -| ``METAR_TEMPERATURE_2_METER`` | ``QTY_2M_TEMPERATURE`` | ``TYPE_T2`` | ``T2`` | -| (VERTISSURFACE) | | | | -+--------------------------------+-----------------------------+-----------------+-----------------+ -| ``RADIOSONDE_TEMPERATURE`` |``QTY_POTENTIAL_TEMPERATURE``| ``TYPE_T`` | ``THM`` | -| (VERTISPRESSURE) | ``QTY_VAPOR_MIXING_RATIO`` | ``TYPE_QV`` | ``QVAPOR`` | -| | ``QTY_PRESSURE`` | ``TYPE_MU`` | ``MU`` | -| | ``QTY_GEOPOTENTIAL_HEIGHT``| ``TYPE_GZ`` | ``PH`` | -+--------------------------------+-----------------------------+-----------------+-----------------+ -| ``METAR_U_10_METER_WIND`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U10`` | ``U10`` | -| (VERTISSURFACE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V10`` | ``V10`` | -+--------------------------------+-----------------------------+-----------------+-----------------+ -| ``ACARS_U_WIND_COMPONENT`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U`` | ``U`` | -| (VERTISPRESSURE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V`` | ``V`` | -+--------------------------------+-----------------------------+-----------------+-----------------+ -| ``METAR_DEWPOINT_2_METER`` | ``QTY_DEWPOINT`` | | | -| (VERTISSURFACE) | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_Q2`` | ``Q2`` | -| | ``QTY_PRESSURE`` | ``TYPE_PS`` | ``PSFC`` | -+--------------------------------+-----------------------------+-----------------+-----------------+ -|``RADIOSONDE_SPECIFIC_HUMIDITY``| ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_QV`` | ``QVAPOR`` | -| (VERTISPRESSURE) | | | | -+--------------------------------+-----------------------------+-----------------+-----------------+ ++----------------------------------+-------------------------------+--------------+-------------+ +| DART Observation Type | DART Observation Quantities | WRF Type | WRF output | +| | | | field | ++==================================+===============================+==============+=============+ +| ``METAR_TEMPERATURE_2_METER`` | ``QTY_2M_TEMPERATURE`` | ``TYPE_T2`` | ``T2`` | +| (VERTISSURFACE) | | | | ++----------------------------------+-------------------------------+--------------+-------------+ +| ``RADIOSONDE_TEMPERATURE`` | ``QTY_POTENTIAL_TEMPERATURE`` | ``TYPE_T`` | ``THM`` | +| (VERTISPRESSURE) | ``QTY_VAPOR_MIXING_RATIO`` | ``TYPE_QV`` | ``QVAPOR`` | +| | ``QTY_PRESSURE`` | ``TYPE_MU`` | ``MU`` | +| | ``QTY_GEOPOTENTIAL_HEIGHT`` | ``TYPE_GZ`` | ``PH`` | ++----------------------------------+-------------------------------+--------------+-------------+ +| ``METAR_U_10_METER_WIND`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U10`` | ``U10`` | +| (VERTISSURFACE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V10`` | ``V10`` | ++----------------------------------+-------------------------------+--------------+-------------+ +| ``ACARS_U_WIND_COMPONENT`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U`` | ``U`` | +| (VERTISPRESSURE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V`` | ``V`` | ++----------------------------------+-------------------------------+--------------+-------------+ +| ``METAR_DEWPOINT_2_METER`` | ``QTY_DEWPOINT`` | | | +| (VERTISSURFACE) | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_Q2`` | ``Q2`` | +| | ``QTY_PRESSURE`` | ``TYPE_PS`` | ``PSFC`` | ++----------------------------------+-------------------------------+--------------+-------------+ +| ``RADIOSONDE_SPECIFIC_HUMIDITY`` | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_QV`` | ``QVAPOR`` | +| (VERTISPRESSURE) | | | | ++----------------------------------+-------------------------------+--------------+-------------+ @@ -987,11 +988,11 @@ on WRF levels k and k+1, followed by vertical interpolation). .. Important:: There are two different 3D temperature WRF output fields that can work to calculate non- - surface temperature observations (e.g. T or THM, T=THM when use_theta_m=0). However, and of - high importance is the variable THM is required to be within the ``&model_nml`` if the + surface temperature observations (e.g. T or THM, T=THM when use_theta_m=0). However, and **of + utmost importance** is the variable THM is required to be within the ``&model_nml`` if the 3D temperature field is to be updated in the ``filter`` step. **This is because the WRF field *T* is a diagnostic variable with no impact on the forecast step, whereas the WRF field *THM* is - a prognostic field.** + a prognostic field which will impact the forecast.** Surface Wind (e.g. METAR_U_10_METER_WIND) @@ -1021,7 +1022,7 @@ pressure (PSFC) and surface vapor mixing ratio (Q2), follwed by horizontal inter Non-Surface Specific Humidity (e.g. RADIOSONDE_SPECIFIC_HUMIDITY) ----------------------------------------------------------------- -Specific humidity observations require (water) vapor mixing ratio (QVAPOR) for the forward operator. +Specific humidity observations require the (water) vapor mixing ratio (QVAPOR) for the forward operator. Although specific humidity and vapor mixing ratio are nearly identical, especially in dry air, they are actually two distinct physical properties -- the ratio of water mass to total air mass versus ratio of water vapor mass to dry air mass respectively. Therefore the forward operator @@ -1433,7 +1434,7 @@ quite high (>90%). This high acceptance percentage is typical of a high-quality assimilation and consistent with the strong reduction in RMSE. -The same plot as above is given below except for the observation type: +The same plot as above is given below excerpt for the observation type: ``RADIOSONE_SPECIFIC_HUMIDITY``. +-------------------------------------------------------------+ diff --git a/models/wrf/tutorial/template/input.nml.template b/models/wrf/tutorial/template/input.nml.template index d85b10372..81b302b40 100644 --- a/models/wrf/tutorial/template/input.nml.template +++ b/models/wrf/tutorial/template/input.nml.template @@ -130,7 +130,7 @@ 'QNRAIN','QTY_RAIN_NUMBER_CONCENTR','TYPE_QNRAIN','UPDATE','999', 'U10','QTY_U_WIND_COMPONENT','TYPE_U10','UPDATE','999', 'V10','QTY_V_WIND_COMPONENT','TYPE_V10','UPDATE','999', - 'T2','QTY_2M_2M_TEMPERATURE','TYPE_T2','UPDATE','999', + 'T2','QTY_2M_TEMPERATURE','TYPE_T2','UPDATE','999', 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', From bbb63ad7ea01326c209f5b49651b561d02711b35 Mon Sep 17 00:00:00 2001 From: braczka Date: Tue, 6 Aug 2024 16:31:37 -0600 Subject: [PATCH 05/19] Update WRF model docs --- models/wrf/readme.rst | 553 ++++++++++++++++----------------- models/wrf/tutorial/README.rst | 8 +- 2 files changed, 277 insertions(+), 284 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index d89fd4046..5d40bebe2 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -19,15 +19,15 @@ There have been several important updates to the WRF-DART interface starting with `DARTv11.5.0. `__ Some important WRF-DART updates include: -1) Version 11.4.1: Detects use of the Hybrid Vertical Coordinate system - (terrain following at surface) and accounts for this in forward - operator calculations. +- Version 11.4.1: Detects use of the Hybrid Vertical Coordinate system + (terrain following at surface) and accounts for this in forward + operator calculations. -2) Version 11.5.0: Improves compatibility with WRFv4+ versions and later - where prognostic 3D temperature variable is THM. +- Version 11.5.0: Improves compatibility with WRFv4+ versions and later + where prognostic 3D temperature variable is THM. It is always recommended that you update your DART version to the `latest tag -`__ before beginning new research. WRF+DART Tutorial ----------------- @@ -36,11 +36,11 @@ This tutorial provides a real-world example of assimilating a wide variety of at observations during an extreme storm event for the United States during April 2017. **It is strongly recommended that you also review and perform the tutorial documentation for -running a WRF-DART assimilation** `here `__ +running a WRF-DART assimilation** `here. `__ Items of Note -~~~~~~~~~~~~~ +------------- - The ``model_mod`` reads WRF netCDF files directly to acquire the model state data. The ``wrf_to_dart`` and ``dart_to_wrf`` programs are no longer @@ -61,6 +61,15 @@ domain case the data in the state vector that came from ``wrfinput_d04`` is searched first, then ``wrfinput_d03``, ``wrfinput_d02``, and finally ``wrfinput_d01``. +.. Important:: + + Although the model interface code is compatible with multiple domains, the + supporting `shell scripts `__ + and WRF-DART tutorial are currently designed for a single domain and will + require some modifications for multiple (nested) domain functionality. If you + need help with these modifications please contact DART support. + + The forward operator is computed from the first domain grid that contains the lat/lon of the observation. During the assimilation phase, when the state values are adjusted based on the correlations and assimilation increments, all points @@ -71,7 +80,7 @@ coefficient based on the correlation between the distributions of the ensemble of state vector points and the ensemble of observation forward operator values. The fields from WRF that are copied into the DART state vector are controlled by -namelist. See below for the documentation on the &model_nml entries. The state +namelist. See below for the documentation on the ``&model_nml`` entries. The state vector should include all fields needed to restart a WRF run. There may be additional fields needed depending on the microphysics scheme selected. See the ascii file ``wrf_state_variables_table`` in the ``models/wrf`` directory for a @@ -108,277 +117,261 @@ prematurely terminating the namelist. allow_perturbed_ics = .false. # testing purposes only / - # Notes for model_nml: - # (1) vert_localization_coord must be one of: - # 1 = model level - # 2 = pressure - # 3 = height - # 4 = scale height - # (2) see bottom of this file for explanations of polar, periodic_x, - # periodic_y, and scm - # (3) calendar = 3 is GREGORIAN, which is what WRF uses. - # (4) if 'default_state_variables' is .true. the model_mod.f90 code will - # fill the state variable table with the following wrf vars: - # U, V, W, PH, T, MU - # you must set it to false before you change the value - # of 'wrf_state_variables' and have it take effect. - # (5) the format for 'wrf_state_variables' is an array of 5 strings: - # wrf netcdf variable name, dart QTY_xxx string, type string (must be - # unique, will soon be obsolete, we hope), 'UPDATE', and '999' if the - # array is part of all domains. otherwise, it is a string with the domain - # numbers (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). - # example: - # wrf_state_variables='U','QTY_U_WIND_COMPONENT','TYPE_U','UPDATE','999', - # 'V','QTY_V_WIND_COMPONENT','TYPE_V','UPDATE','999', - # 'W','QTY_VERTICAL_VELOCITY','TYPE_W','UPDATE','999', - # 'T','QTY_POTENTIAL_TEMPERATURE','TYPE_T','UPDATE','999', - # 'PH','QTY_GEOPOTENTIAL_HEIGHT','TYPE_GZ','UPDATE','999', - # 'MU','QTY_PRESSURE','TYPE_MU','UPDATE','999', - # 'QVAPOR','QTY_VAPOR_MIXING_RATIO','TYPE_QV','UPDATE','999', - # 'QCLOUD','QTY_CLOUD_LIQUID_WATER','TYPE_QC','UPDATE','999', - # 'QRAIN','QTY_RAINWATER_MIXING_RATIO','TYPE_QR','UPDATE','999', - # 'U10','QTY_U_WIND_COMPONENT','TYPE_U10','UPDATE','999', - # 'V10','QTY_V_WIND_COMPONENT','TYPE_V10','UPDATE','999', - # 'T2','QTY_TEMPERATURE','TYPE_T2','UPDATE','999', - # 'TH2','QTY_POTENTIAL_TEMPERATURE','TYPE_TH2','UPDATE','999', - # 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', - # 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', - # (6) the format for 'wrf_state_bounds' is an array of 4 strings: - # wrf netcdf variable name, minimum value, maximum value, and either - # FAIL or CLAMP. FAIL will halt the program if an out of range value - # is detected. CLAMP will set out of range values to the min or max. - # The special string 'NULL' will map to plus or minus infinity and will - # not change the values. arrays not listed in this table will not - # be changed as they are read or written. - # - # - # polar and periodic_x are used in global wrf. if polar is true, the - # grid interpolation routines will wrap over the north and south poles. - # if periodic_x is true, when the east and west edges of the grid are - # reached the interpolation will wrap. note this is a separate issue - # from regional models which cross the GMT line; those grids are marked - # as having a negative offset and do not need to wrap; this flag controls - # what happens when the edges of the grid are reached. - - # the scm flag is used for the 'single column model' version of WRF. - # it needs the periodic_x and periodic_y flags set to true, in which - # case the X and Y directions are periodic; no collapsing of the grid - # into a single location like the 3d-spherical polar flag implies. - -Description of each namelist entry -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -+---------------------------------------+-------------------+---------------------------------------+ -| Item | Type | Description | -+=======================================+===================+=======================================+ -| default_state_variables | logical | If *.true.*, the dart state vector | -| | | contains the fields U, V, W, PH, T, | -| | | MU, in that order, and only those. | -| | | Any values listed in the | -| | | *wrf_state_variables* namelist item | -| | | will be ignored. | -+---------------------------------------+-------------------+---------------------------------------+ -| wrf_state_variables | character(:, 5) | A 2D array of strings, 5 per wrf | -| | | array to be added to the dart state | -| | | vector. If *default_state_variables* | -| | | is *.true.*, this is ignored. When | -| | | *.false.*, this list of array names | -| | | controls which arrays and the order | -| | | that they are added to the state | -| | | vector. The 5 strings are: | -| | | | -| | | #. WRF field name - must match netcdf | -| | | name exactly | -| | | #. DART KIND name - must match a | -| | | valid DART QTY_xxx exactly | -| | | #. TYPE_NN - will hopefully be | -| | | obsolete, but for now NN should | -| | | match the field name. | -| | | #. the string UPDATE. at some future | -| | | point, non-updatable fields may | -| | | become part of the state vector. | -| | | #. A numeric string listing the | -| | | domain numbers this array is part | -| | | of. The specical string 999 means | -| | | all domains. For example, '12' | -| | | means domains 1 and 2, '13' means | -| | | 1 and 3. | -+---------------------------------------+-------------------+---------------------------------------+ -| wrf_state_bounds | character(:, 4) | A 2D array of strings, 4 per wrf | -| | | array. During the copy of data to and | -| | | from the wrf netcdf file, variables | -| | | listed here will have minimum and | -| | | maximum values enforced. The 4 | -| | | strings are: | -| | | | -| | | #. WRF field name - must match netcdf | -| | | name exactly | -| | | #. Minimum -- specified as a string | -| | | but must be a numeric value (e.g. | -| | | '0.1') Can be 'NULL' to allow any | -| | | minimum value. | -| | | #. Maximum -- specified as a string | -| | | but must be a numeric value (e.g. | -| | | '0.1') Can be 'NULL' to allow any | -| | | maximum value. | -| | | #. Action -- valid strings are | -| | | 'CLAMP', 'FAIL'. 'FAIL' means if a | -| | | value is found outside the range, | -| | | the code fails with an error. | -| | | 'CLAMP' simply sets the out of | -| | | range values to the given minimum | -| | | or maximum without error. | -+---------------------------------------+-------------------+---------------------------------------+ -| num_domains | integer | Total number of WRF domains, | -| | | including nested domains. | -+---------------------------------------+-------------------+---------------------------------------+ -| calendar_type | integer | Calendar type. Should be 3 | -| | | (GREGORIAN) for WRF. | -+---------------------------------------+-------------------+---------------------------------------+ -| assimilation_period_seconds | integer | The time (in seconds) between | -| | | assimilations. This is modified if | -| | | necessary to be an integer multiple | -| | | of the underlying model timestep. | -+---------------------------------------+-------------------+---------------------------------------+ -| periodic_x | logical | If *.true.*, the grid is periodic in | -| | | longitude, and points above the last | -| | | grid cell and points below the first | -| | | grid cell are wrapped. Note this is | -| | | not the same as a grid which crosses | -| | | the prime meridian. WRF handles that | -| | | with an offset in longitude and | -| | | points beyond the last grid index are | -| | | outside the domain. | -+---------------------------------------+-------------------+---------------------------------------+ -| periodic_y | logical | Used for the Single Column Model to | -| | | make the grid wrap in Y (see scm | -| | | below). This is NOT the same as | -| | | wrapping in latitude (see polar | -| | | below). | -+---------------------------------------+-------------------+---------------------------------------+ -| polar | logical | If *.true.*, points at the poles are | -| | | wrapped across the grid. It is not | -| | | clear this is a good idea since the | -| | | grid is degnerate here. | -+---------------------------------------+-------------------+---------------------------------------+ -| scm | logical | If *.true.* the Single Column Model | -| | | is assumed. The grid is a single | -| | | vertical column, and there are 9 | -| | | cells arranged in a 3x3 grid. See the | -| | | WRF documentation for more | -| | | information on this configuration. | -| | | *periodic_x* and *periodic_y* should | -| | | also be *.true.* in this case. | -+---------------------------------------+-------------------+---------------------------------------+ -| sfc_elev_max_diff | real(r8) | If > 0, the maximum difference, in | -| | | meters, between an observation marked | -| | | as a 'surface obs' as the vertical | -| | | type (with the surface elevation, in | -| | | meters, as the numerical vertical | -| | | location), and the surface elevation | -| | | as defined by the model. Observations | -| | | further away from the surface than | -| | | this threshold are rejected and not | -| | | assimilated. If the value is | -| | | negative, this test is skipped. | -+---------------------------------------+-------------------+---------------------------------------+ -| allow_obs_below_vol | logical | If *.false.* then if an observation | -| | | with a vertical coordinate of | -| | | pressure or height (i.e. not a | -| | | surface observation) is below the | -| | | lowest 3d sigma level, it is outside | -| | | the field volume and the | -| | | interpolation routine rejects it. If | -| | | this is set to *.true.* and the | -| | | observation is above the surface | -| | | elevation but below the lowest field | -| | | volume level, the code will | -| | | extrapolate downward from data values | -| | | at levels 1 and 2. | -+---------------------------------------+-------------------+---------------------------------------+ -| center_search_half_length | real(r8) | The model_mod now contains two | -| | | schemes for searching for a vortex | -| | | center location. If the **old** | -| | | scheme is compiled in, then this and | -| | | the center_spline_grid_scale namelist | -| | | items are used. (Search code for | -| | | 'use_old_vortex'.) Half length (in | -| | | meters) of a square box for searching | -| | | the vortex center. | -+---------------------------------------+-------------------+---------------------------------------+ -| center_spline_grid_scale | integer | The model_mod now contains two | -| | | schemes for searching for a vortex | -| | | center location. If the **old** | -| | | scheme is compiled in, then this and | -| | | the center_search_half_length | -| | | namelist items are used. (Search code | -| | | for 'use_old_vortex'.) Ratio of | -| | | refining grid for | -| | | spline-interpolation in determining | -| | | the vortex center. | -+---------------------------------------+-------------------+---------------------------------------+ -| circulation_pres_level | real(r8) | The model_mod now contains two | -| | | schemes for searching for a vortex | -| | | center location. If the **new** | -| | | scheme is compiled in, then this and | -| | | the circulation_radius namelist items | -| | | are used. (Search code for | -| | | 'use_old_vortex'.) Pressure, in | -| | | pascals, of the level at which the | -| | | circulation is computed when | -| | | searching for the vortex center. | -+---------------------------------------+-------------------+---------------------------------------+ -| circulation_radius | real(r8) | The model_mod now contains two | -| | | schemes for searching for a vortex | -| | | center location. If the **new** | -| | | scheme is compiled in, then this and | -| | | the circulation_pres_level namelist | -| | | items are used. (Search code for | -| | | 'use_old_vortex'.) Radius, in meters, | -| | | of the circle over which the | -| | | circulation calculation is done when | -| | | searching for the vortex center. | -+---------------------------------------+-------------------+---------------------------------------+ -| vert_localization_coord | integer | Vertical coordinate for vertical | -| | | localization. | -| | | | -| | | - 1 = model level | -| | | - 2 = pressure (in pascals) | -| | | - 3 = height (in meters) | -| | | - 4 = scale height (unitless) | -+---------------------------------------+-------------------+---------------------------------------+ -| allow_perturbed_ics | logical | *allow_perturbed_ics* should not be | -| | | used in most cases. It is provided | -| | | only as a means to create a tiny | -| | | ensemble for non-advancing tests. | -| | | Creating an initial ensemble is | -| | | covered in :doc:`./tutorial/README` | -+---------------------------------------+-------------------+---------------------------------------+ - - -The following items used to be in the WRF namelist but have been removed. The -first 4 are no longer needed, and the last one was moved to the -``&dart_to_wrf_nml`` namelist in 2010. In the Lanai release having these values -in the namelist does not cause a fatal error, but more recent versions of the -code will fail if any of these values are specified. Remove them from your -namelist to avoid errors. - -=================== ================= ========================================= -Item Type Description -=================== ================= ========================================= -``surf_obs`` logical OBSOLETE -- now an error to specify this. -``soil_data`` logical OBSOLETE -- now an error to specify this. -``h_diab`` logical OBSOLETE -- now an error to specify this. -``num_moist_vars`` integer OBSOLETE -- now an error to specify this. -``adv_mod_command`` character(len=32) OBSOLETE -- now an error to specify this. -=================== ================= ========================================= - -Files ------ - -- model_nml in input.nml -- wrfinput_d01, wrfinput_d02, ... (one file for each domain) -- netCDF output state diagnostics files + +Notes for model_nml: + +(1) vert_localization_coord must be one of: + 1 = model level + 2 = pressure + 3 = height + 4 = scale height + +(2) See the bottom of this file for explanations of polar, periodic_x, + periodic_y, and scm. + +(3) calendar = 3 is GREGORIAN, which is what WRF uses. +(4) If 'default_state_variables' is .true. the model_mod.f90 code will + fill the state variable table with the following wrf vars: + U, V, W, PH, T, MU + You must set it to false before you change the value + of 'wrf_state_variables' and have it take effect. + +(5) The format for 'wrf_state_variables' is an array of 5 strings: + WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and '999' if the + array is part of all domains. otherwise, it is a string with the domain + numbers (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). + example: + +.. code-block:: + wrf_state_variables='U','QTY_U_WIND_COMPONENT','TYPE_U','UPDATE','999', + 'V','QTY_V_WIND_COMPONENT','TYPE_V','UPDATE','999', + 'W','QTY_VERTICAL_VELOCITY','TYPE_W','UPDATE','999', + 'THM','QTY_POTENTIAL_TEMPERATURE','TYPE_T','UPDATE','999', + 'PH','QTY_GEOPOTENTIAL_HEIGHT','TYPE_GZ','UPDATE','999', + 'MU','QTY_PRESSURE','TYPE_MU','UPDATE','999', + 'QVAPOR','QTY_VAPOR_MIXING_RATIO','TYPE_QV','UPDATE','999', + 'QCLOUD','QTY_CLOUD_LIQUID_WATER','TYPE_QC','UPDATE','999', + 'QRAIN','QTY_RAINWATER_MIXING_RATIO','TYPE_QR','UPDATE','999', + 'U10','QTY_U_WIND_COMPONENT','TYPE_U10','UPDATE','999', + 'V10','QTY_V_WIND_COMPONENT','TYPE_V10','UPDATE','999', + 'T2','QTY_TEMPERATURE','TYPE_T2','UPDATE','999', + 'TH2','QTY_POTENTIAL_TEMPERATURE','TYPE_TH2','UPDATE','999', + 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', + 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', + +(6) The format for 'wrf_state_bounds' is an array of 4 strings: + WRF output field, minimum value, maximum value, and either + FAIL or CLAMP. FAIL will halt the program if an out of range value + is detected. CLAMP will set the out of range values to the min or max. + The special string 'NULL' will map to plus or minus infinity and will + not change the values. Arrays not listed in this table will not + be changed as they are read or written. + + + Polar and periodic_x namelist values are used in global wrf. If polar is true, + the grid interpolation routines will wrap over the north and south poles. + If periodic_x is true, when the east and west edges of the grid are + reached the interpolation will wrap. Note this is a separate issue + from regional models which cross the GMT line. Those grids are marked + as having a negative offset and do not need to wrap. This flag controls + what happens when the edges of the grid are reached. + + The scm flag is used for the 'single column model' version of WRF. + It needs the periodic_x and periodic_y flags set to true, in which + case the X and Y directions are periodic. There is no collapsing of the grid + into a single location like the 3d-spherical polar flag implies. + +Namelist Description +~~~~~~~~~~~~~~~~~~~~ + ++-------------------------------+-------------------+---------------------------------------+ +| Item | Type | Description | ++===============================+===================+=======================================+ +| default_state_variables | logical | If *.true.*, the dart state vector | +| | | contains the fields U, V, W, PH, T, | +| | | MU, in that order, and only those. | +| | | Any values listed in the | +| | | *wrf_state_variables* namelist item | +| | | will be ignored. | ++-------------------------------+-------------------+---------------------------------------+ +| wrf_state_variables | character(:, 5) | A 2D array of strings, 5 per wrf | +| | | array to be added to the dart state | +| | | vector. If *default_state_variables* | +| | | is *.true.*, this is ignored. When | +| | | *.false.*, this list of array names | +| | | controls which arrays and the order | +| | | that they are added to the state | +| | | vector. The 5 strings are: | +| | | | +| | | #. WRF field name - must match netcdf | +| | | name exactly | +| | | #. DART Quantity name - must match a | +| | | valid DART QTY_xxx exactly | +| | | #. WRF Type - supplements the quantity| +| | | name to control the operation of | +| | | forward operator. | +| | | #. The string UPDATE. At some future | +| | | point, non-updatable fields may | +| | | become part of the state vector. | +| | | #. A numeric string listing the | +| | | domain numbers this array is part | +| | | of. The special string 999 means | +| | | all domains. For example, '12' | +| | | means domains 1 and 2, '13' means | +| | | 1 and 3. | ++-------------------------------+-------------------+---------------------------------------+ +| wrf_state_bounds | character(:, 4) | A 2D array of strings, 4 per wrf | +| | | array. During the copy of data to and | +| | | from the wrf netcdf file, variables | +| | | listed here will have minimum and | +| | | maximum values enforced. The 4 | +| | | strings are: | +| | | | +| | | #. WRF field name - must match netcdf | +| | | name exactly | +| | | #. Minimum -- specified as a string | +| | | but must be a numeric value (e.g. | +| | | '0.1') Can be 'NULL' to allow any | +| | | minimum value. | +| | | #. Maximum -- specified as a string | +| | | but must be a numeric value (e.g. | +| | | '0.1') Can be 'NULL' to allow any | +| | | maximum value. | +| | | #. Action -- valid strings are | +| | | 'CLAMP' or 'FAIL'. 'FAIL' means if | +| | | value is found outside the range, | +| | | the code fails with an error. | +| | | 'CLAMP' sets the out of | +| | | range value to the minimum | +| | | or maximum value. | ++-------------------------------+-------------------+---------------------------------------+ +| num_domains | integer | Total number of WRF domains, | +| | | including nested domains. | ++-------------------------------+-------------------+---------------------------------------+ +| calendar_type | integer | Calendar type. Should be 3 | +| | | (GREGORIAN) for WRF. | ++-------------------------------+-------------------+---------------------------------------+ +| assimilation_period_seconds | integer | The time (in seconds) between | +| | | assimilations. This is modified if | +| | | necessary to be an integer multiple | +| | | of the underlying model timestep. | ++-------------------------------+-------------------+---------------------------------------+ +| periodic_x | logical | If *.true.*, the grid is periodic in | +| | | longitude, and points above the last | +| | | grid cell and points below the first | +| | | grid cell are wrapped. Note this is | +| | | not the same as a grid which crosses | +| | | the prime meridian. WRF handles that | +| | | with an offset in longitude and | +| | | points beyond the last grid index are | +| | | outside the domain. | ++-------------------------------+-------------------+---------------------------------------+ +| periodic_y | logical | Used for the single column model to | +| | | make the grid wrap in Y (see scm | +| | | below). This is NOT the same as | +| | | wrapping in latitude (see polar | +| | | below). | ++-------------------------------+-------------------+---------------------------------------+ +| polar | logical | If *.true.*, points at the poles are | +| | | wrapped across the grid. It is not | +| | | clear this is a good idea since the | +| | | grid is degnerate here. | ++-------------------------------+-------------------+---------------------------------------+ +| scm | logical | If *.true.* the single column model | +| | | is assumed. The grid is a single | +| | | vertical column, and there are 9 | +| | | cells arranged in a 3x3 grid. See the | +| | | WRF documentation for more | +| | | information on this configuration. | +| | | *periodic_x* and *periodic_y* should | +| | | also be *.true.* in this case. | ++-------------------------------+-------------------+---------------------------------------+ +| sfc_elev_max_diff | real(r8) | If > 0, the maximum difference, in | +| | | meters, between an observation marked | +| | | as a 'surface obs' as the vertical | +| | | type (with the surface elevation, in | +| | | meters, as the numerical vertical | +| | | location), and the surface elevation | +| | | as defined by the model. Observations | +| | | further away from the surface than | +| | | this threshold are rejected and not | +| | | assimilated. If the value is | +| | | negative, this test is skipped. | ++-------------------------------+-------------------+---------------------------------------+ +| allow_obs_below_vol | logical | If *.false.* then if an observation | +| | | with a vertical coordinate of | +| | | pressure or height (i.e. not a | +| | | surface observation) is below the | +| | | lowest 3d sigma level, it is outside | +| | | the field volume and the | +| | | interpolation routine rejects it. If | +| | | this is set to *.true.* and the | +| | | observation is above the surface | +| | | elevation but below the lowest field | +| | | volume level, the code will | +| | | extrapolate downward from data values | +| | | at levels 1 and 2. | ++-------------------------------+-------------------+---------------------------------------+ +| center_search_half_length | real(r8) | The model_mod now contains two | +| | | schemes for searching for a vortex | +| | | center location. If the **old** | +| | | scheme is compiled in, then this and | +| | | the center_spline_grid_scale namelist | +| | | items are used. (Search code for | +| | | 'use_old_vortex'.) Half length (in | +| | | meters) of a square box for searching | +| | | the vortex center. | ++-------------------------------+-------------------+---------------------------------------+ +| center_spline_grid_scale | integer | The model_mod now contains two | +| | | schemes for searching for a vortex | +| | | center location. If the **old** | +| | | scheme is compiled in, then this and | +| | | the center_search_half_length | +| | | namelist items are used. (Search code | +| | | for 'use_old_vortex'.) Ratio of | +| | | refining grid for | +| | | spline-interpolation in determining | +| | | the vortex center. | ++-------------------------------+-------------------+---------------------------------------+ +| circulation_pres_level | real(r8) | The model_mod now contains two | +| | | schemes for searching for a vortex | +| | | center location. If the **new** | +| | | scheme is compiled in, then this and | +| | | the circulation_radius namelist items | +| | | are used. (Search code for | +| | | 'use_old_vortex'.) Pressure, in | +| | | pascals, of the level at which the | +| | | circulation is computed when | +| | | searching for the vortex center. | ++-------------------------------+-------------------+---------------------------------------+ +| circulation_radius | real(r8) | The model_mod now contains two | +| | | schemes for searching for a vortex | +| | | center location. If the **new** | +| | | scheme is compiled in, then this and | +| | | the circulation_pres_level namelist | +| | | items are used. (Search code for | +| | | 'use_old_vortex'.) Radius, in meters, | +| | | of the circle over which the | +| | | circulation calculation is done when | +| | | searching for the vortex center. | ++-------------------------------+-------------------+---------------------------------------+ +| vert_localization_coord | integer | Vertical coordinate for vertical | +| | | localization. | +| | | | +| | | - 1 = model level | +| | | - 2 = pressure (in pascals) | +| | | - 3 = height (in meters) | +| | | - 4 = scale height (unitless) | ++-------------------------------+-------------------+---------------------------------------+ +| allow_perturbed_ics | logical | *allow_perturbed_ics* should not be | +| | | used in most cases. It is provided | +| | | only as a means to create a tiny | +| | | ensemble for non-advancing tests. | +| | | Creating an initial ensemble is | +| | | covered in :doc:`./tutorial/README` | ++-------------------------------+-------------------+---------------------------------------+ + + References ---------- diff --git a/models/wrf/tutorial/README.rst b/models/wrf/tutorial/README.rst index b1e99385b..0639b7b18 100644 --- a/models/wrf/tutorial/README.rst +++ b/models/wrf/tutorial/README.rst @@ -996,7 +996,7 @@ on WRF levels k and k+1, followed by vertical interpolation). Surface Wind (e.g. METAR_U_10_METER_WIND) ------------------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Surface winds have a direct WRF output analog (e.g. U10) and requires horizontal interpolation of the 2D zonal wind field. However, the @@ -1006,21 +1006,21 @@ mapped on a 2D grid. Non-Surface Wind (e.g. ACARS_U_WIND_COMPONENT) ----------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is identical to surface winds as described above, except the spatial interpolation requires horizontal interpolation on the k and k+1 WRF levels, followed by vertical interpolation. Surface Dewpoint (e.g. METAR_DEWPOINT_2_METER) ----------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The calculation of surface dewpoint requires a physical conversion using both surface pressure (PSFC) and surface vapor mixing ratio (Q2), follwed by horizontal interpolation. Non-Surface Specific Humidity (e.g. RADIOSONDE_SPECIFIC_HUMIDITY) ------------------------------------------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Specific humidity observations require the (water) vapor mixing ratio (QVAPOR) for the forward operator. Although specific humidity and vapor mixing ratio are nearly identical, especially in dry From 88a55dd08b5f63541738f60b74b9cfabb22cb5d1 Mon Sep 17 00:00:00 2001 From: braczka Date: Tue, 6 Aug 2024 17:54:34 -0600 Subject: [PATCH 06/19] Condensing WRF model docs --- models/wrf/readme.rst | 148 +++++++++++++-------------- models/wrf/wrf_state_variables_table | 11 +- 2 files changed, 74 insertions(+), 85 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index 5d40bebe2..5b046659b 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -20,32 +20,31 @@ with `DARTv11.5.0. `__ Some important WRF-DART updates include: - Version 11.4.1: Detects use of the Hybrid Vertical Coordinate system - (terrain following at surface) and accounts for this in forward + (terrain following at surface) and accounts for this in the forward operator calculations. - Version 11.5.0: Improves compatibility with WRFv4+ versions and later - where prognostic 3D temperature variable is THM. + where the prognostic 3D temperature variable is THM. -It is always recommended that you update your DART version to the `latest tag -`__ before beginning new research. +It is always recommended that you update your DART version to the +`latest release `__ before beginning new research. WRF+DART Tutorial ----------------- This tutorial provides a real-world example of assimilating a wide variety of atmospheric observations during an extreme storm event for the United States during April 2017. - -**It is strongly recommended that you also review and perform the tutorial documentation for +**It is strongly recommended that you also review and perform the tutorial for running a WRF-DART assimilation** `here. `__ -Items of Note +General Overview ------------- -- The ``model_mod`` reads WRF netCDF files directly to acquire the model state - data. The ``wrf_to_dart`` and ``dart_to_wrf`` programs are no longer - necessary. -- A netCDF file named ``wrfinput_d01`` is required and must be at the same +- The WRF ``model_mod.f90`` file reads WRF netCDF files directly to acquire the model state + data. Earlier version required ``wrf_to_dart`` and ``dart_to_wrf`` programs which + are no longer necessary. +- A WRF file named ``wrfinput_d01`` is required and must be at the same resolution and have the same surface elevation data as the files converted to create the DART initial conditions. No data will be read from this file, but the grid information must match exactly. @@ -80,11 +79,10 @@ coefficient based on the correlation between the distributions of the ensemble of state vector points and the ensemble of observation forward operator values. The fields from WRF that are copied into the DART state vector are controlled by -namelist. See below for the documentation on the ``&model_nml`` entries. The state -vector should include all fields needed to restart a WRF run. There may be -additional fields needed depending on the microphysics scheme selected. See the -ascii file ``wrf_state_variables_table`` in the ``models/wrf`` directory for a -list of fields that are often included in the DART state. +the namelist. See below for the documentation on the ``&model_nml`` entries within +``input.nml``. The state vector should include all fields needed to restart a WRF run. +There may be additional fields needed depending on the microphysics scheme selected. See the +ascii file `wrf_state_variables_table `__that includes a list of fields that may be added to the DART state. Namelist -------- @@ -118,69 +116,6 @@ prematurely terminating the namelist. / -Notes for model_nml: - -(1) vert_localization_coord must be one of: - 1 = model level - 2 = pressure - 3 = height - 4 = scale height - -(2) See the bottom of this file for explanations of polar, periodic_x, - periodic_y, and scm. - -(3) calendar = 3 is GREGORIAN, which is what WRF uses. -(4) If 'default_state_variables' is .true. the model_mod.f90 code will - fill the state variable table with the following wrf vars: - U, V, W, PH, T, MU - You must set it to false before you change the value - of 'wrf_state_variables' and have it take effect. - -(5) The format for 'wrf_state_variables' is an array of 5 strings: - WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and '999' if the - array is part of all domains. otherwise, it is a string with the domain - numbers (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). - example: - -.. code-block:: - wrf_state_variables='U','QTY_U_WIND_COMPONENT','TYPE_U','UPDATE','999', - 'V','QTY_V_WIND_COMPONENT','TYPE_V','UPDATE','999', - 'W','QTY_VERTICAL_VELOCITY','TYPE_W','UPDATE','999', - 'THM','QTY_POTENTIAL_TEMPERATURE','TYPE_T','UPDATE','999', - 'PH','QTY_GEOPOTENTIAL_HEIGHT','TYPE_GZ','UPDATE','999', - 'MU','QTY_PRESSURE','TYPE_MU','UPDATE','999', - 'QVAPOR','QTY_VAPOR_MIXING_RATIO','TYPE_QV','UPDATE','999', - 'QCLOUD','QTY_CLOUD_LIQUID_WATER','TYPE_QC','UPDATE','999', - 'QRAIN','QTY_RAINWATER_MIXING_RATIO','TYPE_QR','UPDATE','999', - 'U10','QTY_U_WIND_COMPONENT','TYPE_U10','UPDATE','999', - 'V10','QTY_V_WIND_COMPONENT','TYPE_V10','UPDATE','999', - 'T2','QTY_TEMPERATURE','TYPE_T2','UPDATE','999', - 'TH2','QTY_POTENTIAL_TEMPERATURE','TYPE_TH2','UPDATE','999', - 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', - 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', - -(6) The format for 'wrf_state_bounds' is an array of 4 strings: - WRF output field, minimum value, maximum value, and either - FAIL or CLAMP. FAIL will halt the program if an out of range value - is detected. CLAMP will set the out of range values to the min or max. - The special string 'NULL' will map to plus or minus infinity and will - not change the values. Arrays not listed in this table will not - be changed as they are read or written. - - - Polar and periodic_x namelist values are used in global wrf. If polar is true, - the grid interpolation routines will wrap over the north and south poles. - If periodic_x is true, when the east and west edges of the grid are - reached the interpolation will wrap. Note this is a separate issue - from regional models which cross the GMT line. Those grids are marked - as having a negative offset and do not need to wrap. This flag controls - what happens when the edges of the grid are reached. - - The scm flag is used for the 'single column model' version of WRF. - It needs the periodic_x and periodic_y flags set to true, in which - case the X and Y directions are periodic. There is no collapsing of the grid - into a single location like the 3d-spherical polar flag implies. - Namelist Description ~~~~~~~~~~~~~~~~~~~~ @@ -371,8 +306,63 @@ Namelist Description | | | covered in :doc:`./tutorial/README` | +-------------------------------+-------------------+---------------------------------------+ +Additional Namelist Information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +(1) If ``default_state_variables`` is .true. the ``model_mod.f90`` code will + fill the state variable table with the following wrf vars: + U, V, W, PH, T, MU + You must set it to false before you change the value + of ``wrf_state_variables`` and have it take effect. + + +(2) The format for ``wrf_state_variables`` is an array of 5 strings: + WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and 'XXX'. If XXX + is 999 the variable is part of all domains, otherwise it is limited + to specific domains (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). + example: + +.. code-block:: + wrf_state_variables='U','QTY_U_WIND_COMPONENT','TYPE_U','UPDATE','999', + 'V','QTY_V_WIND_COMPONENT','TYPE_V','UPDATE','999', + 'W','QTY_VERTICAL_VELOCITY','TYPE_W','UPDATE','999', + 'THM','QTY_POTENTIAL_TEMPERATURE','TYPE_T','UPDATE','999', + 'PH','QTY_GEOPOTENTIAL_HEIGHT','TYPE_GZ','UPDATE','999', + 'MU','QTY_PRESSURE','TYPE_MU','UPDATE','999', + 'QVAPOR','QTY_VAPOR_MIXING_RATIO','TYPE_QV','UPDATE','999', + 'QCLOUD','QTY_CLOUD_LIQUID_WATER','TYPE_QC','UPDATE','999', + 'QRAIN','QTY_RAINWATER_MIXING_RATIO','TYPE_QR','UPDATE','999', + 'U10','QTY_U_WIND_COMPONENT','TYPE_U10','UPDATE','999', + 'V10','QTY_V_WIND_COMPONENT','TYPE_V10','UPDATE','999', + 'T2','QTY_TEMPERATURE','TYPE_T2','UPDATE','999', + 'TH2','QTY_POTENTIAL_TEMPERATURE','TYPE_TH2','UPDATE','999', + 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', + 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', + +(3) The format for ``wrf_state_bounds`` is an array of 4 strings: + WRF output field, minimum value, maximum value, and either + FAIL or CLAMP. FAIL will halt the program if an out of range value + is detected. CLAMP will set the out of range values to the min or max. + The special string 'NULL' will map to plus or minus infinity and will + not change the values. Arrays not listed in this table will not + be changed as they are read or written. + + + +(4) The ``Polar`` and ``periodic_x`` namelist values are used in global WRF simulations. + If ``polar`` is true, the grid interpolation routines will wrap over the north and south poles. + If ``periodic_x`` is true, when the east and west edges of the grid are + reached the interpolation will wrap. Note this is a separate issue + from regional models which cross the GMT line. Those grids are marked + as having a negative offset and do not need to wrap. This flag controls + what happens when the edges of the grid are reached. + +(5) The scm flag is used for the ``single column model`` version of WRF. + It needs the periodic_x and periodic_y flags set to true, in which + case the X and Y directions are periodic. There is no collapsing of the grid + into a single location like the 3d-spherical polar flag implies. + References ---------- diff --git a/models/wrf/wrf_state_variables_table b/models/wrf/wrf_state_variables_table index 73ee3b537..5a5ca4584 100644 --- a/models/wrf/wrf_state_variables_table +++ b/models/wrf/wrf_state_variables_table @@ -4,14 +4,13 @@ # # DART $Id$ -This table contains the description of a value, followed by the line(s) +This table contains the description of an atmospheric property, followed by the line(s) that should be added to the DART input.nml namelist &model_nml, 'wrf_state_variables' list. All items must be strings. The 5 columns are: -Exact variable name in WRF netcdf file, DART Kind String, a Type -column that has a suggested value but is unused, a flag to say -whether the variable should be updated or not (currently only 'UPDATE' is -supported), and a flag to say which of multiple domains should have this -variable, where '999' means all domains. +exact variable name in WRF output file, DART Quantity , a WRF Type, +a flag to determine whether the variable is updated during the analysis +(currently only 'UPDATE' is supported), and a flag to identify +which domains include this variable, where '999' means all domains. Horizontal Winds: From 38bee4a7a437faac58a5f3340cec04e2bea147a2 Mon Sep 17 00:00:00 2001 From: braczka Date: Wed, 7 Aug 2024 10:35:12 -0600 Subject: [PATCH 07/19] Improve WRF namelist value description --- models/wrf/readme.rst | 196 ++++++++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 82 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index 5b046659b..1891a81d9 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -42,12 +42,11 @@ General Overview ------------- - The WRF ``model_mod.f90`` file reads WRF netCDF files directly to acquire the model state - data. Earlier version required ``wrf_to_dart`` and ``dart_to_wrf`` programs which + data. Earlier versions required ``wrf_to_dart`` and ``dart_to_wrf`` programs which are no longer necessary. - A WRF file named ``wrfinput_d01`` is required and must be at the same resolution and have the same surface elevation data as the files converted to - create the DART initial conditions. No data will be read from this file, but - the grid information must match exactly. + create the initial conditions. The model interface code supports WRF configurations with multiple domains. Data for all domains is read into the DART state vector. During the computation of @@ -69,20 +68,22 @@ searched first, then ``wrfinput_d03``, ``wrfinput_d02``, and finally need help with these modifications please contact DART support. -The forward operator is computed from the first domain grid that contains the -lat/lon of the observation. During the assimilation phase, when the state values -are adjusted based on the correlations and assimilation increments, all points -in all domains that are within the localization radius are adjusted, regardless -of domain. The impact of an observation on the state depends only on the -distance between the observation and the state vector point, and the regression -coefficient based on the correlation between the distributions of the ensemble -of state vector points and the ensemble of observation forward operator values. +In summary, the forward operator is computed from the first domain grid (searching from +finest grid to coarsest grid) that contains the lat/lon of the observation. During the +assimilation phase, however, when the state values are adjusted based on the correlations +and assimilation increments, all points in all domains that are within the +localization radius are adjusted, regardless of domain. The impact of an observation +on the state depends only on the distance between the observation and the state +vector point, and the regression coefficient based on the correlation between the +distributions of the ensemble of state vector points and the ensemble of observation +forward operator values. The fields from WRF that are copied into the DART state vector are controlled by -the namelist. See below for the documentation on the ``&model_nml`` entries within +the namelist within ``input.nml``. See below for the documentation on the ``&model_nml`` entries within ``input.nml``. The state vector should include all fields needed to restart a WRF run. There may be additional fields needed depending on the microphysics scheme selected. See the -ascii file `wrf_state_variables_table `__that includes a list of fields that may be added to the DART state. +ascii file `wrf_state_variables_table `__ +that includes a list of fields that may be added to the DART state. Namelist -------- @@ -116,8 +117,8 @@ prematurely terminating the namelist. / -Namelist Description -~~~~~~~~~~~~~~~~~~~~ +Namelist Description: +~~~~~~~~~~~~~~~~~~~~~ +-------------------------------+-------------------+---------------------------------------+ | Item | Type | Description | @@ -129,7 +130,7 @@ Namelist Description | | | *wrf_state_variables* namelist item | | | | will be ignored. | +-------------------------------+-------------------+---------------------------------------+ -| wrf_state_variables | character(:, 5) | A 2D array of strings, 5 per wrf | +| wrf_state_variables | character(:,5) | A 2D array of strings, 5 per wrf | | | | array to be added to the dart state | | | | vector. If *default_state_variables* | | | | is *.true.*, this is ignored. When | @@ -149,21 +150,22 @@ Namelist Description | | | point, non-updatable fields may | | | | become part of the state vector. | | | | #. A numeric string listing the | -| | | domain numbers this array is part | -| | | of. The special string 999 means | +| | | domain(s) that include the WRF | +| | | state variable. | +| | | The special string '999' means | | | | all domains. For example, '12' | | | | means domains 1 and 2, '13' means | | | | 1 and 3. | +-------------------------------+-------------------+---------------------------------------+ -| wrf_state_bounds | character(:, 4) | A 2D array of strings, 4 per wrf | +| wrf_state_bounds | character(:,4) | A 2D array of strings, 4 per wrf | | | | array. During the copy of data to and | -| | | from the wrf netcdf file, variables | -| | | listed here will have minimum and | -| | | maximum values enforced. The 4 | -| | | strings are: | +| | | from the WRF (wrfinput*) file, | +| | | variables listed here will have | +| | | minimum and maximum values enforced. | +| | | The 4 strings are: | | | | | -| | | #. WRF field name - must match netcdf | -| | | name exactly | +| | | #. WRF field name - must match | +| | | WRF variable name exactly | | | | #. Minimum -- specified as a string | | | | but must be a numeric value (e.g. | | | | '0.1') Can be 'NULL' to allow any | @@ -201,15 +203,15 @@ Namelist Description | | | points beyond the last grid index are | | | | outside the domain. | +-------------------------------+-------------------+---------------------------------------+ -| periodic_y | logical | Used for the single column model to | -| | | make the grid wrap in Y (see scm | +| periodic_y | logical | Used for the WRF single column model | +| | | to make the grid wrap in Y (see scm | | | | below). This is NOT the same as | | | | wrapping in latitude (see polar | | | | below). | +-------------------------------+-------------------+---------------------------------------+ | polar | logical | If *.true.*, points at the poles are | | | | wrapped across the grid. It is not | -| | | clear this is a good idea since the | +| | | clear this is a good idea because the | | | | grid is degnerate here. | +-------------------------------+-------------------+---------------------------------------+ | scm | logical | If *.true.* the single column model | @@ -221,18 +223,15 @@ Namelist Description | | | *periodic_x* and *periodic_y* should | | | | also be *.true.* in this case. | +-------------------------------+-------------------+---------------------------------------+ -| sfc_elev_max_diff | real(r8) | If > 0, the maximum difference, in | -| | | meters, between an observation marked | -| | | as a 'surface obs' as the vertical | -| | | type (with the surface elevation, in | -| | | meters, as the numerical vertical | -| | | location), and the surface elevation | -| | | as defined by the model. Observations | -| | | further away from the surface than | -| | | this threshold are rejected and not | -| | | assimilated. If the value is | -| | | negative, this test is skipped. | -+-------------------------------+-------------------+---------------------------------------+ +| sfc_elev_max_diff | real(r8) | The maximum elevation difference | +| | | (in meters) between a 'surface' | +| | | observation and the land surface | +| | | elevation defined in WRF. | +| | | If the value is > 0, that value is | +| | | the threshold at which the surface | +| | | observations are rejected. If the | +| | | value is negative the test is skipped.| ++-------------------------------+-------------------+--------------------------------------.+ | allow_obs_below_vol | logical | If *.false.* then if an observation | | | | with a vertical coordinate of | | | | pressure or height (i.e. not a | @@ -247,48 +246,51 @@ Namelist Description | | | extrapolate downward from data values | | | | at levels 1 and 2. | +-------------------------------+-------------------+---------------------------------------+ -| center_search_half_length | real(r8) | The model_mod now contains two | -| | | schemes for searching for a vortex | -| | | center location. If the **old** | -| | | scheme is compiled in, then this and | -| | | the center_spline_grid_scale namelist | -| | | items are used. (Search code for | -| | | 'use_old_vortex'.) Half length (in | -| | | meters) of a square box for searching | -| | | the vortex center. | +| center_search_half_length | real(r8) | A parameter in the 'use_old_vortex' | +| | | scheme used to search for a vortex | +| | | center location. It is the half-length| +| | | (meters) of a square box used during | +| | | the vortex search. This value and the | +| | | 'center_spline_grid_scale' namelist | +| | | items are required. To implement, set | +| | | ``use_old_vortex = .true.`` in | +| | | ``model_mod.f90`` prior to compiling | +| | | DART. | +-------------------------------+-------------------+---------------------------------------+ -| center_spline_grid_scale | integer | The model_mod now contains two | -| | | schemes for searching for a vortex | -| | | center location. If the **old** | -| | | scheme is compiled in, then this and | -| | | the center_search_half_length | -| | | namelist items are used. (Search code | -| | | for 'use_old_vortex'.) Ratio of | -| | | refining grid for | -| | | spline-interpolation in determining | -| | | the vortex center. | +| center_spline_grid_scale | integer | A parameter in the 'use_old_vortex' | +| | | scheme used to search for a vortex | +| | | center location. It is the fine grid | +| | | ratio for the spline interpolation | +| | | used during the vortex search. This | +| | | value and the | | | | 'center_search_half_length' namelist | +| | | items are required. To implement, set | +| | | ``use_old_vortex = .true.`` in | +| | | ``model_mod.f90`` prior to compiling | +| | | DART. | +-------------------------------+-------------------+---------------------------------------+ -| circulation_pres_level | real(r8) | The model_mod now contains two | -| | | schemes for searching for a vortex | -| | | center location. If the **new** | -| | | scheme is compiled in, then this and | -| | | the circulation_radius namelist items | -| | | are used. (Search code for | -| | | 'use_old_vortex'.) Pressure, in | -| | | pascals, of the level at which the | -| | | circulation is computed when | -| | | searching for the vortex center. | +| circulation_pres_level | real(r8) | A parameter in the 'circulation' | +| | | scheme used to search for a vortex | +| | | center location. It is the pressure | +| | | (Pascals) at which the circulation is | +| | | computed during the vortex search. | +| | | This value and the | +| | | 'circulation_radius' namelist items | +| | | are required. To implement, set | +| | | ``use_old_vortex = .false.`` in | +| | | ``model_mod.f90`` prior to compiling | +| | | DART. | +-------------------------------+-------------------+---------------------------------------+ -| circulation_radius | real(r8) | The model_mod now contains two | -| | | schemes for searching for a vortex | -| | | center location. If the **new** | -| | | scheme is compiled in, then this and | -| | | the circulation_pres_level namelist | -| | | items are used. (Search code for | -| | | 'use_old_vortex'.) Radius, in meters, | -| | | of the circle over which the | -| | | circulation calculation is done when | -| | | searching for the vortex center. | +| circulation_radius | real(r8) | A parameter in the 'circulation' | +| | | scheme used to search for a vortex | +| | | center location. It is the radius | +| | | (meters) of the circle over which the | +| | | search for the vortex center is | +| | | performed. This value and the | +| | | 'circulation_pres_level' namelist | +| | | items are required. To implement, | +| | | set ``use_old_vortex = .false.`` in | +| | | ``model_mod.f90`` prior to compiling | +| | | DART. +-------------------------------+-------------------+---------------------------------------+ | vert_localization_coord | integer | Vertical coordinate for vertical | | | | localization. | @@ -317,8 +319,8 @@ Additional Namelist Information (2) The format for ``wrf_state_variables`` is an array of 5 strings: - WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and 'XXX'. If XXX - is 999 the variable is part of all domains, otherwise it is limited + WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and a numerical + string 'XXX'. If XXX=999 the variable is part of all domains, otherwise it is limited to specific domains (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). example: @@ -358,11 +360,41 @@ Additional Namelist Information as having a negative offset and do not need to wrap. This flag controls what happens when the edges of the grid are reached. -(5) The scm flag is used for the ``single column model`` version of WRF. +(5) The ``scm`` flag is used for the single column model version of WRF. It needs the periodic_x and periodic_y flags set to true, in which case the X and Y directions are periodic. There is no collapsing of the grid into a single location like the 3d-spherical polar flag implies. + +(6) The intent of the ``sfc_elev_max_diff`` quality control check is to eliminate + surface observations that are mismatched from the WRF model's surface elevation. + Mismatch can occur if the WRF land surface elevation is not finely resolved (coarse grid) + thus there is a significant representation mismatch between a point observation + and the WRF model. Assimilating surface observations with large mismatch can + deprecate assimilation forecast skill. + This check can only be applied to **surface observations** which are automatically + assigned to observations that use the ``VERTISSURFACE`` vertical coordinate + defined in the ``obs_seq.out`` file. + +(7) The ``allow_obs_below_vol`` enables vertical extrapolation in cases where the + observation vertical location is below the lowest WRF model vertical layer, thus + used as an alternative for the standard vertical interpolation routine. + The bottom WRF layer can vary based on total vertical levels, however, in general, + descends to (roughly) 10-50 meters above the surface and does not encompass common + surface observations at 2 and 10 meters. This is not recommended given + (linear) extrapolation is a poor approximation of surface observations at the + land-atmosphere boundary where energy and vapor exchange are controlled by + similarity theory. When using surface observations it is preferred + (and the default of the WRF ``model_mod.f90``) to operate on the WRF 2D + surface output (e.g. T2, U10) instead of 3D WRF output (e.g. T, THM) to + avoid the need for extrapolation. + +(8) The vortex searching namelist options are only required during WRF simulations + where the spatial domain of interest is dynamic such as with a hurricane. + + + + References ---------- From b9725d1ea5f6dd4210294a26289f261cb2a85424 Mon Sep 17 00:00:00 2001 From: braczka Date: Wed, 7 Aug 2024 10:52:11 -0600 Subject: [PATCH 08/19] WRF doc syntax --- models/wrf/readme.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index 1891a81d9..99cfa876b 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -23,13 +23,13 @@ Some important WRF-DART updates include: (terrain following at surface) and accounts for this in the forward operator calculations. -- Version 11.5.0: Improves compatibility with WRFv4+ versions and later - where the prognostic 3D temperature variable is THM. +- Version 11.5.0: Improves compatibility with WRFv4+ versions where + the prognostic 3D temperature variable is THM. It is always recommended that you update your DART version to the `latest release `__ before beginning new research. -WRF+DART Tutorial +WRF-DART Tutorial ----------------- This tutorial provides a real-world example of assimilating a wide variety of atmospheric @@ -38,7 +38,7 @@ observations during an extreme storm event for the United States during April 20 running a WRF-DART assimilation** `here. `__ -General Overview +General WRF Interface Overview ------------- - The WRF ``model_mod.f90`` file reads WRF netCDF files directly to acquire the model state @@ -231,7 +231,7 @@ Namelist Description: | | | the threshold at which the surface | | | | observations are rejected. If the | | | | value is negative the test is skipped.| -+-------------------------------+-------------------+--------------------------------------.+ ++-------------------------------+-------------------+---------------------------------------+ | allow_obs_below_vol | logical | If *.false.* then if an observation | | | | with a vertical coordinate of | | | | pressure or height (i.e. not a | @@ -276,7 +276,7 @@ Namelist Description: | | | This value and the | | | | 'circulation_radius' namelist items | | | | are required. To implement, set | -| | | ``use_old_vortex = .false.`` in | +| | | ``use_old_vortex = .false.`` in | | | | ``model_mod.f90`` prior to compiling | | | | DART. | +-------------------------------+-------------------+---------------------------------------+ @@ -290,7 +290,7 @@ Namelist Description: | | | items are required. To implement, | | | | set ``use_old_vortex = .false.`` in | | | | ``model_mod.f90`` prior to compiling | -| | | DART. +| | | DART. | +-------------------------------+-------------------+---------------------------------------+ | vert_localization_coord | integer | Vertical coordinate for vertical | | | | localization. | @@ -312,17 +312,17 @@ Additional Namelist Information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (1) If ``default_state_variables`` is .true. the ``model_mod.f90`` code will - fill the state variable table with the following wrf vars: + fill the state variable table with the following WRF variables: U, V, W, PH, T, MU - You must set it to false before you change the value - of ``wrf_state_variables`` and have it take effect. + You must set ``default_state_variables = .false.`` before changing the value + of ``wrf_state_variables`` to have it take effect. (2) The format for ``wrf_state_variables`` is an array of 5 strings: WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and a numerical string 'XXX'. If XXX=999 the variable is part of all domains, otherwise it is limited to specific domains (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). - example: + For example: .. code-block:: @@ -344,9 +344,9 @@ Additional Namelist Information (3) The format for ``wrf_state_bounds`` is an array of 4 strings: WRF output field, minimum value, maximum value, and either - FAIL or CLAMP. FAIL will halt the program if an out of range value - is detected. CLAMP will set the out of range values to the min or max. - The special string 'NULL' will map to plus or minus infinity and will + FAIL or CLAMP. *FAIL* will halt the program if an out of range value + is detected. *CLAMP* will set the out of range values to the min or max. + The special string *NULL* will map to plus or minus infinity and will not change the values. Arrays not listed in this table will not be changed as they are read or written. @@ -386,7 +386,7 @@ Additional Namelist Information land-atmosphere boundary where energy and vapor exchange are controlled by similarity theory. When using surface observations it is preferred (and the default of the WRF ``model_mod.f90``) to operate on the WRF 2D - surface output (e.g. T2, U10) instead of 3D WRF output (e.g. T, THM) to + surface output (e.g. T2, U10) instead of WRF 3D output (e.g. T, THM) to avoid the need for extrapolation. (8) The vortex searching namelist options are only required during WRF simulations From 31030ab3d73df7995514ea740e422751e724568d Mon Sep 17 00:00:00 2001 From: braczka Date: Wed, 7 Aug 2024 11:09:46 -0600 Subject: [PATCH 09/19] WRF docs table rendering --- models/wrf/readme.rst | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index 99cfa876b..ef5158e6f 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -39,7 +39,7 @@ running a WRF-DART assimilation** `here. Date: Wed, 7 Aug 2024 11:45:41 -0600 Subject: [PATCH 10/19] More WRF syntax for docs --- models/wrf/readme.rst | 108 +++++++++++++++++---------------- models/wrf/tutorial/README.rst | 54 ++++++++--------- 2 files changed, 82 insertions(+), 80 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index ef5158e6f..d25d9d7f8 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -312,18 +312,18 @@ Namelist Description: Additional Namelist Information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- If ``default_state_variables`` is .true. the ``model_mod.f90`` code will - fill the state variable table with the following WRF variables: - U, V, W, PH, T, MU - You must set ``default_state_variables = .false.`` before changing the value - of ``wrf_state_variables`` to have it take effect. +- If ``default_state_variables`` is .true. the ``model_mod.f90`` code will + fill the state variable table with the following WRF variables: + U, V, W, PH, T, MU + You must set ``default_state_variables = .false.`` before changing the value + of ``wrf_state_variables`` to have it take effect. -- The format for ``wrf_state_variables`` is an array of 5 strings: - WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and a numerical - string 'XXX'. If XXX=999 the variable is part of all domains, otherwise it is limited - to specific domains (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). - For example: +- The format for ``wrf_state_variables`` is an array of 5 strings: + WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and a numerical + string 'XXX'. If XXX=999 the variable is part of all domains, otherwise it is limited + to specific domains (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). + For example: :: @@ -343,55 +343,57 @@ Additional Namelist Information 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', -- The format for ``wrf_state_bounds`` is an array of 4 strings: - WRF output field, minimum value, maximum value, and either - FAIL or CLAMP. *FAIL* will halt the program if an out of range value - is detected. *CLAMP* will set the out of range values to the min or max. - The special string *NULL* will map to plus or minus infinity and will - not change the values. Arrays not listed in this table will not - be changed as they are read or written. +- The format for ``wrf_state_bounds`` is an array of 4 strings: + WRF output field, minimum value, maximum value, and either + FAIL or CLAMP. *FAIL* will halt the program if an out of range value + is detected. *CLAMP* will set the out of range values to the min or max. + The special string *NULL* will map to plus or minus infinity and will + not change the values. Arrays not listed in this table will not + be changed as they are read or written. +- The ``Polar`` and ``periodic_x`` namelist values are used in global WRF simulations. + If ``polar`` is true, the grid interpolation routines will wrap over the north and south poles. + If ``periodic_x`` is true, when the east and west edges of the grid are + reached the interpolation will wrap. Note this is a separate issue + from regional models which cross the GMT line. Those grids are marked + as having a negative offset and do not need to wrap. This flag controls + what happens when the edges of the grid are reached. -- The ``Polar`` and ``periodic_x`` namelist values are used in global WRF simulations. - If ``polar`` is true, the grid interpolation routines will wrap over the north and south poles. - If ``periodic_x`` is true, when the east and west edges of the grid are - reached the interpolation will wrap. Note this is a separate issue - from regional models which cross the GMT line. Those grids are marked - as having a negative offset and do not need to wrap. This flag controls - what happens when the edges of the grid are reached. -- The ``scm`` flag is used for the single column model version of WRF. - It needs the periodic_x and periodic_y flags set to true, in which - case the X and Y directions are periodic. There is no collapsing of the grid - into a single location like the 3d-spherical polar flag implies. +- The ``scm`` flag is used for the single column model version of WRF. + It needs the periodic_x and periodic_y flags set to true, in which + case the X and Y directions are periodic. There is no collapsing of the grid + into a single location like the 3d-spherical polar flag implies. -- The intent of the ``sfc_elev_max_diff`` quality control check is to eliminate - surface observations that are mismatched from the WRF model's surface elevation. - Mismatch can occur if the WRF land surface elevation is not finely resolved (coarse grid) - thus there is a significant representation mismatch between a point observation - and the WRF model. Assimilating surface observations with large mismatch can - deprecate assimilation forecast skill. - This check can only be applied to **surface observations** which are automatically - assigned to observations that use the ``VERTISSURFACE`` vertical coordinate - defined in the ``obs_seq.out`` file. - -- The ``allow_obs_below_vol`` enables vertical extrapolation in cases where the - observation vertical location is below the lowest WRF model vertical layer, thus - used as an alternative for the standard vertical interpolation routine. - The bottom WRF layer can vary based on total vertical levels, however, in general, - descends to (roughly) 10-50 meters above the surface and does not encompass common - surface observations at 2 and 10 meters. This is not recommended given - (linear) extrapolation is a poor approximation of surface observations at the - land-atmosphere boundary where energy and vapor exchange are controlled by - similarity theory. When using surface observations it is preferred - (and the default of the WRF ``model_mod.f90``) to operate on the WRF 2D - surface output (e.g. T2, U10) instead of WRF 3D output (e.g. T, THM) to - avoid the need for extrapolation. - -- The vortex searching namelist options are only required during WRF simulations - where the spatial domain of interest is dynamic such as with a hurricane. +- The intent of the ``sfc_elev_max_diff`` quality control check is to eliminate + surface observations that are mismatched from the WRF model's surface elevation. + Mismatch can occur if the WRF land surface elevation is not finely resolved (coarse grid) + thus there is a significant representation mismatch between a point observation + and the WRF model. Assimilating surface observations with large mismatch can + deprecate assimilation forecast skill. + This check can only be applied to **surface observations** which are automatically + assigned to observations that use the ``VERTISSURFACE`` vertical coordinate + defined in the ``obs_seq.out`` file. + + +- The ``allow_obs_below_vol`` enables vertical extrapolation in cases where the + observation vertical location is below the lowest WRF model vertical layer, thus + used as an alternative for the standard vertical interpolation routine. + The bottom WRF layer can vary based on total vertical levels, however, in general, + descends to (roughly) 10-50 meters above the surface and does not encompass common + surface observations at 2 and 10 meters. This is not recommended given + (linear) extrapolation is a poor approximation of surface observations at the + land-atmosphere boundary where energy and vapor exchange are controlled by + similarity theory. When using surface observations it is preferred + (and the default of the WRF ``model_mod.f90``) to operate on the WRF 2D + surface output (e.g. T2, U10) instead of WRF 3D output (e.g. T, THM) to + avoid the need for extrapolation. + + +- The vortex searching namelist options are only required during WRF simulations + where the spatial domain of interest is dynamic such as with a hurricane. diff --git a/models/wrf/tutorial/README.rst b/models/wrf/tutorial/README.rst index 0639b7b18..e33a4e11b 100644 --- a/models/wrf/tutorial/README.rst +++ b/models/wrf/tutorial/README.rst @@ -939,36 +939,36 @@ output field for a select number of observation types within the tutorial. -+----------------------------------+-------------------------------+--------------+-------------+ -| DART Observation Type | DART Observation Quantities | WRF Type | WRF output | -| | | | field | -+==================================+===============================+==============+=============+ -| ``METAR_TEMPERATURE_2_METER`` | ``QTY_2M_TEMPERATURE`` | ``TYPE_T2`` | ``T2`` | -| (VERTISSURFACE) | | | | -+----------------------------------+-------------------------------+--------------+-------------+ -| ``RADIOSONDE_TEMPERATURE`` | ``QTY_POTENTIAL_TEMPERATURE`` | ``TYPE_T`` | ``THM`` | -| (VERTISPRESSURE) | ``QTY_VAPOR_MIXING_RATIO`` | ``TYPE_QV`` | ``QVAPOR`` | -| | ``QTY_PRESSURE`` | ``TYPE_MU`` | ``MU`` | -| | ``QTY_GEOPOTENTIAL_HEIGHT`` | ``TYPE_GZ`` | ``PH`` | -+----------------------------------+-------------------------------+--------------+-------------+ -| ``METAR_U_10_METER_WIND`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U10`` | ``U10`` | -| (VERTISSURFACE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V10`` | ``V10`` | -+----------------------------------+-------------------------------+--------------+-------------+ -| ``ACARS_U_WIND_COMPONENT`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U`` | ``U`` | -| (VERTISPRESSURE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V`` | ``V`` | -+----------------------------------+-------------------------------+--------------+-------------+ -| ``METAR_DEWPOINT_2_METER`` | ``QTY_DEWPOINT`` | | | -| (VERTISSURFACE) | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_Q2`` | ``Q2`` | -| | ``QTY_PRESSURE`` | ``TYPE_PS`` | ``PSFC`` | -+----------------------------------+-------------------------------+--------------+-------------+ -| ``RADIOSONDE_SPECIFIC_HUMIDITY`` | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_QV`` | ``QVAPOR`` | -| (VERTISPRESSURE) | | | | -+----------------------------------+-------------------------------+--------------+-------------+ ++----------------------------------+-------------------------------+--------------+------------+ +| DART Observation | DART Observation | WRF Type | WRF output | +| Type | Quantity | | field | ++==================================+===============================+==============+============+ +| ``METAR_TEMPERATURE_2_METER`` | ``QTY_2M_TEMPERATURE`` | ``TYPE_T2`` | ``T2`` | +| (VERTISSURFACE) | | | | ++----------------------------------+-------------------------------+--------------+------------+ +| ``RADIOSONDE_TEMPERATURE`` | ``QTY_POTENTIAL_TEMPERATURE`` | ``TYPE_T`` | ``THM`` | +| (VERTISPRESSURE) | ``QTY_VAPOR_MIXING_RATIO`` | ``TYPE_QV`` | ``QVAPOR`` | +| | ``QTY_PRESSURE`` | ``TYPE_MU`` | ``MU`` | +| | ``QTY_GEOPOTENTIAL_HEIGHT`` | ``TYPE_GZ`` | ``PH`` | ++----------------------------------+-------------------------------+--------------+------------+ +| ``METAR_U_10_METER_WIND`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U10`` | ``U10`` | +| (VERTISSURFACE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V10`` | ``V10`` | ++----------------------------------+-------------------------------+--------------+------------+ +| ``ACARS_U_WIND_COMPONENT`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U`` | ``U`` | +| (VERTISPRESSURE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V`` | ``V`` | ++----------------------------------+-------------------------------+--------------+------------+ +| ``METAR_DEWPOINT_2_METER`` | ``QTY_DEWPOINT`` | | | +| (VERTISSURFACE) | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_Q2`` | ``Q2`` | +| | ``QTY_PRESSURE`` | ``TYPE_PS`` | ``PSFC`` | ++----------------------------------+-------------------------------+--------------+------------+ +| ``RADIOSONDE_SPECIFIC_HUMIDITY`` | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_QV`` | ``QVAPOR`` | +| (VERTISPRESSURE) | | | | ++----------------------------------+-------------------------------+--------------+------------+ Surface Temperature (e.g. METAR_TEMPERATURE_2_METER) ----------------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WRF output includes a direct analog for sensible temperature surface observations (e.g. T2), thus the forward operator requires only 1 variable to calculate the expected observation. @@ -976,7 +976,7 @@ The calculation includes a horizontal interpolation of the 2D temperature variab Non-Surface Temperature (e.g. RADIOSONDE_TEMPERATURE) ------------------------------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In contrast to surface temperature observations, non-surface temperature observations require 4 WRF output fields. This is because observations are sensible temperature, whereas the 3D WRF From 6c312336b55bd134168fb9f62d29a4903388b989 Mon Sep 17 00:00:00 2001 From: braczka Date: Wed, 7 Aug 2024 13:12:06 -0600 Subject: [PATCH 11/19] Table syntax for WRF docs --- models/wrf/readme.rst | 140 +++++++++++++++++++-------------- models/wrf/tutorial/README.rst | 52 ++++++------ 2 files changed, 105 insertions(+), 87 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index d25d9d7f8..d31528d8d 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -38,8 +38,8 @@ observations during an extreme storm event for the United States during April 20 running a WRF-DART assimilation** `here. `__ -General WRF Interface Overview ------------------------------- +WRF Interface Overview +---------------------- - The WRF ``model_mod.f90`` file reads WRF netCDF files directly to acquire the model state data. Earlier versions required ``wrf_to_dart`` and ``dart_to_wrf`` programs which @@ -252,8 +252,8 @@ Namelist Description: | | | (meters) of a square box used during | | | | the vortex search. This value and the | | | | 'center_spline_grid_scale' namelist | -| | | items are required. To implement, set | -| | | ``use_old_vortex = .true.`` in | +| | | items are required. To implement, set | +| | | ``use_old_vortex = .true.`` in | | | | ``model_mod.f90`` prior to compiling | | | | DART. | +-------------------------------+-------------------+---------------------------------------+ @@ -262,7 +262,8 @@ Namelist Description: | | | center location. It is the fine grid | | | | ratio for the spline interpolation | | | | used during the vortex search. This | -| | | value and the | | | | 'center_search_half_length' namelist | +| | | value and the | +| | | 'center_search_half_length' namelist | | | | items are required. To implement, set | | | | ``use_old_vortex = .true.`` in | | | | ``model_mod.f90`` prior to compiling | @@ -312,18 +313,22 @@ Namelist Description: Additional Namelist Information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- If ``default_state_variables`` is .true. the ``model_mod.f90`` code will - fill the state variable table with the following WRF variables: - U, V, W, PH, T, MU - You must set ``default_state_variables = .false.`` before changing the value - of ``wrf_state_variables`` to have it take effect. +- default_state_variables + +If ``default_state_variables`` is .true. the ``model_mod.f90`` code will +fill the state variable table with the following WRF variables: +U, V, W, PH, T, MU +You must set ``default_state_variables = .false.`` before changing the value +of ``wrf_state_variables`` to have it take effect. -- The format for ``wrf_state_variables`` is an array of 5 strings: - WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and a numerical - string 'XXX'. If XXX=999 the variable is part of all domains, otherwise it is limited - to specific domains (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). - For example: +- wrf_state_variables + +The format for ``wrf_state_variables`` is an array of 5 strings: +WRF output field, DART Quantity, WRF TYPE, 'UPDATE', and a numerical +string 'XXX'. If XXX=999 the variable is part of all domains, otherwise it is limited +to specific domains (e.g. '12' for domains 1 and 2, '13' for domains 1 and 3). +For example: :: @@ -343,57 +348,70 @@ Additional Namelist Information 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', -- The format for ``wrf_state_bounds`` is an array of 4 strings: - WRF output field, minimum value, maximum value, and either - FAIL or CLAMP. *FAIL* will halt the program if an out of range value - is detected. *CLAMP* will set the out of range values to the min or max. - The special string *NULL* will map to plus or minus infinity and will - not change the values. Arrays not listed in this table will not - be changed as they are read or written. +- wrf_state_bounds -- The ``Polar`` and ``periodic_x`` namelist values are used in global WRF simulations. - If ``polar`` is true, the grid interpolation routines will wrap over the north and south poles. - If ``periodic_x`` is true, when the east and west edges of the grid are - reached the interpolation will wrap. Note this is a separate issue - from regional models which cross the GMT line. Those grids are marked - as having a negative offset and do not need to wrap. This flag controls - what happens when the edges of the grid are reached. +The format for ``wrf_state_bounds`` is an array of 4 strings: +WRF output field, minimum value, maximum value, and either +FAIL or CLAMP. *FAIL* will halt the program if an out of range value +is detected. *CLAMP* will set the out of range values to the min or max. +The special string *NULL* will map to plus or minus infinity and will +not change the values. Arrays not listed in this table will not +be changed as they are read or written. -- The ``scm`` flag is used for the single column model version of WRF. - It needs the periodic_x and periodic_y flags set to true, in which - case the X and Y directions are periodic. There is no collapsing of the grid - into a single location like the 3d-spherical polar flag implies. - +- polar, periodic_x -- The intent of the ``sfc_elev_max_diff`` quality control check is to eliminate - surface observations that are mismatched from the WRF model's surface elevation. - Mismatch can occur if the WRF land surface elevation is not finely resolved (coarse grid) - thus there is a significant representation mismatch between a point observation - and the WRF model. Assimilating surface observations with large mismatch can - deprecate assimilation forecast skill. - This check can only be applied to **surface observations** which are automatically - assigned to observations that use the ``VERTISSURFACE`` vertical coordinate - defined in the ``obs_seq.out`` file. - - -- The ``allow_obs_below_vol`` enables vertical extrapolation in cases where the - observation vertical location is below the lowest WRF model vertical layer, thus - used as an alternative for the standard vertical interpolation routine. - The bottom WRF layer can vary based on total vertical levels, however, in general, - descends to (roughly) 10-50 meters above the surface and does not encompass common - surface observations at 2 and 10 meters. This is not recommended given - (linear) extrapolation is a poor approximation of surface observations at the - land-atmosphere boundary where energy and vapor exchange are controlled by - similarity theory. When using surface observations it is preferred - (and the default of the WRF ``model_mod.f90``) to operate on the WRF 2D - surface output (e.g. T2, U10) instead of WRF 3D output (e.g. T, THM) to - avoid the need for extrapolation. - - -- The vortex searching namelist options are only required during WRF simulations - where the spatial domain of interest is dynamic such as with a hurricane. +The ``Polar`` and ``periodic_x`` namelist values are used in global WRF simulations. +If ``polar`` is true, the grid interpolation routines will wrap over the north and south poles. +If ``periodic_x`` is true, when the east and west edges of the grid are +reached the interpolation will wrap. Note this is a separate issue +from regional models which cross the GMT line. Those grids are marked +as having a negative offset and do not need to wrap. This flag controls +what happens when the edges of the grid are reached. + + +- Single Column Model (scm) + +The ``scm`` flag is used for the single column model version of WRF. +It needs the periodic_x and periodic_y flags set to true, in which +case the X and Y directions are periodic. There is no collapsing of the grid +into a single location like the 3d-spherical polar flag implies. + + +- sfc_elev_max_diff + +The intent of the ``sfc_elev_max_diff`` quality control check is to eliminate +surface observations that are mismatched from the WRF model's surface elevation. +Mismatch can occur if the WRF land surface elevation is not finely resolved (coarse grid) +thus there is a significant representation mismatch between a point observation +and the WRF model. Assimilating surface observations with large mismatch can +deprecate assimilation forecast skill. +This check can only be applied to **surface observations** which are automatically +assigned to observations that use the ``VERTISSURFACE`` vertical coordinate +defined in the ``obs_seq.out`` file. + + +- allow_obs_below_vol + +The ``allow_obs_below_vol`` enables vertical extrapolation in cases where the +observation vertical location is below the lowest WRF model vertical layer, thus +used as an alternative for the standard vertical interpolation routine. +The bottom WRF layer can vary based on total vertical levels, however, in general, +descends to (roughly) 10-50 meters above the surface and does not encompass common +surface observations at 2 and 10 meters. This is not recommended given +(linear) extrapolation is a poor approximation of surface observations at the +land-atmosphere boundary where energy and vapor exchange are controlled by +similarity theory. When using surface observations it is preferred +(and the default of the WRF ``model_mod.f90``) to operate on the WRF 2D +surface output (e.g. T2, U10) instead of WRF 3D output (e.g. T, THM) to +avoid the need for extrapolation. + + +- Vortex option + +The vortex searching namelist options are only required during WRF simulations +where the spatial domain of interest is dynamic such as with a hurricane. diff --git a/models/wrf/tutorial/README.rst b/models/wrf/tutorial/README.rst index e33a4e11b..6d004bb29 100644 --- a/models/wrf/tutorial/README.rst +++ b/models/wrf/tutorial/README.rst @@ -808,7 +808,7 @@ you would do the following: for the program to access the analysis domain information. Step 4: Overview of forward (observation) operators [OPTIONAL] ---------------------------------------------------- +-------------------------------------------------------------- This section is for informational purposes only and does not include any instructions to complete the tutorial. It provides a description of @@ -939,31 +939,31 @@ output field for a select number of observation types within the tutorial. -+----------------------------------+-------------------------------+--------------+------------+ -| DART Observation | DART Observation | WRF Type | WRF output | -| Type | Quantity | | field | -+==================================+===============================+==============+============+ -| ``METAR_TEMPERATURE_2_METER`` | ``QTY_2M_TEMPERATURE`` | ``TYPE_T2`` | ``T2`` | -| (VERTISSURFACE) | | | | -+----------------------------------+-------------------------------+--------------+------------+ -| ``RADIOSONDE_TEMPERATURE`` | ``QTY_POTENTIAL_TEMPERATURE`` | ``TYPE_T`` | ``THM`` | -| (VERTISPRESSURE) | ``QTY_VAPOR_MIXING_RATIO`` | ``TYPE_QV`` | ``QVAPOR`` | -| | ``QTY_PRESSURE`` | ``TYPE_MU`` | ``MU`` | -| | ``QTY_GEOPOTENTIAL_HEIGHT`` | ``TYPE_GZ`` | ``PH`` | -+----------------------------------+-------------------------------+--------------+------------+ -| ``METAR_U_10_METER_WIND`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U10`` | ``U10`` | -| (VERTISSURFACE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V10`` | ``V10`` | -+----------------------------------+-------------------------------+--------------+------------+ -| ``ACARS_U_WIND_COMPONENT`` | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U`` | ``U`` | -| (VERTISPRESSURE) | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V`` | ``V`` | -+----------------------------------+-------------------------------+--------------+------------+ -| ``METAR_DEWPOINT_2_METER`` | ``QTY_DEWPOINT`` | | | -| (VERTISSURFACE) | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_Q2`` | ``Q2`` | -| | ``QTY_PRESSURE`` | ``TYPE_PS`` | ``PSFC`` | -+----------------------------------+-------------------------------+--------------+------------+ -| ``RADIOSONDE_SPECIFIC_HUMIDITY`` | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_QV`` | ``QVAPOR`` | -| (VERTISPRESSURE) | | | | -+----------------------------------+-------------------------------+--------------+------------+ ++----------------------------------+---------+-------------------------------+--------------+------------+ +| DART Observation Type | Surface | DART Observation Quantity | WRF Type | WRF output | +| | Obs ? | | | field | ++==================================+=========+===============================+==============+============+ +| ``METAR_TEMPERATURE_2_METER`` | Yes | ``QTY_2M_TEMPERATURE`` | ``TYPE_T2`` | ``T2`` | +| | | | | | ++----------------------------------+---------+-------------------------------+--------------+------------+ +| ``RADIOSONDE_TEMPERATURE`` | No | ``QTY_POTENTIAL_TEMPERATURE`` | ``TYPE_T`` | ``THM`` | +| | | ``QTY_VAPOR_MIXING_RATIO`` | ``TYPE_QV`` | ``QVAPOR`` | +| | | ``QTY_PRESSURE`` | ``TYPE_MU`` | ``MU PH`` | +| | | ``QTY_GEOPOTENTIAL_HEIGHT`` | ``TYPE_GZ`` | | ++----------------------------------+---------+-------------------------------+--------------+------------+ +| ``METAR_U_10_METER_WIND`` | Yes | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U10`` | ``U10`` | +| | | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V10`` | ``V10`` | ++----------------------------------+---------+-------------------------------+--------------+------------+ +| ``ACARS_U_WIND_COMPONENT`` | No | ``QTY_U_WIND_COMPONENT`` | ``TYPE_U`` | ``U`` | +| | | ``QTY_V_WIND_COMPONENT`` | ``TYPE_V`` | ``V`` | ++----------------------------------+---------+-------------------------------+--------------+------------+ +| ``METAR_DEWPOINT_2_METER`` | Yes | ``QTY_DEWPOINT`` | | | +| | | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_Q2`` | ``Q2`` | +| | | ``QTY_PRESSURE`` | ``TYPE_PS`` | ``PSFC`` | ++----------------------------------+---------+-------------------------------+--------------+------------+ +| ``RADIOSONDE_SPECIFIC_HUMIDITY`` | No | ``QTY_SPECIFIC_HUMIDITY`` | ``TYPE_QV`` | ``QVAPOR`` | +| | | | | | ++----------------------------------+---------+-------------------------------+--------------+------------+ From 6baf5379b5312d4d62f4ca0a17743f6525ede14c Mon Sep 17 00:00:00 2001 From: braczka Date: Wed, 7 Aug 2024 16:33:58 -0600 Subject: [PATCH 12/19] Fixing WRF mean_increment diagnostic --- models/wrf/shell_scripts/mean_increment.ncl | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/models/wrf/shell_scripts/mean_increment.ncl b/models/wrf/shell_scripts/mean_increment.ncl index d6e230e41..c12b8e7af 100644 --- a/models/wrf/shell_scripts/mean_increment.ncl +++ b/models/wrf/shell_scripts/mean_increment.ncl @@ -1,7 +1,7 @@ ; find the mean state space increment, output the fields to a single mean file ; that can be used to make plots ; G. Romine 2011-12 - +; Updating for 1 domain only B. Raczka 2024-08 begin ; get the list of files to read in @@ -23,9 +23,7 @@ begin ListSetType(fil, "join") pull_2D_field_names = (/"T2", "Q2", "U10", "V10", "PSFC"/) - pull_2D_field_names(:) = pull_2D_field_names(:)+"_d01" - pull_3D_field_names = (/"U", "V", "T", "QVAPOR"/) - pull_3D_field_names(:) = pull_3D_field_names(:)+"_d01" + pull_3D_field_names = (/"U", "V", "THM", "QVAPOR"/) npulls = dimsizes(pull_2D_field_names) ; Below will dump out the data to a file for replotting later @@ -34,16 +32,17 @@ begin do i=0,npulls-1 print(" Extracting 2d variable "+pull_2D_field_names(i)) do fil_num=0,nfils-1 -; print(" reading file "+flist(fil_num)) -; dimensions are ncljoin, copy, Time, south_north, west_east +; print(" reading file "+flist(fil_num)) +; dimensions are ncljoin, Time, south_north, west_east ; copy zero is the ensemble mean - pull_var = fil[fil_num]->$pull_2D_field_names(i)$(:,0,:,:,:) + pull_var = fil[fil_num]->$pull_2D_field_names(i)$(:,:,:,:) dims = dimsizes(pull_var) if (fil_num .eq. 0) then ; first iteration, make var alltimes_var = new ( (/nfils,dims(2),dims(3)/), typeof(pull_var) ) end if ; printVarSummary(pull_var) alltimes_var(fil_num,:,:) = pull_var(0,0,:,:) +; printVarSummary(alltimes_var) delete(pull_var) end do ; average over time (first dimension) @@ -69,9 +68,9 @@ begin print(" Extracting 3d variable "+pull_3D_field_names(i)) do fil_num=0,nfils-1 ; print(" reading file "+flist(fil_num)) -; dimensions are ncljoin, copy, Time, level, south_north, west_east +; dimensions are ncljoin, Time, level, south_north, west_east ; copy zero is the ensemble mean - pull_var = fil[fil_num]->$pull_3D_field_names(i)$(:,0,:,:,:,:) + pull_var = fil[fil_num]->$pull_3D_field_names(i)$(:,:,:,:,:) dims = dimsizes(pull_var) if (fil_num .eq. 0) then ; first iteration, make var alltimes_var = new ( (/nfils,dims(2),dims(3),dims(4)/), typeof(pull_var) ) From e7de249c92f3167f17ee35f43e06d5c00be28ea5 Mon Sep 17 00:00:00 2001 From: braczka Date: Fri, 9 Aug 2024 09:39:05 -0600 Subject: [PATCH 13/19] Remove resubmission option for assim_advance driver.csh has ability to check for assim_advance jobs that fail, and resubmits. Switch to derecho has led to false detections, which leads to errors. Removed resubmission and replaced with warning --- models/wrf/shell_scripts/driver.csh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/models/wrf/shell_scripts/driver.csh b/models/wrf/shell_scripts/driver.csh index dbe9b6c11..f0573607d 100755 --- a/models/wrf/shell_scripts/driver.csh +++ b/models/wrf/shell_scripts/driver.csh @@ -473,19 +473,18 @@ while ( 1 == 1 ) else if ( $SUPER_PLATFORM == 'derecho' ) then - # Prevent double submission for member 1 only - if ( $n == 1) then - sleep 5 - endif if ( `qstat -wa | grep assim_advance_${n} | wc -l` == 0 ) then - echo "assim_advance_${n} is missing from the queue" - qsub assim_advance_mem${n}.csh + echo "Warning, detected that assim_advance_${n} is missing from the queue" + echo "If this warning leads to missing output from ensemble ${n}" + echo "consider enabling the qsub command within keep_trying while statement in driver.csh" + + #qsub assim_advance_mem${n}.csh endif endif - sleep 15 + sleep 5 end set start_time = `head -1 start_member_${n}` From 61ec2e990f13e81684553437da1824e04aa7aed0 Mon Sep 17 00:00:00 2001 From: braczka Date: Fri, 9 Aug 2024 11:02:15 -0600 Subject: [PATCH 14/19] Applying surface obs fix to WRF model_mod Alternative to modifying METART obs_def --- models/wrf/model_mod.f90 | 156 ++++++++++-------- .../wrf/tutorial/template/input.nml.template | 2 +- .../forward_operators/obs_def_metar_mod.f90 | 2 +- 3 files changed, 85 insertions(+), 75 deletions(-) diff --git a/models/wrf/model_mod.f90 b/models/wrf/model_mod.f90 index 29bc27e7a..9ca5ddbe7 100644 --- a/models/wrf/model_mod.f90 +++ b/models/wrf/model_mod.f90 @@ -1648,86 +1648,96 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte elseif ( obs_kind == QTY_TEMPERATURE ) then ! This is for 3D temperature field -- surface temps later - !print*, 'k ', k + if(.not. surf_var) then - if ( wrf%dom(id)%type_t >= 0 ) then + if ( wrf%dom(id)%type_t >= 0 ) then - do uk = 1, count ! for the different ks + do uk = 1, count ! for the different ks - ! Check to make sure retrieved integer gridpoints are in valid range - if ( boundsCheck( i, wrf%dom(id)%periodic_x, id, dim=1, type=wrf%dom(id)%type_t ) .and. & - boundsCheck( j, wrf%dom(id)%polar, id, dim=2, type=wrf%dom(id)%type_t ) .and. & - boundsCheck( uniquek(uk), .false., id, dim=3, type=wrf%dom(id)%type_t ) ) then + ! Check to make sure retrieved integer gridpoints are in valid range + if ( boundsCheck( i, wrf%dom(id)%periodic_x, id, dim=1, type=wrf%dom(id)%type_t ) .and. & + boundsCheck( j, wrf%dom(id)%polar, id, dim=2, type=wrf%dom(id)%type_t ) .and. & + boundsCheck( uniquek(uk), .false., id, dim=3, type=wrf%dom(id)%type_t ) ) then - call getCorners(i, j, id, wrf%dom(id)%type_t, ll, ul, lr, ur, rc ) - if ( rc .ne. 0 ) & - print*, 'model_mod.f90 :: model_interpolate :: getCorners T rc = ', rc + call getCorners(i, j, id, wrf%dom(id)%type_t, ll, ul, lr, ur, rc ) + if ( rc .ne. 0 ) & + print*, 'model_mod.f90 :: model_interpolate :: getCorners T rc = ', rc - ! Interpolation for T field at level k - ill = get_dart_vector_index(ll(1), ll(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_t) - iul = get_dart_vector_index(ul(1), ul(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_t) - ilr = get_dart_vector_index(lr(1), lr(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_t) - iur = get_dart_vector_index(ur(1), ur(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_t) - - x_iul = get_state(iul, state_handle) - x_ill = get_state(ill, state_handle) - x_ilr = get_state(ilr, state_handle) - x_iur = get_state(iur, state_handle) - - ! In terms of perturbation potential temperature - a1 = dym*( dxm*x_ill + dx*x_ilr ) + dy*( dxm*x_iul + dx*x_iur ) - - pres1 = model_pressure_t_distrib(ll(1), ll(2), uniquek(uk), id, state_handle, ens_size) - pres2 = model_pressure_t_distrib(lr(1), lr(2), uniquek(uk), id, state_handle, ens_size) - pres3 = model_pressure_t_distrib(ul(1), ul(2), uniquek(uk), id, state_handle, ens_size) - pres4 = model_pressure_t_distrib(ur(1), ur(2), uniquek(uk), id, state_handle, ens_size) - - ! Pressure at location - pres = dym*( dxm*pres1 + dx*pres2 ) + dy*( dxm*pres3 + dx*pres4 ) - - do e = 1, ens_size - if ( k(e) == uniquek(uk) ) then - ! Full sensible temperature field - fld(1, e) = (ts0 + a1(e))*(pres(e)/ps0)**kappa - endif - enddo - - ! Interpolation for T field at level k+1 - ill = get_dart_vector_index(ll(1), ll(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_t) - iul = get_dart_vector_index(ul(1), ul(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_t) - ilr = get_dart_vector_index(lr(1), lr(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_t) - iur = get_dart_vector_index(ur(1), ur(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_t) - - x_ill = get_state(ill, state_handle) - x_iul = get_state(iul, state_handle) - x_iur = get_state(iur, state_handle) - x_ilr = get_state(ilr, state_handle) - - ! In terms of perturbation potential temperature - a1 = dym*( dxm*x_ill + dx*x_ilr ) + dy*( dxm*x_iul + dx*x_iur ) - - pres1 = model_pressure_t_distrib(ll(1), ll(2), uniquek(uk)+1, id, state_handle, ens_size) - pres2 = model_pressure_t_distrib(lr(1), lr(2), uniquek(uk)+1, id, state_handle, ens_size) - pres3 = model_pressure_t_distrib(ul(1), ul(2), uniquek(uk)+1, id, state_handle, ens_size) - pres4 = model_pressure_t_distrib(ur(1), ur(2), uniquek(uk)+1, id, state_handle, ens_size) - - ! Pressure at location - pres = dym*( dxm*pres1 + dx*pres2 ) + dy*( dxm*pres3 + dx*pres4 ) - - do e = 1, ens_size - if ( k(e) == uniquek(uk) ) then - ! Full sensible temperature field - fld(2, e) = (ts0 + a1(e))*(pres(e)/ps0)**kappa - endif - enddo - endif - enddo + ! Interpolation for T field at level k + ill = get_dart_vector_index(ll(1), ll(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_t) + iul = get_dart_vector_index(ul(1), ul(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_t) + ilr = get_dart_vector_index(lr(1), lr(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_t) + iur = get_dart_vector_index(ur(1), ur(2), uniquek(uk), domain_id(id), wrf%dom(id)%type_t) + + x_iul = get_state(iul, state_handle) + x_ill = get_state(ill, state_handle) + x_ilr = get_state(ilr, state_handle) + x_iur = get_state(iur, state_handle) + + ! In terms of perturbation potential temperature + a1 = dym*( dxm*x_ill + dx*x_ilr ) + dy*( dxm*x_iul + dx*x_iur ) + + pres1 = model_pressure_t_distrib(ll(1), ll(2), uniquek(uk), id, state_handle, ens_size) + pres2 = model_pressure_t_distrib(lr(1), lr(2), uniquek(uk), id, state_handle, ens_size) + pres3 = model_pressure_t_distrib(ul(1), ul(2), uniquek(uk), id, state_handle, ens_size) + pres4 = model_pressure_t_distrib(ur(1), ur(2), uniquek(uk), id, state_handle, ens_size) + + ! Pressure at location + pres = dym*( dxm*pres1 + dx*pres2 ) + dy*( dxm*pres3 + dx*pres4 ) + + do e = 1, ens_size + if ( k(e) == uniquek(uk) ) then + ! Full sensible temperature field + fld(1, e) = (ts0 + a1(e))*(pres(e)/ps0)**kappa + endif + enddo + + ! Interpolation for T field at level k+1 + ill = get_dart_vector_index(ll(1), ll(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_t) + iul = get_dart_vector_index(ul(1), ul(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_t) + ilr = get_dart_vector_index(lr(1), lr(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_t) + iur = get_dart_vector_index(ur(1), ur(2), uniquek(uk)+1, domain_id(id), wrf%dom(id)%type_t) + + x_ill = get_state(ill, state_handle) + x_iul = get_state(iul, state_handle) + x_iur = get_state(iur, state_handle) + x_ilr = get_state(ilr, state_handle) + + ! In terms of perturbation potential temperature + a1 = dym*( dxm*x_ill + dx*x_ilr ) + dy*( dxm*x_iul + dx*x_iur ) + + pres1 = model_pressure_t_distrib(ll(1), ll(2), uniquek(uk)+1, id, state_handle, ens_size) + pres2 = model_pressure_t_distrib(lr(1), lr(2), uniquek(uk)+1, id, state_handle, ens_size) + pres3 = model_pressure_t_distrib(ul(1), ul(2), uniquek(uk)+1, id, state_handle, ens_size) + pres4 = model_pressure_t_distrib(ur(1), ur(2), uniquek(uk)+1, id, state_handle, ens_size) + + ! Pressure at location + pres = dym*( dxm*pres1 + dx*pres2 ) + dy*( dxm*pres3 + dx*pres4 ) + + do e = 1, ens_size + if ( k(e) == uniquek(uk) ) then + ! Full sensible temperature field + fld(2, e) = (ts0 + a1(e))*(pres(e)/ps0)**kappa + endif + enddo + endif + enddo + endif else - fld = missing_r8 - end if + + ! This is for surface temperature (T2) + if ( wrf%dom(id)%type_t2 >= 0 ) then + call surface_interp_distrib(fld, wrf, id, i, j, obs_kind, wrf%dom(id)%type_t2, dxm, dx, dy, dym, ens_size, state_handle) + if (all(fld == missing_r8)) goto 200 + else + call error_handler(E_MSG, 'model_mod section 1.b Sensible Temperature:', & + 'WARNING: Surface temperature variable not found in &model_nml') + fld = missing_r8 + end if + end if elseif (obs_kind == QTY_2M_TEMPERATURE) then ! This is for 2-meter temperature - if ( wrf%dom(id)%type_t2 >= 0 ) then ! HK is there a better way to do this? + if ( wrf%dom(id)%type_t2 >= 0 ) then call surface_interp_distrib(fld, wrf, id, i, j, obs_kind, wrf%dom(id)%type_t2, dxm, dx, dy, dym, ens_size, state_handle) if (all(fld == missing_r8)) goto 200 else @@ -1801,7 +1811,7 @@ subroutine model_interpolate(state_handle, ens_size, location, obs_kind, expecte call surface_interp_distrib(fld, wrf, id, i, j, obs_kind, wrf%dom(id)%type_th2, dxm, dx, dy, dym, ens_size, state_handle) if (all(fld == missing_r8)) goto 200 - endif + endif endif !----------------------------------------------------- diff --git a/models/wrf/tutorial/template/input.nml.template b/models/wrf/tutorial/template/input.nml.template index 81b302b40..3e2a1c100 100644 --- a/models/wrf/tutorial/template/input.nml.template +++ b/models/wrf/tutorial/template/input.nml.template @@ -130,7 +130,7 @@ 'QNRAIN','QTY_RAIN_NUMBER_CONCENTR','TYPE_QNRAIN','UPDATE','999', 'U10','QTY_U_WIND_COMPONENT','TYPE_U10','UPDATE','999', 'V10','QTY_V_WIND_COMPONENT','TYPE_V10','UPDATE','999', - 'T2','QTY_2M_TEMPERATURE','TYPE_T2','UPDATE','999', + 'T2','QTY_TEMPERATURE','TYPE_T2','UPDATE','999', 'Q2','QTY_SPECIFIC_HUMIDITY','TYPE_Q2','UPDATE','999', 'PSFC','QTY_PRESSURE','TYPE_PS','UPDATE','999', diff --git a/observations/forward_operators/obs_def_metar_mod.f90 b/observations/forward_operators/obs_def_metar_mod.f90 index 969b983e2..c06b64924 100644 --- a/observations/forward_operators/obs_def_metar_mod.f90 +++ b/observations/forward_operators/obs_def_metar_mod.f90 @@ -6,7 +6,7 @@ ! BEGIN DART PREPROCESS TYPE DEFINITIONS ! METAR_U_10_METER_WIND, QTY_U_WIND_COMPONENT, COMMON_CODE ! METAR_V_10_METER_WIND, QTY_V_WIND_COMPONENT, COMMON_CODE -! METAR_TEMPERATURE_2_METER, QTY_2M_TEMPERATURE, COMMON_CODE +! METAR_TEMPERATURE_2_METER, QTY_TEMPERATURE, COMMON_CODE ! METAR_SPECIFIC_HUMIDITY_2_METER, QTY_SPECIFIC_HUMIDITY, COMMON_CODE ! METAR_SURFACE_PRESSURE, QTY_SURFACE_PRESSURE, COMMON_CODE ! METAR_POT_TEMP_2_METER, QTY_POTENTIAL_TEMPERATURE, COMMON_CODE From 275465b79f492937bef0a852bc4a5039b4a6169d Mon Sep 17 00:00:00 2001 From: braczka Date: Fri, 9 Aug 2024 13:45:46 -0600 Subject: [PATCH 15/19] Updating WRF docs from feedback --- models/wrf/readme.rst | 41 ++++++---------------------- models/wrf/tutorial/README.rst | 27 ++++++++---------- models/wrf/wrf_state_variables_table | 6 ++-- 3 files changed, 24 insertions(+), 50 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index d31528d8d..01eb64bee 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -41,13 +41,6 @@ running a WRF-DART assimilation** `here. `__ - - +<../../../models/wrf/readme.html#namelist>`__ The ``obs_seq.out`` file generated as described in Step 3 includes a total @@ -855,7 +853,7 @@ on a single temperature observation to describe the process: A critical piece of observation metadata includes the observation type -(``METAR_TEMPERATURE_2_METER``) which is linked to the observation quantity +(``METAR_TEMPERATURE_2_METER``) which is linked to the quantity (``QTY_2M_TEMPERATURE``) through the observation definition file (``obs_def_metar_mod.f90``). This file is included within the ``&preprocess_nml`` section of the namelist file as: @@ -878,8 +876,7 @@ A critical piece of observation metadata includes the observation type .. During the DART compilation described within Step 1 this information is -included within the ``obs_def_mod.f90`` which is read during the execution of -``filter``. +included within the ``obs_def_mod.f90``. The vertical coordinate type is the 4th column beneath the loc3d header within ``obs_seq.out``. In this example the value -1 indicates the vertical coordinate is ``VERTISSURFACE``. It defines the @@ -894,7 +891,7 @@ observations. All other coordinates are considered non-surface observations only the ``VERTISSURFACE`` is a surface observation. For more information on the vertical coordinate metadata see the detailed structure of -an `obs_seq file. `__ +an `obs_seq file. <../../../guide/creating-obs-seq-real.html#observation-location>`__ In order to connect this observation to the appropriate WRF output variables the ``wrf_state_variables`` within ``&model_nml`` defines the *WRF field name* and @@ -909,17 +906,17 @@ the *WRF TYPE* in the 1st and 3rd columns as shown in the tutorial example below .. For more information on the ``&model_nml`` variables see the `WRF documentation page -`__ +<../../../models/wrf/readme.html#namelist>`__ As described above, the linkage between the observation type and the WRF output field -is defined through the observation quantity, surface variable (observation +is defined through the physical quantity, surface variable designation (observation vertical coordinate), and WRF TYPE. The current design of the WRF ``model_mod.f90`` -is such that the observation quantity is a general classification (e.g. temperature, wind +is such that the quantity is a general classification (e.g. temperature, wind specific humidity), whereas the WRF TYPE classification is more precisely -mapped to the WRF output field. Future DART versions may remove the need for the WRF TYPE. -The table below summarizes the dependency between the observation type and the WRF -output field for a select number of observation types within the tutorial. +mapped to the WRF output field. The table below summarizes the dependency between +the observation type and the WRF output field for a select number of observation types +within the tutorial. .. Note:: @@ -940,7 +937,7 @@ output field for a select number of observation types within the tutorial. +----------------------------------+---------+-------------------------------+--------------+------------+ -| DART Observation Type | Surface | DART Observation Quantity | WRF Type | WRF output | +| DART Observation Type | Surface | DART Quantity | WRF Type | WRF output | | | Obs ? | | | field | +==================================+=========+===============================+==============+============+ | ``METAR_TEMPERATURE_2_METER`` | Yes | ``QTY_2M_TEMPERATURE`` | ``TYPE_T2`` | ``T2`` | @@ -1434,7 +1431,7 @@ quite high (>90%). This high acceptance percentage is typical of a high-quality assimilation and consistent with the strong reduction in RMSE. -The same plot as above is given below excerpt for the observation type: +The same plot as above except for the observation type: ``RADIOSONE_SPECIFIC_HUMIDITY``. +-------------------------------------------------------------+ diff --git a/models/wrf/wrf_state_variables_table b/models/wrf/wrf_state_variables_table index 5a5ca4584..a224cfb8a 100644 --- a/models/wrf/wrf_state_variables_table +++ b/models/wrf/wrf_state_variables_table @@ -9,8 +9,8 @@ that should be added to the DART input.nml namelist &model_nml, 'wrf_state_variables' list. All items must be strings. The 5 columns are: exact variable name in WRF output file, DART Quantity , a WRF Type, a flag to determine whether the variable is updated during the analysis -(currently only 'UPDATE' is supported), and a flag to identify -which domains include this variable, where '999' means all domains. +('UPDATE' 'NO_COPY_BACK'), and a flag to identify which domains include + this variable, where '999' means all domains. Horizontal Winds: @@ -20,7 +20,7 @@ Horizontal Winds: 'V10', 'QTY_V_WIND_COMPONENT', 'TYPE_V10', 'UPDATE', '999', Sensible Temperature: - 'T', 'QTY_TEMPERATURE', 'TYPE_T', 'UPDATE', '999', + 'THM', 'QTY_TEMPERATURE', 'TYPE_T', 'UPDATE', '999', 'T2', 'QTY_TEMPERATURE', 'TYPE_T2', 'UPDATE', '999', Potential Temperature: From 58b40e32eb962eace826d78dcdd708d1df215f87 Mon Sep 17 00:00:00 2001 From: Helen Kershaw Date: Thu, 15 Aug 2024 10:36:48 -0400 Subject: [PATCH 16/19] revert obs_def_metar_mod to main --- observations/forward_operators/obs_def_metar_mod.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observations/forward_operators/obs_def_metar_mod.f90 b/observations/forward_operators/obs_def_metar_mod.f90 index c06b64924..f559d0086 100644 --- a/observations/forward_operators/obs_def_metar_mod.f90 +++ b/observations/forward_operators/obs_def_metar_mod.f90 @@ -6,7 +6,7 @@ ! BEGIN DART PREPROCESS TYPE DEFINITIONS ! METAR_U_10_METER_WIND, QTY_U_WIND_COMPONENT, COMMON_CODE ! METAR_V_10_METER_WIND, QTY_V_WIND_COMPONENT, COMMON_CODE -! METAR_TEMPERATURE_2_METER, QTY_TEMPERATURE, COMMON_CODE +! METAR_TEMPERATURE_2_METER, QTY_TEMPERATURE, COMMON_CODE ! METAR_SPECIFIC_HUMIDITY_2_METER, QTY_SPECIFIC_HUMIDITY, COMMON_CODE ! METAR_SURFACE_PRESSURE, QTY_SURFACE_PRESSURE, COMMON_CODE ! METAR_POT_TEMP_2_METER, QTY_POTENTIAL_TEMPERATURE, COMMON_CODE From 1f221da7f6ad84958104de97cae603c57f2d4b17 Mon Sep 17 00:00:00 2001 From: Helen Kershaw Date: Thu, 15 Aug 2024 13:15:12 -0400 Subject: [PATCH 17/19] doc: note on clamp or fail ignored by filter --- models/wrf/readme.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/models/wrf/readme.rst b/models/wrf/readme.rst index 01eb64bee..ebb322751 100644 --- a/models/wrf/readme.rst +++ b/models/wrf/readme.rst @@ -168,10 +168,9 @@ Namelist Description: | | | '0.1') Can be 'NULL' to allow any | | | | maximum value. | | | | #. Action -- valid strings are | -| | | 'CLAMP' or 'FAIL'. 'FAIL' ignores | -| | | the bounds whereas 'CLAMP' sets | -| | | the out of range value to the | -| | | minimum or maximum value. | +| | | 'CLAMP' or 'FAIL'. Ignored by | +| | | filter. Filter will always clamp | +| | | if min and/or max is set. | +-------------------------------+-------------------+---------------------------------------+ | num_domains | integer | Total number of WRF domains, | | | | including nested domains. | From 2a45c2972091b33ec9d4666085ae4d84bc4efe98 Mon Sep 17 00:00:00 2001 From: Helen Kershaw Date: Thu, 15 Aug 2024 13:34:15 -0400 Subject: [PATCH 18/19] bump version and changelog for release --- CHANGELOG.rst | 7 +++++++ conf.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5e2c1706f..45147eac3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,6 +22,13 @@ individual files. The changes are now listed with the most recent at the top. +**August 15 2024 :: WRF fwd operator bug fixes. Tag v11.6.1** + +- Bug fix for surface temperature observations to use QTY_2M_TEMPERATURE +- Bug fix for conversion of vapor mixing ratio to specific humidity +- Bug fix for diagnostics_obs.csh +- Improved documentation for WRF model_mod and WRF-DART Tutorial + **July 26 2024 :: Library build tools for DART. Tag v11.6.0** - Buildtools for compiling DART as a shared or a static library. diff --git a/conf.py b/conf.py index deb053a0b..fdfe8997c 100644 --- a/conf.py +++ b/conf.py @@ -21,7 +21,7 @@ author = 'Data Assimilation Research Section' # The full version, including alpha/beta/rc tags -release = '11.6.0' +release = '11.6.1' root_doc = 'index' # -- General configuration --------------------------------------------------- From b5e8ac13934239ec715fb2832ae0a86041005a81 Mon Sep 17 00:00:00 2001 From: Helen Kershaw Date: Thu, 15 Aug 2024 13:39:00 -0400 Subject: [PATCH 19/19] extra line to make clear these fixes are for wrf-dart --- CHANGELOG.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 45147eac3..db39b1910 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,10 +24,12 @@ The changes are now listed with the most recent at the top. **August 15 2024 :: WRF fwd operator bug fixes. Tag v11.6.1** -- Bug fix for surface temperature observations to use QTY_2M_TEMPERATURE -- Bug fix for conversion of vapor mixing ratio to specific humidity -- Bug fix for diagnostics_obs.csh -- Improved documentation for WRF model_mod and WRF-DART Tutorial +WRF-DART bug-fixes: + + - Bug fix for surface temperature observations to use QTY_2M_TEMPERATURE + - Bug fix for conversion of vapor mixing ratio to specific humidity + - Bug fix for diagnostics_obs.csh + - Improved documentation for WRF model_mod and WRF-DART Tutorial **July 26 2024 :: Library build tools for DART. Tag v11.6.0**