diff --git a/.gitignore b/.gitignore index 767f024c2..bf5d7035f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ scm/bin/* non-tracked_files/ scm/data/physics_input_data/qr_acr*.dat scm/data/physics_input_data/freezeH2O.dat +scm/data/physics_input_data/CCN_ACTIVATE.BIN diff --git a/.gitmodules b/.gitmodules index 1a1a9b5d7..746d5c258 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,8 +1,8 @@ [submodule "ccpp-framework"] path = ccpp/framework url = https://github.com/NCAR/ccpp-framework - branch = master + branch = dtc/develop [submodule "ccpp-physics"] path = ccpp/physics url = https://github.com/NCAR/ccpp-physics - branch = master + branch = dtc/develop diff --git a/README.md b/README.md index 01d1efdb3..5a1e5796e 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,3 @@ # User's Guide -A more complete User's Guide can be found at https://dtcenter.org/GMTB/v3.0/scm-ccpp-guide-v3.pdf. If the instructions in this README and the more complete User's Guide differ, the linked guide should be more up-to-date and accurate. - -This guide provides instructions for obtaining, compiling and running a simple -case for the GMTB single column model (SCM). The SCM code calls CCPP-compliant -physics schemes through the CCPP infrastructure code. As such, it requires the -CCPP infrastructure code and physics code, both of which are included as git -submodules within the SCM code. This package can be considered a simple example -for an atmospheric model to interact with physics through the CCPP. - -## Prerequisite -There are several utility libraries as part of the NCEPlibs package that must be installed prior to building the SCM. -* bacio - Binary I/O Library -* sp - Spectral Transformation Library -* w3nco - GRIB decoder and encoder library - -These libraries are prebuilt on most NOAA machines using the Intel compiler. For those needing to build the libraries themselves, GMTB recommends using the source code from GitHub at https://github.com/NCAR/NCEPlibs.git, which includes build files for various compilers and machines using OpenMP flags and which are threadsafe. Instructions for installing NCEPlibs are included on the GitHub repository webpage, but for the sake of example, execute the following for obtaining and building from source in /usr/local/NCEPlibs on a Mac: -1. `cd /usr/local/src` -2. `git clone https://github.com/NCAR/NCEPlibs.git` -3. `cd NCEPlibs` -4. `./make_ncep_libs.sh -s macosx -c gnu -d /usr/local/NCEPlibs -o 1 -m 0` - -Note that the option `-m 0` can be used if MPI is not installed on the machine that is being used. The nemsio library will not be installed, however, since it requires MPI. Once NCEPlibs is built, the NCEPLIBS_DIR environment variable must be set to the location of the installation. For example, if NCEPlibs was installed in /usr/local/NCEPlibs, one would execute - -`export NCEPLIBS_DIR=/usr/local/NCEPlibs` - -If using Theia or Cheyenne HPC systems, this environment variable is automatically set to an appropriate installation of NCEPlibs on those machines through use of one of the setup scripts described below. - -## Obtaining Code - -For obtaining the last stable release, execute the following: - -1. Clone the source using: - * `git clone --recursive -b v3.0 https://github.com/NCAR/gmtb-scm` -2. Change directory into the project. - * `cd gmtb-scm` - -For working with the development branches, after executing the steps above, check out the master branches of the repository (and submodules): - -1. `git checkout master` -2. `cd ccpp/physics` -3. `git checkout master` -4. `cd ../framework` -5. `git checkout master` -6. `cd ../..` - -## Building and Compiling the SCM with CCPP -1. Run the CCPP prebuild script to match required physics variables with those -available from the dycore (SCM) and to generate physics caps and makefile -segments. - * `./ccpp/framework/scripts/ccpp_prebuild.py --config=./ccpp/config/ccpp_prebuild_config.py` - Note: add `--debug` to see the full output of the script. -2. Change directory to the top-level SCM directory. - * `cd scm` -3. [Optional] Run the machine setup script if necessary. This script loads -compiler modules (Fortran 2003-compliant), netCDF module, etc. and sets -compiler environment variables. - * `source etc/Theia_setup_gnu.csh` (for csh) or `. etc/Theia_setup_gnu.sh` (for bash) - * `source etc/Theia_setup_intel.csh` (for csh) or `. etc/Theia_setup_intel.sh` (for bash) - * `source etc/Theia_setup_pgi.csh` (for csh) or `. etc/Theia_setup_pgi.sh` (for bash) - * `source etc/Cheyenne_setup_gnu.csh` (for csh) or `. etc/Cheyenne_setup_gnu.sh` (for bash) - * `source etc/Cheyenne_setup_intel.csh` (for csh) or `. etc/Cheyenne_setup_intel.sh` (for bash) - * `source etc/Cheyenne_setup_pgi.csh` (for csh) or `. etc/Cheyenne_setup_pgi.sh` (for bash) - * `source etc/UBUNTU_setup.csh` (for csh) or `. etc/UBUNTU_setup.sh` (for bash) if following the instructions in doc/README_UBUNTU.txt - * `source etc/CENTOS_setup.csh` (for csh) or `. etc/CENTOS_setup.sh` (for bash) if following the instructions in doc/README_CENTOS.txt - * `source etc/MACOSX_setup.csh` (for csh) or `. etc/MACOSX_setup.sh` (for bash) if following the instructions in doc/README_MACOSX.txt - * NOTE: The NETCDF environment variable must be set to the path of the netCDF installation that was compiled with the same compiler used in the following steps. -4. Make a build directory and change into it. - * `mkdir bin && cd bin` -5. Invoke cmake on the source code to build. - * `cmake ../src` (without threading/OpenMP) - * `cmake -DOPENMP=1 ../src` (with threading/OpenMP) - * `cmake -DCMAKE_BUILD_TYPE=Debug ../src` (debug mode) -6. Compile. Add `VERBOSE=1` to obtain more information on the build process. - * `make` - -## Running the SCM with CCPP -1. Run the SCM with a supplied case. The SCM will go through the time - steps, applying forcing and calling the physics defined in the suite definition - file. - * `.run_gmtb_scm.py -c CASE_NAME [-s SUITE_NAME] [-n PHYSICS_NAMELIST_PATH] [-g]` - * When invoking the run script, the only required argument is the name of the case to run. The case name used must match one of the case configuration files located in ../etc/case_config (without the .nml extension!). If specifying a suite other than the default, the suite name used must match the value of the suite name in one of the suite definition files located in ../../ccpp/suites, (e.g. `SCM_GFS_v15`). If specifying a namelist other than the default, the value must be an entire filename that exists in ../../ccpp/physics_namelists. The -g flag can be used to run the executable through the gdb debugger (assuming it is installed on the system). -2. A netcdf output file is generated in the location specified in the case -configuration file (is present), or in an output directory created by default in `bin` with the case name and suite name appended. - -## Running the SCM with FV3GFS initial conditions -model initial conditions are needed to initialize the land surface in order to run with an interactive land model -1. Prepare model initial conditions. - * `cd to scm/etc/scripts/` - modify path to files you can read in extract_FV3GFS_column_ic.py, this is set up for C96 -2. run extract_FV3GFS_column_ic.py, it will create fv3_model_point.nc in ../../data/processed_case_input/ - * `./extract_FV3GFS_column_ic.py` -3. cd to bin directory - * `cd ../../bin/` -4. Run the SCM with the fv3_model_point case and C96 namelist - * `./run_gmtb_scm.py -c fv3_model_point -n input_GFS_v15_C96.nml` +Please find the up-to-date User's Guide located in this repository in gmtb-scm/scm/doc/TechGuide/main.pdf \ No newline at end of file diff --git a/ccpp/config/ccpp_prebuild_config.py b/ccpp/config/ccpp_prebuild_config.py index d499067b9..48add6b70 100755 --- a/ccpp/config/ccpp_prebuild_config.py +++ b/ccpp/config/ccpp_prebuild_config.py @@ -9,15 +9,22 @@ HOST_MODEL_IDENTIFIER = "SCM" -# Add all files with metadata tables on the host model side, -# relative to basedir = top-level directory of host model +# Add all files with metadata tables on the host model side and in CCPP, +# relative to basedir = top-level directory of host model. This includes +# kind and type definitions used in CCPP physics. VARIABLE_DEFINITION_FILES = [ 'ccpp/physics/physics/machine.F', 'ccpp/physics/physics/radsw_param.f', 'ccpp/physics/physics/radlw_param.f', 'scm/src/GFS_typedefs.F90', - 'scm/src/gmtb_scm_type_defs.f90', - 'scm/src/gmtb_scm_physical_constants.f90' + 'scm/src/gmtb_scm_kinds.F90', + 'scm/src/gmtb_scm_type_defs.F90', + 'scm/src/gmtb_scm_physical_constants.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_optical_props.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/cloud_optics/mo_cloud_optics.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_source_functions.F90' ] TYPEDEFS_NEW_METADATA = { @@ -55,6 +62,27 @@ 'gmtb_scm_type_defs' : '', 'physics_type' : 'physics', }, + 'mo_gas_concentrations' : { + 'ty_gas_concs' : '', + 'mo_gas_concentrations' : '', + }, + 'mo_gas_optics_rrtmgp' : { + 'ty_gas_optics_rrtmgp' : '', + 'mo_gas_optics_rrtmgp' : '', + }, + 'mo_optical_props' : { + 'ty_optical_props_1scl' : '', + 'ty_optical_props_2str' : '', + 'mo_optical_props' : '', + }, + 'mo_cloud_optics' : { + 'ty_cloud_optics' : '', + 'mo_cloud_optics' : '', + }, + 'mo_source_functions' : { + 'ty_source_func_lw' : '', + 'mo_source_functions' : '', + }, } # Add all physics scheme dependencies relative to basedir - note that the CCPP @@ -142,10 +170,38 @@ 'ccpp/physics/physics/namelist_soilveg_ruc.F90', 'ccpp/physics/physics/set_soilveg_ruc.F90', 'ccpp/physics/physics/module_soil_pre.F90', + # RRTMGP + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/mo_gas_concentrations.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/mo_gas_optics.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/mo_gas_optics_rrtmgp.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_constants.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_util_reorder.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/mo_rrtmgp_util_string.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/kernels/mo_gas_optics_kernels.F90', + 'ccpp/physics/physics/rte-rrtmgp/rrtmgp/kernels/mo_rrtmgp_util_reorder_kernels.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_fluxes.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_rte_util_array.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_optical_props.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_rte_kind.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_rte_lw.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_rte_sw.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/mo_source_functions.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/kernels/mo_fluxes_broadband_kernels.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/kernels/mo_optical_props_kernels.F90', + 'ccpp/physics/physics/rte-rrtmgp/rte/kernels/mo_rte_solver_kernels.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/mo_compute_bc.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/mo_fluxes_byband.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/mo_fluxes_byband_kernels.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/mo_fluxes_bygpoint.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/mo_heating_rates.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/mo_rrtmgp_clr_all_sky.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/cloud_optics/mo_cloud_optics.F90', + 'ccpp/physics/physics/rte-rrtmgp/extensions/cloud_optics/mo_cloud_sampling.F90', # derived data type definitions 'scm/src/GFS_typedefs.F90', - 'scm/src/gmtb_scm_kinds.f90', - 'scm/src/gmtb_scm_type_defs.f90', + 'scm/src/gmtb_scm_kinds.F90', + 'scm/src/gmtb_scm_physical_constants.F90', + 'scm/src/gmtb_scm_type_defs.F90', ] # Add all physics scheme files relative to basedir @@ -233,12 +289,37 @@ 'ccpp/physics/physics/sfc_sice.f' : ['physics'], 'ccpp/physics/physics/mp_fer_hires.F90' : ['physics'], 'ccpp/physics/physics/gmtb_scm_sfc_flux_spec.F90' : ['physics'], + # RRTMGP + 'ccpp/physics/physics/rrtmg_lw_cloud_optics.F90' : ['physics'], + 'ccpp/physics/physics/rrtmg_sw_cloud_optics.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_aux.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_lw_gas_optics.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_lw_cloud_optics.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_sw_gas_optics.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_sw_cloud_optics.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_sw_aerosol_optics.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_lw_rte.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_lw_cloud_sampling.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_sw_rte.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_sw_cloud_sampling.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_lw_aerosol_optics.F90' : ['physics'], + 'ccpp/physics/physics/GFS_rrtmgp_setup.F90' : ['physics'], + 'ccpp/physics/physics/GFS_rrtmgp_pre.F90' : ['physics'], + 'ccpp/physics/physics/rrtmgp_lw_pre.F90' : ['physics'], + 'ccpp/physics/physics/GFS_rrtmgp_sw_pre.F90' : ['physics'], + 'ccpp/physics/physics/GFS_rrtmgp_lw_post.F90' : ['physics'], + 'ccpp/physics/physics/GFS_rrtmgp_sw_post.F90' : ['physics'], } # Default build dir, relative to current working directory, # if not specified as command-line argument DEFAULT_BUILD_DIR = 'scm/bin' +# Auto-generated makefile/cmakefile snippets that contain all type definitions +TYPEDEFS_MAKEFILE = 'ccpp/physics/CCPP_TYPEDEFS.mk' +TYPEDEFS_CMAKEFILE = 'ccpp/physics/CCPP_TYPEDEFS.cmake' +TYPEDEFS_SOURCEFILE = 'ccpp/physics/CCPP_TYPEDEFS.sh' + # Auto-generated makefile/cmakefile snippets that contain all schemes SCHEMES_MAKEFILE = 'ccpp/physics/CCPP_SCHEMES.mk' SCHEMES_CMAKEFILE = 'ccpp/physics/CCPP_SCHEMES.cmake' @@ -247,7 +328,7 @@ # CCPP host cap in which to insert the ccpp_field_add statements; # determines the directory to place ccpp_{modules,fields}.inc TARGET_FILES = [ - 'scm/src/gmtb_scm.f90', + 'scm/src/gmtb_scm.F90', ] # Auto-generated makefile/cmakefile snippets that contain all caps @@ -269,7 +350,7 @@ OPTIONAL_ARGUMENTS = { 'rrtmg_sw' : { 'rrtmg_sw_run' : [ - 'tendency_of_air_temperature_due_to_shortwave_heating_assuming_clear_sky_on_radiation_time_step', + 'tendency_of_air_temperature_due_to_shortwave_heating_assuming_clear_sky_on_radiation_time_step_and_radiation_levels', 'components_of_surface_downward_shortwave_fluxes', 'cloud_liquid_water_path', 'mean_effective_radius_for_liquid_cloud', @@ -283,7 +364,7 @@ }, 'rrtmg_lw' : { 'rrtmg_lw_run' : [ - 'tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_time_step', + 'tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_time_step_and_radiation_levels', 'cloud_liquid_water_path', 'mean_effective_radius_for_liquid_cloud', 'cloud_ice_water_path', @@ -328,6 +409,37 @@ 'rime_factor', ], }, + 'rrtmgp_sw_rte' : { + 'rrtmgp_sw_rte_run' : [ + 'components_of_surface_downward_shortwave_fluxes', + 'sw_fluxes_sfc', + 'sw_fluxes_toa', + ], + }, + 'GFS_rrtmgp_sw_post' : { + 'GFS_rrtmgp_sw_post_run' : [ + 'components_of_surface_downward_shortwave_fluxes', + 'sw_fluxes_sfc', + 'sw_fluxes_toa', + ], + }, + 'rrtmgp_lw_rte' : { + 'rrtmgp_lw_rte_run' : [ + 'lw_fluxes_sfc', + 'lw_fluxes_toa', + ], + }, + 'GFS_rrtmgp_lw_post' : { + 'GFS_rrtmgp_lw_post_run' : [ + 'lw_fluxes_sfc', + 'lw_fluxes_toa', + ], + }, + 'GFS_rrtmgp_post' : { + 'GFS_rrtmgp_post_run' : [ + 'components_of_surface_downward_shortwave_fluxes', + ], + }, #'subroutine_name_1' : 'all', #'subroutine_name_2' : 'none', #'subroutine_name_2' : [ 'var1', 'var3'], diff --git a/ccpp/framework b/ccpp/framework index 7ab419eee..54f9b0709 160000 --- a/ccpp/framework +++ b/ccpp/framework @@ -1 +1 @@ -Subproject commit 7ab419eeebe133e706d9825d14c5bdc5d190e60d +Subproject commit 54f9b07098dc6fc3c25f0b38a7d047b5274d3afb diff --git a/ccpp/physics b/ccpp/physics index 39981891a..0aa89846e 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 39981891a5b84e0f08acdf4d9e72d31c0c07aa82 +Subproject commit 0aa89846e9bb0c22482fa131aba39b85f9ac4ff2 diff --git a/ccpp/physics_namelists/input_GFS_v15p2.nml b/ccpp/physics_namelists/input_GFS_v15p2.nml index 00c39cd0b..09974c0a2 100644 --- a/ccpp/physics_namelists/input_GFS_v15p2.nml +++ b/ccpp/physics_namelists/input_GFS_v15p2.nml @@ -1,11 +1,8 @@ &gfs_physics_nml fhzero = 6. + h2o_phys = .true. ldiag3d = .true. - ldiag_ugwp = .false. - do_ugwp = .false. - do_tofd = .false. fhcyc = 24. - nst_anl = .true. use_ufo = .true. pre_rad = .false. ncld = 5 @@ -15,7 +12,7 @@ fhlwr = 3600. ialb = 1 iems = 1 - IAER = 111 + iaer = 111 ico2 = 2 isubc_sw = 2 isubc_lw = 2 @@ -28,14 +25,6 @@ redrag = .true. dspheat = .true. hybedmf = .true. - satmedmf = .false. - do_myjsfc = .false. - do_myjpbl = .false. - shinhong = .false. - do_ysu = .false. - lheatstrg = .false. - lgfdlmprad = .true. - effr_in = .true. random_clds = .false. trans_trac = .true. cnvcld = .true. @@ -45,29 +34,15 @@ prslrd0 = 0. ivegsrc = 1 isot = 1 - lsm = 1 - iopt_dveg = 2 - iopt_crs = 1 - iopt_btr = 1 - iopt_run = 1 - iopt_sfc = 1 - iopt_frz = 1 - iopt_inf = 1 - iopt_rad = 1 - iopt_alb = 2 - iopt_snf = 4 - iopt_tbot = 2 - iopt_stc = 1 debug = .false. oz_phys = .false. oz_phys_2015 = .true. - h2o_phys = .true. nstf_name = 2,1,0,0,0 + nst_anl = .true. psautco = 0.0008,0.0005 prautco = 0.00015,0.00015 - xkzminv = 0.3 - xkzm_m = 1.0 - xkzm_h = 1.0 + lgfdlmprad = .true. + effr_in = .true. do_sppt = .false. do_shum = .false. do_skeb = .false. diff --git a/ccpp/physics_namelists/input_GFS_v15_FA.nml b/ccpp/physics_namelists/input_GFS_v15p2_FA.nml similarity index 66% rename from ccpp/physics_namelists/input_GFS_v15_FA.nml rename to ccpp/physics_namelists/input_GFS_v15p2_FA.nml index 33314abcb..54b5db7ea 100644 --- a/ccpp/physics_namelists/input_GFS_v15_FA.nml +++ b/ccpp/physics_namelists/input_GFS_v15p2_FA.nml @@ -1,11 +1,8 @@ &gfs_physics_nml fhzero = 6. + h2o_phys = .true. ldiag3d = .true. - ldiag_ugwp = .false. - do_ugwp = .false. - do_tofd = .false. fhcyc = 24. - nst_anl = .true. use_ufo = .true. pre_rad = .false. ncld = 5 @@ -17,7 +14,7 @@ fhlwr = 3600. ialb = 1 iems = 1 - IAER = 111 + iaer = 111 ico2 = 2 isubc_sw = 2 isubc_lw = 2 @@ -30,16 +27,8 @@ redrag = .true. dspheat = .true. hybedmf = .true. - satmedmf = .false. - do_myjsfc = .false. - do_myjpbl = .false. - shinhong = .false. - do_ysu = .false. - lheatstrg = .false. - lgfdlmprad = .false. - effr_in = .false. random_clds = .false. - trans_trac = .false. + trans_trac = .true. cnvcld = .true. imfshalcnv = 2 imfdeepcnv = 2 @@ -47,27 +36,15 @@ prslrd0 = 0. ivegsrc = 1 isot = 1 - lsm = 1 - iopt_dveg = 2 - iopt_crs = 1 - iopt_btr = 1 - iopt_run = 1 - iopt_sfc = 1 - iopt_frz = 1 - iopt_inf = 1 - iopt_rad = 1 - iopt_alb = 2 - iopt_snf = 4 - iopt_tbot = 2 - iopt_stc = 1 debug = .false. oz_phys = .false. oz_phys_2015 = .true. - h2o_phys = .true. - nstf_name = 2,1,1,0,5 - xkzminv = 0.3 - xkzm_m = 1.0 - xkzm_h = 1.0 + nstf_name = 2,1,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .true. + effr_in = .true. do_sppt = .false. do_shum = .false. do_skeb = .false. @@ -124,16 +101,16 @@ / &cires_ugwp_nml - knob_ugwp_solver = 2 - knob_ugwp_source = 1,1,0,0 - knob_ugwp_wvspec = 1,25,25,25 - knob_ugwp_azdir = 2,4,4,4 - knob_ugwp_stoch = 0,0,0,0 - knob_ugwp_effac = 1,1,1,1 - knob_ugwp_doaxyz = 1 - knob_ugwp_doheat = 1 - knob_ugwp_dokdis = 1 - knob_ugwp_ndx4lh = 1 - knob_ugwp_version = 0 - launch_level = 25 + knob_ugwp_solver = 2 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 1 + knob_ugwp_ndx4lh = 1 + knob_ugwp_version = 0 + launch_level = 25 / diff --git a/ccpp/physics_namelists/input_GFS_2017_myj.nml b/ccpp/physics_namelists/input_GFS_v15p2_MYJ.nml similarity index 67% rename from ccpp/physics_namelists/input_GFS_2017_myj.nml rename to ccpp/physics_namelists/input_GFS_v15p2_MYJ.nml index f7cb686d9..05f8fbf7b 100644 --- a/ccpp/physics_namelists/input_GFS_2017_myj.nml +++ b/ccpp/physics_namelists/input_GFS_v15p2_MYJ.nml @@ -1,11 +1,8 @@ &gfs_physics_nml fhzero = 6. + h2o_phys = .true. ldiag3d = .true. - ldiag_ugwp = .false. - do_ugwp = .false. - do_tofd = .false. fhcyc = 24. - nst_anl = .true. use_ufo = .true. pre_rad = .false. ncld = 5 @@ -15,7 +12,7 @@ fhlwr = 3600. ialb = 1 iems = 1 - IAER = 111 + iaer = 111 ico2 = 2 isubc_sw = 2 isubc_lw = 2 @@ -28,16 +25,10 @@ redrag = .true. dspheat = .true. hybedmf = .false. - satmedmf = .false. do_myjsfc = .true. do_myjpbl = .true. - shinhong = .false. - do_ysu = .false. - lheatstrg = .false. - lgfdlmprad = .false. - effr_in = .false. random_clds = .false. - trans_trac = .false. + trans_trac = .true. cnvcld = .true. imfshalcnv = 2 imfdeepcnv = 2 @@ -45,27 +36,15 @@ prslrd0 = 0. ivegsrc = 1 isot = 1 - lsm = 1 - iopt_dveg = 2 - iopt_crs = 1 - iopt_btr = 1 - iopt_run = 1 - iopt_sfc = 1 - iopt_frz = 1 - iopt_inf = 1 - iopt_rad = 1 - iopt_alb = 2 - iopt_snf = 4 - iopt_tbot = 2 - iopt_stc = 1 debug = .false. oz_phys = .false. oz_phys_2015 = .true. - h2o_phys = .true. - nstf_name = 2,1,1,0,5 - xkzminv = 0.3 - xkzm_m = 1.0 - xkzm_h = 1.0 + nstf_name = 2,1,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .true. + effr_in = .true. do_sppt = .false. do_shum = .false. do_skeb = .false. @@ -122,16 +101,16 @@ / &cires_ugwp_nml - knob_ugwp_solver = 2 - knob_ugwp_source = 1,1,0,0 - knob_ugwp_wvspec = 1,25,25,25 - knob_ugwp_azdir = 2,4,4,4 - knob_ugwp_stoch = 0,0,0,0 - knob_ugwp_effac = 1,1,1,1 - knob_ugwp_doaxyz = 1 - knob_ugwp_doheat = 1 - knob_ugwp_dokdis = 1 - knob_ugwp_ndx4lh = 1 - knob_ugwp_version = 0 - launch_level = 25 + knob_ugwp_solver = 2 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 1 + knob_ugwp_ndx4lh = 1 + knob_ugwp_version = 0 + launch_level = 25 / diff --git a/ccpp/physics_namelists/input_GFS_v15.nml b/ccpp/physics_namelists/input_GFS_v15p2_RRTMGP.nml similarity index 65% rename from ccpp/physics_namelists/input_GFS_v15.nml rename to ccpp/physics_namelists/input_GFS_v15p2_RRTMGP.nml index 2c5211079..708829108 100644 --- a/ccpp/physics_namelists/input_GFS_v15.nml +++ b/ccpp/physics_namelists/input_GFS_v15p2_RRTMGP.nml @@ -1,11 +1,8 @@ &gfs_physics_nml fhzero = 6. + h2o_phys = .true. ldiag3d = .true. - ldiag_ugwp = .false. - do_ugwp = .false. - do_tofd = .false. fhcyc = 24. - nst_anl = .true. use_ufo = .true. pre_rad = .false. ncld = 5 @@ -15,7 +12,7 @@ fhlwr = 3600. ialb = 1 iems = 1 - IAER = 111 + iaer = 111 ico2 = 2 isubc_sw = 2 isubc_lw = 2 @@ -28,16 +25,8 @@ redrag = .true. dspheat = .true. hybedmf = .true. - satmedmf = .false. - do_myjsfc = .false. - do_myjpbl = .false. - shinhong = .false. - do_ysu = .false. - lheatstrg = .false. - lgfdlmprad = .false. - effr_in = .false. random_clds = .false. - trans_trac = .false. + trans_trac = .true. cnvcld = .true. imfshalcnv = 2 imfdeepcnv = 2 @@ -45,31 +34,30 @@ prslrd0 = 0. ivegsrc = 1 isot = 1 - lsm = 1 - iopt_dveg = 2 - iopt_crs = 1 - iopt_btr = 1 - iopt_run = 1 - iopt_sfc = 1 - iopt_frz = 1 - iopt_inf = 1 - iopt_rad = 1 - iopt_alb = 2 - iopt_snf = 4 - iopt_tbot = 2 - iopt_stc = 1 debug = .false. oz_phys = .false. oz_phys_2015 = .true. - h2o_phys = .true. - nstf_name = 2,1,1,0,5 - xkzminv = 0.3 - xkzm_m = 1.0 - xkzm_h = 1.0 + nstf_name = 2,1,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .true. + effr_in = .true. do_sppt = .false. do_shum = .false. do_skeb = .false. do_sfcperts = .false. + do_RRTMGP = .true. + active_gases = 'h2o_co2_o3_n2o_ch4_o2' + ngases = 6 + rrtmgp_root = '../../ccpp/physics/physics/rte-rrtmgp/' + lw_file_gas = 'rrtmgp/data/rrtmgp-data-lw-g256-2018-12-04.nc' + lw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-lw.nc' + sw_file_gas = 'rrtmgp/data/rrtmgp-data-sw-g224-2018-12-04.nc' + sw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-sw.nc' + rrtmgp_cld_optics = 0 + rrtmgp_ngauss_ang = 3 + rrtmgp_nrghice = 3 / &gfdl_cloud_microphysics_nml @@ -122,16 +110,16 @@ / &cires_ugwp_nml - knob_ugwp_solver = 2 - knob_ugwp_source = 1,1,0,0 - knob_ugwp_wvspec = 1,25,25,25 - knob_ugwp_azdir = 2,4,4,4 - knob_ugwp_stoch = 0,0,0,0 - knob_ugwp_effac = 1,1,1,1 - knob_ugwp_doaxyz = 1 - knob_ugwp_doheat = 1 - knob_ugwp_dokdis = 1 - knob_ugwp_ndx4lh = 1 - knob_ugwp_version = 0 - launch_level = 25 + knob_ugwp_solver = 2 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 1 + knob_ugwp_ndx4lh = 1 + knob_ugwp_version = 0 + launch_level = 25 / diff --git a/ccpp/physics_namelists/input_GFS_v15_noahmp.nml b/ccpp/physics_namelists/input_GFS_v15p2_noahmp.nml similarity index 66% rename from ccpp/physics_namelists/input_GFS_v15_noahmp.nml rename to ccpp/physics_namelists/input_GFS_v15p2_noahmp.nml index 4b301c804..f019d2702 100644 --- a/ccpp/physics_namelists/input_GFS_v15_noahmp.nml +++ b/ccpp/physics_namelists/input_GFS_v15p2_noahmp.nml @@ -1,11 +1,8 @@ &gfs_physics_nml fhzero = 6. + h2o_phys = .true. ldiag3d = .true. - ldiag_ugwp = .false. - do_ugwp = .false. - do_tofd = .false. fhcyc = 24. - nst_anl = .true. use_ufo = .true. pre_rad = .false. ncld = 5 @@ -15,7 +12,7 @@ fhlwr = 3600. ialb = 1 iems = 1 - IAER = 111 + iaer = 111 ico2 = 2 isubc_sw = 2 isubc_lw = 2 @@ -28,16 +25,8 @@ redrag = .true. dspheat = .true. hybedmf = .true. - satmedmf = .false. - do_myjsfc = .false. - do_myjpbl = .false. - shinhong = .false. - do_ysu = .false. - lheatstrg = .false. - lgfdlmprad = .false. - effr_in = .false. random_clds = .false. - trans_trac = .false. + trans_trac = .true. cnvcld = .true. imfshalcnv = 2 imfdeepcnv = 2 @@ -46,26 +35,15 @@ ivegsrc = 1 isot = 1 lsm = 2 - iopt_dveg = 2 - iopt_crs = 1 - iopt_btr = 1 - iopt_run = 1 - iopt_sfc = 1 - iopt_frz = 1 - iopt_inf = 1 - iopt_rad = 1 - iopt_alb = 2 - iopt_snf = 4 - iopt_tbot = 2 - iopt_stc = 1 debug = .false. oz_phys = .false. oz_phys_2015 = .true. - h2o_phys = .true. - nstf_name = 2,1,1,0,5 - xkzminv = 0.3 - xkzm_m = 1.0 - xkzm_h = 1.0 + nstf_name = 2,1,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .true. + effr_in = .true. do_sppt = .false. do_shum = .false. do_skeb = .false. @@ -122,16 +100,16 @@ / &cires_ugwp_nml - knob_ugwp_solver = 2 - knob_ugwp_source = 1,1,0,0 - knob_ugwp_wvspec = 1,25,25,25 - knob_ugwp_azdir = 2,4,4,4 - knob_ugwp_stoch = 0,0,0,0 - knob_ugwp_effac = 1,1,1,1 - knob_ugwp_doaxyz = 1 - knob_ugwp_doheat = 1 - knob_ugwp_dokdis = 1 - knob_ugwp_ndx4lh = 1 - knob_ugwp_version = 0 - launch_level = 25 + knob_ugwp_solver = 2 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 1 + knob_ugwp_ndx4lh = 1 + knob_ugwp_version = 0 + launch_level = 25 / diff --git a/ccpp/physics_namelists/input_GFS_v15plus.nml b/ccpp/physics_namelists/input_GFS_v15plus.nml deleted file mode 100644 index 997472832..000000000 --- a/ccpp/physics_namelists/input_GFS_v15plus.nml +++ /dev/null @@ -1,137 +0,0 @@ -&gfs_physics_nml - fhzero = 6. - ldiag3d = .true. - ldiag_ugwp = .false. - do_ugwp = .false. - do_tofd = .false. - fhcyc = 24. - nst_anl = .true. - use_ufo = .true. - pre_rad = .false. - ncld = 5 - imp_physics = 11 - pdfcld = .false. - fhswr = 3600. - fhlwr = 3600. - ialb = 1 - iems = 1 - IAER = 111 - ico2 = 2 - isubc_sw = 2 - isubc_lw = 2 - isol = 2 - lwhtr = .true. - swhtr = .true. - cnvgwd = .true. - shal_cnv = .true. - cal_pre = .false. - redrag = .true. - dspheat = .true. - hybedmf = .false. - satmedmf = .true. - do_myjsfc = .false. - do_myjpbl = .false. - shinhong = .false. - do_ysu = .false. - lheatstrg = .false. - lgfdlmprad = .false. - effr_in = .false. - random_clds = .false. - trans_trac = .false. - cnvcld = .true. - imfshalcnv = 2 - imfdeepcnv = 2 - cdmbgwd = 3.5,0.25 - prslrd0 = 0. - ivegsrc = 1 - isot = 1 - lsm = 1 - iopt_dveg = 2 - iopt_crs = 1 - iopt_btr = 1 - iopt_run = 1 - iopt_sfc = 1 - iopt_frz = 1 - iopt_inf = 1 - iopt_rad = 1 - iopt_alb = 2 - iopt_snf = 4 - iopt_tbot = 2 - iopt_stc = 1 - debug = .false. - oz_phys = .false. - oz_phys_2015 = .true. - h2o_phys = .true. - nstf_name = 2,1,1,0,5 - xkzminv = 0.3 - xkzm_m = 1.0 - xkzm_h = 1.0 - do_sppt = .false. - do_shum = .false. - do_skeb = .false. - do_sfcperts = .false. -/ - -&gfdl_cloud_microphysics_nml - sedi_transport = .true. - do_sedi_heat = .false. - rad_snow = .true. - rad_graupel = .true. - rad_rain = .true. - const_vi = .F. - const_vs = .F. - const_vg = .F. - const_vr = .F. - vi_max = 1. - vs_max = 2. - vg_max = 12. - vr_max = 12. - qi_lim = 1. - prog_ccn = .false. - do_qa = .false. - fast_sat_adj = .false. - tau_l2v = 225. - tau_v2l = 150. - tau_g2v = 900. - rthresh = 10.e-6 ! This is a key parameter for cloud water - dw_land = 0.16 - dw_ocean = 0.10 - ql_gen = 1.0e-3 - ql_mlt = 1.0e-3 - qi0_crt = 8.0E-5 - qs0_crt = 1.0e-3 - tau_i2s = 1000. - c_psaci = 0.05 - c_pgacs = 0.01 - rh_inc = 0.30 - rh_inr = 0.30 - rh_ins = 0.30 - ccn_l = 300. - ccn_o = 100. - c_paut = 0.5 - c_cracw = 0.8 - use_ppm = .false. - use_ccn = .true. - mono_prof = .true. - z_slope_liq = .true. - z_slope_ice = .true. - de_ice = .false. - fix_negative = .true. - icloud_f = 1 - mp_time = 150. -/ - -&cires_ugwp_nml - knob_ugwp_solver = 2 - knob_ugwp_source = 1,1,0,0 - knob_ugwp_wvspec = 1,25,25,25 - knob_ugwp_azdir = 2,4,4,4 - knob_ugwp_stoch = 0,0,0,0 - knob_ugwp_effac = 1,1,1,1 - knob_ugwp_doaxyz = 1 - knob_ugwp_doheat = 1 - knob_ugwp_dokdis = 1 - knob_ugwp_ndx4lh = 1 - knob_ugwp_version = 0 - launch_level = 25 -/ diff --git a/ccpp/physics_namelists/input_GFS_v16beta.nml b/ccpp/physics_namelists/input_GFS_v16beta.nml index e6dd1a24a..2678ba7a0 100644 --- a/ccpp/physics_namelists/input_GFS_v16beta.nml +++ b/ccpp/physics_namelists/input_GFS_v16beta.nml @@ -1,11 +1,8 @@ &gfs_physics_nml - fhzero = 6. + fhzero = 6 + h2o_phys = .true. ldiag3d = .true. - ldiag_ugwp = .false. - do_ugwp = .false. - do_tofd = .true. - fhcyc = 24. - nst_anl = .true. + fhcyc = 24 use_ufo = .true. pre_rad = .false. ncld = 5 @@ -15,7 +12,7 @@ fhlwr = 3600. ialb = 1 iems = 1 - IAER = 5111 + iaer = 5111 icliq_sw = 2 iovr_lw = 3 iovr_sw = 3 @@ -33,13 +30,7 @@ hybedmf = .false. satmedmf = .true. isatmedmf = 1 - do_myjsfc = .false. - do_myjpbl = .false. - shinhong = .false. - do_ysu = .false. lheatstrg = .true. - lgfdlmprad = .true. - effr_in = .true. random_clds = .false. trans_trac = .true. cnvcld = .true. @@ -49,8 +40,8 @@ prslrd0 = 0. ivegsrc = 1 isot = 1 - lsm = 1 lsoil = 4 + lsm = 1 iopt_dveg = 1 iopt_crs = 1 iopt_btr = 1 @@ -66,17 +57,19 @@ debug = .false. oz_phys = .false. oz_phys_2015 = .true. - h2o_phys = .true. nstf_name = 2,1,0,0,0 - xkzminv = 0.3 - xkzm_m = 1.0 - xkzm_h = 1.0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .true. + effr_in = .true. + ldiag_ugwp = .false. + do_ugwp = .false. + do_tofd = .true. do_sppt = .false. do_shum = .false. do_skeb = .false. do_sfcperts = .false. - psautco = 0.0008,0.0005 - prautco = 0.00015,0.00015 / &gfdl_cloud_microphysics_nml diff --git a/ccpp/physics_namelists/input_csawmg.nml b/ccpp/physics_namelists/input_csawmg.nml index 5d88a3ee0..7a5071a42 100644 --- a/ccpp/physics_namelists/input_csawmg.nml +++ b/ccpp/physics_namelists/input_csawmg.nml @@ -72,8 +72,7 @@ mg_qcvar = 1.0 fprcp = 2 pdfflag = 4 - iccn = .false. - aero_in = .false. + iccn = 0 mg_do_graupel = .true. mg_do_hail = .false. do_sb_physics = .true. diff --git a/ccpp/suites/suite_SCM_GFS_v15p2.xml b/ccpp/suites/suite_SCM_GFS_v15p2.xml index 61b7a838f..88c3a16f2 100644 --- a/ccpp/suites/suite_SCM_GFS_v15p2.xml +++ b/ccpp/suites/suite_SCM_GFS_v15p2.xml @@ -1,6 +1,6 @@ - + GFS_time_vary_pre @@ -48,7 +48,6 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post diff --git a/ccpp/suites/suite_SCM_GFS_v15_FA.xml b/ccpp/suites/suite_SCM_GFS_v15p2_FA.xml similarity index 94% rename from ccpp/suites/suite_SCM_GFS_v15_FA.xml rename to ccpp/suites/suite_SCM_GFS_v15p2_FA.xml index 0ff3d1788..c0d8b820b 100644 --- a/ccpp/suites/suite_SCM_GFS_v15_FA.xml +++ b/ccpp/suites/suite_SCM_GFS_v15p2_FA.xml @@ -1,7 +1,6 @@ - - + GFS_time_vary_pre @@ -49,7 +48,6 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post @@ -80,5 +78,4 @@ maximum_hourly_diagnostics - diff --git a/ccpp/suites/suite_SCM_GFS_2017_myj.xml b/ccpp/suites/suite_SCM_GFS_v15p2_MYJ.xml similarity index 95% rename from ccpp/suites/suite_SCM_GFS_2017_myj.xml rename to ccpp/suites/suite_SCM_GFS_v15p2_MYJ.xml index 4e49839f3..cf05de2d9 100644 --- a/ccpp/suites/suite_SCM_GFS_2017_myj.xml +++ b/ccpp/suites/suite_SCM_GFS_v15p2_MYJ.xml @@ -1,7 +1,6 @@ - - + GFS_time_vary_pre @@ -49,7 +48,6 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post @@ -80,5 +78,4 @@ maximum_hourly_diagnostics - diff --git a/ccpp/suites/suite_SCM_GFS_v15p2_RRTMGP.xml b/ccpp/suites/suite_SCM_GFS_v15p2_RRTMGP.xml new file mode 100644 index 000000000..24f5565eb --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v15p2_RRTMGP.xml @@ -0,0 +1,88 @@ + + + + + + GFS_time_vary_pre + GFS_rrtmgp_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmgp_pre + GFS_rrtmgp_sw_pre + rrtmgp_sw_gas_optics + rrtmgp_sw_aerosol_optics + rrtmgp_sw_cloud_optics + rrtmgp_sw_cloud_sampling + rrtmgp_sw_rte + GFS_rrtmgp_sw_post + rrtmgp_lw_pre + rrtmgp_lw_gas_optics + rrtmgp_lw_aerosol_optics + rrtmgp_lw_cloud_optics + rrtmgp_lw_cloud_sampling + rrtmgp_lw_rte + GFS_rrtmgp_lw_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + GFS_surface_composites_pre + dcyc2t3 + GFS_surface_composites_inter + GFS_suite_interstitial_2 + + + + sfc_diff + GFS_surface_loop_control_part1 + sfc_nst_pre + sfc_nst + sfc_nst_post + lsm_noah + sfc_sice + GFS_surface_loop_control_part2 + + + + GFS_surface_composites_post + sfc_diag + sfc_diag_post + GFS_surface_generic_post + GFS_PBL_generic_pre + hedmf + GFS_PBL_generic_post + GFS_GWD_generic_pre + cires_ugwp + cires_ugwp_post + GFS_GWD_generic_post + rayleigh_damp + GFS_suite_stateout_update + ozphys_2015 + h2ophys + GFS_DCNV_generic_pre + get_phi_fv3 + GFS_suite_interstitial_3 + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + gfdl_cloud_microphys + GFS_MP_generic_post + maximum_hourly_diagnostics + + + diff --git a/ccpp/suites/suite_SCM_GFS_v15p2_RRTMGP_ps.xml b/ccpp/suites/suite_SCM_GFS_v15p2_RRTMGP_ps.xml new file mode 100644 index 000000000..704ae22d3 --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v15p2_RRTMGP_ps.xml @@ -0,0 +1,69 @@ + + + + + + GFS_time_vary_pre + GFS_rrtmgp_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmgp_pre + GFS_rrtmgp_sw_pre + rrtmgp_sw_gas_optics + rrtmgp_sw_aerosol_optics + rrtmgp_sw_cloud_optics + rrtmgp_sw_cloud_sampling + rrtmgp_sw_rte + GFS_rrtmgp_sw_post + rrtmgp_lw_pre + rrtmgp_lw_gas_optics + rrtmgp_lw_aerosol_optics + rrtmgp_lw_cloud_optics + rrtmgp_lw_cloud_sampling + rrtmgp_lw_rte + GFS_rrtmgp_lw_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + dcyc2t3 + GFS_suite_interstitial_2 + gmtb_scm_sfc_flux_spec + GFS_PBL_generic_pre + hedmf + GFS_PBL_generic_post + GFS_GWD_generic_pre + cires_ugwp + cires_ugwp_post + GFS_GWD_generic_post + rayleigh_damp + GFS_suite_stateout_update + ozphys_2015 + h2ophys + GFS_DCNV_generic_pre + get_phi_fv3 + GFS_suite_interstitial_3 + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + gfdl_cloud_microphys + GFS_MP_generic_post + maximum_hourly_diagnostics + + + diff --git a/ccpp/suites/suite_SCM_GFS_v15.xml b/ccpp/suites/suite_SCM_GFS_v15p2_no_nsst.xml similarity index 91% rename from ccpp/suites/suite_SCM_GFS_v15.xml rename to ccpp/suites/suite_SCM_GFS_v15p2_no_nsst.xml index cbcacbba8..aacdc9cae 100644 --- a/ccpp/suites/suite_SCM_GFS_v15.xml +++ b/ccpp/suites/suite_SCM_GFS_v15p2_no_nsst.xml @@ -1,7 +1,6 @@ - - + GFS_time_vary_pre @@ -39,9 +38,7 @@ sfc_diff GFS_surface_loop_control_part1 - sfc_nst_pre - sfc_nst - sfc_nst_post + sfc_ocean lsm_noah sfc_sice GFS_surface_loop_control_part2 @@ -49,7 +46,6 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post @@ -64,9 +60,9 @@ GFS_suite_stateout_update ozphys_2015 h2ophys - GFS_DCNV_generic_pre get_phi_fv3 GFS_suite_interstitial_3 + GFS_DCNV_generic_pre samfdeepcnv GFS_DCNV_generic_post GFS_SCNV_generic_pre @@ -80,5 +76,4 @@ maximum_hourly_diagnostics - diff --git a/ccpp/suites/suite_SCM_GFS_v15p2_prescribed_surface.xml b/ccpp/suites/suite_SCM_GFS_v15p2_no_nsst_ps.xml similarity index 95% rename from ccpp/suites/suite_SCM_GFS_v15p2_prescribed_surface.xml rename to ccpp/suites/suite_SCM_GFS_v15p2_no_nsst_ps.xml index fa8c10d51..3d76f48a8 100644 --- a/ccpp/suites/suite_SCM_GFS_v15p2_prescribed_surface.xml +++ b/ccpp/suites/suite_SCM_GFS_v15p2_no_nsst_ps.xml @@ -1,6 +1,6 @@ - + GFS_time_vary_pre @@ -32,7 +32,6 @@ dcyc2t3 GFS_suite_interstitial_2 gmtb_scm_sfc_flux_spec - dcyc2t3_post GFS_PBL_generic_pre hedmf GFS_PBL_generic_post diff --git a/ccpp/suites/suite_SCM_GFS_v15_noahmp.xml b/ccpp/suites/suite_SCM_GFS_v15p2_noahmp.xml similarity index 94% rename from ccpp/suites/suite_SCM_GFS_v15_noahmp.xml rename to ccpp/suites/suite_SCM_GFS_v15p2_noahmp.xml index 40f449f98..87decb00b 100644 --- a/ccpp/suites/suite_SCM_GFS_v15_noahmp.xml +++ b/ccpp/suites/suite_SCM_GFS_v15p2_noahmp.xml @@ -1,7 +1,6 @@ - - + GFS_time_vary_pre @@ -49,7 +48,6 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post @@ -80,5 +78,4 @@ maximum_hourly_diagnostics - diff --git a/ccpp/suites/suite_SCM_GFS_v15_prescribed_surface.xml b/ccpp/suites/suite_SCM_GFS_v15p2_ps.xml similarity index 92% rename from ccpp/suites/suite_SCM_GFS_v15_prescribed_surface.xml rename to ccpp/suites/suite_SCM_GFS_v15p2_ps.xml index 59dc53c48..6846f32e5 100644 --- a/ccpp/suites/suite_SCM_GFS_v15_prescribed_surface.xml +++ b/ccpp/suites/suite_SCM_GFS_v15p2_ps.xml @@ -1,7 +1,6 @@ - - + GFS_time_vary_pre @@ -33,7 +32,6 @@ dcyc2t3 GFS_suite_interstitial_2 gmtb_scm_sfc_flux_spec - dcyc2t3_post GFS_PBL_generic_pre hedmf GFS_PBL_generic_post @@ -61,5 +59,4 @@ maximum_hourly_diagnostics - diff --git a/ccpp/suites/suite_SCM_GFS_v16beta.xml b/ccpp/suites/suite_SCM_GFS_v16beta.xml index 48412b280..85987551c 100644 --- a/ccpp/suites/suite_SCM_GFS_v16beta.xml +++ b/ccpp/suites/suite_SCM_GFS_v16beta.xml @@ -1,6 +1,6 @@ - + GFS_time_vary_pre @@ -48,7 +48,6 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post diff --git a/ccpp/suites/suite_SCM_GFS_v15plus.xml b/ccpp/suites/suite_SCM_GFS_v16beta_no_nsst.xml similarity index 90% rename from ccpp/suites/suite_SCM_GFS_v15plus.xml rename to ccpp/suites/suite_SCM_GFS_v16beta_no_nsst.xml index 069b40be5..165c8dab0 100644 --- a/ccpp/suites/suite_SCM_GFS_v15plus.xml +++ b/ccpp/suites/suite_SCM_GFS_v16beta_no_nsst.xml @@ -1,7 +1,6 @@ - - + GFS_time_vary_pre @@ -39,9 +38,7 @@ sfc_diff GFS_surface_loop_control_part1 - sfc_nst_pre - sfc_nst - sfc_nst_post + sfc_ocean lsm_noah sfc_sice GFS_surface_loop_control_part2 @@ -49,12 +46,11 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post GFS_PBL_generic_pre - satmedmfvdif + satmedmfvdifq GFS_PBL_generic_post GFS_GWD_generic_pre cires_ugwp @@ -64,9 +60,9 @@ GFS_suite_stateout_update ozphys_2015 h2ophys - GFS_DCNV_generic_pre get_phi_fv3 GFS_suite_interstitial_3 + GFS_DCNV_generic_pre samfdeepcnv GFS_DCNV_generic_post GFS_SCNV_generic_pre @@ -80,5 +76,4 @@ maximum_hourly_diagnostics - diff --git a/ccpp/suites/suite_SCM_GFS_v16beta_prescribed_surface.xml b/ccpp/suites/suite_SCM_GFS_v16beta_no_nsst_ps.xml similarity index 95% rename from ccpp/suites/suite_SCM_GFS_v16beta_prescribed_surface.xml rename to ccpp/suites/suite_SCM_GFS_v16beta_no_nsst_ps.xml index 128c5b140..3a543af16 100644 --- a/ccpp/suites/suite_SCM_GFS_v16beta_prescribed_surface.xml +++ b/ccpp/suites/suite_SCM_GFS_v16beta_no_nsst_ps.xml @@ -1,6 +1,6 @@ - + GFS_time_vary_pre @@ -32,7 +32,6 @@ dcyc2t3 GFS_suite_interstitial_2 gmtb_scm_sfc_flux_spec - dcyc2t3_post GFS_PBL_generic_pre satmedmfvdifq GFS_PBL_generic_post diff --git a/ccpp/suites/suite_SCM_GFS_v15plus_prescribed_surface.xml b/ccpp/suites/suite_SCM_GFS_v16beta_ps.xml similarity index 91% rename from ccpp/suites/suite_SCM_GFS_v15plus_prescribed_surface.xml rename to ccpp/suites/suite_SCM_GFS_v16beta_ps.xml index 53815641e..0d6d03aad 100644 --- a/ccpp/suites/suite_SCM_GFS_v15plus_prescribed_surface.xml +++ b/ccpp/suites/suite_SCM_GFS_v16beta_ps.xml @@ -1,7 +1,6 @@ - - + GFS_time_vary_pre @@ -33,9 +32,8 @@ dcyc2t3 GFS_suite_interstitial_2 gmtb_scm_sfc_flux_spec - dcyc2t3_post GFS_PBL_generic_pre - satmedmfvdif + satmedmfvdifq GFS_PBL_generic_post GFS_GWD_generic_pre cires_ugwp @@ -61,5 +59,4 @@ maximum_hourly_diagnostics - diff --git a/ccpp/suites/suite_SCM_GSD_v1.xml b/ccpp/suites/suite_SCM_GSD_v1.xml index c45e8de7f..7798b4a95 100644 --- a/ccpp/suites/suite_SCM_GSD_v1.xml +++ b/ccpp/suites/suite_SCM_GSD_v1.xml @@ -1,6 +1,6 @@ - + @@ -53,7 +53,6 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post diff --git a/ccpp/suites/suite_SCM_GSD_v1_prescribed_surface.xml b/ccpp/suites/suite_SCM_GSD_v1_ps.xml similarity index 95% rename from ccpp/suites/suite_SCM_GSD_v1_prescribed_surface.xml rename to ccpp/suites/suite_SCM_GSD_v1_ps.xml index ccd849443..559401e03 100644 --- a/ccpp/suites/suite_SCM_GSD_v1_prescribed_surface.xml +++ b/ccpp/suites/suite_SCM_GSD_v1_ps.xml @@ -1,6 +1,6 @@ - + @@ -35,7 +35,6 @@ dcyc2t3 GFS_suite_interstitial_2 gmtb_scm_sfc_flux_spec - dcyc2t3_post mynnedmf_wrapper GFS_GWD_generic_pre cires_ugwp diff --git a/ccpp/suites/suite_SCM_csawmg.xml b/ccpp/suites/suite_SCM_csawmg.xml index 5b2ecf12f..0747565d3 100644 --- a/ccpp/suites/suite_SCM_csawmg.xml +++ b/ccpp/suites/suite_SCM_csawmg.xml @@ -1,6 +1,6 @@ - + @@ -49,7 +49,6 @@ GFS_surface_composites_post - dcyc2t3_post sfc_diag sfc_diag_post GFS_surface_generic_post diff --git a/ccpp/suites/suite_SCM_csawmg_prescribed_surface.xml b/ccpp/suites/suite_SCM_csawmg_ps.xml similarity index 95% rename from ccpp/suites/suite_SCM_csawmg_prescribed_surface.xml rename to ccpp/suites/suite_SCM_csawmg_ps.xml index c94dcdfe6..030fa4bb8 100644 --- a/ccpp/suites/suite_SCM_csawmg_prescribed_surface.xml +++ b/ccpp/suites/suite_SCM_csawmg_ps.xml @@ -1,6 +1,6 @@ - + @@ -33,7 +33,6 @@ dcyc2t3 GFS_suite_interstitial_2 gmtb_scm_sfc_flux_spec - dcyc2t3_post GFS_PBL_generic_pre hedmf GFS_PBL_generic_post diff --git a/contrib/build_nceplibs.sh b/contrib/build_nceplibs.sh new file mode 100755 index 000000000..4cac5b712 --- /dev/null +++ b/contrib/build_nceplibs.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +set -e + +if [ "$#" -ne 1 ]; then + echo "Illegal number of parameters, need to specify install directory for NCEPLIBS." + exit 1 +fi + +NCEPLIBS_DIR=$1 +if [ -d $NCEPLIBS_DIR ]; then + while true; do + read -p "Warning, destination $NCEPLIBS_DIR already exists. Proceed [y/n]? " yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done +fi +NCEPLIBS_SRC=$NCEPLIBS_DIR/src +mkdir -p $NCEPLIBS_SRC + +cd $NCEPLIBS_SRC +git clone -b release/public-v1 --recursive https://github.com/NOAA-EMC/NCEPLIBS-bacio +cd NCEPLIBS-bacio +BACIO_VERSION=`cat VERSION` +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=$NCEPLIBS_DIR .. +make VERBOSE=1 +make install + +cd $NCEPLIBS_SRC +git clone -b release/public-v1 --recursive https://github.com/NOAA-EMC/NCEPLIBS-sp +cd NCEPLIBS-sp +SP_VERSION=`cat VERSION` +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=$NCEPLIBS_DIR .. +make VERBOSE=1 +make install + +cd $NCEPLIBS_SRC +git clone -b release/public-v1 --recursive https://github.com/NOAA-EMC/NCEPLIBS-w3nco +cd NCEPLIBS-w3nco +W3NCO_VERSION=`cat VERSION` +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=$NCEPLIBS_DIR .. +make VERBOSE=1 +make install + +echo " " +echo " " +echo "Set the following environment variables for building the single column model:" +echo "=============================================================================" +echo "# for bash" +echo "export BACIO_LIB4=$NCEPLIBS_DIR/lib/libbacio_v${BACIO_VERSION}_4.a" +echo "export SP_LIBd=$NCEPLIBS_DIR/lib/libsp_v${SP_VERSION}_d.a" +echo "export W3NCO_LIBd=$NCEPLIBS_DIR/lib/libw3nco_v${W3NCO_VERSION}_d.a" +echo "# for csh" +echo "setenv BACIO_LIB4 $NCEPLIBS_DIR/lib/libbacio_v${BACIO_VERSION}_4.a" +echo "setenv SP_LIBd $NCEPLIBS_DIR/lib/libsp_v${SP_VERSION}_d.a" +echo "setenv W3NCO_LIBd $NCEPLIBS_DIR/lib/libw3nco_v${W3NCO_VERSION}_d.a" +echo "=============================================================================" +echo " " +echo " " diff --git a/contrib/get_thompson_tables.sh b/contrib/get_thompson_tables.sh new file mode 100755 index 000000000..32b75a1c2 --- /dev/null +++ b/contrib/get_thompson_tables.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -ex + +# Directory where this script is located +if [[ $(uname -s) == Darwin ]]; then + MYDIR=$(cd "$(dirname "$(greadlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P) +else + MYDIR=$(cd "$(dirname "$(readlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P) +fi +BASEDIR=$MYDIR/.. + +# Change to directory containing the physics input data, download and extract archive +cd $BASEDIR/scm/data/physics_input_data/ +wget https://github.com/NCAR/gmtb-scm/releases/download/v4.0.0/thompson_tables.tar +tar -xvf thompson_tables.tar +rm -f thompson_tables.tar diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 000000000..0e3e2e4ad --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,46 @@ +FROM dtcenter/common-community-container:latest +MAINTAINER Michelle Harrold or Grant Firl + +# +# Dockerfile for building CCPP SCM container +# + +# Note: The common community container image contains the following packages, which are used to build the SCM: +# gfortran, gcc, cmake, netCDF, HDF5, ZLIB, SZIP, Python, and libxml2 +# To access the common community container repository: https://github.com/NCAR/Common-Community-Container + +# Obtain CCPP SCM source code +RUN cd /comsoftware \ + && git clone --recursive -b dtc/develop https://github.com/NCAR/gmtb-scm + +# Obtain the pre-computed look-up tables for running with Thompson microphysics +RUN cd /comsoftware/gmtb-scm/scm/data/physics_input_data \ + && curl -L -O https://dtcenter.org/GMTB/freezeH2O.dat \ + && curl -L -O https://dtcenter.org/GMTB/qr_acr_qg.dat \ + && curl -L -O https://dtcenter.org/GMTB/qr_acr_qs.dat + +# Run the machine setup script to set environment variables +RUN cd /comsoftware/gmtb-scm/scm/ \ + && . etc/CENTOS_docker_setup.sh + +ENV BACIO_LIB4 /comsoftware/gmtb-scm/nceplibs/lib/libbacio_v2.2.0_4.a +ENV SP_LIBd /comsoftware/gmtb-scm/nceplibs/lib/libsp_v2.1.0_d.a +ENV W3NCO_LIBd /comsoftware/gmtb-scm/nceplibs/lib/libw3nco_v2.1.0_d.a + +# Invoke cmake on the source code to build +RUN cd /comsoftware/gmtb-scm/scm \ + && mkdir bin \ + && cd bin \ + && cmake ../src \ + && make + +# The analysis scripts have options for using LaTeX when making figure labels. +# If you would like to install LaTeK, uncomment the section below. +# Note: This will increase the image size by 1 GB. +#USER root +#RUN yum -y update \ +# && yum -y install texlive-* +#USER comuser + +# Set working directory +WORKDIR /comsoftware/gmtb-scm/scm/bin diff --git a/scm/data/physics_input_data/CCN_ACTIVATE.BIN b/scm/data/physics_input_data/CCN_ACTIVATE.BIN deleted file mode 100644 index 9026e073e..000000000 Binary files a/scm/data/physics_input_data/CCN_ACTIVATE.BIN and /dev/null differ diff --git a/scm/data/processed_case_input/fv3_model_point_noah.nc b/scm/data/processed_case_input/fv3_model_point_noah.nc index ca2b61c33..685e999d2 100644 Binary files a/scm/data/processed_case_input/fv3_model_point_noah.nc and b/scm/data/processed_case_input/fv3_model_point_noah.nc differ diff --git a/scm/data/processed_case_input/fv3_model_point_noahmp.nc b/scm/data/processed_case_input/fv3_model_point_noahmp.nc index b41113cbd..ff4066378 100644 Binary files a/scm/data/processed_case_input/fv3_model_point_noahmp.nc and b/scm/data/processed_case_input/fv3_model_point_noahmp.nc differ diff --git a/scm/doc/README_CENTOS.txt b/scm/doc/README_CENTOS.txt deleted file mode 100644 index c72ecefd5..000000000 --- a/scm/doc/README_CENTOS.txt +++ /dev/null @@ -1,98 +0,0 @@ -# Dom Heinzeller, 08/28/2018 - -In order to build and run SCM-CCPP v2 on CentOS Linux, the following installation steps can be used: - -1. Install "Gnome Desktop / Development Tools" CentOS system from CentOS-7-x86_64-DVD-1804.iso with network enabled - -2. As root (su), install additional packages: - yum --enablerepo=extras install epel-release - yum update - yum install gmp-devel - yum install mpfr-devel - yum install libmpc-devel - yum install autogen - yum install libxml2-devel - yum install libaec-devel - yum install libcurl-devel - yum install cmake - yum install dejagnu - yum install texinfo - yum install ncview - -3. As root (su), install modern GNU compilers - curl https://ftp.gnu.org/gnu/gcc/gcc-7.3.0/gcc-7.3.0.tar.gz -O - tar xvf gcc-7.3.0.tar.gz - mkdir gcc-7.3.0-build - cd gcc-7.3.0-build - ../gcc-7.3.0/configure --disable-multilib 2>&1 | tee log.config - make 2>&1 | tee log.make - make install 2>&1 | tee log.install - -4. As root (su), install netCDF library/headers for same compiler - - export LD_LIBRARY_PATH="/usr/local/lib64:/usr/local/lib:$LD_LIBRARY_PATH" - - cd /usr/local/src - - # Download the following src files from the web to /usr/local/src - hdf5-1.8.21.tar.gz - netcdf-4.6.1.tar.gz - netcdf-cxx4-4.3.0.tar.gz - netcdf-fortran-4.4.4.tar.gz - parallel-netcdf-1.9.0.tar.gz - szip-2.1.1.tar.gz - zlib-1.2.11.tar.gz - - # zlib-1.2.11 - tar -xvf zlib-1.2.11.tar.gz - cd zlib-1.2.11/ - ./configure 2>&1 | tee log.config - make 2>&1 | tee log.make - make install 2>&1 | tee log.install - cd .. - rm -fr zlib-1.2.11 - - # szip-2.1.1 - gunzip szip-2.1.1.tar.gz - tar -xvf szip-2.1.1.tar - gzip szip-2.1.1.tar - cd szip-2.1.1/ - ./configure 2>&1 | tee log.config - make 2>&1 | tee log.make - make install 2>&1 | tee log.install - cd .. - rm -fr szip-2.1.1 - - # hdf5-1.8.21 - gunzip hdf5-1.8.21.tar.gz - tar -xvf hdf5-1.8.21.tar - gzip hdf5-1.8.21.tar - cd hdf5-1.8.21/ - ./configure --with-szlib=/usr/local --with-zlib=/usr/local --prefix=/usr/local 2>&1 | tee log.config - make 2>&1 | tee log.make - make install 2>&1 | tee log.install - cd .. - rm -fr hdf5-1.8.20 - - # netcdf-4.6.1 - tar -xvf netcdf-4.6.1.tar.gz - cd netcdf-4.6.1/ - CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib -lhdf5 -lhdf5_hl -lsz -lz" ./configure 2>&1 | tee log.config - make 2>&1 | tee log.make - make install 2>&1 | tee log.install - cd .. - rm -fr netcdf-4.6.1 - - # netcdf-fortran-4.4.4 - tar -xvf netcdf-fortran-4.4.4.tar.gz - cd netcdf-fortran-4.4.4/ - FFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib -lnetcdf -lhdf5 -lhdf5_hl -lsz -lz" ./configure 2>&1 | tee log.config - make 2>&1 | tee log.make - make install 2>&1 | tee log.install - cd .. - rm -fr netcdf-fortran-4.4.4 - -5. As standard user, add to .bashrc - - export PATH="/usr/local/bin:$PATH" - export LD_LIBRARY_PATH="/usr/local/lib64:/usr/local/lib:$LD_LIBRARY_PATH" diff --git a/scm/doc/README_MACOSX.txt b/scm/doc/README_MACOSX.txt deleted file mode 100644 index fbd8a11b8..000000000 --- a/scm/doc/README_MACOSX.txt +++ /dev/null @@ -1,41 +0,0 @@ -# Dom Heinzeller, 03/23/2018 - -In order to build and run SCM-CCPP v1 on Mac OS X, the following installation steps are suggested: - -(tested on macOS High Sierra 10.13.3 with Xcode 9.3, llvm-clang 5.0.0, gfortran 7.3.0) - -1. Install homebrew (enter sudo password when requested) - /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" - -2. Install gcc-7.2.0, gfortran-7.2.0 - brew install -v gcc --verbose --without-multilib - -3. Install clang-5.0.0 with openmp support - brew install -v llvm - -4. Install mpich-3.2.1 (note: MPI itself not required to run SCM-CCPP, but installing mpich fixes issues with detecting OpenMP for the clang compilers) - brew install -v mpich - -5. Install netCDF library - brew install -v netcdf - -6. Install realpath for MacOSX - mkdir -p /usr/local/src - cd /usr/local/src - git clone https://github.com/harto/realpath-osx.git - cd realpath-osx - make 2>&1 | tee log.make - make install 2>&1 | tee log.install - cd /usr/local/src - rm -fr realpath-osx - -7. Install the f90nml Python library - cd /usr/local/src - git clone https://github.com/marshallward/f90nml.git - cd f90nml - python setup.py install --user 2>&1 | tee log.install - # Test if the installation was successful - python -c "import f90nml" && echo "Installation of f90nml successful" - -8. Install ncview for viewing netCDF files - brew install -v ncview diff --git a/scm/doc/README_UBUNTU.txt b/scm/doc/README_UBUNTU.txt deleted file mode 100644 index 93296a588..000000000 --- a/scm/doc/README_UBUNTU.txt +++ /dev/null @@ -1,22 +0,0 @@ -# Dom Heinzeller, 08/28/2018 - -In order to build and run SCM-CCPP v2 on Ubuntu Linux, the following installation steps are suggested: - -(tested on Ubuntu 18.04.1 LTS with gcc/gfortran 7.3.0) - -1. Install default UBUNTU system from ubuntu-18.04.1-desktop-amd64 - -2. As root (sudo su), install additional packages: - apt-get update - apt install synaptic - apt install gfortran - apt install libnetcdf-dev - apt install libnetcdff-dev - apt install git - apt install cmake - apt install libxml2-dev - # the following two packages are for convenience - apt install medit - apt install ncview - -3. As standard user, proceed with checking out the code and building as described in the quick start guide diff --git a/scm/doc/TechGuide/acknow.tex b/scm/doc/TechGuide/acknow.tex index d92353230..01c686c0b 100644 --- a/scm/doc/TechGuide/acknow.tex +++ b/scm/doc/TechGuide/acknow.tex @@ -8,11 +8,11 @@ \textcolor{darkgray}{\LARGE Acknowledgement} \vspace*{1cm}\par -If significant help was provided via the GMTB helpdesk for work resulting in a publication, please acknowledge the Developmental Testbed Center GMTB Team.\\ +If significant help was provided via the helpdesk for work resulting in a publication, please acknowledge the Developmental Testbed Center team.\\ \vspace*{1cm}\par For referencing this document please use:\\ \vspace*{1cm}\par -Firl, G., L. Carson, L. Bernardet, and D. Heinzeller, 2019. Global Model Test Bed Single Column Model v3.0 User and Technical Guide. 31pp. Available at https://dtcenter.org/GMTB/v3.0/scm-ccpp-guide-v3.pdf +Firl, G., L. Carson, L. Bernardet, D. Heinzeller, and M. Harrold, 2020. Common Community Physics Package Single Column Model v4.0 User and Technical Guide. 38pp. Available at https://dtcenter.org/GMTB/v4.0/scm-ccpp-guide-v4.pdf \end{flushleft} \end{titlepage} diff --git a/scm/doc/TechGuide/chap_cases.tex b/scm/doc/TechGuide/chap_cases.tex index 00edc4738..98c7b09ef 100644 --- a/scm/doc/TechGuide/chap_cases.tex +++ b/scm/doc/TechGuide/chap_cases.tex @@ -137,7 +137,7 @@ \section{Included Cases} For the ARM SGP case, several case configuration files representing different time periods of the observational dataset are included, denoted by a trailing letter. The LASSO case may be run with different forcing applied, so three case configuration files corresponding to these different forcing are included. In addition, two example cases are included for using UFS Atmosphere initial conditions: \begin{itemize} \item UFS initial conditions for 38.1 N, 98.5 W (central Kansas) for 00Z on Oct. 3, 2016 with Noah variables on the C96 FV3 grid (\execout{fv3\_model\_point\_noah.nc}) -\item UFS initial conditions for 38.1 N, 98.5 W (central Kansas) for 00Z on Oct. 3, 2016 with NoahMP variables on the C96 FV3 grid (\execout{fv3\_model\_point\_noah.nc}) +\item UFS initial conditions for 38.1 N, 98.5 W (central Kansas) for 00Z on Oct. 3, 2016 with NoahMP variables on the C96 FV3 grid (\execout{fv3\_model\_point\_noahmp.nc}) \end{itemize} See \ref{sec:UFS ICs} for information on how to generate these files for other locations and dates, given appropriate UFS Atmosphere initial conditions. @@ -201,17 +201,27 @@ \section{Using other LASSO cases} ./lasso1_forcing_file_generator_gjf.py \end{lstlisting} \item Create a new case configuration file (or copy and modify an existing one) in \execout{gmtb-scm/scm/etc/case\_config}. Be sure that the \execout{case\_name} variable points to the newly created/processed case input file from above. -\end{enumerate} +\end{enumerate} \section{Using UFS Initial Conditions} \label{sec:UFS ICs} -A script exists in \execout{scm/etc/scripts/UFS\_IC\_generator.py} to read in UFS Atmosphere cold start initial conditions and generate a case input data file that the SCM can use. Since the Noah LSM is the operational LSM, it is assumed that initial variables for it exist in the UFS Atmosphere initial condition files. If NoahMP is to be used, its initial conditions are generated from the Noah initial conditions using the same algorithm used in the UFS Atmosphere. The usage is as follows: +A script exists in \execout{scm/etc/scripts/UFS\_IC\_generator.py} to read in UFS Atmosphere cold start initial conditions and generate a case input data file that the SCM can use. Since the Noah LSM is the operational LSM, it is assumed that initial variables for it exist in the UFS Atmosphere initial condition files. Although NoahMP is not a member of any officially supported suite as of this release, if NoahMP is to be used, its initial conditions are generated from the Noah initial conditions using the same algorithm used in the UFS Atmosphere. Note that the script requires a few python packages that may not be found by default in all python installations: \exec{argparse}, \exec{fnmatch}, \exec{logging}, \exec{netCDF4}, \exec{numpy}, \exec{shapely}, \exec{f90nml}, and \exec{re}. + +NOTE: If using NOAA's Hera HPC, the \execout{shapely} python package does not seem to be installed with the version of Anaconda used by the rest of this software package by default so it is installed when users execute \execout{scm/etc/Hera\_setup\_intel.[csh/sh]}. + +Users on other systems can test if \execout{shapely} is installed using this command in the shell: +\begin{lstlisting} +python -c "import shapely" +\end{lstlisting} +If \execout{shapely} is installed, this command will succeed silently, otherwise an \execout{ImportError: No module named shapely} will be printed to screen. To install the \execout{shapely} Python module, use the install method preferred for your Python environment (\execout{easy\_install}, \execout{pip}, \execout{conda}, \dots). + +The \execout{UFS\_IC\_generator.py} script usage is as follows: \begin{lstlisting}[language=bash] ./UFS_IC_generator.py [-h] (-l LOCATION LOCATION | -ij INDEX INDEX) -d DATE -i IN_DIR -g GRID_DIR [-t {1,2,3,4,5,6}] -[-a AREA] [-mp] -n CASE_NAME +[-a AREA] [-mp] -n CASE_NAME [-oc] \end{lstlisting} Mandatory arguments: @@ -232,32 +242,25 @@ \section{Using UFS Initial Conditions} \item \exec{-{}-tile (-t)}: if one already knows the correct tile for the given longitude and latitude OR one is specifying the UFS grid index (\exec{-{}-index} argument) \item \exec{-{}-noahmp (-mp)}: flag to generate cold-start initial conditions for NoahMP LSM from Noah LSM initial conditions \item \exec{-{}-area (-a)}: area of grid cell in $m^2$ (if known or different than the value calculated from the supergrid file) +\item \exec{-{}-old\_chgres (-oc)}: flag if UFS initial conditions were generated using older version of chgres (global\_chgres); might be the case for pre-2018 data \end{enumerate} -The following commands were used from within the \exec{scm/etc/scripts} directory to generate the example UFS Atmosphere initial condition case input files: +The following commands were used from within the \exec{scm/etc/scripts} directory to generate the example UFS Atmosphere initial condition case input file: \begin{lstlisting}[language=bash] -./UFS_IC_generator.py -l 261.51 38.2 -d 201610030000 -i ../../data/raw_case_input/FV3_C96_example_ICs -g ../../data/raw_case_input/FV3_C96_example_ICs -n fv3_model_point_noah +./UFS_IC_generator.py -l 261.51 38.2 -d 201610030000 -i ../../data/raw_case_input/FV3_C96_example_ICs -g ../../data/raw_case_input/FV3_C96_example_ICs -n fv3_model_point_noah -oc \end{lstlisting} - \begin{lstlisting}[language=bash] -./UFS_IC_generator.py -l 261.51 38.2 -d 201610030000 -i ../../data/raw_case_input/FV3_C96_example_ICs -g ../../data/raw_case_input/FV3_C96_example_ICs -n fv3_model_point_noahmp -mp +./UFS_IC_generator.py -l 261.51 38.2 -d 201610030000 -i ../../data/raw_case_input/FV3_C96_example_ICs -g ../../data/raw_case_input/FV3_C96_example_ICs -n fv3_model_point_noahmp -mp -oc \end{lstlisting} -Note that the \exec{-{}-in\_dir (-i)} and \exec{-{}-grid\_dir (-g)} arguments are the same in this case (since the supergrid files were copied to the same directory as the initial conditions files for point of example), but they will not in general be the same. +Note that the \exec{-{}-in\_dir (-i)} and \exec{-{}-grid\_dir (-g)} arguments are the same in this case (since the supergrid files were copied to the same directory as the initial conditions files for point of example), but they will not in general be the same. Also note that the default behavior of the script is to expect that the netCDF initial condition files were generated from \execout{chgres\_cube} and not the older \execout{global\_chgres}. If they were generated from the older version (which is likely for pre-2018 data), they will have a slightly different format requiring the \exec{-{}-old\_chgres (-oc)} option to be set in order for the files to be read properly by the script. If you try without the \exec{-{}-old\_chgres (-oc)} flag and receive a ``IndexError: t not found'' error, try the script again with the flag. -In addition to the case input files generated by this script, one will need appropriate case configuration files. Make sure that the \exec{model\_ics} variable is set to \exec{.true.} and that the \exec{C\_RES}, \exec{year}, \exec{month}, \exec{day}, and \exec{hour} are all set to the appropriate values that match the UFS Atmosphere initial conditions used. See \execout{scm/etc/case\_config/fv3\_model\_point\_noah.nml} and \execout{scm/etc/case\_config/fv3\_model\_point\_noahmp.nml} for examples. +In addition to the case input files generated by this script, one will need appropriate case configuration files. Make sure that the \exec{model\_ics} variable is set to \exec{.true.} and that the \exec{C\_RES}, \exec{year}, \exec{month}, \exec{day}, and \exec{hour} are all set to the appropriate values that match the UFS Atmosphere initial conditions used. See \execout{scm/etc/case\_config/fv3\_model\_point\_noah.nml} for an example. Running the model is the same as for observational field campaign cases: \begin{lstlisting}[language=bash] -./run_gmtb_scm.py -c fv3_model_point_noah -s SCM_GFS_v15 -n input_GFS_v15.nml +./run_gmtb_scm.py -c fv3_model_point_noah -s SCM_GFS_v15p2 \end{lstlisting} \begin{lstlisting}[language=bash] -./run_gmtb_scm.py -c fv3_model_point_noahmp -s SCM_GFS_v15_noahmp -n input_GFS_v15_noahmp.nml +./run_gmtb_scm.py -c fv3_model_point_noahmp -s SCM_GFS_v15p2_noahmp -n input_GFS_v15p2_noahmp.nml \end{lstlisting} - - - - - - - diff --git a/scm/doc/TechGuide/chap_ccpp.tex b/scm/doc/TechGuide/chap_ccpp.tex index af4829ebd..4ab12d984 100644 --- a/scm/doc/TechGuide/chap_ccpp.tex +++ b/scm/doc/TechGuide/chap_ccpp.tex @@ -1,7 +1,7 @@ \chapter{CCPP Interface} \label{chapter: ccpp_interface} -Chapter 6 of the CCPP Technical Documentation (\url{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide}) provides a wealth of information on the overall process of connecting a host model to the CCPP framework for calling physics. This chapter describes the particular implementation within the GMTB SCM, including how to set up, initialize, call, and change a physics suite using the CCPP framework. +Chapter 6 of the CCPP v4 Technical Documentation (\url{https://ccpp-techdoc.readthedocs.io/en/v4.0}) provides a wealth of information on the overall process of connecting a host model to the CCPP framework for calling physics. This chapter describes the particular implementation within this SCM, including how to set up, initialize, call, and change a physics suite using the CCPP framework. \section{Setting up a suite} @@ -9,29 +9,29 @@ \section{Setting up a suite} \subsection{Preparing data from the SCM} -As described in sections 6.1 and 6.2 of the \href{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide}{CCPP Technical Documentation} a host model must allocate memory and provide metadata for variables that are passed into and out of the schemes within the physics suite. As of this release, in practice this means that a host model must do this for all variables needed by all physics schemes that are expected to be used with the host model. For the GMTB SCM, all variables needed by the physics schemes are allocated and documented in the file \execout{gmtb-scm/scm/src/gmtb\_scm\_type\_defs.f90} and are contained within the \execout{physics} derived data type. This derived data type initializes its component variables in a \execout{create} type-bound procedure. As mentioned in section 6.2 of the \href{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide}{CCPP Technical Documentation}, a table containing all required metadata was constructed for describing all variables in the \execout{physics} derived data type. The standard names of all variables in this table must match with a corresponding variable within one or more of the physics schemes. A list of all standard names used can be found in \execout{ccpp/framework/doc/DevelopersGuide/CCPP\_VARIABLES\_SCM.pdf}. The \execout{local\_name} for each variable corresponds to how a variable is referenced from the point in the code where \execout{ccpp\_field\_add()} statements are made. For the GMTB SCM, then, all \execout{local\_name}s begin with the \execout{physics} derived data type. Nested within most of the \execout{local\_name}s is also the name of a derived data type used within the UFS Atmosphere cap (re-used here for expediency). Since the \execout{ccpp\_field\_add()} statements are made within a loop over all columns within \execout{gmtb\_scm.F90}, most \execout{local\_name}s are also referenced with \execout{i} as an array index. +As described in sections 6.1 and 6.2 of the \href{https://ccpp-techdoc.readthedocs.io/en/v4.0}{CCPP Technical Documentation} a host model must allocate memory and provide metadata for variables that are passed into and out of the schemes within the physics suite. As of this release, in practice this means that a host model must do this for all variables needed by all physics schemes that are expected to be used with the host model. For this SCM, all variables needed by the physics schemes are allocated and documented in the file \execout{gmtb-scm/scm/src/gmtb\_scm\_type\_defs.f90} and are contained within the \execout{physics} derived data type. This derived data type initializes its component variables in a \execout{create} type-bound procedure. As mentioned in section 6.2 of the \href{https://ccpp-techdoc.readthedocs.io/en/v4.0/}{CCPP Technical Documentation}, a table containing all required metadata was constructed for describing all variables in the \execout{physics} derived data type. The standard names of all variables in this table must match with a corresponding variable within one or more of the physics schemes. A list of all standard names used can be found in \execout{ccpp/framework/doc/DevelopersGuide/CCPP\_VARIABLES\_SCM.pdf}. The \execout{local\_name} for each variable corresponds to how a variable is referenced from the point in the code where \execout{ccpp\_field\_add()} statements are made. For this SCM, then, all \execout{local\_name}s begin with the \execout{physics} derived data type. Nested within most of the \execout{local\_name}s is also the name of a derived data type used within the UFS Atmosphere cap (re-used here for expediency). Since the \execout{ccpp\_field\_add()} statements are made within a loop over all columns within \execout{gmtb\_scm.F90}, most \execout{local\_name}s are also referenced with \execout{i} as an array index. \subsection{Editing and running \exec{ccpp\_prebuild.py}} -General instructions for configuring and running the \execout{ccpp\_prebuild.py} script can be found in chapter 8 of the \href{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide}{CCPP Technical Documentation}. The script expects to be run with a host-model-dependent configuration file, passed as argument \execout{--config=path\_to\_config\_file}. Within this configuration file are variables that hold paths to the variable definition files (where metadata tables can be found on the host model side), the scheme files (a list of paths to all source files containing scheme entry points), the auto-generated physics schemes makefile snippet, the auto-generated physics scheme caps makefile snippet, the file where \execout{ccpp\_modules.inc} and \execout{ccpp\_fields.inc} are included, and the directory where the auto-generated physics caps should be written out to. Other variables less likely to be modified by a user are included in this configuration file as well, such as code sections to be included in the auto-generated scheme caps. As mentioned in section \ref{section: compiling}, this script must be run to reconcile data provided by the SCM with data required by the physics schemes before compilation by following step 1 in that section. +General instructions for configuring and running the \execout{ccpp\_prebuild.py} script can be found in chapter 8 of the \href{https://ccpp-techdoc.readthedocs.io/en/v4.0/}{CCPP Technical Documentation}. The script expects to be run with a host-model-dependent configuration file, passed as argument \execout{--config=path\_to\_config\_file}. Within this configuration file are variables that hold paths to the variable definition files (where metadata tables can be found on the host model side), the scheme files (a list of paths to all source files containing scheme entry points), the auto-generated physics schemes makefile snippet, the auto-generated physics scheme caps makefile snippet, the file where \execout{ccpp\_modules.inc} and \execout{ccpp\_fields.inc} are included, and the directory where the auto-generated physics caps should be written out to. Other variables less likely to be modified by a user are included in this configuration file as well, such as code sections to be included in the auto-generated scheme caps. As mentioned in section \ref{section: compiling}, this script must be run to reconcile data provided by the SCM with data required by the physics schemes before compilation by following step 1 in that section. \subsection{Preparing a suite definition file} -The suite definition file is a text file read by the model at run time. It is used to specify the physical parameterization suite, and includes information about the number of parameterization groupings, which parameterizations that are part of each of the groups, the order in which the parameterizations should be run, and whether subcycling will be used to run any of the parameterizations with shorter timesteps. +The suite definition file is a text file read by the model at compile time. It is used to specify the physical parameterization suite, and includes information about the number of parameterization groupings, which parameterizations that are part of each of the groups, the order in which the parameterizations should be run, and whether subcycling will be used to run any of the parameterizations with shorter timesteps. In addition to the six or so major parameterization categories (such as radiation, boundary layer, deep convection, resolved moist physics, etc.), the suite definition file can also have an arbitrary number of additional interstitial schemes in between the parameterizations to prepare or postprocess data. In many models, this interstitial code is not known to the model user but with the suite definition file, both the physical parameterizations and the interstitial processing are listed explicitly. The suite definition file also invokes an initialization step, which is run only once when the model is first initialized. Finally, the name of the suite is listed in the suite definition file. By default, this suite name is used to compose the name of the shared library (.so file) that contains the code for the physical parameterizations and that must be dynamically linked at run time. -For this release, supported suite definition files used with the GMTB SCM are found in \execout{gmtb-scm/ccpp/suites}. For all of these suites, the physics schemes have been organized into 3 groupings following how the physics are called in the UFS Atmosphere model, although no code is executed in the SCM time loop between execution of the grouped schemes. Several ``interstitial'' schemes are included in the suite definition file to execute code that previously was part of a hard-coded physics driver. Some of these schemes may eventually be rolled into the schemes themselves, improving portability. +For this release, supported suite definition files used with this SCM are found in \execout{gmtb-scm/ccpp/suites}. For all of these suites, the physics schemes have been organized into 3 groupings following how the physics are called in the UFS Atmosphere model, although no code is executed in the SCM time loop between execution of the grouped schemes. Several ``interstitial'' schemes are included in the suite definition file to execute code that previously was part of a hard-coded physics driver. Some of these schemes may eventually be rolled into the schemes themselves, improving portability. \section{Initializing/running a suite} -The process for initializing and running a suite in the GMTB SCM is described in sections \ref{section: physics init} and \ref{section: time integration}, respectively. A more general description of the process for performing suite initialization and running can also be found in sections 6.4 and 6.5 of the \href{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide}{CCPP Technical Documentation}. +The process for initializing and running a suite in this SCM is described in sections \ref{section: physics init} and \ref{section: time integration}, respectively. A more general description of the process for performing suite initialization and running can also be found in sections 6.4 and 6.5 of the \href{https://ccpp-techdoc.readthedocs.io/en/v4.0/}{CCPP Technical Documentation}. \section{Changing a suite} \subsection{Replacing a scheme with another} -When the CCPP has reached a state of maturity, the process for modifying the contents of an existing physics suite will be a very straightforward process, consisting of merely changing the name of the scheme in the suite definition file. As of this release, which consists of one scheme of each ``type'' in the pool of CCPP-compliant physics schemes with many short interstitial schemes, the process requires some consideration. Of course, prior to being able to swap a scheme within a suite, one must first add a CCPP-compliant scheme to the pool of available schemes in the CCPP physics repository. This process is described in chapter 2 of the \href{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide}{CCPP Technical Documentation}. +When the CCPP has reached a state of maturity, the process for modifying the contents of an existing physics suite will be a very straightforward process, consisting of merely changing the name of the scheme in the suite definition file. As of this release, which consists of one scheme of each ``type'' in the pool of CCPP-compliant physics schemes with many short interstitial schemes, the process requires some consideration. Of course, prior to being able to swap a scheme within a suite, one must first add a CCPP-compliant scheme to the pool of available schemes in the CCPP physics repository. This process is described in chapter 2 of the \href{https://ccpp-techdoc.readthedocs.io/en/v4.0/}{CCPP Technical Documentation}. Once a CCPP-compliant scheme has been added to the CCPP physics repository, the process for modifying an existing suite should take the following steps into account: @@ -39,7 +39,7 @@ \subsection{Replacing a scheme with another} \item Examine and compare the arguments of the scheme being replaced and the replacement scheme. \begin{itemize} \item Are there any new variables that the replacement scheme needs from the host application? If so, these new variables must be added to the host model cap. For the SCM, this involves adding a component variable to the \execout{physics} derived data type and a corresponding entry in the metadata table. The new variables must also be allocated and initialized in the \execout{physics\%create} type-bound procedure. -\item Do any of the new variables need to be calculated in an interstitial scheme? If so, one must be written and made CCPP-compliant itself. The \href{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide}{CCPP Technical Documentation} will help in this endeavor, and the process outlined in its chapter 2 should be followed. +\item Do any of the new variables need to be calculated in an interstitial scheme? If so, one must be written and made CCPP-compliant itself. The \href{https://ccpp-techdoc.readthedocs.io/en/v4.0/}{CCPP Technical Documentation} will help in this endeavor, and the process outlined in its chapter 2 should be followed. \item Do other schemes in the suite rely on output variables from the scheme being replaced that are no longer being supplied by the replacement scheme? Do these output variables need to be derived/calculated in an interstitial scheme? If so, see the previous bullet about adding one. \end{itemize} \item Examine existing interstitial schemes related to the scheme being replaced. @@ -47,7 +47,7 @@ \subsection{Replacing a scheme with another} \item There may be scheme-specific interstitial schemes (needed for one specific scheme) and/or type-generic interstitial schemes (those that are called for all schemes of a given type, i.e. all PBL schemes). Does one need to write analogous scheme-specific interstitial schemes for the replacement? \item Are the type-generic interstitial schemes relevant or do they need to be modified? \end{itemize} -\item Depending on the answers to the above considerations, edit the suite definition file as necessary. Typically, this would involve finding the \execout{} elements associated with the scheme to be replaced and its associated interstitial \execout{} elements and simply replacing the scheme names to reflect their replacements. See chapter 4 of the \href{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide}{CCPP Technical Documentation} for further details. +\item Depending on the answers to the above considerations, edit the suite definition file as necessary. Typically, this would involve finding the \execout{} elements associated with the scheme to be replaced and its associated interstitial \execout{} elements and simply replacing the scheme names to reflect their replacements. See chapter 4 of the \href{https://ccpp-techdoc.readthedocs.io/en/v4.0/}{CCPP Technical Documentation} for further details. \end{itemize} \subsection{Modifying ``groups'' of parameterizations} @@ -56,7 +56,7 @@ \subsection{Modifying ``groups'' of parameterizations} \subsection{Subcycling parameterizations} -The suite definition file allows subcycling of schemes, or calling a subset of schemes at a smaller time step than others. The \execout{} element in the suite definition file controls this function. All schemes within such an element are called \exec{n} times during one \execout{ccpp\_physics\_run} call. An example of this is found in the \execout{suite\_SCM\_GFS\_v15.xml} suite definition file, where the surface schemes are executed twice for each timestep (implementing a predictor/corrector paradigm). Note that no time step information is included in the suite definition file. If subcycling is used for a set of parameterizations, the smaller time step must be an input argument for those schemes. +The suite definition file allows subcycling of schemes, or calling a subset of schemes at a smaller time step than others. The \execout{} element in the suite definition file controls this function. All schemes within such an element are called \exec{n} times during one \execout{ccpp\_physics\_run} call. An example of this is found in the \execout{suite\_SCM\_GFS\_v15p2.xml} suite definition file, where the surface schemes are executed twice for each timestep (implementing a predictor/corrector paradigm). Note that no time step information is included in the suite definition file. If subcycling is used for a set of parameterizations, the smaller time step must be an input argument for those schemes. \section{Adding variables} @@ -70,7 +70,7 @@ \subsection{Adding a physics-only variable} \label{adding_physics_only_variable} real(kind=kind_phys), allocatable :: foo(:,:) \end{lstlisting} -\item Second, within the \execout{physics\_create} subroutine, add an allocate and initialization statement. +\item Second, within the \execout{physics\_create} subroutine, add an allocate and initialization statement. \begin{lstlisting}[language=Fortran] allocate(foo(n_columns, n_levels)) physics%foo = 0.0 @@ -86,7 +86,7 @@ \subsection{Adding a physics-only variable} \label{adding_physics_only_variable} The elements of the metadata entry are all on one line (following the same format as other entries) and include the variable's ``local name'' or how it is referenced from \execout{gmtb\_scm.F90/main}, its ``standard name'' or how it is referenced by both the host model and the physics code, its units, its rank (dimensionality), Fortran intrinsic data type, the real kind if necessary, its intent (must be none for this host-side table), its optionality (must be F for this host-side table). This metadata entry is parsed by the CCPP framework and makes this variable available for any CCPP-compliant physics schemes to use. \item On the physics scheme side, there will also be a metadata table entry for \exec{foo} preceding the subroutine in which it is used. For example, say that scheme \exec{bar} uses \exec{foo}. If \exec{foo} is further initialized in \exec{bar}'s \execout{\_init} subroutine, a metadata entry for \exec{foo} must precede the \execout{bar\_init} subroutine's code. If it is used in \exec{bar}'s run subroutine, a metadata entry for foo must also appear in the preceding metadata table for \execout{bar\_run}. The metadata entry on the physics scheme side has the same format as the one on the host model side described above. The standard name, units, rank, type, and kind must match the entry from the host model table. Others attributes (local name, description, intent, optional) can differ. The local name corresponds to the name of the variable used within the scheme subroutine, and intent and optional attributes should reflect how the variable is actually used within the scheme. - + Note: In addition to the metadata table, the argument list for the scheme subroutine must include the new variable (i.e., \exec{foo} must actually be in the argument list for \execout{bar\_run} and be declared appropriately in regular Fortran). \end{enumerate} @@ -94,7 +94,7 @@ \subsection{Adding a physics-only variable} \label{adding_physics_only_variable} If a variable is declared following these steps, it can be used in any CCPP-compliant physics scheme and it will retain its value from timestep to timestep. A variable will ONLY be zeroed out (either every timestep or periodically) if it is in the \execout{GFS\_interstitial} or \execout{GFS\_diag} data types. So, if one needs the new variable to be `prognostic', one would need to handle updating its value within the scheme, something like: \begin{equation} -\text{foo}^{t+1} = \text{foo}^t + \Delta t*\text{foo\_tendency} +\text{foo}^{t+1} = \text{foo}^t + \Delta t*\text{foo\_tendency} \end{equation} Technically, the host model can ``see'' foo between calls to physics (since the host model allocated its memory at initialization), but it will not be touching it. @@ -166,8 +166,3 @@ \subsection{Adding a prognostic SCM variable} \end{itemize} \item There may be additional steps depending on how the tracer is used in the physics and how the physics scheme is integrated with the current GFS physics suite. For example, the GFS physics has two tracer arrays, one for holding tracer values before the physics timestep (\execout{gmtb-scm/scm/src/GFS\_typedefs.F90/GFS\_statein\_type/qgrs}) and one for holding tracer values that are updated during/after the physics (\execout{gmtb-scm/scm/src/GFS\_typedefs.F90/GFS\_stateout\_type/gq0}). If the tracer needs to be part of these arrays, there are a few additional steps to take. \end{enumerate} - - - - - diff --git a/scm/doc/TechGuide/chap_function.tex b/scm/doc/TechGuide/chap_function.tex index 3ab4897bc..d646760f4 100644 --- a/scm/doc/TechGuide/chap_function.tex +++ b/scm/doc/TechGuide/chap_function.tex @@ -3,7 +3,7 @@ \chapter{Algorithm} \section{Algorithm Overview} -Like most SCMs, the algorithm for the GMTB SCM is quite simple. In a nutshell, the SCM code performs the following: +Like most SCMs, the algorithm for the CCPP SCM is quite simple. In a nutshell, the SCM code performs the following: \begin{itemize} \item Read in an initial profile and the forcing data. \item Create a vertical grid and interpolate the initial profile and forcing data to it. @@ -22,7 +22,7 @@ \section{Reading input} \end{enumerate} \section{Setting up vertical grid and interpolating input data} -The GMTB SCM uses pressure for the vertical coordinate (lowest index is the surface). There are two choices for generating the vertical coordinate corresponding to a) the 2017 operational GFS v14 based on the Global Spectral Model (GSM) (set \execout{model\_name} $=$ \exec{`GFS'} in the \execout{case\_config} file), and b) the FV3-based GFS v15 (set \execout{model\_name} $=$ \exec{`FV3'} in the \execout{case\_config} file). For both methods, the pressure levels are calculated using the surface pressure and coefficients ($a_k$ and $b_k$). For the GSM-based vertical coordinate, the coefficient data is read from an external file. Only 28, 42, 60, 64, and 91 levels are supported. If using the FV3-based vertical coordinate, it is possible to use potentially any (integer) number of vertical levels. Depending on the vertical levels specified, however, the method of specification of the coefficients may change. Please see the subroutine \execout{get\_FV3\_vgrid} in the source file \execout{gmtb-scm/scm/src/gmtb\_scm\_vgrid.F90} for details. This subroutine was minimally adapted from the source file \execout{fv\_eta.F90} from the v0 release version of the FV3GFS model. +The CCPP SCM uses pressure for the vertical coordinate (lowest index is the surface). There are two choices for generating the vertical coordinate corresponding to a) the 2017 operational GFS v14 based on the Global Spectral Model (GSM) (set \execout{model\_name} $=$ \exec{`GFS'} in the \execout{case\_config} file), and b) the FV3-based GFS v15 (set \execout{model\_name} $=$ \exec{`FV3'} in the \execout{case\_config} file). For both methods, the pressure levels are calculated using the surface pressure and coefficients ($a_k$ and $b_k$). For the GSM-based vertical coordinate, the coefficient data is read from an external file. Only 28, 42, 60, 64, and 91 levels are supported. If using the FV3-based vertical coordinate, it is possible to use potentially any (integer) number of vertical levels. Depending on the vertical levels specified, however, the method of specification of the coefficients may change. Please see the subroutine \execout{get\_FV3\_vgrid} in the source file \execout{gmtb-scm/scm/src/gmtb\_scm\_vgrid.F90} for details. This subroutine was minimally adapted from the source file \execout{fv\_eta.F90} from the v0 release version of the FV3GFS model. After the vertical grid has been set up, the state variable profiles stored in the \execout{scm\_state} derived data type are interpolated from the input and reference profiles in the \execout{set\_state} subroutine of the \execout{gmtb\_scm\_setup} module. @@ -39,7 +39,7 @@ \section{Physics suite initialization} \section{Time integration} \label{section: time integration} -Two time-stepping schemes have been implemented within the GMTB SCM: forward Euler (\execout{time\_scheme} $=$ \exec{1} in the \execout{case\_config} namelist) and filtered leapfrog (\execout{time\_scheme} $=$ \exec{2} in the \execout{case\_config} namelist). If the leapfrog scheme is chosen, two time levels of state variables are saved and the first time step is implemented as forward time step over $\sfrac{\Delta t}{2}$. +Two time-stepping schemes have been implemented within the CCPP SCM: forward Euler (\execout{time\_scheme} $=$ \exec{1} in the \execout{case\_config} namelist) and filtered leapfrog (\execout{time\_scheme} $=$ \exec{2} in the \execout{case\_config} namelist). If the leapfrog scheme is chosen, two time levels of state variables are saved and the first time step is implemented as forward time step over $\sfrac{\Delta t}{2}$. During each step of the time integration, the following sequence occurs: \begin{enumerate} diff --git a/scm/doc/TechGuide/chap_intro.tex b/scm/doc/TechGuide/chap_intro.tex index 8f859aa15..1c03d40bc 100644 --- a/scm/doc/TechGuide/chap_intro.tex +++ b/scm/doc/TechGuide/chap_intro.tex @@ -1,30 +1,29 @@ \chapter{Introduction} \label{chapter: introduction} -A single column model (SCM) can be a valuable tool for diagnosing the performance of a physics suite, from validating that schemes have been integrated into a suite correctly to deep dives into how physical processes are being represented by the approximating code. The Global Model Test Bed (GMTB) SCM has the advantage of working with the Common Community Physics Package (CCPP), a library of physical parameterizations for atmospheric numerical models and the associated framework for connecting potentially any atmospheric model to physics suites constructed from its member parameterizations. In fact, this SCM serves as perhaps the simplest example for using the CCPP and its framework in an atmospheric model. This version contains all parameterizations of the current operational GFS v15 (implemented on June 12, 2019), plus additional developmental schemes. The schemes are grouped in four supported suites described in detail in the \href{https://dtcenter.org/GMTB/v3.0/sci\_doc/}{CCPP Scientific Documentation} (GFS\_v15, GFS\_v15plus, csawmg, and GSD\_v0). The Zhao-Carr microphysics and the GFS\_v14 suite are no longer supported. +A single column model (SCM) can be a valuable tool for diagnosing the performance of a physics suite, from validating that schemes have been integrated into a suite correctly to deep dives into how physical processes are being represented by the approximating code. This SCM has the advantage of working with the Common Community Physics Package (CCPP), a library of physical parameterizations for atmospheric numerical models and the associated framework for connecting potentially any atmospheric model to physics suites constructed from its member parameterizations. In fact, this SCM serves as perhaps the simplest example for using the CCPP and its framework in an atmospheric model. This version contains all parameterizations of NOAA's evolved operational GFS v15.2 suite (implemented in 2019), plus additional developmental schemes. The schemes are grouped in four supported suites described in detail in the \href{https://dtcenter.org/GMTB/v4.0/sci\_doc/}{CCPP Scientific Documentation} (GFS\_v15p2, GFS\_v16beta, csawmg, and GSD\_v1). Two additional suites without the near sea surface temperature scheme are available to match the first Unified Forecast System (UFS) public release. This document serves as both the User and Technical Guides for this model. It contains a Quick Start Guide with instructions for obtaining the code, compiling, and running a sample test case, an explanation for what is included in the repository, a brief description of the operation of the model, a description of how cases are set up and run, and finally, an explanation for how the model interfaces with physics through the CCPP infrastructure. -Please refer to the release web page for further documentation and user notes:\\ \url{https://dtcenter.org/community-code/common-community-physics-package-ccpp/ccpp-scm-version-3-0} +Please refer to the release web page for further documentation and user notes:\\ \url{https://dtcenter.org/community-code/common-community-physics-package-ccpp/download} \section{Version Notes} -GMTB SCM v3.0 contains the following major and minor changes since v2.1. +The CCPP SCM v4.0 contains the following major and minor changes since v3.0. Major \begin{itemize} -\item Codebase updated to work with latest ccpp-framework (v3.0) and ccpp-physics (v3.0), allowing use of 4 supported physics suites -\item Added Python scripts for running a single integration or multiple integrations serially +\item Codebase updated to work with latest ccpp-framework (v4.0) and ccpp-physics (v4.0), allowing use of 6 supported physics suites +\item Support added for NOAA's Hera HPC platform and Docker containers +\item Support added for CCPP's ``static'' build. This release no longer supports the ``dynamic'' build. +\item Added capability to utilize UFS initial conditions and initialize the Noah LSM (without advective forcing) \end{itemize} Minor \begin{itemize} -\item Assumed that NCEPlibs are installed as a software prerequisite with an environment variable pointing to the installation location; remove repository copies of NCEPlib files -\item Assumed that NetCDF is installed as a software prerequisite with an environment variable pointing to the installation location -\item Updated User's/Technical Guide (this document) -\item Separated case configuration (remained in \execout{scm/etc/case\_config}) from physics suite configuration (configured through Python run script) -\item Streamlined CMakeLists.txt; moved file operations from CMakelists.txt and Fortran code to Python run script (except output) -\item Changed how ozone, stratospheric H2O, aerosols, and ICN were initialized and handled in SCM code +\item Integrated CCPP code generation with the CMake step +\item Adopted the new CCPP metadata format +\item Name change: this code is now known as the CCPP SCM instead of the ``GMTB'' SCM, although filenames in the code have not been changed yet. \end{itemize} \subsection{Limitations} @@ -32,12 +31,14 @@ \subsection{Limitations} This release bundle has some known limitations: \begin{itemize} -\item The SCM cannot run over a land surface point using an LSM at this time due to the absence of necessary staged files that are used to initialize the LSM. Therefore, if the SCM is run over a land point (where sfc\_type = 1 is set in the case configuration file), prescribed surface fluxes must be used: +\item The provided cases over land points cannot use an LSM at this time due to the lack of initialization data for the LSMs. Therefore, for the provided cases over land points (ARM\_SGP\_summer\_1997\_* and LASSO\_*, where sfc\_type = 1 is set in the case configuration file), prescribed surface fluxes must be used: \begin{itemize} \item surface sensible and latent heat fluxes must be provided in the case data file \item sfc\_flux\_spec must be set to true in the case configuration file \item the surface roughness length in cm must be set in the case configuration file -\item the suite defintion file used (physics\_suite variable in the case configuration file) must have been modified to use prescribed surface fluxes rather than an LSM. An example is included in the development repository +\item the suite defintion file used (physics\_suite variable in the case configuration file) must have been modified to use prescribed surface fluxes rather than an LSM. +\item NOTE: If one can develop appropriate initial conditions for the LSMs for the supplied cases over land points, there should be no technical reason why they cannot be used with LSMs, however. \end{itemize} -If the SCM is told to use an LSM (sfc\_type = 1) without using prescribed surface fluxes as described above, the model will exit with a segmentation fault due to uninitialized variables. An update to use an LSM with the SCM will be forthcoming. +\item As of this release, using the SCM over a land point with an LSM is possible through the use of UFS initial conditions (see section \ref{sec:UFS ICs}). However, advective forcing terms are unavailable as of this release, so only short integrations using this configuration should be employed. Using dynamical tendencies (advective forcing terms) from the UFS will be part of a future release. +\item There are several capabilities of the developmental code that have not been tested sufficiently to be considered part of the supported release. Those include additional parameterizations, such as the Noah Multi-Parameterization (Noah-MP) scheme. User that want to use experimental capabilities should refer to Subsection \ref{section: development_code}. \end{itemize} diff --git a/scm/doc/TechGuide/chap_quick.tex b/scm/doc/TechGuide/chap_quick.tex index 707755e94..489c4cee1 100644 --- a/scm/doc/TechGuide/chap_quick.tex +++ b/scm/doc/TechGuide/chap_quick.tex @@ -1,44 +1,57 @@ \chapter{Quick Start Guide} \label{chapter: quick} -This chapter provides instructions for obtaining and compiling the GMTB SCM. The SCM code calls CCPP-compliant physics schemes through the CCPP framework code. As such, it requires the CCPP framework code and physics code, both of which are included as submodules within the SCM code. This package can be considered a simple example for an atmospheric model to interact with physics through the CCPP. +This chapter provides instructions for obtaining and compiling the CCPP SCM. The SCM code calls CCPP-compliant physics schemes through the CCPP framework code. As such, it requires the CCPP framework code and physics code, both of which are included as submodules within the SCM code. This package can be considered a simple example for an atmospheric model to interact with physics through the CCPP. + +Alternatively, if one doesn't have access or care to set up a machine with the appropriate system requirements but has a working Docker installation, it is possible to create and use a Docker container with a pre-configured computing environment with a pre-compiled model. This is also an avenue for running this software with a Windows PC. See section \ref{docker} for more information. \section{Obtaining Code} +\label{obtaining_code} -The source code for the CCPP and SCM is provided through GitHub.com. This release branch contains the tested and supported version for general use. +The source code for the CCPP and SCM is provided through GitHub.com. This release branch contains the tested and supported version for general use, while a development branch is less stable, yet contains the latest developer code. Instructions for using either option are discussed here. -\begin{enumerate} - \item Clone the source using +\subsection{Release Code} + +Clone the source using \begin{lstlisting}[language=bash] -git clone --recursive -b v3.0 https://github.com/NCAR/gmtb-scm +git clone --recursive -b v4.0.0 https://github.com/NCAR/gmtb-scm \end{lstlisting} Recall that the \execout{recursive} option in this command clones the main gmtb-scm repository and all subrepositories (ccpp-physics and ccpp-framework). Using this option, there is no need to execute \exec{git submodule init} and \exec{git submodule update}. - \item Change directory into the project. -\begin{lstlisting}[language=bash] -cd gmtb-scm -\end{lstlisting} -\end{enumerate} The CCPP framework can be found in the ccpp/framework subdirectory at this level. The CCPP physics parameterizations can be found in the ccpp/physics subdirectory. +\subsection{Development Code} +\label{section: development_code} + If you would like to contribute as a developer to this project, please see (in addition to the rest of this guide) the scientific and technical documentation included with this release: \url{https://dtcenter.org/community-code/common-community-physics-package-ccpp/documentation} There you will find links to all of the documentation pertinent to developers. -For working with the development branches (stability not guaranteed), after executing the steps above, check out the \exec{dtc/develop} branches of the repository (and submodules): +For working with the development branches (stability not guaranteed), check out the \exec{dtc/develop} branches of the repository (and submodules): +\begin{lstlisting}[language=bash] +git clone --recursive -b dtc/develop https://github.com/NCAR/gmtb-scm +\end{lstlisting} +You may want to double-check that the dtc/develop branch of the SCM is pointing to the latest commits of the dtc/develop branches of ccpp-physics and ccpp-framework. While we update the submodule pointers often, it is occasionally forgotten. To ensure that you have the latest development code for the submodules, execute the following: \begin{enumerate} - \item Check out the dtc/develop branch of gmtb-scm. +\item Navigate to the ccpp-physics directory. \begin{lstlisting}[language=bash] -git checkout dtc/develop +cd gmtb-scm/ccpp/physics \end{lstlisting} -\item Check out the dtc/develop branches of ccpp-physics and ccpp-framework. +\item Check out the right branch (cloning recursively as instructed above creates a ``detached head'' state for the submodules by default). \begin{lstlisting}[language=bash] -cd ccpp/physics git checkout dtc/develop +\end{lstlisting} +\item Pull down the latest changes just to be sure. +\begin{lstlisting}[language=bash] +git pull +\end{lstlisting} +\item Do the same for ccpp-framework +\begin{lstlisting}[language=bash] cd ../framework git checkout dtc/develop +git pull \end{lstlisting} \item Change back to the main directory for following the instructions in section \ref{section: compiling} assuming system requirements in section \ref{section: systemrequirements} are met. \begin{lstlisting}[language=bash] @@ -56,124 +69,174 @@ \section{System Requirements, Libraries, and Tools} \begin{itemize} \item FORTRAN 90+ compiler \begin{itemize} - \item ifort 18.0.1.163 and 19.0.2 - \item gfortran 6.2, 8.1, and 9.1 - \item pgf90 17.7 and 17.9 + \item ifort 18.0.5.274, 19.0.2 and 19.0.5 + \item gfortran 6.2, 8.3, and 9.2 \end{itemize} \item C compiler \begin{itemize} - \item icc 18.0.1.163 and 19.0.2 - \item gcc 6.2 and 8.1 - \item Apple Clang 10.0.0.10001145 - \item pgcc 17.7 and 17.9 + \item icc 18.0.5.274, 19.0.2 and 19.0.5 + \item gcc 6.2, 8.3, and 9.2 + \item Apple clang 11.0.0.11000033, LLVM clang 9.0.0 + \end{itemize} + \item cmake 2.8.12.1, 2.8.12.2, 3.6.2, 3.16.3, 3.16.4 + \begin{itemize} + \item NOTE: Version 3.15+ is required if installing NCEPLIBS \end{itemize} - \item cmake 2.8.12.1, 2.8.12.2, and 3.6.2 - \item netCDF 4.3.0, 4.4.0, 4.4.1.1, 4.5.0, 4.6.1 and 4.6.3 (not 3.x) with HDF5, ZLIB and SZIP - \item Python 2.7.5, 2.7.9, and 2.7.13 (not 3.x) - \item Libxml2 2.2, 2.9.7, 2.9.9 + \item netCDF 4.3.0, 4.4.0, 4.4.1.1, 4.5.0, 4.6.1, 4.6.3, 4.7.0, 4.7.3 (not 3.x) with HDF5 and ZLIB + \item Python 2.7.5, 2.7.9, 2.7.13, and 2.7.16 (not 3.x) with f90nml module (and Shapely if using the \execout{UFS\_IC\_generator.py} script) \end{itemize} -Because these tools and libraries are typically the purview of system administrators to install and maintain, they are considered part of the basic system requirements. +Because these tools and libraries are typically the purview of system administrators to install and maintain, they are considered part of the basic system requirements. The Unified Forecast System (UFS) Medium-Range Weather Application release v1.0.0 of March 11, 2020, provides software packages and detailed instructions to install these prerequisites and the NCEPlibs on supported platforms (see section~\ref{section: setup_supported_platforms}). -Further, there are several utility libraries as part of the NCEPlibs package that must be installed prior to building the SCM. +Further, there are several utility libraries as part of the NCEPlibs package that must be installed with environment variables pointing to their locations prior to building the SCM. \begin{itemize} \item bacio - Binary I/O Library \item sp - Spectral Transformation Library \item w3nco - GRIB decoder and encoder library \end{itemize} -These libraries are prebuilt on most NOAA machines using the Intel compiler. For those needing to build the libraries themselves, GMTB recommends using the source code from GitHub at \url{https://github.com/NCAR/NCEPlibs}, which includes build files for various compilers and machines using OpenMP flags and which are threadsafe. Instructions for installing NCEPlibs are included on the GitHub repository webpage, but for the sake of example, execute the following for obtaining and building from source in \execout{/usr/local/NCEPlibs} on a Mac: -\begin{lstlisting} - mkdir /usr/local/NCEPlibs - cd /usr/local/src - git clone https://github.com/NCAR/NCEPlibs.git - cd NCEPlibs - ./make_ncep_libs.sh -s macosx -c gnu -d /usr/local/NCEPlibs -o 1 -m 0 -\end{lstlisting} -Note that the option \execout{-m 0} can be used if MPI is not installed on the machine that is being used. The \execout{nemsio} library will not be installed, however, since it requires MPI. Once NCEPlibs is built, the \execout{NCEPLIBS\_DIR} environment variable must be set to the location of the installation. For example, if NCEPlibs was installed in \execout{/usr/local/NCEPlibs}, one would execute -\begin{lstlisting} -export NCEPLIBS_DIR=/usr/local/NCEPlibs -\end{lstlisting} -If using Hera or Cheyenne HPC systems, this environment variable is automatically set to an appropriate installation of NCEPlibs on those machines through use of one of the setup scripts described in section \ref{section: compiling}. - +The following environment variables are used by the build system to properly link these libraries: \execout{BACIO\_LIB4}, \execout{SP\_LIBd}, and \execout{W3NCO\_LIBd}. Computational platforms in which the NCEPLIBS are prebuilt and installed in a central location are referred to as preconfigured platforms. Examples of preconfigured platforms are most NOAA high-performance computing machines (using the Intel compiler) and the NCAR Cheyenne system (using the Intel and GNU compilers). The machine setup scripts mentioned in section \ref{section: compiling} load these libraries (which are identical to those used by the UFS Medium Range Weather Application on those machines) and set these environment variables for the user automatically. For installing the libraries and its prerequisites on supported platforms, existing UFS packages can be used (see section~\ref{section: setup_supported_platforms}). \subsection{Compilers} The CCPP and SCM have been tested on a variety of computing platforms. Currently the CCPP system is actively supported -on Linux and MacOS computing platforms using the Intel, PGI or GNU Fortran +on Linux and MacOS computing platforms using the Intel or GNU Fortran compilers. Please use versions listed in the previous section as unforeseen build issues may occur when using older compiler versions. Typically the best results come from using the most recent version of a compiler. If you have problems with compilers, please check the ``Known Issues'' section of the -community website (\url{https://dtcenter.org/gmtb/users/ccpp/support/CCPP_KnownIssues.php}). +release website (\url{https://dtcenter.org/community-code/common-community-physics-package-ccpp/download}). -\section{Compiling SCM with CCPP} -\label{section: compiling} -The first step in compiling the CCPP and SCM is to properly setup your user environment. Platform-specific scripts are provided to load modules and set the user environment for common platforms. If you are not using one of these platforms, you will need to set up the same environment on your platform. Following this step, the top level build system will use \execout{cmake} to query system parameters, execute the CCPP prebuild script to match the physics variables (between what the host model -- SCM -- can provide and what is needed by physics schemes in the CCPP), and build the physics caps needed to use them. Finally, \execout{make} is used to compile the components. -\begin{enumerate} - \item Change directory to the top-level SCM directory. +\subsection{Installing Libraries on Supported Platforms}\label{section: setup_supported_platforms} +For users on supported platforms such as generic Linux or macOS systems, the UFS Medium-Range Weather Application v1.0.0 release provides software packages and detailed setup instructions at \url{https://github.com/NOAA-EMC/NCEPLIBS-external/tree/ufs-v1.0.0} and \url{https://github.com/NOAA-EMC/NCEPLIBS/tree/ufs-v1.0.0}. UFS users who already installed the \execout{NCEPLIBS} package only need to set the compiler environment variables as indicated in the relevant \execout{README\_*.txt} file in \url{https://github.com/NOAA-EMC/NCEPLIBS-external/tree/ufs-v1.0.0/doc/} and source the shell script that is created by the \execout{NCEPLIBS} install process to set the required environment variables for compiling the SCM. + +The SCM uses only a small part of the UFS \execout{NCEPLIBS} package and has fewer prerequisites (i.e. no \execout{ESMF} or \execout{wgrib2} needed). Users who are not planning to use the UFS can follow the machine setup instructions in the relevant \execout{README*.txt} files in \url{https://github.com/NOAA-EMC/NCEPLIBS-external/tree/ufs-v1.0.0/doc} and, instead of installing \execout{NCEPLIBS-external} and \execout{NCEPLIBS}, install only NetCDF/NetCDF-Fortran manually or using the software package manager (\execout{apt}, \execout{yum}, \execout{brew}). + +\textbf{Note.} On macOS systems, it may be necessary to add the (future) location of the NetCDF libraries \execout{libnetcdf.dylib} and \execout{libnetcdff.dylib} to the \execout{rpath} linker flags before compiling the NetCDF/NetCDF-Fortran libraries. Execute the following command before running \execout{configure} and \execout{make} for \execout{netcdf-c} and \execout{netcdf-fortran}: \begin{lstlisting}[language=bash] -cd scm +export LDFLAGS="-L/dir/where/libnetcdf/and/libnetcdff/live -Wl,-rpath,/dir/where/libnetcdf/and/libnetcdff/live" +\end{lstlisting} + +Users need to set the compiler enviroment variables \execout{CC}, \execout{CXX}, \execout{FC} and the environment variable \execout{NETCDF} for compiling the three NCEP libraries (instead of the \execout{NCEPLIBS} umbrella build referred to in the \execout{NCEPLIBS-external} instructions) and the SCM. + +Installing the NCEP libraries: The SCM repository contains a bash installation script in \execout{gmtb-scm/contrib/build\_nceplibs.sh} that will fetch the source code of the three required NCEP libraries from their authoritative repositories on GitHub and install them locally for the SCM to use. To execute this script, perform the following step from the top level directory (\execout{gmtb-scm}). +\begin{lstlisting} +./contrib/build_nceplibs.sh /path/to/nceplibs +\end{lstlisting} + +Following successful execution of this script, the commands to set the proper environment variables mentioned above will be written to the terminal as output. One must execute the correct set for the active shell to finish the installation, e.g., for bash +\begin{lstlisting} +export BACIO_LIB4=/path/to/nceplibs/lib/libbacio_v2.2.0_4.a +export SP_LIBd=/path/to/nceplibs/lib/libsp_v2.1.0_d.a +export W3NCO_LIBd=/path/to/nceplibs/lib/libw3nco_v2.1.0_d.a \end{lstlisting} - \item (Optional) Run the machine setup script if necessary. This script loads compiler modules (Fortran 2003-compliant), netCDF module, etc. and sets compiler environment variables. For \textit{t/csh} shells, +and for t/csh +\begin{lstlisting} +setenv BACIO_LIB4 /path/to/nceplibs/lib/libbacio_v2.2.0_4.a +setenv SP_LIBd /path/to/nceplibs/lib/libsp_v2.1.0_d.a +setenv W3NCO_LIBd /path/to/nceplibs/lib/libw3nco_v2.1.0_d.a +\end{lstlisting} + +The installation of NCEPLIBS requires \execout{cmake} v3.15+. There are many ways to obtain the required version, either by following instructions provided by \execout{cmake} (\url{https://cmake.org/install/}), or by following the instructions provided for the UFS Medium-Range Weather Application release (\url{https://github.com/NOAA-EMC/NCEPLIBS-external/tree/ufs-v1.0.0}). Prepend this installation directory of \execout{cmake} to your path environment variable to use it for building the NCEPLIBS. + +The Python environment must provide the \execout{f90nml} module for the SCM scripts to function. Users can test if f90nml is installed using this command in the shell: +\begin{lstlisting} +python -c "import f90nml" +\end{lstlisting} +If \execout{f90nml} is installed, this command will succeed silently, otherwise an \execout{ImportError: No module named f90nml} will be printed to screen. To install the \execout{f90nml} (v0.19) Python module, use the install method preferred for your Python environment (one of the following): +\begin{itemize} +\item +\begin{lstlisting} +easy_install f90nml==0.19 +\end{lstlisting} +\end{itemize} +\begin{itemize} +\item +\begin{lstlisting} +pip install f90nml==0.19 +\end{lstlisting} +\end{itemize} +\begin{itemize} +\item +\begin{lstlisting} +conda install f90nml=0.19 +\end{lstlisting} +\end{itemize} + +or perform the following steps to install it manually from source: +\begin{lstlisting} +cd /directory/with/write/priveleges +git clone -b v0.19 https://github.com/marshallward/f90nml +cd f90nml +python setup.py install [--prefix=/my/install/directory or --user] +\end{lstlisting} +The directory \execout{/my/install/directory} must exist and its subdirectory \execout{/my/install/directory/lib/python2.7/site-packages} (or \execout{lib64} instead of \execout{lib}, depending on the system) must be in the \execout{PYTHONPATH} environment variable. + +\subsection{Using Existing Libraries on Preconfigured Platforms}\label{section: use_preconfigured_platforms} +Platform-specific scripts are provided to load modules and set the user environment for preconfigured platforms. These scripts load compiler modules (Fortran 2003-compliant), the netCDF module, Python environment, etc. and set compiler and NCEPlibs environment variables. From the top-level code directory (\execout{gmtb-scm} by default), source the correct script for your platform and shell. For \textit{t/csh} shells, \begin{lstlisting}[language=csh] -source etc/Hera_setup_intel.csh -source etc/Cheyenne_setup_gnu.csh -source etc/Cheyenne_setup_intel.csh -source etc/Cheyenne_setup_pgi.csh -source etc/UBUNTU_setup.csh -source etc/CENTOS_setup.csh -source etc/MACOSX_setup.csh +source scm/etc/Hera_setup_intel.csh +source scm/etc/Cheyenne_setup_gnu.csh +source scm/etc/Cheyenne_setup_intel.csh \end{lstlisting} For bourne/bash shells, \begin{lstlisting}[language=bash] -. etc/Hera_setup_intel.sh -. etc/Cheyenne_setup_gnu.sh -. etc/Cheyenne_setup_intel.sh -. etc/Cheyenne_setup_pgi.sh -. etc/UBUNTU_setup.sh -. etc/CENTOS_setup.sh -. etc/MACOSX_setup.sh +. scm/etc/Hera_setup_intel.sh +. scm/etc/Cheyenne_setup_gnu.sh +. scm/etc/Cheyenne_setup_intel.sh \end{lstlisting} -\emph{Note:} If using a local Linux or Mac system, we provide instructions for how to set up your development system (compilers and libraries) in \execout{doc/README\_\{MACOSX,UBUNTU,CENTOS\}.txt}. If following these, you will need to run the respective setup script listed above. If your computing environment was previously set up to use modern compilers with an associated netCDF installation, it may not be necessary, although we recommend setting environment variables such as \execout{CC} and \execout{FC}. \textbf{For version 3.0 and above, it is required to have the \execout{NETCDF} environment variable set to the path of the netCDF installation that was compiled with the same compiler used in the following steps}. Otherwise, the \execout{cmake} step will not complete successfully. - \item Make a build directory and change into it. +\section{Compiling SCM with CCPP} +\label{section: compiling} +The first step in compiling the CCPP and SCM is to properly setup your user environment as described in sections~\ref{section: setup_supported_platforms} and~\ref{section: use_preconfigured_platforms}. The second step is to download the lookup tables (large binaries, $~$324\,MB) for the Thompson microphysics package and place them in the correct directory: +From the top-level code directory (\execout{gmtb-scm} by default), execute the following script: \begin{lstlisting}[language=bash] -mkdir bin && cd bin +./contrib/get_thompson_tables.sh \end{lstlisting} +If the download step fails, make sure that your system's firewall does not block access to GitHub. If it does, download the file \execout{thompson\_tables.tar} from the GitHub release website using your browser and manually extract its contents in the directory \execout{scm/data/physics\_input\_data/}. - \item Invoke cmake on the source code to build. +Following this step, the top level build system will use \execout{cmake} to query system parameters, execute the CCPP prebuild script to match the physics variables (between what the host model -- SCM -- can provide and what is needed by physics schemes in the CCPP), and build the physics caps needed to use them. Finally, \execout{make} is used to compile the components. +\begin{enumerate} + \item From the top-level code directory (\execout{gmtb-scm} by default), change directory to the top-level SCM directory. \begin{lstlisting}[language=bash] -cmake ../src # without threading/OpenMP -cmake -DOPENMP=ON ../src # with threading/OpenMP -cmake -DCMAKE_BUILD_TYPE=Debug ../src # debug mode -cmake -DSTATIC=ON ../src. #static mode +cd scm \end{lstlisting} -Cmake automatically runs the CCPP prebuild script to match required physics variables with those available from the dycore (SCM) and to generate physics caps and makefile segments. The default behavior is to use the so-called ``dynamic'' mode where software caps for all schemes in the CCPP repository are generated and a dynamic, shared library is generated for the CCPP physics. A second, more performant ``static'' mode is available that generates software caps for each physics group defined in the supplied SDFs and generates a static library that becomes part of the SCM executable. Using this mode, flexibility of defining suites at runtime is lost, although one can choose among a set of suites defined at compilation time. Adding the cmake variable \exec{-DSTATIC=ON} will turn this feature on and appropriate software caps will be generated for all suites defined in the \execout{gmtb-scm/ccpp/suites} directory automatically. - -If necessary, the CCPP prebuild script can be executed manually from the top level directory (\execout{gmtb-scm}). The basic syntax for the dynamic mode is +\item Make a build directory and change into it. \begin{lstlisting}[language=bash] -./ccpp/framework/scripts/ccpp_prebuild.py --config=./ccpp/config/ccpp_prebuild_config.py --builddir=./scm/bin [--debug] +mkdir bin && cd bin \end{lstlisting} -To use the static mode, the syntax becomes +\item Invoke \exec{cmake} on the source code to build using one of the options below. +\begin{itemize} +\item Default mode \begin{lstlisting}[language=bash] -./ccpp/framework/scripts/ccpp_prebuild.py --config=./ccpp/config/ccpp_prebuild_config.py --static --suites=SCM_GFS_v15p2,SCM_GFS_v16beta,SCM_GSD_v1[...] --builddir=./scm/bin [--debug] +cmake ../src \end{lstlisting} -where the argument supplied via the \execout{-{}-suites} variable is a comma-separated list of suite names that exist in the \execout{./ccpp/suites} directory. Note that suite names are the suite definition filenames minus the \exec{suite\_} prefix and \exec{.xml} suffix. - - \item If cmake cannot find \execout{libxml2} because it is installed in a non-standard location, add +\item The statements above can be modified with the following options (put before \execout{../src}): +\begin{itemize} +\item Use threading with openmp (not for macOS with clang+gfortran) \begin{lstlisting}[language=bash] --DPC_LIBXML_INCLUDEDIR=... -DPC_LIBXML_LIBDIR=... +-DOPENMP=ON \end{lstlisting} - to the cmake command. If a compilation error appears related to \execout{libxml2}, namely that a unicode file is not found in the include path, add the appropriate include path to the \execout{CFLAGS} environment variable +\item Debug mode \begin{lstlisting}[language=bash] -export CFLAGS="-I/include_path" -\end{lstlisting} before cleaning out the \execout{bin} directory and rerunning \execout{cmake}. - \item Compile. Add \execout{VERBOSE=1} to obtain more information on the build process. +-DCMAKE_BUILD_TYPE=Debug +\end{lstlisting} +\end{itemize} +\end{itemize} + +CMake automatically runs the CCPP prebuild script to match required physics variables with those available from the dycore (SCM) and to generate physics caps and makefile segments. It generates software caps for each physics group defined in the supplied Suite Definition Files (SDFs) and generates a static library that becomes part of the SCM executable. Appropriate software caps \textbf{will be generated for all suites defined in the \execout{gmtb-scm/ccpp/suites} directory automatically.} + +If necessary, the CCPP prebuild script can be executed manually from the top level directory (\execout{gmtb-scm}). The basic syntax is +\begin{lstlisting}[language=bash] +./ccpp/framework/scripts/ccpp_prebuild.py --config=./ccpp/config/ccpp_prebuild_config.py --static --suites=SCM_GFS_v15p2,SCM_GFS_v16beta,SCM_GSD_v1[...] --builddir=./scm/bin [--debug] +\end{lstlisting} +where the argument supplied via the \execout{-{}-suites} variable is a comma-separated list of suite names that exist in the \execout{./ccpp/suites} directory. Note that suite names are the suite definition filenames minus the \exec{suite\_} prefix and \exec{.xml} suffix. + +\item Compile. Add \execout{VERBOSE=1} to obtain more information on the build process. \begin{lstlisting}[language=bash] make \end{lstlisting} \end{enumerate} -The resulting executable may be found at \execout{./gmtb-scm} (Full path of \execout{gmtb-scm/scm/bin/gmtb-scm}). Depending on the system, it may be necessary to add the location of the CCPP framework and physics libraries to \execout{LD\_LIBRARY\_PATH} to run \execout{./gmtb-scm} (see next section). +The resulting executable may be found at \execout{./gmtb-scm} (Full path of \execout{gmtb-scm/scm/bin/gmtb-scm}). Although \execout{make clean} is not currently implemented, an out-of-source build is used, so all that is required to clean the build/run directory is (from the \execout{bin} directory) \begin{lstlisting}[language=bash] @@ -185,60 +248,46 @@ \section{Compiling SCM with CCPP} If you encounter errors, please capture a log file from all of the steps, and contact the helpdesk at: \url{gmtb-help@ucar.edu} \section{Run the SCM with a supplied case} -There are several test cases provided with this version of the SCM. For all cases, the SCM will go through the time steps, applying forcing and calling the physics defined in the chosen suite definition file using physics configuration options from an associated namelist. The model is executed through one of two Python run scripts that are pre-staged into the \execout{bin} directory: \execout{run\_gmtb\_scm.py} or \execout{multi\_run\_gmtb\_scm.py}. The first sets up and runs one integration while the latter will set up and run several integrations serially. +There are several test cases provided with this version of the SCM. For all cases, the SCM will go through the time steps, applying forcing and calling the physics defined in the chosen suite definition file using physics configuration options from an associated namelist. The model is executed through one of two Python run scripts that are pre-staged into the \execout{bin} directory: \execout{run\_gmtb\_scm.py} or \execout{multi\_run\_gmtb\_scm.py}. The first sets up and runs one integration while the latter will set up and run several integrations serially. \subsection{Single Run Script Usage} \label{subsection: singlerunscript} Running a case requires three pieces of information: the case to run (consisting of initial conditions, geolocation, forcing data, etc.), the physics suite to use (through a CCPP suite definition file), and a physics namelist (that specifies configurable physics options to use). As discussed in chapter \ref{chapter: cases}, cases are set up via their own namelists in \execout{../etc/case\_config}. A default physics suite is provided as a user-editable variable in the script and default namelists are associated with each physics suite (through \execout{../src/default\_namelists.py}), so, technically, one must only specify a case to run with the SCM. The single run script's interface is described below. \begin{lstlisting}[language=bash] -./run_gmtb_scm.py -c CASE_NAME [-s SUITE_NAME] [-n PHYSICS_NAMELIST_WITH_PATH] [-g] +./run_gmtb_scm.py -c CASE_NAME [-s SUITE_NAME] [-n PHYSICS_NAMELIST_WITH_PATH] [-g] [-d] \end{lstlisting} -When invoking the run script, the only required argument is the name of the case to run. The case name used must match one of the case configuration files located in \execout{../etc/case\_config} (\emph{without the .nml extension!}). If specifying a suite other than the default, the suite name used must match the value of the suite name in one of the suite definition files located in \execout{../../ccpp/suites} (Note: not the filename of the suite definition file). As part of the third CCPP release, the following suite names are valid: +When invoking the run script, the only required argument is the name of the case to run. The case name used must match one of the case configuration files located in \execout{../etc/case\_config} (\emph{without the .nml extension!}). If specifying a suite other than the default, the suite name used must match the value of the suite name in one of the suite definition files located in \execout{../../ccpp/suites} (Note: not the filename of the suite definition file). As part of the fourth CCPP release, the following suite names are valid: \begin{enumerate} -\item SCM\_GFS\_v15 -\item SCM\_GFS\_v15plus +\item SCM\_GFS\_v15p2 +\item SCM\_GFS\_v16beta +\item SCM\_GFS\_v15p2\_no\_nsst +\item SCM\_GFS\_v16beta\_no\_nsst \item SCM\_csawmg -\item SCM\_GSD\_v0 +\item SCM\_GSD\_v1 \end{enumerate} -Note that using the Thompson microphysics scheme (as in SCM\_GSD\_v0) requires the computation of look-up tables during its initialization phase. As of the release, this process has been prohibitively slow with this model, so it is HIGHLY suggested that these look-up tables are downloaded and staged to use this scheme (and the SCM\_GSD\_v0 suite). Pre-computed tables have been created and are available for download at the following URLs: -\begin{itemize} -\item \url{https://dtcenter.org/GMTB/freezeH2O.dat} (243 M) -\item \url{https://dtcenter.org/GMTB/qr_acr_qg.dat} (49 M) -\item \url{https://dtcenter.org/GMTB/qr_acr_qs.dat} (32 M) -\end{itemize} -These files should be staged in \execout{gmtb-scm/scm/data/physics\_input\_data} prior to executing the run script. Since binary files can be system-dependent (due to endianness), it is possible that these files will not be read correctly on your system. For reference, the linked files were generated on Theia using the Intel v18 compiler. +Note that using the Thompson microphysics scheme (as in SCM\_GSD\_v1) requires the computation of look-up tables during its initialization phase. As of the release, this process has been prohibitively slow with this model, so it is HIGHLY suggested that these look-up tables are downloaded and staged to use this scheme (and the SCM\_GSD\_v1 suite) as described in section~\ref{section: compiling}. Also note that some cases require specified surface fluxes. Special suite definition files that correspond to the suites listed above have been created and use the \execout{*\_prescribed\_surface} decoration. It is not necessary to specify this filename decoration when specifying the suite name. If the \execout{spec\_sfc\_flux} variable in the configuration file of the case being run is set to \execout{.true.}, the run script will automatically use the special suite definition file that corresponds to the chosen suite from the list above. -If specifying a namelist other than the default, the value must be an entire filename that exists in \execout{../../ccpp/physics\_namelists}. Caution should be exercised when modifying physics namelists since some redundancy between flags to control some physics parameterizations and scheme entries in the CCPP suite definition files currently exists. Values of numerical parameters are typically OK to change without fear of inconsistencies. Lastly, the \execout{-g} flag can be used to run the executable through the \exec{gdb} debugger (assuming it is installed on the system). - -If the run aborts with the error message -\begin{lstlisting}[language=bash] -gmtb_scm: libccppphys.so.X.X.X: cannot open shared object file: No such file or directory -\end{lstlisting} -the environment variable \execout{LD\_LIBRARY\_PATH} must be set to -\begin{lstlisting}[language=bash] -export LD_LIBRARY_PATH=$PWD/ccpp/physics:$LD_LIBRARY_PATH -\end{lstlisting} -before running the model. +If specifying a namelist other than the default, the value must be an entire filename that exists in \execout{../../ccpp/physics\_namelists}. Caution should be exercised when modifying physics namelists since some redundancy between flags to control some physics parameterizations and scheme entries in the CCPP suite definition files currently exists. Values of numerical parameters are typically OK to change without fear of inconsistencies. Lastly, the \execout{-g} flag can be used to run the executable through the \exec{gdb} debugger (assuming it is installed on the system), and the \execout{-d} flag is required when running this command in a Docker container in order to successfully mount a volume between the host machine and the Docker container instance and to share the output and plots with the host machine. A netCDF output file is generated in the location specified in the case -configuration file, if the \execout{output\_dir} variable exists in that file. Otherwise an output directory is constructed from the case, suite, and namelist used (if different from the default). All output directories are placed in the \execout{bin} directory. Any standard netCDF file viewing or analysis tools may be used to +configuration file, if the \execout{output\_dir} variable exists in that file. Otherwise an output directory is constructed from the case, suite, and namelist used (if different from the default). All output directories are placed in the \execout{bin} directory. If using a Docker container, all output is copied to the \execout{/home} directory in container space for volume-mounting purposes. Any standard netCDF file viewing or analysis tools may be used to examine the output file (ncdump, ncview, NCL, etc). -\subsection{Multiple Run Script Usage} +\subsection{Multiple Run Script Usage}\label{subsection: multirunscript} A second Python script is provided for automating the execution of multiple integrations through repeated calling of the single run script. From the run directory, one may use this script through the following interface. \begin{lstlisting}[language=bash] -./multi_run_gmtb_scm.py {[-c CASE_NAME] [-s SUITE_NAME] [-f PATH_TO_FILE]} [-v{v}] [-t] +./multi_run_gmtb_scm.py {[-c CASE_NAME] [-s SUITE_NAME] [-f PATH_TO_FILE]} [-v{v}] [-t] [-d] \end{lstlisting} No arguments are required for this script. The \execout{-c or --case}, \execout{-s or --suite}, or \execout{-f or --file} options form a mutually-exclusive group, so exactly one of these is allowed at one time. If \execout{--c} is specified with a case name, the script will run a set of integrations for all supported suites (defined in \execout{../src/supported\_suites.py}) for that case. If \execout{-s} is specified with a suite name, the script will run a set of integrations for all supported cases (defined in \execout{../src/supported\_cases.py}) for that that suite. If \execout{-f} is specified with the path to a filename, it will read in lists of cases, suites, and namelists to use from that file. An example for this file's syntax can be found in \execout{../src/example\_multi\_run.py}. If multiple namelists are specified in the file, there either must be one suite specified \emph{or} the number of suites must match the number of namelists. If none of the \execout{-c or --case}, \execout{-s or --suite}, or \execout{-f or --file} options group is specified, the script will run through all permutations of supported cases and suites (as defined in the files previously mentioned). -In addition to the main options, some helper options can also be used with any of those above. The \execout{-v{v} or --verbose} option can be used to output more information from the script to the console and to a log file. If this option is not used, only completion progress messages are written out. If one \execout{-v} is used, the script will write out completion progress messages and all messages and output from the single run script. If two \execout{-vv} are used, the script will also write out all messages and single run script output to a log file (\execout{multi\_run\_gmtb\_scm.log}) in the \execout{bin} directory. The final option, \execout{-t or --timer}, can be used to output the elapsed time for each integration executed by the script. Note that the execution time includes file operations performed by the single run script in addition to the execution of the underlying (Fortran) SCM executable. By default, this option will execute one integration of each subprocess. Since some variability is expected for each model run, if greater precision is required, the number of integrations for timing averaging can be set through an internal script variable. This option can be useful, for example, for getting a rough idea of relative computational expense of different physics suites. +In addition to the main options, some helper options can also be used with any of those above. The \execout{-v{v} or --verbose} option can be used to output more information from the script to the console and to a log file. If this option is not used, only completion progress messages are written out. If one \execout{-v} is used, the script will write out completion progress messages and all messages and output from the single run script. If two \execout{-vv} are used, the script will also write out all messages and single run script output to a log file (\execout{multi\_run\_gmtb\_scm.log}) in the \execout{bin} directory. The option, \execout{-t or --timer}, can be used to output the elapsed time for each integration executed by the script. Note that the execution time includes file operations performed by the single run script in addition to the execution of the underlying (Fortran) SCM executable. By default, this option will execute one integration of each subprocess. Since some variability is expected for each model run, if greater precision is required, the number of integrations for timing averaging can be set through an internal script variable. This option can be useful, for example, for getting a rough idea of relative computational expense of different physics suites. Finally, the \execout{-d} flag is required when running this command in a Docker container in order to successfully mount a volume between the host machine and the Docker container instance and to share the output and plots with the host machine. \subsection{Batch Run Script} @@ -248,4 +297,110 @@ \subsection{Batch Run Script} \end{lstlisting} from the \execout{bin} directory. -Additional details regarding the SCM may be found in the remainder of this guide. More information on the CCPP can be found in the CCPP Technical Documentation available at \url{https://dtcenter.org/GMTB/v3.0/ccpp\_tech\_guide/}. +Additional details regarding the SCM may be found in the remainder of this guide. More information on the CCPP can be found in the CCPP Technical Documentation available at \url{https://ccpp-techdoc.readthedocs.io/en/v4.0/}. + +\section{Creating and Using a Docker Container with SCM and CCPP} +\label{docker} + +In order to run a precompiled version of the CCPP SCM in a container, Docker will need to be available on your machine. Please visit \url{https://www.docker.com} to download and install the version compatible with your system. Docker frequently releases updates to the software; it is recommended to apply all available updates. NOTE: In order to install Docker on your machine, you will be required to have root access privileges. More information about getting started can be found at \url{https://docs.docker.com/get-started} + +The following tips were acquired during a recent installation of Docker on a machine with Windows 10 Home Edition. Further help should be obtained from your system administrator or, lacking other resources, an internet search. + +\begin{itemize} +\item Windows 10 Home Edition does not support Docker Desktop due to lack of ``Hyper-V'' support, but does work with Docker Toolbox. See the installation guide (\url{https://docs.docker.com/toolbox/toolbox_install_windows/}). +\item You may need to turn on your CPU's hardware virtualization capability through your system's BIOS. +\item After a successful installation of Docker Toolbox, starting with Docker Quickstart may result in the following error even with virtualization correctly enabled: \execout{This computer doesn’t have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory}. We were able to bypass this error by opening a bash terminal installed with Docker Toolbox, navigating to the directory where it was installed, and executing the following command: +\begin{lstlisting}[language=bash] +docker-machine create default --virtualbox-no-vtx-check +\end{lstlisting} +\end{itemize} + +\subsection{Building the Docker image} + +The Dockerfile builds CCPP SCM v4.0 from source using the GNU compiler. A number of required codes are built and installed via the DTC-supported common community container. For reference, the common community container repository can be accessed here: \url{https://github.com/NCAR/Common-Community-Container}. + +The CCPP SCM has a number of system requirements and necessary libraries and tools. Below is a list, including versions, used to create the the GNU-based Docker image: +\begin{itemize} +\item gfortran - 8.3.1 +\item gcc - 8.3.1 +\item cmake - 3.16.5 +\item netCDF - 4.6.2 +\item HDF5 - 1.10.4 +\item ZLIB - 1.2.7 +\item SZIP - 2.1.1 +\item Python - 2.7.5 +\item NCEPLIBS subset: bacio v2.2.0\_4, sp v2.1.0\_d, w3nco v2.1.0\_d +\end{itemize} + +A Docker image containing the SCM, CCPP, and its software prerequisites can be generated from the code in the software repository obtained by following section \ref{obtaining_code} by executing the following steps: + +NOTE: Windows users can execute these steps in the terminal application that was installed as part of Docker Toolbox. + +\begin{enumerate} +\item Navigate to the \execout{gmtb-scm/docker} directory. +\item Run the \execout{docker build} command to generate the Docker image, using the supplied Dockerfile. +\begin{lstlisting}[language=bash] +docker build -t ccpp-scm . +\end{lstlisting} +Inspect the Dockerfile if you would like to see details for how the image is built. The image will contain SCM prerequisite software from DTC, the SCM and CCPP code, and a pre-compiled executable for the SCM with the 6 supported suites for the SCM. A successful build will show two images: dtcenter/common-community-container, and ccpp-scm. To list images, type: +\begin{lstlisting}[language=bash] +docker images +\end{lstlisting} +\end{enumerate} + +\subsection{Using a prebuilt Docker image from Dockerhub} + +A prebuilt Docker image for this release is available on Dockerhub if it is not desired to build from source. In order to use this, execute the following from the terminal where Docker is run: +\begin{lstlisting}[language=bash] +docker pull dtcenter/ccpp-scm:v4.0.0 +\end{lstlisting} +To verify that it exists afterward, run +\begin{lstlisting}[language=bash] +docker images +\end{lstlisting} + +\subsection{Running the Docker image} + +NOTE: Windows users can execute these steps through the Docker Quickstart application installed with Docker Toolbox. + +\begin{enumerate} +\item Set up a directory that will be shared between the host machine and the Docker container. When set up correctly, it will contain output generated by the SCM within the container for manipulation by the host machine. For Mac/Linux, +\begin{lstlisting}[language=bash] +mkdir -p /path/to/output +\end{lstlisting} +For Windows, you can try to create a directory of your choice to mount to the container, but it may not work or require more configuration, depending on your particular Docker installation. We have found that Docker volume mounting in Windows can be difficult to set up correctly. One method that worked for us was to create a new directory under our local user space, and specifying the volume mount as below. In addition, with Docker Toolbox, double check that the mounted directory has correct permissions. For example, open VirtualBox, right click on the running virtual machine, and choose ``Settings''. In the dialog that appears, make sure that the directory you're trying to share shows up in ``Shared Folders" (and add it if it does not) and make sure that the ``auto-mount" and ``permanent" options are checked. +\item Set an environment variable to use for your SCM output directory. For \textit{t/csh} shells, +\begin{lstlisting}[language=bash] +setenv OUT_DIR /path/to/output +\end{lstlisting} +For bourne/bash shells, +\begin{lstlisting}[language=bash] +export OUT_DIR=/path/to/output +\end{lstlisting} +For Windows, the format that worked for us followed this example: \execout{/c/Users/my username/path/to/directory/to/mount} +\item To run the SCM, you can run the Docker container that was just created and give it the same run commands as discussed in sections \ref{subsection: singlerunscript} and \ref{subsection: multirunscript}. \textbf{Be sure to remember to include the \execout{-d} option for all run commands}. For example, +\begin{lstlisting}[language=bash] +docker run --rm -it -v ${OUT_DIR}:/home --name run-ccpp-scm ccpp-scm ./run_gmtb_scm.py -c twpice -d +\end{lstlisting} +will run through the TWPICE case using the default suite and namelist and put the output in the shared directory. NOTE: Windows users may need to omit the curly braces around environment variables: use \execout{\$OUT\_DIR} instead of \execout{\$\{OUT\_DIR\}}. For running through all supported cases and suites, use +\begin{lstlisting}[language=bash] +docker run --rm -it -v ${OUT_DIR}:/home --name run-ccpp-scm ccpp-scm ./multi_run_gmtb_scm.py -d +\end{lstlisting} +The options included in the above \execout{run} commands are the following: +\begin{itemize} +\item \execout{$--$rm} removes the container when it exits +\item \execout{-it} interactive mode with terminal access +\item \execout{-v} specifies the volume mount from host directory (outside container) to inside the container. Using volumes allows you to share data between the host machine and container. For running the SCM, the output is being mounted from \execout{/home} inside the container to the \execout{OUT\_DIR} on the host machine. Upon exiting the container, data mounted to the host machine will still be accessible. +\item \execout{$--$name} names the container. If no name is provided, the daemon will autogenerate a random string name. +\end{itemize} +NOTE: If you are using a prebuilt image from Dockerhub, substitute the name of the image that was pulled from Dockerhub in the commands above; i.e. instead of \execout{ccpp-scm} above, one would have \execout{dtcenter/ccpp-scm:v4.0.0}. +\item To use the SCM interactively, run non-default configurations, create plots, or even develop code, issue the following command: +\begin{lstlisting}[language=bash] +docker run --rm -it -v ${OUT_DIR}:/home --name run-ccpp-scm ccpp-scm /bin/bash +\end{lstlisting} +You will be placed within the container space and within the \execout{bin} directory of the SCM with a pre-compiled executable. At this point, one could use the run scripts as described in previous sections (remembering to include the \execout{-d} option on run scripts if output is to be shared with the host machine). To create plots, from within the \execout{bin} directory of the SCM in container space, issue the following command, with an appropriately configured \execout{*.ini} file, .i.e. +\begin{lstlisting}[language=bash] +./gmtb_scm_analysis.py twpice_all_suites.ini -d +\end{lstlisting} +NOTE: If developing, since the container is ephemeral, one should push their changes to a remote git repository to save them (i.e. a fork on GitHub.com). +\end{enumerate} diff --git a/scm/doc/TechGuide/chap_repo.tex b/scm/doc/TechGuide/chap_repo.tex index 6a016b652..b3ac507b7 100644 --- a/scm/doc/TechGuide/chap_repo.tex +++ b/scm/doc/TechGuide/chap_repo.tex @@ -2,16 +2,18 @@ \chapter{Repository} \label{chapter: repository} \section{What is included in the repository?} -The repository contains all code and data required to run the GMTB SCM (with the exception of large initialization tables for the Thompson microphysics scheme discussed in subsection \ref{subsection: singlerunscript}). It is functionally separated into 3 subdirectories representing the SCM model infrastructure (\execout{scm} directory), the CCPP infrastructure (\execout{ccpp/framework} directory), and the CCPP physics schemes (\execout{ccpp/physics} directory). The entire \execout{gmtb-scm} repository resides on Github's NCAR account, and the \execout{ccpp/framework} and \execout{ccpp/physics} directories are git submodules that point to repositories \execout{ccpp-framework} and \execout{ccpp-physics} on the same account. The structure of the entire repository is represented below. Note that the \execout{ccpp-physics} repository contains files needed for using the CCPP with the UFS Atmosphere host model that uses the Finite-Volume Cubed-Sphere (FV3) dynamical core, even though the use of CCPP with the UFS Atmosphere is not supported in this release. +The repository contains all code and data required to run the CCPP SCM (with the exception of large initialization tables for the Thompson microphysics scheme discussed in subsection \ref{subsection: singlerunscript}). It is functionally separated into 3 subdirectories representing the SCM model infrastructure (\execout{scm} directory), the CCPP infrastructure (\execout{ccpp/framework} directory), and the CCPP physics schemes (\execout{ccpp/physics} directory). The entire \execout{gmtb-scm} repository resides on Github's NCAR space, and the \execout{ccpp/framework} and \execout{ccpp/physics} directories are git submodules that point to repositories \execout{ccpp-framework} and \execout{ccpp-physics} on the same space. The structure of the entire repository is represented below. Note that the \execout{ccpp-physics} repository also contains files needed for using the CCPP with the UFS Atmosphere host model that uses the Finite-Volume Cubed-Sphere (FV3) dynamical core. {\small\justify \dirtree{% .1 gmtb-scm/. .2 ccpp/. + .3 config/\DTcomment{contains the CCPP prebuild configuration file}. .3 framework/. .4 cmake/\DTcomment{custom cmake code for building ccpp-framework}. .4 CMakeLists.txt\DTcomment{cmake configuration file for ccpp-framework}. - .4 doc/\DTcomment{doxygen configuration, output, and Technical Documentation}. + .4 CODEOWNERS\DTcomment{list of GitHub users with permission to merge}. + .4 doc/\DTcomment{doxygen configuration, output, and Technical Documentation (obsolete)}. .4 LICENSE. .4 README.md. .4 schemes/\DTcomment{contains schemes used for testing}. @@ -20,54 +22,46 @@ \section{What is included in the repository?} .4 test/\DTcomment{contains scripts and configurations for testing}. .4 tests\DTcomment{contains next-generation files for testing}. .3 physics/\DTcomment{contains all physics schemes}. - .4 CCPP\_CAPS.cmake\DTcomment{auto-generated cmake section for physics caps}. - .4 CCPP\_CAPS.mk\DTcomment{auto-generated makefile section for physics caps}. - .4 CCPP\_schemes.cmake\DTcomment{auto-generated cmake section for physics schemes}. - .4 CCPP\_schemes.mk\DTcomment{auto-generated makefile section for physics schemes}. .4 CMakeLists.txt\DTcomment{cmake configuration file for ccpp-physics}. + .4 CODEOWNERS\DTcomment{list of GitHub users with permission to merge}. .4 LICENSE. .4 pgifix.py. .4 physics/\DTcomment{contains all CCPP physics and interstitial schemes}. .5 docs/\DTcomment{contains CCPP physics doxygen documentation}. .4 README.md. - .4 stochastic\_physics\DTcomment{contains all stochastic physics code - FV3 only for now}. - .3 config/\DTcomment{contains the CCPP prebuild config}. - .3 suites/\DTcomment{contains suite definition files}. .3 physics\_namelists\DTcomment{contains physics namelist files associated with suites}. + .3 suites/\DTcomment{contains suite definition files}. + .2 CODEOWNERS\DTcomment{list of GitHub users with permission to merge}. + .2 contrib/. + .3 build\_nceplibs.sh\DTcomment{script for installing prerequisite NCEPLIBS locally}. + .3 get\_thompson\_tables.sh\DTcomment{script for downloading/extracting the Thompson lookup tables}. + .2 docker/. + .3 Dockerfile\DTcomment{contains Docker instructions for building the CCPP SCM image}. + .2 README.md. .2 scm/. .3 bin/\DTcomment{build directory (initially empty; populated by cmake)}. .3 data/. .4 comparison\_data/\DTcomment{contains data with which to compare SCM output}. - .4 GFS\_physics\_data/\DTcomment{contains data needed by the GFS physics suite}. + .4 physics\_input\_data/\DTcomment{contains data needed by the CCPP physics}. .4 processed\_case\_input/\DTcomment{contains initialization and forcing data for cases}. .4 raw\_case\_input/\DTcomment{contains case data to be processed by scripts}. - .4 vert\_coord\_data/\DTcomment{contains data to calculate vertical coordinates}. - .3 doc/\DTcomment{contains doxygen configuration file, images, and output}. - .4 html/\DTcomment{contains HTML output from doxygen}. - .4 README\_MACOSX.txt. - .4 README\_UBUNTU.txt. - .4 README\_CENTOS.txt. - .5 TechGuide/\DTcomment{contains LaTeX for this User's Guide}. + .4 vert\_coord\_data/\DTcomment{contains data to calculate vertical coordinates (from GSM-based GFS only)}. + .3 doc/\DTcomment{contains this User's/Technical Guide}. + .4 TechGuide/\DTcomment{contains LaTeX for this User's Guide}. .3 etc/\DTcomment{contains case configuration, machine setup scripts, and plotting scripts}. .4 case\_config/\DTcomment{contains case configuration files}. - .4 CENTOS\_setup.csh\DTcomment{setup script for CentOS Linux for csh, tcsh}. - .4 CENTOS\_setup.sh\DTcomment{setup script for CentOS Linux for sh, bash}. + .4 CENTOS\_docker\_setup.sh\DTcomment{contains machine setup for Docker container}. .4 Cheyenne\_setup\_gnu.csh\DTcomment{setup script for Cheyenne HPC for csh, tcsh}. .4 Cheyenne\_setup\_gnu.sh\DTcomment{setup script for Cheyenne HPC for sh, bash}. .4 Cheyenne\_setup\_intel.csh\DTcomment{setup script for Cheyenne HPC for csh, tcsh}. .4 Cheyenne\_setup\_intel.sh\DTcomment{setup script for Cheyenne HPC for sh, bash}. - .4 Cheyenne\_setup\_pgi.csh\DTcomment{setup script for Cheyenne HPC for csh, tcsh}. - .4 Cheyenne\_setup\_pgi.sh\DTcomment{setup script for Cheyenne HPC for sh, bash}. .4 gmtb\_scm\_slurm\_example.py\DTcomment{example QSUB run script}. - .4 MACOSX\_setup.csh\DTcomment{setup script for Mac OS X for csh, tcsh}. - .4 MACOSX\_setup.sh\DTcomment{setup script for Mac OS X for sh, bash}. + .4 Hera\_setup\_intel.csh\DTcomment{setup script for Theia HPC for csh, tcsh}. + .4 Hera\_setup\_intel.sh\DTcomment{setup script for Theia HPC for sh, bash}. .4 scripts/\DTcomment{Python scripts for setting up cases and plotting}. .5 f90nml.0.19/\DTcomment{f90nml Python package}. + .5 Shapely-1.7.0\DTcomment{Shapely Python package}. .5 plot\_configs/\DTcomment{plot configuration files}. - .4 Hera\_setup\_intel.csh\DTcomment{setup script for Theia HPC for csh, tcsh}. - .4 Hera\_setup\_intel.sh\DTcomment{setup script for Theia HPC for sh, bash}. - .4 UBUNTU\_setup.csh\DTcomment{setup script for Ubuntu Linux for csh, tcsh}. - .4 UBUNTU\_setup.sh\DTcomment{setup script for Ubuntu Linux for sh, bash}. .3 LICENSE.txt. .3 src/\DTcomment{source code for SCM infrastructure and Python run scripts}. }} diff --git a/scm/doc/TechGuide/main.pdf b/scm/doc/TechGuide/main.pdf index ae315d61d..a18457338 100644 Binary files a/scm/doc/TechGuide/main.pdf and b/scm/doc/TechGuide/main.pdf differ diff --git a/scm/doc/TechGuide/main.tex b/scm/doc/TechGuide/main.tex index 769fc9a06..308a0dbc8 100644 --- a/scm/doc/TechGuide/main.tex +++ b/scm/doc/TechGuide/main.tex @@ -8,7 +8,7 @@ \hypersetup{ pdfauthor={Grant Firl / Laurie Carson / Ligia Bernardet / Dom Heinzeller}, - pdftitle={Global Model Test Bed Single Column Model (SCM)}, + pdftitle={Common Community Physics Packaged (CCPP) Single Column Model (SCM)}, } \begin{document} diff --git a/scm/doc/TechGuide/title.tex b/scm/doc/TechGuide/title.tex index cf0a669e3..60cb350ce 100644 --- a/scm/doc/TechGuide/title.tex +++ b/scm/doc/TechGuide/title.tex @@ -5,19 +5,22 @@ \noindent \begin{center} -\textcolor{darkgray}{\bigsf Global Model Test Bed\\[0.5ex] Single Column Model (SCM)} +\textcolor{darkgray}{\bigsf Common Community Physics Package\\[0.5ex] Single Column Model (SCM)} \vspace*{1em}\par -\textcolor{darkgray}{\bigst User and Technical Guide\\[0.5ex] v3.0} +\textcolor{darkgray}{\bigst User and Technical Guide\\[0.5ex] v4.0} \vspace*{1em}\par -\large{June 2019}\\ +\large{March 2020}\\ -Grant Firl, Laurie Carson\\ +Grant Firl, Laurie Carson, Michelle Harrold\\ \textit{\small{National Center for Atmospheric Research and Developmental Testbed Center}}\\[4em] -Ligia Bernardet, Dom Heinzeller\\ -\textit{\small{NOAA/ESRL Global Systems Division, Developmental Testbed Center and CIRES/CU}}\\[4em] +Ligia Bernardet\\ +\textit{\small{NOAA/ESRL Global Systems Laboratory and Developmental Testbed Center}}\\[4em] + +Dom Heinzeller\\ +\textit{\small{NOAA/ESRL Global Systems Laboratory, Developmental Testbed Center and CIRES/CU}}\\[4em] \vspace{4em} diff --git a/scm/etc/CENTOS_docker_setup.sh b/scm/etc/CENTOS_docker_setup.sh new file mode 100755 index 000000000..854178cf8 --- /dev/null +++ b/scm/etc/CENTOS_docker_setup.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +echo "Setting environment variables for SCM-CCPP on CENTOS with gcc/gfortran" + +export CC=/opt/rh/devtoolset-8/root/usr/bin/gcc +export CXX=/opt/rh/devtoolset-8/root/usr/bin/g++ +export F77=/opt/rh/devtoolset-8/root/usr/bin/gfortran +export F90=/opt/rh/devtoolset-8/root/usr/bin/gfortran +export FC=/opt/rh/devtoolset-8/root/usr/bin/gfortran + +export NETCDF=/comsoftware/libs/netcdf + +echo "Running NCEPLIBS installation script for SCM-CCPP" +cd .. +./contrib/build_nceplibs.sh $PWD/nceplibs +cd scm diff --git a/scm/etc/CENTOS_setup.csh b/scm/etc/CENTOS_setup.csh deleted file mode 100755 index 2b8a58f1e..000000000 --- a/scm/etc/CENTOS_setup.csh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/tcsh - -echo "Setting environment variables for SCM-CCPP on CENTOS with gcc/gfortran" - -setenv CC /usr/local/bin/gcc -setenv CXX /usr/local/bin/g++ -setenv F77 /usr/local/bin/gfortran -setenv F90 /usr/local/bin/gfortran -setenv FC /usr/local/bin/gfortran - -setenv NETCDF /usr/local - diff --git a/scm/etc/CENTOS_setup.sh b/scm/etc/CENTOS_setup.sh deleted file mode 100755 index ba627d4ce..000000000 --- a/scm/etc/CENTOS_setup.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -echo "Setting environment variables for SCM-CCPP on CENTOS with gcc/gfortran" - -export CC=/usr/local/bin/gcc -export CXX=/usr/local/bin/g++ -export F77=/usr/local/bin/gfortran -export F90=/usr/local/bin/gfortran -export FC=/usr/local/bin/gfortran - -export NETCDF=/usr/local - diff --git a/scm/etc/Cheyenne_setup_gnu.csh b/scm/etc/Cheyenne_setup_gnu.csh index 5ba9f6971..e05643ba2 100755 --- a/scm/etc/Cheyenne_setup_gnu.csh +++ b/scm/etc/Cheyenne_setup_gnu.csh @@ -7,31 +7,42 @@ echo "Loading gnu and netcdf modules..." module purge module load ncarenv/1.3 module load gnu/8.3.0 -module load ncarcompilers/0.5.0 module load mpt/2.19 -module load netcdf/4.6.3 -module load python/2.7.16 +module load ncarcompilers/0.5.0 +module load netcdf/4.7.3 echo "Setting CC/CXX/FC environment variables" setenv CC gcc setenv CXX g++ setenv FC gfortran -echo "Setting NCEPLIBS_DIR environment variable" -set NCEPLIBS_DIR = "/glade/p/ral/jntp/GMTB/tools/NCEPlibs/20190703/gnu-8.3.0/mpt-2.19" -setenv NCEPLIBS_DIR $NCEPLIBS_DIR +echo "Setting NCEPLIBS environment variables" +module use /glade/p/ral/jntp/GMTB/tools/modulefiles/gnu-8.3.0/mpt-2.19 +module load NCEPlibs/1.0.0 + +echo "Loading cmake" +module load cmake/3.16.4 +setenv CMAKE_Platform cheyenne.gnu -#install f90nml for the local user +echo "Setting up python environment for plotting. A NCAR Package Library for python will be cloned into /glade/work/$USER." +module load python/2.7.16 +ncar_pylib +if (-d "/glade/work/$USER/gmtb_scm_python_clone") then + echo "gmtb_scm_python_clone NPL exists. Loading..." + ncar_pylib gmtb_scm_python_clone +else + echo "gmtb_scm_python_clone does not exist yet. Creating..." + ncar_pylib -c 20190627 /glade/work/$USER/gmtb_scm_python_clone + ncar_pylib gmtb_scm_python_clone +endif #check to see if f90nml is installed locally echo "Checking if f90nml python module is installed" python -c "import f90nml" if ( $? != 0 ) then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. + echo "Not found; installing f90nml" + pip install --no-cache-dir f90nml==0.19 else - echo "f90nml is installed" + echo "f90nml is installed" endif diff --git a/scm/etc/Cheyenne_setup_gnu.sh b/scm/etc/Cheyenne_setup_gnu.sh index 38e2b72a3..7094f5d21 100755 --- a/scm/etc/Cheyenne_setup_gnu.sh +++ b/scm/etc/Cheyenne_setup_gnu.sh @@ -7,32 +7,42 @@ echo "Loading gnu and netcdf modules..." module purge module load ncarenv/1.3 module load gnu/8.3.0 -module load ncarcompilers/0.5.0 module load mpt/2.19 -module load netcdf/4.6.3 -module load python/2.7.16 +module load ncarcompilers/0.5.0 +module load netcdf/4.7.3 echo "Setting CC/CXX/FC environment variables" export CC=gcc export CXX=g++ export FC=gfortran -echo "Setting NCEPLIBS_DIR environment variable" -NCEPLIBS_DIR=/glade/p/ral/jntp/GMTB/tools/NCEPlibs/20190703/gnu-8.3.0/mpt-2.19 -export NCEPLIBS_DIR=$NCEPLIBS_DIR +echo "Setting NCEPLIBS environment variables" +module use /glade/p/ral/jntp/GMTB/tools/modulefiles/gnu-8.3.0/mpt-2.19 +module load NCEPlibs/1.0.0 +echo "Loading cmake" +module load cmake/3.16.4 +export CMAKE_Platform=cheyenne.gnu -#install f90nml for the local user +echo "Setting up python environment for plotting. A NCAR Package Library for python will be cloned into /glade/work/$USER." +module load python/2.7.16 +ncar_pylib +if [ -d "/glade/work/$USER/gmtb_scm_python_clone" ]; then + echo "gmtb_scm_python_clone NPL exists. Loading..." + ncar_pylib gmtb_scm_python_clone +else + echo "gmtb_scm_python_clone does not exist yet. Creating..." + ncar_pylib -c 20190627 /glade/work/$USER/gmtb_scm_python_clone + ncar_pylib gmtb_scm_python_clone +fi #check to see if f90nml is installed locally echo "Checking if f90nml python module is installed" python -c "import f90nml" if [ $? -ne 0 ]; then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. + echo "Not found; installing f90nml" + pip install --no-cache-dir f90nml==0.19 else - echo "f90nml is installed" + echo "f90nml is installed" fi diff --git a/scm/etc/Cheyenne_setup_intel.csh b/scm/etc/Cheyenne_setup_intel.csh index 62b7eb3fa..a04e9fdf9 100755 --- a/scm/etc/Cheyenne_setup_intel.csh +++ b/scm/etc/Cheyenne_setup_intel.csh @@ -6,32 +6,43 @@ echo "Setting environment variables for SCM-CCPP on Cheyenne with icc/ifort" echo "Loading intel and netcdf modules..." module purge module load ncarenv/1.3 -module load intel/19.0.2 -module load ncarcompilers/0.5.0 +module load intel/19.0.5 module load mpt/2.19 -module load netcdf/4.6.3 -module load python/2.7.16 +module load ncarcompilers/0.5.0 +module load netcdf/4.7.3 echo "Setting CC/CXX/FC environment variables" setenv CC icc setenv CXX icpc setenv FC ifort -echo "Setting NCEPLIBS_DIR environment variable" -set NCEPLIBS_DIR = "/glade/p/ral/jntp/GMTB/tools/NCEPlibs/20190703/intel-19.0.2/mpt-2.19" -setenv NCEPLIBS_DIR $NCEPLIBS_DIR +echo "Setting NCEPLIBS environment variables" +module use /glade/p/ral/jntp/GMTB/tools/modulefiles/intel-19.0.5/mpt-2.19 +module load NCEPlibs/1.0.0 + +echo "Loading cmake" +module load cmake/3.16.4 +setenv CMAKE_Platform cheyenne.intel -#install f90nml for the local user +echo "Setting up python environment for plotting. A NCAR Package Library for python will be cloned into /glade/work/$USER." +module load python/2.7.16 +ncar_pylib +if (-d "/glade/work/$USER/gmtb_scm_python_clone") then + echo "gmtb_scm_python_clone NPL exists. Loading..." + ncar_pylib gmtb_scm_python_clone +else + echo "gmtb_scm_python_clone does not exist yet. Creating..." + ncar_pylib -c 20190627 /glade/work/$USER/gmtb_scm_python_clone + ncar_pylib gmtb_scm_python_clone +endif #check to see if f90nml is installed locally echo "Checking if f90nml python module is installed" python -c "import f90nml" if ( $? != 0 ) then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. + echo "Not found; installing f90nml" + pip install --no-cache-dir f90nml==0.19 else - echo "f90nml is installed" + echo "f90nml is installed" endif diff --git a/scm/etc/Cheyenne_setup_intel.sh b/scm/etc/Cheyenne_setup_intel.sh index 2722a3d84..64b664159 100755 --- a/scm/etc/Cheyenne_setup_intel.sh +++ b/scm/etc/Cheyenne_setup_intel.sh @@ -6,32 +6,43 @@ echo "Setting environment variables for SCM-CCPP on Cheyenne with icc/ifort" echo "Loading intel and netcdf modules..." module purge module load ncarenv/1.3 -module load intel/19.0.2 -module load ncarcompilers/0.5.0 +module load intel/19.0.5 module load mpt/2.19 -module load netcdf/4.6.3 -module load python/2.7.16 +module load ncarcompilers/0.5.0 +module load netcdf/4.7.3 echo "Setting CC/CXX/FC environment variables" export CC=icc export CXX=icpc export FC=ifort -echo "Setting NCEPLIBS_DIR environment variable" -NCEPLIBS_DIR=/glade/p/ral/jntp/GMTB/tools/NCEPlibs/20190703/intel-19.0.2/mpt-2.19 -export NCEPLIBS_DIR=$NCEPLIBS_DIR +echo "Setting NCEPLIBS environment variables" +module use /glade/p/ral/jntp/GMTB/tools/modulefiles/intel-19.0.5/mpt-2.19 +module load NCEPlibs/1.0.0 -#install f90nml for the local user +echo "Loading cmake" +module load cmake/3.16.4 +export CMAKE_Platform=cheyenne.intel + +echo "Setting up python environment for plotting. A NCAR Package Library for python will be cloned into /glade/work/$USER." +module load python/2.7.16 +ncar_pylib +if [ -d "/glade/work/$USER/gmtb_scm_python_clone" ]; then + echo "gmtb_scm_python_clone NPL exists. Loading..." + ncar_pylib gmtb_scm_python_clone +else + echo "gmtb_scm_python_clone does not exist yet. Creating..." + ncar_pylib -c 20190627 /glade/work/$USER/gmtb_scm_python_clone + ncar_pylib gmtb_scm_python_clone +fi #check to see if f90nml is installed locally echo "Checking if f90nml python module is installed" python -c "import f90nml" - if [ $? -ne 0 ]; then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. + echo "Not found; installing f90nml" + pip install f90nml==0.19 else - echo "f90nml is installed" + echo "f90nml is installed" fi + diff --git a/scm/etc/Cheyenne_setup_pgi.csh b/scm/etc/Cheyenne_setup_pgi.csh deleted file mode 100755 index 4ca119f62..000000000 --- a/scm/etc/Cheyenne_setup_pgi.csh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/tcsh - -echo "Setting environment variables for SCM-CCPP on Cheyenne with pgcc/pgf90" - -#load the modules in order to compile the GMTB SCM -echo "Loading pgi and netcdf modules..." -module purge -module load ncarenv/1.3 -module load pgi/19.3 -module load ncarcompilers/0.5.0 -module load netcdf/4.6.3 -module load python/2.7.16 - -echo "Setting CC/CXX/FC environment variables" -setenv CC pgcc -setenv CXX pgc++ -setenv FC pgf90 - -echo "Setting NCEPLIBS_DIR environment variable" -set NCEPLIBS_DIR = "/glade/p/ral/jntp/GMTB/tools/NCEPlibs/20190307/pgi-17.9/mpt-2.19" -setenv NCEPLIBS_DIR $NCEPLIBS_DIR - -#install f90nml for the local user - -#check to see if f90nml is installed locally -echo "Checking if f90nml python module is installed" -python -c "import f90nml" - -if ( $? != 0 ) then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. -else - echo "f90nml is installed" -endif diff --git a/scm/etc/Cheyenne_setup_pgi.sh b/scm/etc/Cheyenne_setup_pgi.sh deleted file mode 100755 index c764416b3..000000000 --- a/scm/etc/Cheyenne_setup_pgi.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -echo "Setting environment variables for SCM-CCPP on Cheyenne with pgcc/pgf90" - -#load the modules in order to compile the GMTB SCM -echo "Loading pgi and netcdf modules..." -module purge -module load ncarenv/1.3 -module load pgi/19.3 -module load ncarcompilers/0.5.0 -module load netcdf/4.6.3 -module load python/2.7.16 - -echo "Setting CC/CXX/FC environment variables" -export CC=pgcc -export CXX=pgc++ -export FC=pgf90 - -echo "Setting NCEPLIBS_DIR environment variable" -NCEPLIBS_DIR=/glade/p/ral/jntp/GMTB/tools/NCEPlibs/20190307/pgi-17.9/mpt-2.19 -export NCEPLIBS_DIR=$NCEPLIBS_DIR - -#install f90nml for the local user - -#check to see if f90nml is installed locally -echo "Checking if f90nml python module is installed" -python -c "import f90nml" - -if [ $? -ne 0 ]; then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. -else - echo "f90nml is installed" -fi diff --git a/scm/etc/Hera_setup_intel.csh b/scm/etc/Hera_setup_intel.csh index eb0703ebd..9b6b772d4 100755 --- a/scm/etc/Hera_setup_intel.csh +++ b/scm/etc/Hera_setup_intel.csh @@ -7,20 +7,24 @@ echo "Loading intel and netcdf modules..." module purge module load intel/18.0.5.274 module load impi/2018.0.4 -module load netcdf/4.6.1 -module load pnetcdf/1.10.0 +module load netcdf/4.7.0 echo "Setting CC/CXX/FC environment variables" setenv CC icc setenv CXX icpc setenv FC ifort -echo "Setting NCEPLIBS_DIR environment variable" +echo "Setting NCEPLIBS environment variables" ## ## load modules for above compiler / MPI combination ## module use -a /scratch1/BMC/gmtb/software/modulefiles/intel-18.0.5.274/impi-2018.0.4 -module load NCEPlibs/9.9.9 +module load NCEPlibs/1.0.0 + +echo "Loading cmake" +module use -a /scratch1/BMC/gmtb/software/modulefiles/generic +module load cmake/3.16.3 +setenv CMAKE_Platform hera.intel echo "Loading the anaconda python distribution" module load contrib @@ -34,9 +38,20 @@ python -c "import f90nml" if ( $? != 0 ) then echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. + pip install -e git://github.com/marshallward/f90nml.git@v0.19#egg=f90nml --user else echo "f90nml is installed" endif + +#install shapely for the local user + +#check to see if shapely is installed locally +echo "Checking if shapely python module is installed" +python -c "import shapely" + +if ( $? != 0 ) then + echo "Not found; installing shapely" + pip install --index-url http://anaconda.rdhpcs.noaa.gov/simple --trusted-host anaconda.rdhpcs.noaa.gov shapely --user +else + echo "shapely is installed" +endif diff --git a/scm/etc/Hera_setup_intel.sh b/scm/etc/Hera_setup_intel.sh index 6bbde8a93..4282c64ee 100755 --- a/scm/etc/Hera_setup_intel.sh +++ b/scm/etc/Hera_setup_intel.sh @@ -7,17 +7,21 @@ echo "Loading intel and netcdf modules..." module purge module load intel/18.0.5.274 module load impi/2018.0.4 -module load netcdf/4.6.1 -module load pnetcdf/1.10.0 +module load netcdf/4.7.0 echo "Setting CC/CXX/FC environment variables" export CC=icc export CXX=icpc export FC=ifort -echo "Setting NCEPLIBS_DIR environment variable" +echo "Setting NCEPLIBS environment variables" module use -a /scratch1/BMC/gmtb/software/modulefiles/intel-18.0.5.274/impi-2018.0.4 -module load NCEPlibs/9.9.9 +module load NCEPlibs/1.0.0 + +echo "Loading cmake" +module use -a /scratch1/BMC/gmtb/software/modulefiles/generic +module load cmake/3.16.3 +export CMAKE_Platform=hera.intel echo "Loading the anaconda python distribution" module load contrib @@ -31,9 +35,20 @@ python -c "import f90nml" if [ $? -ne 0 ]; then echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. + pip install -e git://github.com/marshallward/f90nml.git@v0.19#egg=f90nml --user else echo "f90nml is installed" fi + +#install shapely for the local user + +#check to see if shapely is installed locally +echo "Checking if shapely python module is installed" +python -c "import shapely" + +if [ $? -ne 0 ]; then + echo "Not found; installing shapely" + pip install --index-url http://anaconda.rdhpcs.noaa.gov/simple --trusted-host anaconda.rdhpcs.noaa.gov shapely --user +else + echo "shapely is installed" +fi diff --git a/scm/etc/MACOSX_setup.csh b/scm/etc/MACOSX_setup.csh deleted file mode 100755 index 01e7f9b2c..000000000 --- a/scm/etc/MACOSX_setup.csh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/tcsh - -echo "Setting environment variables for SCM-CCPP on MACOSX with clang/gfortran" - -setenv CC /usr/local/bin/mpicc -setenv CXX /usr/local/bin/mpicxx -setenv F77 /usr/local/bin/mpif77 -setenv F90 /usr/local/bin/mpif90 -setenv FC /usr/local/bin/mpif90 -setenv CPP "/usr/local/bin/mpif90 -E -x f95-cpp-input" - -setenv LDFLAGS "-L/usr/local/opt/zlib/lib -L/usr/local/opt/llvm/lib" -setenv CPPFLAGS "-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" -setenv CFLAGS "-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" -setenv CXXFLAGS "-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" -setenv FFLAGS "-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" -setenv FCFLAGS " -I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" - -if (! $?PATH) then - setenv PATH "/usr/local/opt/llvm/bin" -else - setenv PATH "/usr/local/opt/llvm/bin:$PATH" -endif -if (! $?LD_LIBRARY_PATH) then - setenv LD_LIBRARY_PATH "/usr/local/opt/zlib/lib:/usr/local/opt/llvm/lib" -else - setenv LD_LIBRARY_PATH "/usr/local/opt/zlib/lib:/usr/local/opt/llvm/lib:$LD_LIBRARY_PATH" -endif -if (! $?DYLD_LIBRARY_PATH) then - setenv DYLD_LIBRARY_PATH "/usr/local/opt/zlib/lib:/usr/local/opt/llvm/lib" -else - setenv DYLD_LIBRARY_PATH "/usr/local/opt/zlib/lib:/usr/local/opt/llvm/lib:$DYLD_LIBRARY_PATH" -endif - -setenv NETCDF /usr/local diff --git a/scm/etc/MACOSX_setup.sh b/scm/etc/MACOSX_setup.sh deleted file mode 100755 index d1030f3e1..000000000 --- a/scm/etc/MACOSX_setup.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -echo "Setting environment variables for SCM-CCPP on MACOSX with clang/gfortran" - -export CC=/usr/local/bin/mpicc -export CXX=/usr/local/bin/mpicxx -export F77=/usr/local/bin/mpif77 -export F90=/usr/local/bin/mpif90 -export FC=/usr/local/bin/mpif90 -export CPP="/usr/local/bin/mpif90 -E -x f95-cpp-input" - -export LDFLAGS="-L/usr/local/opt/zlib/lib -L/usr/local/opt/llvm/lib" -export CPPFLAGS="-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" -export CFLAGS="-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" -export CXXFLAGS="-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" -export FFLAGS="-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" -export FCFLAGS="-I/usr/local/opt/zlib/include -I/usr/local/opt/llvm/include" - -export PATH="/usr/local/opt/llvm/bin${PATH:+:$PATH}" -export LD_LIBRARY_PATH="/usr/local/opt/zlib/lib:/usr/local/opt/llvm/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" -export DYLD_LIBRARY_PATH="/usr/local/opt/zlib/lib:/usr/local/opt/llvm/lib:${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" - -export NETCDF=/usr/local diff --git a/scm/etc/Theia_setup_gnu.csh b/scm/etc/Theia_setup_gnu.csh deleted file mode 100755 index d0915daee..000000000 --- a/scm/etc/Theia_setup_gnu.csh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/tcsh - -echo "Setting environment variables for SCM-CCPP on Theia with gcc/gfortran" - -#load the modules in order to compile the GMTB SCM -echo "Loading intel and netcdf modules..." -module purge -module load gcc/6.2.0 -# netcdf-4.5.0, compiled with gnu/6.2.0 and mvapich2-2.2, and its dependencies -if (! $?PATH) then - setenv PATH "/scratch4/BMC/gmtb/netcdf-4.5.0/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/parallel-netcdf-1.8.1/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/hdf5-1.8.20/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/szip-2.1.1/gnu-6.2.0/bin:/scratch4/BMC/gmtb/zlib-1.2.11/gnu-6.2.0/bin:/scratch4/BMC/gmtb/mvapich2-2.2/gnu-6.2.0/bin" -else - setenv PATH "/scratch4/BMC/gmtb/netcdf-4.5.0/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/parallel-netcdf-1.8.1/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/hdf5-1.8.20/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/szip-2.1.1/gnu-6.2.0/bin:/scratch4/BMC/gmtb/zlib-1.2.11/gnu-6.2.0/bin:/scratch4/BMC/gmtb/mvapich2-2.2/gnu-6.2.0/bin:${PATH}" -endif -if (! $?LD_LIBRARY_PATH) then - setenv LD_LIBRARY_PATH "/scratch4/BMC/gmtb/netcdf-4.5.0/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/parallel-netcdf-1.8.1/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/hdf5-1.8.20/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/szip-2.1.1/gnu-6.2.0/lib:/scratch4/BMC/gmtb/zlib-1.2.11/gnu-6.2.0/lib:/scratch4/BMC/gmtb/mvapich2-2.2/gnu-6.2.0/lib" -else - setenv LD_LIBRARY_PATH "/scratch4/BMC/gmtb/netcdf-4.5.0/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/parallel-netcdf-1.8.1/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/hdf5-1.8.20/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/szip-2.1.1/gnu-6.2.0/lib:/scratch4/BMC/gmtb/zlib-1.2.11/gnu-6.2.0/lib:/scratch4/BMC/gmtb/mvapich2-2.2/gnu-6.2.0/lib:${LD_LIBRARY_PATH}" -endif - -setenv MV2_ENABLE_AFFINITY 0 -setenv NETCDF /scratch4/BMC/gmtb/netcdf-4.5.0/gnu-6.2.0/mvapich2-2.2 - -echo "Setting CC/CXX/FC environment variables" -setenv CC gcc -setenv CXX g++ -setenv FC gfortran - -echo "Setting NCEPLIBS_DIR environment variable" -set NCEPLIBS_DIR = "/scratch4/home/Dom.Heinzeller/NEMSfv3gfs_vlab_portability/NCEPlibs-gnu-20181105" -setenv NCEPLIBS_DIR $NCEPLIBS_DIR - -#prepend the anaconda installation to the path so that the anaconda version of python (with its many installed modules) is used; check if the path already contains the right path first -echo "Checking if the path to the anaconda python distribution is in PATH" -echo $PATH | grep '/contrib/ananconda/2.3.0/bin$' >&/dev/null -if ( $? != 0 ) then - echo "anaconda path not found in PATH; prepending anaconda path to PATH environment variable" - setenv PATH /contrib/anaconda/2.3.0/bin:$PATH -else - echo "PATH already has the anaconda path in it" -endif - -#install f90nml for the local user - -#check to see if f90nml is installed locally -echo "Checking if f90nml python module is installed" -python -c "import f90nml" - -if ( $? != 0 ) then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. -else - echo "f90nml is installed" -endif diff --git a/scm/etc/Theia_setup_gnu.sh b/scm/etc/Theia_setup_gnu.sh deleted file mode 100755 index cc898ca1c..000000000 --- a/scm/etc/Theia_setup_gnu.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -echo "Setting environment variables for SCM-CCPP on Theia with gcc/gfortran" - -#load the modules in order to compile the GMTB SCM -echo "Loading gnu and netcdf modules..." -module purge -module load gcc/6.2.0 -# netcdf-4.5.0, compiled with gnu/6.2.0 and mvapich2-2.2, and its dependencies -export PATH="/scratch4/BMC/gmtb/netcdf-4.5.0/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/parallel-netcdf-1.8.1/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/hdf5-1.8.20/gnu-6.2.0/mvapich2-2.2/bin:/scratch4/BMC/gmtb/szip-2.1.1/gnu-6.2.0/bin:/scratch4/BMC/gmtb/zlib-1.2.11/gnu-6.2.0/bin:/scratch4/BMC/gmtb/mvapich2-2.2/gnu-6.2.0/bin${PATH:+:$PATH}" -export LD_LIBRARY_PATH="/scratch4/BMC/gmtb/netcdf-4.5.0/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/parallel-netcdf-1.8.1/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/hdf5-1.8.20/gnu-6.2.0/mvapich2-2.2/lib:/scratch4/BMC/gmtb/szip-2.1.1/gnu-6.2.0/lib:/scratch4/BMC/gmtb/zlib-1.2.11/gnu-6.2.0/lib:/scratch4/BMC/gmtb/mvapich2-2.2/gnu-6.2.0/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" -export MV2_ENABLE_AFFINITY=0 -export NETCDF=/scratch4/BMC/gmtb/netcdf-4.5.0/gnu-6.2.0/mvapich2-2.2 - -echo "Setting CC/CXX/FC environment variables" -export CC=gcc -export CXX=g++ -export FC=gfortran - -echo "Setting NCEPLIBS_DIR environment variable" -NCEPLIBS_DIR=/scratch4/home/Dom.Heinzeller/NEMSfv3gfs_vlab_portability/NCEPlibs-gnu-20181105 -export NCEPLIBS_DIR=$NCEPLIBS_DIR - -#prepend the anaconda installation to the path so that the anaconda version of python (with its many installed modules) is used; check if the path already contains the right path first -echo "Checking if the path to the anaconda python distribution is in PATH" -echo $PATH | grep '/contrib/ananconda/2.3.0/bin$' >&/dev/null -if [ $? -ne 0 ]; then - echo "anaconda path not found in PATH; prepending anaconda path to PATH environment variable" - export PATH=/contrib/anaconda/2.3.0/bin:$PATH -else - echo "PATH already has the anaconda path in it" -fi - -#install f90nml for the local user - -#check to see if f90nml is installed locally -echo "Checking if f90nml python module is installed" -python -c "import f90nml" - -if [ $? -ne 0 ]; then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. -else - echo "f90nml is installed" -fi diff --git a/scm/etc/Theia_setup_intel.csh b/scm/etc/Theia_setup_intel.csh deleted file mode 100755 index 5649c1bc9..000000000 --- a/scm/etc/Theia_setup_intel.csh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/tcsh - -echo "Setting environment variables for SCM-CCPP on Theia with icc/ifort" - -#load the modules in order to compile the GMTB SCM -echo "Loading intel and netcdf modules..." -module purge -module load intel/18.0.1.163 -module load netcdf/4.3.0 - -echo "Setting CC/CXX/FC environment variables" -setenv CC icc -setenv CXX icpc -setenv FC ifort - -echo "Setting NCEPLIBS_DIR environment variable" -set NCEPLIBS_DIR = "/scratch4/home/Dom.Heinzeller/NEMSfv3gfs_vlab_portability/NCEPlibs-intel-18.1.163-20181105" -setenv NCEPLIBS_DIR $NCEPLIBS_DIR - -#prepend the anaconda installation to the path so that the anaconda version of python (with its many installed modules) is used; check if the path already contains the right path first -echo "Checking if the path to the anaconda python distribution is in PATH" -echo $PATH | grep '/contrib/ananconda/2.3.0/bin$' >&/dev/null -if ( $? != 0 ) then - echo "anaconda path not found in PATH; prepending anaconda path to PATH environment variable" - setenv PATH /contrib/anaconda/2.3.0/bin:$PATH -else - echo "PATH already has the anaconda path in it" -endif - -#install f90nml for the local user - -#check to see if f90nml is installed locally -echo "Checking if f90nml python module is installed" -python -c "import f90nml" - -if ( $? != 0 ) then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. -else - echo "f90nml is installed" -endif diff --git a/scm/etc/Theia_setup_intel.sh b/scm/etc/Theia_setup_intel.sh deleted file mode 100755 index d0d72dbad..000000000 --- a/scm/etc/Theia_setup_intel.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -echo "Setting environment variables for SCM-CCPP on Theia with icc/ifort" - -#load the modules in order to compile the GMTB SCM -echo "Loading intel and netcdf modules..." -module purge -module load intel/18.0.1.163 -module load netcdf/4.3.0 - -echo "Setting CC/CXX/FC environment variables" -export CC=icc -export CXX=icpc -export FC=ifort - -echo "Setting NCEPLIBS_DIR environment variable" -NCEPLIBS_DIR=/scratch4/home/Dom.Heinzeller/NEMSfv3gfs_vlab_portability/NCEPlibs-intel-18.1.163-20181105 -export NCEPLIBS_DIR=$NCEPLIBS_DIR - -#prepend the anaconda installation to the path so that the anaconda version of python (with its many installed modules) is used; check if the path already contains the right path first -echo "Checking if the path to the anaconda python distribution is in PATH" -echo $PATH | grep '/contrib/ananconda/2.3.0/bin$' >&/dev/null -if [ $? -ne 0 ]; then - echo "anaconda path not found in PATH; prepending anaconda path to PATH environment variable" - export PATH=/contrib/anaconda/2.3.0/bin:$PATH -else - echo "PATH already has the anaconda path in it" -fi - -#install f90nml for the local user - -#check to see if f90nml is installed locally -echo "Checking if f90nml python module is installed" -python -c "import f90nml" - -if [ $? -ne 0 ]; then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. -else - echo "f90nml is installed" -fi diff --git a/scm/etc/Theia_setup_pgi.csh b/scm/etc/Theia_setup_pgi.csh deleted file mode 100755 index 505eb8cba..000000000 --- a/scm/etc/Theia_setup_pgi.csh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/tcsh - -echo "Setting environment variables for SCM-CCPP on Theia with pgcc/pgf90" - -#load the modules in order to compile the GMTB SCM -echo "Loading pgi and netcdf modules..." -module purge -module load pgi/17.7 -module load netcdf/4.4.0 - -echo "Setting CC/CXX/FC environment variables" -setenv CC pgcc -setenv CXX pgc++ -setenv FC pgf90 - -echo "Setting NCEPLIBS_DIR environment variable" -set NCEPLIBS_DIR = "/scratch4/home/Dom.Heinzeller/NEMSfv3gfs_vlab_portability/NCEPlibs-pgi-20181105" -setenv NCEPLIBS_DIR $NCEPLIBS_DIR - -#prepend the anaconda installation to the path so that the anaconda version of python (with its many installed modules) is used; check if the path already contains the right path first -echo "Checking if the path to the anaconda python distribution is in PATH" -echo $PATH | grep '/contrib/ananconda/2.3.0/bin$' >&/dev/null -if ( $? != 0 ) then - echo "anaconda path not found in PATH; prepending anaconda path to PATH environment variable" - setenv PATH /contrib/anaconda/2.3.0/bin:$PATH -else - echo "PATH already has the anaconda path in it" -endif - -#install f90nml for the local user - -#check to see if f90nml is installed locally -echo "Checking if f90nml python module is installed" -python -c "import f90nml" - -if ( $? != 0 ) then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. -else - echo "f90nml is installed" -endif diff --git a/scm/etc/Theia_setup_pgi.sh b/scm/etc/Theia_setup_pgi.sh deleted file mode 100755 index a9303d877..000000000 --- a/scm/etc/Theia_setup_pgi.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -echo "Setting environment variables for SCM-CCPP on Theia with pgcc/pgf90" - -#load the modules in order to compile the GMTB SCM -echo "Loading pgi and netcdf modules..." -module purge -module load pgi/17.7 -module load netcdf/4.4.0 - -echo "Setting CC/CXX/FC environment variables" -export CC=pgcc -export CXX=pgc++ -export FC=pgf90 - -echo "Setting NCEPLIBS_DIR environment variable" -NCEPLIBS_DIR=/scratch4/home/Dom.Heinzeller/NEMSfv3gfs_vlab_portability/NCEPlibs-pgi-20181105 -export NCEPLIBS_DIR=$NCEPLIBS_DIR - -#prepend the anaconda installation to the path so that the anaconda version of python (with its many installed modules) is used; check if the path already contains the right path first -echo "Checking if the path to the anaconda python distribution is in PATH" -echo $PATH | grep '/contrib/ananconda/2.3.0/bin$' >&/dev/null -if [ $? -ne 0 ]; then - echo "anaconda path not found in PATH; prepending anaconda path to PATH environment variable" - export PATH=/contrib/anaconda/2.3.0/bin:$PATH -else - echo "PATH already has the anaconda path in it" -fi - -#install f90nml for the local user - -#check to see if f90nml is installed locally -echo "Checking if f90nml python module is installed" -python -c "import f90nml" - -if [ $? -ne 0 ]; then - echo "Not found; installing f90nml" - cd etc/scripts/f90nml-0.19 - python setup.py install --user - cd ../.. -else - echo "f90nml is installed" -fi diff --git a/scm/etc/UBUNTU_setup.csh b/scm/etc/UBUNTU_setup.csh deleted file mode 100755 index caef138a7..000000000 --- a/scm/etc/UBUNTU_setup.csh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/tcsh - -echo "Setting environment variables for SCM-CCPP on UBUNTU with gcc/gfortran" - -setenv CC gcc -setenv CXX g++ -setenv F77 gfortran -setenv F90 gfortran -setenv FC gfortran - -setenv NETCDF /usr diff --git a/scm/etc/UBUNTU_setup.sh b/scm/etc/UBUNTU_setup.sh deleted file mode 100755 index 9f9463389..000000000 --- a/scm/etc/UBUNTU_setup.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -echo "Setting environment variables for SCM-CCPP on UBUNTU with gcc/gfortran" - -export CC=gcc -export CXX=g++ -export F77=gfortran -export F90=gfortran -export FC=gfortran - -export NETCDF=/usr diff --git a/scm/etc/pjpegion_setup.sh b/scm/etc/pjpegion_setup.sh deleted file mode 100755 index 1c7def263..000000000 --- a/scm/etc/pjpegion_setup.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -echo "Setting environment variables for SCM-CCPP on MACOSX with clang/gfortran" - -export CFLAGS="-fmax-stack-var-size=30000 -I /Volumes/Cluster/opt/local/include/" -export FFLAGS="-fmax-stack-var-size=30000 -fbounds-check -fcheck=all -gdwarf-4 -fvar-tracking-assignments -fbacktrace -fcheck=bounds -fdec" \ No newline at end of file diff --git a/scm/etc/scripts/UFS_IC_generator.py b/scm/etc/scripts/UFS_IC_generator.py index b40f69f20..62e461119 100755 --- a/scm/etc/scripts/UFS_IC_generator.py +++ b/scm/etc/scripts/UFS_IC_generator.py @@ -50,6 +50,7 @@ parser.add_argument('-a', '--area', help='area of grid cell in m^2', type=float) parser.add_argument('-mp','--noahmp', help='flag to generate cold-start ICs for NoahMP LSM from Noah LSM ICs', action='store_true') parser.add_argument('-n', '--case_name', help='name of case', required=True) +parser.add_argument('-oc','--old_chgres', help='flag to denote that the initial conditions use an older data format (pre-chgres_cube)', action='store_true') ############################################################################### # Functions and subroutines # @@ -67,6 +68,7 @@ def parse_arguments(): area = args.area case_name = args.case_name noahmp = args.noahmp + old_chgres = args.old_chgres #validate args if not os.path.exists(in_dir): @@ -97,7 +99,7 @@ def parse_arguments(): date_dict["hour"] = np.int(date[8:10]) date_dict["minute"] = np.int(date[10:]) - return (location, index, date_dict, in_dir, grid_dir, tile, area, noahmp, case_name) + return (location, index, date_dict, in_dir, grid_dir, tile, area, noahmp, case_name, old_chgres) def setup_logging(): """Sets up the logging module.""" @@ -192,15 +194,24 @@ def find_loc_indices(loc, dir, tile): """Find the nearest neighbor FV3 grid point given a lon/lat pair and the tile number""" #returns the indices of the nearest neighbor point in the given tile, the lon/lat of the nearest neighbor, #and the distance (m) from the given point to the nearest neighbor grid cell - - filename_pattern = 'sfc_data.tile{0}.nc'.format(tile) + + filename_pattern = '*grid.tile{0}.nc'.format(tile) for f_name in os.listdir(dir): if fnmatch.fnmatch(f_name, filename_pattern): filename = f_name + if not filename: + message = 'No filenames matching the pattern {0} found in {1}'.format(filename_pattern,dir) + logging.critical(message) + raise Exception(message) nc_file = Dataset('{0}/{1}'.format(dir,filename)) - longitude = np.array(nc_file['geolon']) #[lat,lon] or [y,x] #.swapaxes(0,1) - latitude = np.array(nc_file['geolat']) #[lat,lon] or [y,x] #.swapaxes(0,1) + #read in supergrid longitude and latitude + lon_super = np.array(nc_file['x']) #[lat,lon] or [y,x] #.swapaxes(0,1) + lat_super = np.array(nc_file['y']) #[lat,lon] or [y,x] #.swapaxes(0,1) + #get the longitude and latitude data for the grid centers by slicing the supergrid + #and taking only odd-indexed values + longitude = lon_super[1::2,1::2] + latitude = lat_super[1::2,1::2] nc_file.close() adj_long = False @@ -236,14 +247,23 @@ def find_loc_indices(loc, dir, tile): def find_lon_lat_of_indices(indices, dir, tile): """Find the longitude and latitude of the given indices within the given tile.""" - filename_pattern = 'sfc_data.tile{0}.nc'.format(tile) + filename_pattern = '*grid.tile{0}.nc'.format(tile) for f_name in os.listdir(dir): if fnmatch.fnmatch(f_name, filename_pattern): filename = f_name + if not filename: + message = 'No filenames matching the pattern {0} found in {1}'.format(filename_pattern,dir) + logging.critical(message) + raise Exception(message) nc_file = Dataset('{0}/{1}'.format(dir,filename)) - longitude = np.array(nc_file['geolon']) #[lat,lon] or [y,x] #.swapaxes(0,1) - latitude = np.array(nc_file['geolat']) #[lat,lon] or [y,x] #.swapaxes(0,1) + #read in supergrid longitude and latitude + lon_super = np.array(nc_file['x']) #[lat,lon] or [y,x] #.swapaxes(0,1) + lat_super = np.array(nc_file['y']) #[lat,lon] or [y,x] #.swapaxes(0,1) + #get the longitude and latitude data for the grid centers by slicing the supergrid + #and taking only odd-indexed values + longitude = lon_super[1::2,1::2] + latitude = lat_super[1::2,1::2] nc_file.close() return (longitude[indices[1],indices[0]], latitude[indices[1],indices[0]]) @@ -258,32 +278,32 @@ def sph2cart(az, el, r): return (x, y, z) -def get_UFS_IC_data(dir, tile, i, j): +def get_UFS_IC_data(dir, tile, i, j, old_chgres): """Get the state, surface, and orographic data for the given tile and indices""" #returns dictionaries with the data - state_data = get_UFS_state_data(dir, tile, i, j) - surface_data = get_UFS_surface_data(dir, tile, i, j) + state_data = get_UFS_state_data(dir, tile, i, j, old_chgres) + surface_data = get_UFS_surface_data(dir, tile, i, j, old_chgres) oro_data = get_UFS_oro_data(dir, tile, i, j) vgrid_data = get_UFS_vgrid_data(dir) #only needed for ak, bk to calculate pressure #calculate derived quantities - - #temperature - nlevs = state_data["nlevs"] - gz=state_data["z"]*grav - pn1=np.zeros([nlevs+1]) - temp=np.zeros([nlevs]) - for k in range(nlevs+1): - pn1[k]=np.log(vgrid_data["ak"][k]+state_data["p_surf"]*vgrid_data["bk"][k]) - for k in range(nlevs): - temp[k] = (gz[k]-gz[k+1])/( rdgas*(pn1[k+1]-pn1[k])*(1.+zvir*state_data["qv"][k]) ) - state_data["T"] = temp - state_data["pres"] = np.exp(pn1[0:nlevs]) + if old_chgres: + #temperature + nlevs = state_data["nlevs"] + gz=state_data["z"]*grav + pn1=np.zeros([nlevs+1]) + temp=np.zeros([nlevs]) + for k in range(nlevs+1): + pn1[k]=np.log(vgrid_data["ak"][k]+state_data["p_surf"]*vgrid_data["bk"][k]) + for k in range(nlevs): + temp[k] = (gz[k]-gz[k+1])/( rdgas*(pn1[k+1]-pn1[k])*(1.+zvir*state_data["qv"][k]) ) + state_data["T"] = temp + state_data["pres"] = np.exp(pn1[0:nlevs]) return (state_data, surface_data, oro_data) -def get_UFS_state_data(dir, tile, i, j): +def get_UFS_state_data(dir, tile, i, j, old_chgres): """Get the state data for the given tile and indices""" nc_file = Dataset('{0}/{1}'.format(dir,'gfs_data.tile{0}.nc'.format(tile))) @@ -308,62 +328,122 @@ def get_UFS_state_data(dir, tile, i, j): sphum=nc_file['sphum'][::-1,j,i] # o3 and qv are taken from ics. o3=nc_file['o3mr'][::-1,j,i] - liqwat=nc_file['liq_wat'][:-1,j,i] + liqwat=nc_file['liq_wat'][::-1,j,i] - # surface pressure and skin temperature + # surface pressure ps=nc_file['ps'][j,i] + if not old_chgres: + #gfs_data.tileX.nc files created from chgres_cube already containt temperature and pressure profiles(well, surface pressure and delp); use those + #older version of global_chgres did not include these vars + t = nc_file['t'][::-1,j,i] + delp = nc_file['delp'][::-1,j,i] + + p = np.zeros(nlevs) + p[0] = ps + for k in range(1, nlevs): + p[k] = p[k-1] - delp[k-1] + nc_file.close() #put data in a dictionary - state = { - "nlevs": nlevs, - "z": zh, - "u": ucomp, - "v": vcomp, - "qv": sphum, - "o3": o3, - "ql": liqwat, - "p_surf": ps - } + if old_chgres: + state = { + "nlevs": nlevs, + "z": zh, + "u": ucomp, + "v": vcomp, + "qv": sphum, + "o3": o3, + "ql": liqwat, + "p_surf": ps + } + else: + state = { + "nlevs": nlevs, + "z": zh, + "u": ucomp, + "v": vcomp, + "qv": sphum, + "o3": o3, + "ql": liqwat, + "p_surf": ps, + "T": t, + "pres": p + } + return state -def get_UFS_surface_data(dir, tile, i, j): +def get_UFS_surface_data(dir, tile, i, j, old_chgres): """Get the surface data for the given tile and indices""" nc_file = Dataset('{0}/{1}'.format(dir,'sfc_data.tile{0}.nc'.format(tile))) - ts_in=nc_file['tsea'][j,i] + if old_chgres: + ts_in=nc_file['tsea'][j,i] - # land state - stc_in=nc_file['stc'][:,j,i] - smc_in=nc_file['smc'][:,j,i] - slc_in=nc_file['slc'][:,j,i] - tg3_in=nc_file['tg3'][j,i] + # land state + stc_in=nc_file['stc'][:,j,i] + smc_in=nc_file['smc'][:,j,i] + slc_in=nc_file['slc'][:,j,i] + tg3_in=nc_file['tg3'][j,i] - # surface properties - uustar_in=nc_file['uustar'][j,i] - alvsf_in=nc_file['alvsf'][j,i] - alvwf_in=nc_file['alvwf'][j,i] - alnsf_in=nc_file['alnsf'][j,i] - alnwf_in=nc_file['alnwf'][j,i] - facsf_in=nc_file['facsf'][j,i] - facwf_in=nc_file['facwf'][j,i] - styp_in=nc_file['stype'][j,i] - slope_in=nc_file['slope'][j,i] - vtyp_in=nc_file['vtype'][j,i] - vfrac_in=nc_file['vfrac'][j,i] - shdmin_in=nc_file['shdmin'][j,i] - shdmax_in=nc_file['shdmax'][j,i] - zorl_in=nc_file['zorl'][j,i] - slmsk_in=nc_file['slmsk'][j,i] - canopy_in=nc_file['canopy'][j,i] - hice_in=nc_file['hice'][j,i] - fice_in=nc_file['fice'][j,i] - tisfc_in=nc_file['tisfc'][j,i] - snwdph_in=nc_file['snwdph'][j,i] - snoalb_in=nc_file['snoalb'][j,i] - sheleg_in=nc_file['sheleg'][j,i] + # surface properties + uustar_in=nc_file['uustar'][j,i] + alvsf_in=nc_file['alvsf'][j,i] + alvwf_in=nc_file['alvwf'][j,i] + alnsf_in=nc_file['alnsf'][j,i] + alnwf_in=nc_file['alnwf'][j,i] + facsf_in=nc_file['facsf'][j,i] + facwf_in=nc_file['facwf'][j,i] + styp_in=nc_file['stype'][j,i] + slope_in=nc_file['slope'][j,i] + vtyp_in=nc_file['vtype'][j,i] + vfrac_in=nc_file['vfrac'][j,i] + shdmin_in=nc_file['shdmin'][j,i] + shdmax_in=nc_file['shdmax'][j,i] + zorl_in=nc_file['zorl'][j,i] + slmsk_in=nc_file['slmsk'][j,i] + canopy_in=nc_file['canopy'][j,i] + hice_in=nc_file['hice'][j,i] + fice_in=nc_file['fice'][j,i] + tisfc_in=nc_file['tisfc'][j,i] + snwdph_in=nc_file['snwdph'][j,i] + snoalb_in=nc_file['snoalb'][j,i] + sheleg_in=nc_file['sheleg'][j,i] + else: + #the sfc_data.tileX.nc files created from chgres_cube have an extra time dimension in front compared to those created from global_chgres + ts_in=nc_file['tsea'][0,j,i] + + # land state + stc_in=nc_file['stc'][0,:,j,i] + smc_in=nc_file['smc'][0,:,j,i] + slc_in=nc_file['slc'][0,:,j,i] + tg3_in=nc_file['tg3'][0,j,i] + + # surface properties + uustar_in=nc_file['uustar'][0,j,i] + alvsf_in=nc_file['alvsf'][0,j,i] + alvwf_in=nc_file['alvwf'][0,j,i] + alnsf_in=nc_file['alnsf'][0,j,i] + alnwf_in=nc_file['alnwf'][0,j,i] + facsf_in=nc_file['facsf'][0,j,i] + facwf_in=nc_file['facwf'][0,j,i] + styp_in=nc_file['stype'][0,j,i] + slope_in=nc_file['slope'][0,j,i] + vtyp_in=nc_file['vtype'][0,j,i] + vfrac_in=nc_file['vfrac'][0,j,i] + shdmin_in=nc_file['shdmin'][0,j,i] + shdmax_in=nc_file['shdmax'][0,j,i] + zorl_in=nc_file['zorl'][0,j,i] + slmsk_in=nc_file['slmsk'][0,j,i] + canopy_in=nc_file['canopy'][0,j,i] + hice_in=nc_file['hice'][0,j,i] + fice_in=nc_file['fice'][0,j,i] + tisfc_in=nc_file['tisfc'][0,j,i] + snwdph_in=nc_file['snwdph'][0,j,i] + snoalb_in=nc_file['snoalb'][0,j,i] + sheleg_in=nc_file['sheleg'][0,j,i] nc_file.close() @@ -472,13 +552,13 @@ def get_UFS_grid_area(dir, tile, i, j): for f_name in os.listdir(dir): if fnmatch.fnmatch(f_name, filename_pattern): - file_name = f_name - if not file_name: + filename = f_name + if not filename: message = 'No filenames matching the pattern {0} found in {1}'.format(filename_pattern,dir) logging.critical(message) raise Exception(message) - nc_file = Dataset('{0}/{1}'.format(dir,file_name)) + nc_file = Dataset('{0}/{1}'.format(dir,filename)) # extract out area of grid cell @@ -1438,7 +1518,7 @@ def main(): setup_logging() #read in arguments - (location, indices, date, in_dir, grid_dir, tile, area, noahmp, case_name) = parse_arguments() + (location, indices, date, in_dir, grid_dir, tile, area, noahmp, case_name, old_chgres) = parse_arguments() #find tile containing the point using the supergrid if no tile is specified if not tile: @@ -1464,7 +1544,7 @@ def main(): print 'This index has a central longitude/latitude of [{0},{1}]'.format(point_lon,point_lat) #get UFS IC data (TODO: flag to read in RESTART data rather than IC data and implement different file reads) - (state_data, surface_data, oro_data) = get_UFS_IC_data(in_dir, tile, tile_i, tile_j) + (state_data, surface_data, oro_data) = get_UFS_IC_data(in_dir, tile, tile_i, tile_j, old_chgres) #cold start NoahMP variables if (noahmp): diff --git a/scm/etc/scripts/f90nml-0.19/AUTHORS b/scm/etc/scripts/f90nml-0.19/AUTHORS deleted file mode 100644 index dc65d7303..000000000 --- a/scm/etc/scripts/f90nml-0.19/AUTHORS +++ /dev/null @@ -1,20 +0,0 @@ -Marshall Ward - - Maintainer, Creator - -Jacob Williams - - Derived type support and testing - -Michael Lamparski - - File object support - -Martin Dix - - Sparse array support - -Huziy Oleksander - - Streamlined namelist output interface - -Kai Li - - Python 2.6 output support - -dwwork - - Multidimensional support diff --git a/scm/etc/scripts/f90nml-0.19/CHANGELOG b/scm/etc/scripts/f90nml-0.19/CHANGELOG deleted file mode 100644 index 24593c1ca..000000000 --- a/scm/etc/scripts/f90nml-0.19/CHANGELOG +++ /dev/null @@ -1,38 +0,0 @@ -v0.19: - - Array patching is now supported - - Numpy primitives can be converted to Fortran types - - File objects can now be used as input arguments - -v0.18: - - File object read and write support - - Escape (\) character support in strings - - Fortran floating point `E` symbol is now optional (with +/- exponent) - -v0.17: - - `f90nml.write()` works for normal (non-`Namelist`) dicts - - `Parser` properties moved outside of function arguments, and are now - handled with property decorators (as in `Namelist`) - - Namelists built from (unsorted) dicts are now pre-sorted by key - -v0.16: - - User-defined comment delimiters (e.g. `#` comment support) - -v0.15: - - Null values are now always followed by commas - -v0.14: - - Default logical parsing is now more strict. Only `true`, `false`, `t`, - and `f` (and with surrounding `.`) are now parsed to equivalent values. - - Extensive documentation update - -v0.13: - - Multidimensional array support - -v0.12: - - Namelist output formatting (column width, indent, etc.) - - Improved user-defined type output support - - Arch (AUR) distribution configuration - - Setuptools is now the install default - -v0.11: - - TODO diff --git a/scm/etc/scripts/f90nml-0.19/LICENSE b/scm/etc/scripts/f90nml-0.19/LICENSE deleted file mode 100644 index f433b1a53..000000000 --- a/scm/etc/scripts/f90nml-0.19/LICENSE +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/scm/etc/scripts/f90nml-0.19/MANIFEST.in b/scm/etc/scripts/f90nml-0.19/MANIFEST.in deleted file mode 100644 index c6ff2c48d..000000000 --- a/scm/etc/scripts/f90nml-0.19/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -recursive-include test *.nml *.txt -recursive-include docs/source * -include docs/Makefile -include AUTHORS -include CHANGELOG -include LICENSE -include MANIFEST.in -include NOTICE -include README.rst diff --git a/scm/etc/scripts/f90nml-0.19/NOTICE b/scm/etc/scripts/f90nml-0.19/NOTICE deleted file mode 100644 index 8ead04afa..000000000 --- a/scm/etc/scripts/f90nml-0.19/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ - Copyright 2014 Marshall Ward - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/scm/etc/scripts/f90nml-0.19/PKG-INFO b/scm/etc/scripts/f90nml-0.19/PKG-INFO deleted file mode 100644 index bb3f65ce1..000000000 --- a/scm/etc/scripts/f90nml-0.19/PKG-INFO +++ /dev/null @@ -1,139 +0,0 @@ -Metadata-Version: 1.1 -Name: f90nml -Version: 0.19 -Summary: Fortran 90 namelist parser -Home-page: http://github.com/marshallward/f90nml -Author: Marshall Ward -Author-email: f90nml@marshallward.org -License: UNKNOWN -Description: ====== - f90nml - ====== - - A Python module for parsing Fortran namelist files - - .. image:: https://travis-ci.org/marshallward/f90nml.svg?branch=master - :target: https://travis-ci.org/marshallward/f90nml - - .. image:: https://coveralls.io/repos/marshallward/f90nml/badge.png?branch=master - :target: https://coveralls.io/r/marshallward/f90nml?branch=master - - Documentation: http://f90nml.readthedocs.org/en/latest/ - - - About f90nml - ============ - - ``f90nml`` is a Python module that provides a simple interface for the reading, - writing, and the general manipulation of Fortran namelist files. - - A namelist file is parsed and converted into an ``Namelist`` object, which - behaves like a standard Python ``dict``. Values are converted from Fortran - data types to equivalent primitive Python types. - - - Quick usage guide - ================= - - To read a namelist file ``sample.nml`` which contains the following namelists: - - .. code:: fortran - - &config_nml - input = 'wind.nc' - steps = 864 - layout = 8, 16 - visc = 1e-4 - use_biharmonic = .false. - / - - we would use the following script: - - .. code:: python - - import f90nml - nml = f90nml.read('sample.nml') - - which would would point ``nml`` to the following ``dict``: - - .. code:: python - - nml = {'config_nml': - {'input': 'wind.nc', - 'steps': 864, - 'layout': [8, 16], - 'visc': 0.0001 - 'use_biharmonic': False - } - } - - File objects can also be used as inputs: - - .. code:: python - - with open('sample.nml') as nml_file: - nml = f90nml.read(nml_file) - - To modify one of the values, say ``steps``, and save the output, just - manipulate the ``nml`` contents and write to disk using the ``write`` function: - - .. code:: python - - nml['config_nml']['steps'] = 432 - nml.write('new_sample.nml') - - Namelists can also be saved to file objects: - - .. code:: python - - with open('target.nml') as nml_file: - nml.write(nml_file) - - To modify a namelist but preserve its comments and formatting, create a - namelist patch and apply it to a target file using the ``patch`` function: - - .. code:: python - - patch_nml = {'config_nml': {'visc': 1e-6}} - nml.patch('sample.nml', 'new_sample.nml', patch_nml) - - - Installation - ============ - - ``f90nml`` is available on PyPI and can be installed via pip:: - - $ pip install f90nml - - It is also available on Arch Linux via the AUR:: - - $ git clone https://aur.archlinux.org/python-f90nml.git - $ cd python-f90nml - $ makepkg -sri - - ``f90nml`` is not yet available on other Linux distributions. - - The latest version of ``f90nml`` can be installed from source:: - - $ git clone https://github.com/marshallward/f90nml.git - $ cd f90nml - $ python setup.py install - - Users without install privileges can append the ``--user`` flag to - ``setup.py``:: - - $ python setup.py --user install - -Platform: UNKNOWN -Classifier: Development Status :: 4 - Beta -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.2 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Topic :: Utilities diff --git a/scm/etc/scripts/f90nml-0.19/README.rst b/scm/etc/scripts/f90nml-0.19/README.rst deleted file mode 100644 index fa4fa396c..000000000 --- a/scm/etc/scripts/f90nml-0.19/README.rst +++ /dev/null @@ -1,117 +0,0 @@ -====== -f90nml -====== - -A Python module for parsing Fortran namelist files - -.. image:: https://travis-ci.org/marshallward/f90nml.svg?branch=master - :target: https://travis-ci.org/marshallward/f90nml - -.. image:: https://coveralls.io/repos/marshallward/f90nml/badge.png?branch=master - :target: https://coveralls.io/r/marshallward/f90nml?branch=master - -Documentation: http://f90nml.readthedocs.org/en/latest/ - - -About f90nml -============ - -``f90nml`` is a Python module that provides a simple interface for the reading, -writing, and the general manipulation of Fortran namelist files. - -A namelist file is parsed and converted into an ``Namelist`` object, which -behaves like a standard Python ``dict``. Values are converted from Fortran -data types to equivalent primitive Python types. - - -Quick usage guide -================= - -To read a namelist file ``sample.nml`` which contains the following namelists: - -.. code:: fortran - - &config_nml - input = 'wind.nc' - steps = 864 - layout = 8, 16 - visc = 1e-4 - use_biharmonic = .false. - / - -we would use the following script: - -.. code:: python - - import f90nml - nml = f90nml.read('sample.nml') - -which would would point ``nml`` to the following ``dict``: - -.. code:: python - - nml = {'config_nml': - {'input': 'wind.nc', - 'steps': 864, - 'layout': [8, 16], - 'visc': 0.0001 - 'use_biharmonic': False - } - } - -File objects can also be used as inputs: - -.. code:: python - - with open('sample.nml') as nml_file: - nml = f90nml.read(nml_file) - -To modify one of the values, say ``steps``, and save the output, just -manipulate the ``nml`` contents and write to disk using the ``write`` function: - -.. code:: python - - nml['config_nml']['steps'] = 432 - nml.write('new_sample.nml') - -Namelists can also be saved to file objects: - -.. code:: python - - with open('target.nml') as nml_file: - nml.write(nml_file) - -To modify a namelist but preserve its comments and formatting, create a -namelist patch and apply it to a target file using the ``patch`` function: - -.. code:: python - - patch_nml = {'config_nml': {'visc': 1e-6}} - nml.patch('sample.nml', 'new_sample.nml', patch_nml) - - -Installation -============ - -``f90nml`` is available on PyPI and can be installed via pip:: - - $ pip install f90nml - -It is also available on Arch Linux via the AUR:: - - $ git clone https://aur.archlinux.org/python-f90nml.git - $ cd python-f90nml - $ makepkg -sri - -``f90nml`` is not yet available on other Linux distributions. - -The latest version of ``f90nml`` can be installed from source:: - - $ git clone https://github.com/marshallward/f90nml.git - $ cd f90nml - $ python setup.py install - -Users without install privileges can append the ``--user`` flag to -``setup.py``:: - - $ python setup.py --user install diff --git a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/__init__.py b/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/__init__.py deleted file mode 100644 index f841fe434..000000000 --- a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/__init__.py +++ /dev/null @@ -1,112 +0,0 @@ -"""f90nml - ====== - - A Fortran 90 namelist parser and generator. - - :copyright: Copyright 2014 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" -from f90nml.parser import Parser -from f90nml.namelist import Namelist - -__version__ = '0.19' - - -def read(nml_path, row_major=None, strict_logical=None): - """Parse a Fortran 90 namelist file ``nml_file`` or file path ``nml_path`` - and return its contents as a ``Namelist``. - - File object usage: - - >>> with open(nml_path) as nml_file: - >>> nml = f90nml.read(nml_file) - - File path usage: - - >>> nml = f90nml.read(nml_path) - - This function is equivalent to the ``read`` function of the ``Parser`` - object. - - >>> parser = f90nml.Parser() - >>> nml = parser.read(nml_file) - - Multidimensional array data contiguity is preserved by default, so that - column-major Fortran data is represented as row-major Python list of - lists. - - The ``row_major`` flag will reorder the data to preserve the index rules - between Fortran to Python, but the data will be converted to row-major form - (with respect to Fortran). - - The ``strict_logical`` flag will limit the parsing of non-delimited logical - strings as logical values. The default value is ``True``. - - When ``strict_logical`` is enabled, only ``.true.``, ``.t.``, ``true``, and - ``t`` are interpreted as ``True``, and only ``.false.``, ``.f.``, - ``false``, and ``.false.`` are interpreted as false. - - When ``strict_logical`` is disabled, any value starting with ``.t`` or - ``t`` are interpreted as ``True``, while any string starting with ``.f`` or - ``f`` is interpreted as ``False``.""" - - parser = Parser() - parser.row_major = row_major - parser.strict_logical = strict_logical - - return parser.read(nml_path) - - -def write(nml, nml_path, force=False): - """Output namelist ``nml`` to a Fortran 90 namelist file ``nml_file`` or - file path ``nml_path``. - - File object usage: - - >>> with open(nml_path, 'w') as nml_file: - >>> f90nml.write(nml, nml_file) - - File path usage: - - >>> f90nml.write(nml, 'data.nml') - - This function is equivalent to the ``write`` function of the ``Namelist`` - object ``nml``. - - >>> nml.write('data.nml') - - By default, ``write`` will not overwrite an existing file. To override - this, use the ``force`` flag. - - >>> nml.write('data.nml', force=True)""" - - # Promote dicts to Namelists - if not isinstance(nml, Namelist) and isinstance(nml, dict): - nml_in = Namelist(nml) - else: - nml_in = nml - - nml_in.write(nml_path, force=force) - - -def patch(nml_path, nml_patch, out_path=None, row_major=None, - strict_logical=None): - """Create a new namelist based on an input namelist and reference dict. - - >>> f90nml.patch('data.nml', nml_patch, 'patched_data.nml') - - This function is equivalent to the ``read`` function of the ``Parser`` - object with the patch output arguments. - - >>> parser = f90nml.Parser() - >>> nml = parser.read('data.nml', nml_path, 'patched_data.nml') - - A patched namelist file will retain any formatting or comments from the - original namelist file. Any modified values will be formatted based on the - settings of the ``Namelist`` object.""" - - parser = Parser() - parser.row_major = row_major - parser.strict_logical = strict_logical - - return parser.read(nml_path, nml_patch, out_path) diff --git a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/findex.py b/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/findex.py deleted file mode 100644 index df471cb5a..000000000 --- a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/findex.py +++ /dev/null @@ -1,41 +0,0 @@ -"""f90nml.findex - ============= - - Column-major Fortran iterator of indices across multipe dimensions. - - :copyright: Copyright 2015 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" - - -class FIndex(object): - """Column-major multidimensional index iterator""" - - def __init__(self, bounds): - self.start = [1 if not b[0] else b[0] for b in bounds] - self.end = [b[1] for b in bounds] - self.step = [1 if not b[2] else b[2] for b in bounds] - - self.current = self.start[:] - - def __iter__(self): - return self - - def next(self): - return self.__next__() - - def __next__(self): - if self.end[-1] and self.current[-1] >= self.end[-1]: - raise StopIteration - - state = self.current[:] - # Allow the final index to exceed self.end[-1] as a finalisation check - for rank, idx in enumerate(self.current): - if ((not self.end[rank] or idx < (self.end[rank] - 1)) or - rank == (len(self.current) - 1)): - self.current[rank] = idx + self.step[rank] - break - else: - self.current[rank] = self.start[rank] - - return state diff --git a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/fpy.py b/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/fpy.py deleted file mode 100644 index f42fdac08..000000000 --- a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/fpy.py +++ /dev/null @@ -1,67 +0,0 @@ -"""f90nml.fpy - ============= - - Module for conversion between basic data types and Fortran string - representations. - - :copyright: Copyright 2014 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" -import re - - -def pyfloat(v_str): - """Convert string repr of Fortran floating point to Python double.""" - # NOTE: There is no loss of information from SP to DP floats - - return float(re.sub('(?<=[^eEdD])(?=[+-])', 'e', - v_str.lower().replace('d', 'e'))) - - -def pycomplex(v_str): - """Convert string repr of Fortran complex to Python complex.""" - assert isinstance(v_str, str) - - if v_str[0] == '(' and v_str[-1] == ')' and len(v_str.split(',')) == 2: - v_re, v_im = v_str[1:-1].split(',', 1) - - # NOTE: Failed float(str) will raise ValueError - return complex(pyfloat(v_re), pyfloat(v_im)) - else: - raise ValueError('{0} must be in complex number form (x, y).' - ''.format(v_str)) - - -def pybool(v_str, strict_logical=True): - """Convert string repr of Fortran logical to Python logical.""" - assert isinstance(v_str, str) - assert isinstance(strict_logical, bool) - - if strict_logical: - v_bool = v_str.lower() - else: - try: - if v_str.startswith('.'): - v_bool = v_str[1].lower() - else: - v_bool = v_str[0].lower() - except IndexError: - raise ValueError('{0} is not a valid logical constant.' - ''.format(v_str)) - - if v_bool in ('.true.', '.t.', 'true', 't'): - return True - elif v_bool in ('.false.', '.f.', 'false', 'f'): - return False - else: - raise ValueError('{0} is not a valid logical constant.'.format(v_str)) - - -def pystr(v_str): - """Convert string repr of Fortran string to Python string.""" - assert isinstance(v_str, str) - - if v_str[0] in ("'", '"') and v_str[0] == v_str[-1]: - return v_str[1:-1] - else: - return v_str diff --git a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/namelist.py b/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/namelist.py deleted file mode 100644 index a5f06f72f..000000000 --- a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/namelist.py +++ /dev/null @@ -1,377 +0,0 @@ -"""f90nml.namelist - =============== - - Tools for creating Fortran namelist files from Python ``dict``s. - - :copyright: Copyright 2014 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" -from __future__ import print_function - -import numbers -import os -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict - - -class Namelist(OrderedDict): - """Case-insensitive Python dict""" - - def __init__(self, *args, **kwds): - - # If using (unordered) dict, then resort the keys for reproducibility - s_args = list(args) - if (args and not isinstance(args[0], OrderedDict) and - isinstance(args[0], dict)): - s_args[0] = sorted(args[0].items()) - - super(Namelist, self).__init__(*s_args, **kwds) - - # Convert any internal dicts to Namelists - for key, val in self.items(): - if isinstance(val, dict): - self[key] = Namelist(val) - - # Formatting properties - self._colwidth = 72 - self._indent = 4 * ' ' - self._end_comma = False - self._uppercase = False - self._floatformat = '' - self._logical_repr = {False: '.false.', True: '.true.'} - - # Namelist group spacing flag - self._newline = False - - def __contains__(self, key): - return super(Namelist, self).__contains__(key.lower()) - - def __delitem__(self, key): - return super(Namelist, self).__delitem__(key.lower()) - - def __getitem__(self, key): - return super(Namelist, self).__getitem__(key.lower()) - - def __setitem__(self, key, value): - super(Namelist, self).__setitem__(key.lower(), value) - - # Format configuration - - # Column width - @property - def colwidth(self): - """Return the target column width of the namelist file.""" - return self._colwidth - - @colwidth.setter - def colwidth(self, width): - """Validate and set the column width.""" - if isinstance(width, int): - if width >= 0: - self._colwidth = width - else: - raise ValueError('Column width must be nonnegative.') - else: - raise TypeError('Column width must be a nonnegative integer.') - - # Variable indent - @property - def indent(self): - """Return the indentation string within namelist group entries.""" - return self._indent - - @indent.setter - def indent(self, value): - """Validate and set the indent width, either as an explicit whitespace - string or by the number of whitespace characters. - """ - - # Explicit indent setting - if isinstance(value, str): - if value.isspace(): - self._indent = value - else: - raise ValueError('String indentation can only contain ' - 'whitespace.') - - # Set indent width - elif isinstance(value, int): - if value >= 0: - self._indent = value * ' ' - else: - raise ValueError('Indentation spacing must be nonnegative.') - - else: - raise TypeError('Indentation must be specified by string or space ' - 'width.') - - # Terminal comma - @property - def end_comma(self): - """Return True if entries are terminated with commas.""" - return self._end_comma - - @end_comma.setter - def end_comma(self, value): - """Validate and set the comma termination flag.""" - if not isinstance(value, bool): - raise TypeError('end_comma attribute must be a logical type.') - self._end_comma = value - - # Uppercase - @property - def uppercase(self): - """Return True if names are displayed in upper case.""" - return self._uppercase - - @uppercase.setter - def uppercase(self, value): - """Validate and set the upper case flag.""" - if not isinstance(value, bool): - raise TypeError('uppercase attribute must be a logical type.') - self._uppercase = value - - # Float format - @property - def floatformat(self): - """Return the current floating point format code.""" - return self._floatformat - - @floatformat.setter - def floatformat(self, value): - """Validate and set the upper case flag.""" - if isinstance(value, str): - # Duck-test the format string; raise ValueError on fail - '{0:{1}}'.format(1.23, value) - - self._floatformat = value - else: - raise TypeError('Floating point format code must be a string.') - - # Logical representation - # NOTE: This presumes that bools and ints are identical as dict keys - @property - def logical_repr(self): - """Return the namelist representations of logical values.""" - return self._logical_repr - - @logical_repr.setter - def logical_repr(self, value): - """Set the namelist representations of logical values.""" - - if not any(isinstance(value, t) for t in (list, tuple)): - raise TypeError("Logical representation must be a tuple with " - "a valid true and false value.") - if not len(value) == 2: - raise ValueError("List must contain two values.") - - self.false_repr = value[0] - self.true_repr = value[1] - - @property - def true_repr(self): - """Return the namelist representation of logical true.""" - return self._logical_repr[1] - - @true_repr.setter - def true_repr(self, value): - """Validate and set the logical true representation.""" - if isinstance(value, str): - if not (value.lower().startswith('t') or - value.lower().startswith('.t')): - raise ValueError("Logical true representation must start with " - "'T' or '.T'.") - else: - self._logical_repr[1] = value - else: - raise TypeError('Logical true representation must be a string.') - - @property - def false_repr(self): - """Return the namelist representation of logical false.""" - return self._logical_repr[0] - - @false_repr.setter - def false_repr(self, value): - """Validate and set the logical false representation.""" - if isinstance(value, str): - if not (value.lower().startswith('f') or - value.lower().startswith('.f')): - raise ValueError("Logical false representation must start " - "with 'F' or '.F'.") - else: - self._logical_repr[0] = value - else: - raise TypeError('Logical false representation must be a string.') - - # File output - - def write(self, nml_path, force=False): - """Output dict to a Fortran 90 namelist file.""" - - # Reset newline flag - self._newline = False - - nml_is_file = hasattr(nml_path, 'read') - if not force and not nml_is_file and os.path.isfile(nml_path): - raise IOError('File {0} already exists.'.format(nml_path)) - - nml_file = nml_path if nml_is_file else open(nml_path, 'w') - try: - for grp_name, grp_vars in self.items(): - # Check for repeated namelist records (saved as lists) - if isinstance(grp_vars, list): - for g_vars in grp_vars: - self.write_nmlgrp(grp_name, g_vars, nml_file) - else: - self.write_nmlgrp(grp_name, grp_vars, nml_file) - finally: - if not nml_is_file: - nml_file.close() - - def write_nmlgrp(self, grp_name, grp_vars, nml_file): - """Write namelist group to target file.""" - - if self._newline: - print(file=nml_file) - self._newline = True - - if self.uppercase: - grp_name = grp_name.upper() - - print('&{0}'.format(grp_name), file=nml_file) - - for v_name, v_val in grp_vars.items(): - - for v_str in self.var_strings(v_name, v_val): - nml_line = self.indent + '{0}'.format(v_str) - print(nml_line, file=nml_file) - - print('/', file=nml_file) - - def var_strings(self, v_name, v_values, v_idx=None): - """Convert namelist variable to list of fixed-width strings.""" - - if self.uppercase: - v_name = v_name.upper() - - var_strs = [] - - # Parse derived type contents - if isinstance(v_values, dict): - for f_name, f_vals in v_values.items(): - v_title = '%'.join([v_name, f_name]) - - v_strs = self.var_strings(v_title, f_vals) - var_strs.extend(v_strs) - - # Parse an array of derived types - elif (isinstance(v_values, list) and - any(isinstance(v, dict) for v in v_values) and - all((isinstance(v, dict) or v is None) for v in v_values)): - for idx, val in enumerate(v_values, start=1): - - if val is None: - continue - - v_title = v_name + '({0})'.format(idx) - - v_strs = self.var_strings(v_title, val) - var_strs.extend(v_strs) - - # Parse a multidimensional array - # TODO: Merge with the array of derived types - elif (isinstance(v_values, list) and - any(isinstance(v, list) for v in v_values) and - all((isinstance(v, list) or v is None) for v in v_values)): - - if not v_idx: - v_idx = [] - - v_title = v_name - for idx, val in enumerate(v_values, start=1): - - v_idx_new = v_idx + [idx] - v_strs = self.var_strings(v_title, val, v_idx_new) - var_strs.extend(v_strs) - - else: - if not isinstance(v_values, list): - v_values = [v_values] - - if v_idx: - v_name += '(:, ' + ', '.join(str(i) for i in v_idx[::-1]) + ')' - - # Split output across multiple lines (if necessary) - val_strs = [] - - val_line = '' - for v_val in v_values: - - v_width = self.colwidth - len(self.indent + v_name + ' = ') - - if len(val_line) < v_width: - val_line += self.f90repr(v_val) + ', ' - - if len(val_line) >= v_width: - val_strs.append(val_line.rstrip()) - val_line = '' - - # Append any remaining values - if val_line: - if self.end_comma or v_values[-1] is None: - val_strs.append(val_line) - else: - val_strs.append(val_line[:-2]) - - # Complete the set of values - if val_strs: - var_strs.append('{0} = {1}' - ''.format(v_name, val_strs[0]).strip()) - - for v_str in val_strs[1:]: - var_strs.append(' ' * (len(v_name + ' = ')) + v_str) - - return var_strs - - def f90repr(self, value): - """Convert primitive Python types to equivalent Fortran strings.""" - - if isinstance(value, bool): - return self.f90bool(value) - elif isinstance(value, numbers.Integral): - return self.f90int(value) - elif isinstance(value, numbers.Real): - return self.f90float(value) - elif isinstance(value, numbers.Complex): - return self.f90complex(value) - elif isinstance(value, str): - return self.f90str(value) - elif value is None: - return '' - else: - raise ValueError('Type {0} of {1} cannot be converted to a Fortran' - ' type.'.format(type(value), value)) - - def f90bool(self, value): - """Return a Fortran 90 representation of a logical value.""" - return self.logical_repr[value] - - def f90int(self, value): - """Return a Fortran 90 representation of an integer.""" - return str(value) - - def f90float(self, value): - """Return a Fortran 90 representation of a floating point number.""" - return '{0:{fmt}}'.format(value, fmt=self.floatformat) - - def f90complex(self, value): - """Return a Fortran 90 representation of a complex number.""" - return '({0:{fmt}}, {1:{fmt}})'.format(value.real, value.imag, - fmt=self.floatformat) - - def f90str(self, value): - """Return a Fortran 90 representation of a string.""" - return repr(value).replace("\\'", "''").replace('\\"', '""').replace('\\\\', '\\') diff --git a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/parser.py b/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/parser.py deleted file mode 100644 index 9c45981c3..000000000 --- a/scm/etc/scripts/f90nml-0.19/build/lib/f90nml/parser.py +++ /dev/null @@ -1,573 +0,0 @@ -"""f90nml.parser - ============= - - Fortran namelist parser and tokenizer to convert contents into a hierarchy - of dicts containing intrinsic Python data types. - - :copyright: Copyright 2014 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" -import copy -import shlex -from string import whitespace - -from f90nml.fpy import pyfloat, pycomplex, pybool, pystr -from f90nml.namelist import Namelist -from f90nml.findex import FIndex - - -class Parser(object): - """shlex-based Fortran namelist parser.""" - - def __init__(self): - - # Token management - self.tokens = None - self.token = None - self.prior_token = None - - # Patching - self.pfile = None - - # Control flags - self._row_major = False - self._strict_logical = True - - # Configuration - self.comment_tokens = '!' - - @property - def row_major(self): - """Return true if multidimensional arrays are in row-major format.""" - return self._row_major - - @row_major.setter - def row_major(self, value): - """Validate and set row-major format for multidimensional arrays.""" - - if value is not None: - if not isinstance(value, bool): - raise ValueError( - 'f90nml: error: row_major must be a logical value.') - else: - self._row_major = value - - @property - def strict_logical(self): - """Return true for strict logical value parsing.""" - return self._strict_logical - - @strict_logical.setter - def strict_logical(self, value): - """Validate and set the strict logical flag.""" - - if value is not None: - if not isinstance(value, bool): - raise ValueError( - 'f90nml: error: strict_logical must be a logical value.') - else: - self._strict_logical = value - - def read(self, nml_fname, nml_patch_in=None, patch_fname=None): - """Parse a Fortran namelist file and store the contents. - - >>> from f90nml.parser import Parser - >>> parser = Parser() - >>> data_nml = parser.read('data.nml')""" - - # For switching based on files versus paths - nml_is_path = not hasattr(nml_fname, 'read') - patch_is_path = not hasattr(patch_fname, 'read') - - # Convert patch data to a Namelist object - if nml_patch_in: - if not isinstance(nml_patch_in, dict): - raise ValueError('Input patch must be a dict or a Namelist.') - - nml_patch = copy.deepcopy(Namelist(nml_patch_in)) - - if not patch_fname and nml_is_path: - patch_fname = nml_fname + '~' - elif not patch_fname: - raise ValueError('f90nml: error: No output file for patch.') - elif nml_fname == patch_fname: - raise ValueError('f90nml: error: Patch filepath cannot be the ' - 'same as the original filepath.') - if patch_is_path: - self.pfile = open(patch_fname, 'w') - else: - self.pfile = patch_fname - else: - nml_patch = Namelist() - - try: - nml_file = open(nml_fname, 'r') if nml_is_path else nml_fname - try: - return self.readstream(nml_file, nml_patch) - - # Close the files we opened on any exceptions within readstream - finally: - if nml_is_path: - nml_file.close() - finally: - if self.pfile and patch_is_path: - self.pfile.close() - - def readstream(self, nml_file, nml_patch): - """Parse an input stream containing a Fortran namelist.""" - - f90lex = shlex.shlex(nml_file) - f90lex.whitespace = '' - f90lex.wordchars += '.-+' # Include floating point tokens - if nml_patch: - f90lex.commenters = '' - else: - f90lex.commenters = self.comment_tokens - - self.tokens = iter(f90lex) - - nmls = Namelist() - - # TODO: Replace "while True" with an update_token() iterator - self.update_tokens(write_token=False) - while True: - try: - # Check for classic group terminator - if self.token == 'end': - self.update_tokens() - - # Ignore tokens outside of namelist groups - while self.token not in ('&', '$'): - self.update_tokens() - - except StopIteration: - break - - # Create the next namelist - self.update_tokens() - g_name = self.token - - g_vars = Namelist() - v_name = None - - # TODO: Edit `Namelist` to support case-insensitive `get` calls - grp_patch = nml_patch.get(g_name.lower(), {}) - - # Populate the namelist group - while g_name: - - if self.token not in ('=', '%', '('): - self.update_tokens() - - # Set the next active variable - if self.token in ('=', '(', '%'): - - v_name, v_values = self.parse_variable(g_vars, - patch_nml=grp_patch) - - if v_name in g_vars: - v_prior_values = g_vars[v_name] - v_values = merge_values(v_prior_values, v_values) - - if v_name in g_vars and isinstance(g_vars[v_name], dict): - g_vars[v_name].update(v_values) - else: - g_vars[v_name] = v_values - - # Deselect variable - v_name = None - v_values = [] - - # Finalise namelist group - if self.token in ('/', '&', '$'): - - # Append any remaining patched variables - for v_name, v_val in grp_patch.items(): - g_vars[v_name] = v_val - v_strs = nmls.var_strings(v_name, v_val) - for v_str in v_strs: - self.pfile.write(' {0}\n'.format(v_str)) - - # Append the grouplist to the namelist - if g_name in nmls: - g_update = nmls[g_name] - - # Update to list of groups - if not isinstance(g_update, list): - g_update = [g_update] - - g_update.append(g_vars) - - else: - g_update = g_vars - - nmls[g_name] = g_update - - # Reset state - g_name, g_vars = None, None - - try: - self.update_tokens() - except StopIteration: - break - - return nmls - - def parse_variable(self, parent, patch_nml=None): - """Parse a variable and return its name and values.""" - - if not patch_nml: - patch_nml = Namelist() - - v_name = self.prior_token - v_values = [] - - # Patch state - patch_values = None - - if self.token == '(': - - v_idx_bounds = self.parse_indices() - v_idx = FIndex(v_idx_bounds) - - self.update_tokens() - else: - v_idx = None - - if self.token == '%': - - # Resolve the derived type - - if parent and v_name in parent: - v_parent = parent[v_name] - else: - v_parent = [] - - self.update_tokens() - self.update_tokens() - - v_att, v_att_vals = self.parse_variable(v_parent) - - next_value = Namelist() - next_value[v_att] = v_att_vals - self.append_value(v_values, next_value, v_idx) - - else: - # Construct the variable array - - assert self.token == '=' - n_vals = None - prior_ws_sep = ws_sep = False - - self.update_tokens() - - # Check if value is in the namelist patch - # TODO: Edit `Namelist` to support case-insensitive `pop` calls - # (Currently only a problem in PyPy2) - if v_name in patch_nml: - patch_values = patch_nml.pop(v_name.lower()) - - if not isinstance(patch_values, list): - patch_values = [patch_values] - - p_idx = 0 - - # Add variables until next variable trigger - while (self.token not in ('=', '(', '%') or - (self.prior_token, self.token) == ('=', '(')): - - # Check for repeated values - if self.token == '*': - n_vals = self.parse_value() - assert isinstance(n_vals, int) - self.update_tokens() - elif not n_vals: - n_vals = 1 - - # First check for implicit null values - if self.prior_token in ('=', '%', ','): - if (self.token in (',', '/', '&', '$') and - not (self.prior_token == ',' and - self.token in ('/', '&', '$'))): - self.append_value(v_values, None, v_idx, n_vals) - - elif self.prior_token == '*': - - if self.token not in ('/', '&', '$'): - self.update_tokens() - - if (self.token == '=' or (self.token in ('/', '&', '$') and - self.prior_token == '*')): - next_value = None - else: - next_value = self.parse_value() - - self.append_value(v_values, next_value, v_idx, n_vals) - - else: - next_value = self.parse_value() - - # Check for escaped strings - if (v_values and isinstance(v_values[-1], str) and - isinstance(next_value, str) and not prior_ws_sep): - - quote_char = self.prior_token[0] - v_values[-1] = quote_char.join([v_values[-1], - next_value]) - else: - self.append_value(v_values, next_value, v_idx, n_vals) - - # Exit for end of nml group (/, &, $) or null broadcast (=) - if self.token in ('/', '&', '$', '='): - break - else: - prior_ws_sep = ws_sep - if (patch_values and p_idx < len(patch_values) and - len(patch_values) > 0 and self.token != ','): - p_val = patch_values[p_idx] - p_repr = patch_nml.f90repr(patch_values[p_idx]) - p_idx += 1 - ws_sep = self.update_tokens(override=p_repr) - if isinstance(p_val, complex): - # Skip over the complex content - # NOTE: Assumes input and patch are complex - self.update_tokens(write_token=False) - self.update_tokens(write_token=False) - self.update_tokens(write_token=False) - self.update_tokens(write_token=False) - else: - ws_sep = self.update_tokens() - - if patch_values: - v_values = patch_values - - if not v_idx: - v_values = delist(v_values) - - return v_name, v_values - - def parse_indices(self): - """Parse a sequence of Fortran vector indices as a list of tuples.""" - - v_name = self.prior_token - v_indices = [] - - while self.token in (',', '('): - v_indices.append(self.parse_index(v_name)) - - return v_indices - - def parse_index(self, v_name): - """Parse Fortran vector indices into a tuple of Python indices.""" - - i_start = i_end = i_stride = None - - # Start index - self.update_tokens() - try: - i_start = int(self.token) - self.update_tokens() - except ValueError: - if self.token in (',', ')'): - raise ValueError('{0} index cannot be empty.'.format(v_name)) - elif not self.token == ':': - raise - - # End index - if self.token == ':': - self.update_tokens() - try: - i_end = 1 + int(self.token) - self.update_tokens() - except ValueError: - if self.token == ':': - raise ValueError('{0} end index cannot be implicit ' - 'when using stride.'.format(v_name)) - elif self.token not in (',', ')'): - raise - elif self.token in (',', ')'): - # Replace index with single-index range - if i_start: - i_end = 1 + i_start - - # Stride index - if self.token == ':': - self.update_tokens() - try: - i_stride = int(self.token) - except ValueError: - if self.token == ')': - raise ValueError('{0} stride index cannot be ' - 'implicit.'.format(v_name)) - else: - raise - - if i_stride == 0: - raise ValueError('{0} stride index cannot be zero.' - ''.format(v_name)) - - self.update_tokens() - - if self.token not in (',', ')'): - raise ValueError('{0} index did not terminate ' - 'correctly.'.format(v_name)) - - idx_triplet = (i_start, i_end, i_stride) - return idx_triplet - - def parse_value(self, write_token=True, override=None): - """Convert string repr of Fortran type to equivalent Python type.""" - v_str = self.prior_token - - # Construct the complex string - if v_str == '(': - v_re = self.token - - self.update_tokens(write_token) - assert self.token == ',' - - self.update_tokens(write_token) - v_im = self.token - - self.update_tokens(write_token) - assert self.token == ')' - - self.update_tokens(write_token, override) - v_str = '({0}, {1})'.format(v_re, v_im) - - recast_funcs = [int, pyfloat, pycomplex, pybool, pystr] - - for f90type in recast_funcs: - try: - # Unclever hack.. integrate this better - if f90type == pybool: - value = pybool(v_str, self.strict_logical) - else: - value = f90type(v_str) - return value - except ValueError: - continue - - def update_tokens(self, write_token=True, override=None): - """Update tokens to the next available values.""" - - ws_sep = False - next_token = next(self.tokens) - - if self.pfile and write_token: - token = override if override else self.token - self.pfile.write(token) - - # Commas between values are interpreted as whitespace - if self.token == ',': - ws_sep = True - - while next_token in tuple(whitespace + '!'): - - if self.pfile: - if next_token == '!': - while not next_token == '\n': - self.pfile.write(next_token) - next_token = next(self.tokens) - self.pfile.write(next_token) - - ws_sep = True - next_token = next(self.tokens) - - self.token, self.prior_token = next_token, self.token - - return ws_sep - - def append_value(self, v_values, next_value, v_idx=None, n_vals=1): - """Update a list of parsed values with a new value.""" - - for _ in range(n_vals): - if v_idx: - v_i = next(v_idx) - - if not self.row_major: - v_i = v_i[::-1] - - # Multidimensional arrays - # TODO: support both row and column ordering in Python - - v_tmp = v_values - for idx in v_i[:-1]: - try: - v_tmp = v_tmp[idx - 1] - except IndexError: - size = len(v_tmp) - v_tmp.extend([] for i in range(size, idx)) - v_tmp = v_tmp[idx - 1] - - try: - v_tmp[v_i[-1] - 1] = next_value - except IndexError: - size = len(v_tmp) - v_tmp.extend(None for i in range(size, v_i[-1])) - v_tmp[v_i[-1] - 1] = next_value - else: - v_values.append(next_value) - - -# Support functions - -def merge_values(src, new): - """Merge two lists or dicts into a single element.""" - - if isinstance(src, dict) and isinstance(new, dict): - return merge_dicts(src, new) - else: - if not isinstance(src, list): - src = [src] - if not isinstance(new, list): - new = [new] - - return merge_lists(src, new) - - -def merge_lists(src, new): - """Update a value list with a list of new or updated values.""" - - l_min, l_max = (src, new) if len(src) < len(new) else (new, src) - - l_min.extend(None for i in range(len(l_min), len(l_max))) - - for i, val in enumerate(new): - if isinstance(val, dict) and isinstance(src[i], dict): - new[i] = merge_dicts(src[i], val) - elif isinstance(val, list) and isinstance(src[i], list): - new[i] = merge_lists(src[i], val) - elif val is not None: - new[i] = val - else: - new[i] = src[i] - - return new - - -def merge_dicts(src, patch): - """Merge contents of dict `patch` into `src`.""" - - for key in patch: - if key in src: - if isinstance(src[key], dict) and isinstance(patch[key], dict): - merge_dicts(src[key], patch[key]) - else: - src[key] = merge_values(src[key], patch[key]) - else: - src[key] = patch[key] - - return src - - -def delist(values): - """Reduce lists of zero or one elements to individual values.""" - assert isinstance(values, list) - - if not values: - return None - elif len(values) == 1: - return values[0] - else: - return values diff --git a/scm/etc/scripts/f90nml-0.19/dist/f90nml-0.19-py2.6.egg b/scm/etc/scripts/f90nml-0.19/dist/f90nml-0.19-py2.6.egg deleted file mode 100644 index e179cdd4c..000000000 Binary files a/scm/etc/scripts/f90nml-0.19/dist/f90nml-0.19-py2.6.egg and /dev/null differ diff --git a/scm/etc/scripts/f90nml-0.19/dist/f90nml-0.19-py2.7.egg b/scm/etc/scripts/f90nml-0.19/dist/f90nml-0.19-py2.7.egg deleted file mode 100644 index 92809d5f6..000000000 Binary files a/scm/etc/scripts/f90nml-0.19/dist/f90nml-0.19-py2.7.egg and /dev/null differ diff --git a/scm/etc/scripts/f90nml-0.19/docs/Makefile b/scm/etc/scripts/f90nml-0.19/docs/Makefile deleted file mode 100644 index 29c28b656..000000000 --- a/scm/etc/scripts/f90nml-0.19/docs/Makefile +++ /dev/null @@ -1,153 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/f90nml.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/f90nml.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/f90nml" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/f90nml" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/scm/etc/scripts/f90nml-0.19/docs/source/conf.py b/scm/etc/scripts/f90nml-0.19/docs/source/conf.py deleted file mode 100644 index eeedd7983..000000000 --- a/scm/etc/scripts/f90nml-0.19/docs/source/conf.py +++ /dev/null @@ -1,211 +0,0 @@ -import os -import sys - -sys.path.insert(1, '../../') -import f90nml - -# Path to extensions -sys.path.insert(0, os.path.dirname(os.path.abspath(os.pardir))) - -# Sphinx setup -#needs_sphinx = '1.0' -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage'] -templates_path = ['_templates'] -source_suffix = '.rst' -#source_encoding = 'utf-8-sig' -master_doc = 'index' - -# General information about the project. -project = f90nml.__name__ -version = f90nml.__version__ -release = f90nml.__version__ -#copyright = "Copyright 2014-2015 Marshall Ward, see AUTHORS for details." - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'sphinxdoc' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'f90nmldoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'f90nml.tex', u'f90nml Documentation', - u'Marshall Ward', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'f90nml', u'f90nml Documentation', - [u'Marshall Ward'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'f90nml', u'f90nml Documentation', - u'Marshall Ward', 'f90nml', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' diff --git a/scm/etc/scripts/f90nml-0.19/docs/source/index.rst b/scm/etc/scripts/f90nml-0.19/docs/source/index.rst deleted file mode 100644 index d0cb14a82..000000000 --- a/scm/etc/scripts/f90nml-0.19/docs/source/index.rst +++ /dev/null @@ -1,265 +0,0 @@ -============================================================== -``f90nml`` -- A Fortran namelist parser, generator, and editor -============================================================== - -A Python module for parsing Fortran namelist files - -.. image:: https://travis-ci.org/marshallward/f90nml.svg?branch=master - :target: https://travis-ci.org/marshallward/f90nml - -.. image:: https://coveralls.io/repos/marshallward/f90nml/badge.png?branch=master - :target: https://coveralls.io/r/marshallward/f90nml?branch=master - - -About ``f90nml`` -================ - -``f90nml`` is a Python module that provides a simple interface for the reading, -writing, and the general manipulation of Fortran namelist files. - -A namelist file is parsed and converted into an ``Namelist`` object, which -behaves like a standard Python ``dict``. Values are converted from Fortran -data types to equivalent primitive Python types. - - -Quick usage guide -================= - -To read a namelist file ``sample.nml`` which contains the following namelists: - -.. code:: fortran - - &config_nml - input = 'wind.nc' - steps = 864 - layout = 8, 16 - visc = 1e-4 - use_biharmonic = .false. - / - -we would use the following script: - -.. code:: python - - import f90nml - nml = f90nml.read('sample.nml') - -which would would point ``nml`` to the following ``dict``: - -.. code:: python - - nml = {'config_nml': - {'input': 'wind.nc', - 'steps': 864, - 'layout': [8, 16], - 'visc': 0.0001 - 'use_biharmonic': False - } - } - -File objects can also be used as inputs: - -.. code:: python - - with open('sample.nml') as nml_file: - nml = f90nml.read(nml_file) - -To modify one of the values, say ``steps``, and save the output, just -manipulate the ``nml`` contents and write to disk using the ``write`` function: - -.. code:: python - - nml['config_nml']['steps'] = 432 - nml.write('new_sample.nml') - -Namelists can also be saved to file objects: - -.. code:: python - - with open('target.nml') as nml_file: - nml.write(nml_file) - -To modify a namelist but preserve its comments and formatting, create a -namelist (or ``dict``) patch and apply it to a target file using the ``patch`` -function: - -.. code:: python - - patch_nml = {'config_nml': {'visc': 1e-6}} - f90nml.patch('sample.nml', patch_nml, 'new_sample.nml') - - -Installation -============ - -``f90nml`` is available on PyPI and can be installed via pip:: - - $ pip install f90nml - -It is also available on Arch Linux via the AUR:: - - $ git clone https://aur.archlinux.org/python-f90nml.git - $ cd python-f90nml - $ makepkg -sri - -``f90nml`` is not yet available on other Linux distributions. - -The latest version of ``f90nml`` can be installed from source:: - - $ git clone https://github.com/marshallward/f90nml.git - $ cd f90nml - $ python setup.py install - -Users without install privileges can append the ``--user`` flag to -``setup.py``:: - - $ python setup.py --user install - - -Basic Usage -=========== - -.. autofunction:: f90nml.read - -.. autofunction:: f90nml.write - -.. autofunction:: f90nml.patch - - -Notes -===== - -Data types ----------- - -Fortran namelists do not contain any information about data type, which is -determined by the target variables of the Fortran executable. ``f90nml`` -infers the data type based on the value, but not all cases can be explicitly -resolved. - -``f90nml`` tests values as one of each data type in the order listed below: - -* Integer - -* Floating point - -* Complex floating point - -* Logical (boolean) - -* String - -Strings acts as a fallback type. If a value cannot be matched to any other -value, then it is interpreted as a string. - -In order to get the best results from ``f90nml``, it is best to follow these -guidelines: - -* All strings should be enclosed by string delimiters (``'``, ``"``). - -* Floating point values should use decimals (``.``) or `E notation`_. - -* Array indices should be explicit - -* Array values should be separated by commas (``,``) - -.. _E notation: https://en.wikipedia.org/wiki/Scientific_notation#E_notation - - -Derived Types -------------- - -User-defined types are saved as a nested hierarcy of ``dict``\ s. For example, -the following namelist - -.. code:: fortran - - &dtype_nml - a%b%c = 1 - / - -would be saved as the following ``Namelist``: - -.. code:: python - - nml = {'dtype_nml': - {'a': - {'b': - {'c': 1} - } - } - } - - -Output formatting ------------------ - -The output format of ``f90nml.write`` can be altered by modifying the -properties of the ``Namelist`` object. The properties for a sample namelist -``nml`` are shown below. - -``nml.colwidth`` (Default: 72) - Maximum number of characters per line of the namelist file. Tokens longer - than ``colwidth`` are allowed to extend past this limit. - -``nml.indent`` (Default: 4) - Whitespace indentation. This can be set to an integer, denoting the number - of spaces, or to an explicit whitespace character, such as a tab (``\t``). - -``nml.end_comma`` (Default: ``False``) - Append a comma (``,``) to the end of each namelist entry. - -``nml.uppercase`` (Default: ``False``) - Display namelist and variable names in uppercase. - -``nml.floatformat`` (Default: ``None``) - Specify the floating point output format, as expected by Python ``format`` - function. - -``nml.logical_repr`` (Default: ``.false., .true.``) - String representation of logical values ``False`` and ``True``. The - properties ``true_repr`` and ``false_repr`` are also provided as interfaces - to the ``logical_repr`` tuple. - - -Comment tokens --------------- - -Some Fortran programs will introduce alternative comment tokens (e.g. ``#``) -for internal preprocessing. - -If you need to support these tokens, create a ``Parser`` object and set the -comment token as follows: - -.. code:: python - - parser = f90nml.Parser() - parser.comment_tokens += '#' - nml = Parser.read('sample.nml') - -Be aware that this is non-standard Fortran and could mangle any strings using -the '#' characters. Characters inside string delimiters should be protected. - - -Classes -======= - -.. autoclass:: f90nml.parser.Parser - -.. autoclass:: f90nml.namelist.Namelist - -.. autoclass:: f90nml.findex.FIndex - - -Licensing -========= - -``f90nml`` is distributed under the `Apache 2.0 License`_. - -.. _Apache 2.0 License: - http://www.apache.org/licenses/LICENSE-2.0.txt - -Contact -======= - -Marshall Ward diff --git a/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/PKG-INFO b/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/PKG-INFO deleted file mode 100644 index bb3f65ce1..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/PKG-INFO +++ /dev/null @@ -1,139 +0,0 @@ -Metadata-Version: 1.1 -Name: f90nml -Version: 0.19 -Summary: Fortran 90 namelist parser -Home-page: http://github.com/marshallward/f90nml -Author: Marshall Ward -Author-email: f90nml@marshallward.org -License: UNKNOWN -Description: ====== - f90nml - ====== - - A Python module for parsing Fortran namelist files - - .. image:: https://travis-ci.org/marshallward/f90nml.svg?branch=master - :target: https://travis-ci.org/marshallward/f90nml - - .. image:: https://coveralls.io/repos/marshallward/f90nml/badge.png?branch=master - :target: https://coveralls.io/r/marshallward/f90nml?branch=master - - Documentation: http://f90nml.readthedocs.org/en/latest/ - - - About f90nml - ============ - - ``f90nml`` is a Python module that provides a simple interface for the reading, - writing, and the general manipulation of Fortran namelist files. - - A namelist file is parsed and converted into an ``Namelist`` object, which - behaves like a standard Python ``dict``. Values are converted from Fortran - data types to equivalent primitive Python types. - - - Quick usage guide - ================= - - To read a namelist file ``sample.nml`` which contains the following namelists: - - .. code:: fortran - - &config_nml - input = 'wind.nc' - steps = 864 - layout = 8, 16 - visc = 1e-4 - use_biharmonic = .false. - / - - we would use the following script: - - .. code:: python - - import f90nml - nml = f90nml.read('sample.nml') - - which would would point ``nml`` to the following ``dict``: - - .. code:: python - - nml = {'config_nml': - {'input': 'wind.nc', - 'steps': 864, - 'layout': [8, 16], - 'visc': 0.0001 - 'use_biharmonic': False - } - } - - File objects can also be used as inputs: - - .. code:: python - - with open('sample.nml') as nml_file: - nml = f90nml.read(nml_file) - - To modify one of the values, say ``steps``, and save the output, just - manipulate the ``nml`` contents and write to disk using the ``write`` function: - - .. code:: python - - nml['config_nml']['steps'] = 432 - nml.write('new_sample.nml') - - Namelists can also be saved to file objects: - - .. code:: python - - with open('target.nml') as nml_file: - nml.write(nml_file) - - To modify a namelist but preserve its comments and formatting, create a - namelist patch and apply it to a target file using the ``patch`` function: - - .. code:: python - - patch_nml = {'config_nml': {'visc': 1e-6}} - nml.patch('sample.nml', 'new_sample.nml', patch_nml) - - - Installation - ============ - - ``f90nml`` is available on PyPI and can be installed via pip:: - - $ pip install f90nml - - It is also available on Arch Linux via the AUR:: - - $ git clone https://aur.archlinux.org/python-f90nml.git - $ cd python-f90nml - $ makepkg -sri - - ``f90nml`` is not yet available on other Linux distributions. - - The latest version of ``f90nml`` can be installed from source:: - - $ git clone https://github.com/marshallward/f90nml.git - $ cd f90nml - $ python setup.py install - - Users without install privileges can append the ``--user`` flag to - ``setup.py``:: - - $ python setup.py --user install - -Platform: UNKNOWN -Classifier: Development Status :: 4 - Beta -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.2 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Topic :: Utilities diff --git a/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/SOURCES.txt b/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/SOURCES.txt deleted file mode 100644 index c01bc7500..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/SOURCES.txt +++ /dev/null @@ -1,70 +0,0 @@ -AUTHORS -CHANGELOG -LICENSE -MANIFEST.in -NOTICE -README.rst -setup.cfg -setup.py -docs/Makefile -docs/source/conf.py -docs/source/index.rst -f90nml/__init__.py -f90nml/findex.py -f90nml/fpy.py -f90nml/namelist.py -f90nml/parser.py -f90nml.egg-info/PKG-INFO -f90nml.egg-info/SOURCES.txt -f90nml.egg-info/dependency_links.txt -f90nml.egg-info/top_level.txt -test/bcast.nml -test/bcast_target.nml -test/comment.nml -test/comment_alt.nml -test/comment_patch.nml -test/comment_target.nml -test/dollar.nml -test/dollar_target.nml -test/dtype.nml -test/dtype_target.nml -test/empty.nml -test/ext_token.nml -test/f77.nml -test/f77_target.nml -test/float.nml -test/float_format.nml -test/float_target.nml -test/grp_repeat.nml -test/grp_repeat_target.nml -test/index_bad.nml -test/index_bad_end.nml -test/index_bad_start.nml -test/index_bad_stride.nml -test/index_empty.nml -test/index_empty_end.nml -test/index_empty_stride.nml -test/index_zero_stride.nml -test/logical.nml -test/logical_repr.nml -test/multidim.nml -test/multidim_target.nml -test/multiline.nml -test/multiline_colwidth.nml -test/null.nml -test/null_target.nml -test/numpy_types.nml -test/requirements_test.txt -test/string.nml -test/string_target.nml -test/test_f90nml.py -test/types.nml -test/types_dict.nml -test/types_end_comma.nml -test/types_indent_2.nml -test/types_indent_tab.nml -test/types_patch.nml -test/types_uppercase.nml -test/unset.nml -test/vector.nml -test/vector_target.nml \ No newline at end of file diff --git a/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/dependency_links.txt b/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/dependency_links.txt deleted file mode 100644 index 8b1378917..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/top_level.txt b/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/top_level.txt deleted file mode 100644 index 9476cdf4b..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -f90nml diff --git a/scm/etc/scripts/f90nml-0.19/f90nml/__init__.py b/scm/etc/scripts/f90nml-0.19/f90nml/__init__.py deleted file mode 100644 index f841fe434..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml/__init__.py +++ /dev/null @@ -1,112 +0,0 @@ -"""f90nml - ====== - - A Fortran 90 namelist parser and generator. - - :copyright: Copyright 2014 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" -from f90nml.parser import Parser -from f90nml.namelist import Namelist - -__version__ = '0.19' - - -def read(nml_path, row_major=None, strict_logical=None): - """Parse a Fortran 90 namelist file ``nml_file`` or file path ``nml_path`` - and return its contents as a ``Namelist``. - - File object usage: - - >>> with open(nml_path) as nml_file: - >>> nml = f90nml.read(nml_file) - - File path usage: - - >>> nml = f90nml.read(nml_path) - - This function is equivalent to the ``read`` function of the ``Parser`` - object. - - >>> parser = f90nml.Parser() - >>> nml = parser.read(nml_file) - - Multidimensional array data contiguity is preserved by default, so that - column-major Fortran data is represented as row-major Python list of - lists. - - The ``row_major`` flag will reorder the data to preserve the index rules - between Fortran to Python, but the data will be converted to row-major form - (with respect to Fortran). - - The ``strict_logical`` flag will limit the parsing of non-delimited logical - strings as logical values. The default value is ``True``. - - When ``strict_logical`` is enabled, only ``.true.``, ``.t.``, ``true``, and - ``t`` are interpreted as ``True``, and only ``.false.``, ``.f.``, - ``false``, and ``.false.`` are interpreted as false. - - When ``strict_logical`` is disabled, any value starting with ``.t`` or - ``t`` are interpreted as ``True``, while any string starting with ``.f`` or - ``f`` is interpreted as ``False``.""" - - parser = Parser() - parser.row_major = row_major - parser.strict_logical = strict_logical - - return parser.read(nml_path) - - -def write(nml, nml_path, force=False): - """Output namelist ``nml`` to a Fortran 90 namelist file ``nml_file`` or - file path ``nml_path``. - - File object usage: - - >>> with open(nml_path, 'w') as nml_file: - >>> f90nml.write(nml, nml_file) - - File path usage: - - >>> f90nml.write(nml, 'data.nml') - - This function is equivalent to the ``write`` function of the ``Namelist`` - object ``nml``. - - >>> nml.write('data.nml') - - By default, ``write`` will not overwrite an existing file. To override - this, use the ``force`` flag. - - >>> nml.write('data.nml', force=True)""" - - # Promote dicts to Namelists - if not isinstance(nml, Namelist) and isinstance(nml, dict): - nml_in = Namelist(nml) - else: - nml_in = nml - - nml_in.write(nml_path, force=force) - - -def patch(nml_path, nml_patch, out_path=None, row_major=None, - strict_logical=None): - """Create a new namelist based on an input namelist and reference dict. - - >>> f90nml.patch('data.nml', nml_patch, 'patched_data.nml') - - This function is equivalent to the ``read`` function of the ``Parser`` - object with the patch output arguments. - - >>> parser = f90nml.Parser() - >>> nml = parser.read('data.nml', nml_path, 'patched_data.nml') - - A patched namelist file will retain any formatting or comments from the - original namelist file. Any modified values will be formatted based on the - settings of the ``Namelist`` object.""" - - parser = Parser() - parser.row_major = row_major - parser.strict_logical = strict_logical - - return parser.read(nml_path, nml_patch, out_path) diff --git a/scm/etc/scripts/f90nml-0.19/f90nml/findex.py b/scm/etc/scripts/f90nml-0.19/f90nml/findex.py deleted file mode 100644 index df471cb5a..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml/findex.py +++ /dev/null @@ -1,41 +0,0 @@ -"""f90nml.findex - ============= - - Column-major Fortran iterator of indices across multipe dimensions. - - :copyright: Copyright 2015 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" - - -class FIndex(object): - """Column-major multidimensional index iterator""" - - def __init__(self, bounds): - self.start = [1 if not b[0] else b[0] for b in bounds] - self.end = [b[1] for b in bounds] - self.step = [1 if not b[2] else b[2] for b in bounds] - - self.current = self.start[:] - - def __iter__(self): - return self - - def next(self): - return self.__next__() - - def __next__(self): - if self.end[-1] and self.current[-1] >= self.end[-1]: - raise StopIteration - - state = self.current[:] - # Allow the final index to exceed self.end[-1] as a finalisation check - for rank, idx in enumerate(self.current): - if ((not self.end[rank] or idx < (self.end[rank] - 1)) or - rank == (len(self.current) - 1)): - self.current[rank] = idx + self.step[rank] - break - else: - self.current[rank] = self.start[rank] - - return state diff --git a/scm/etc/scripts/f90nml-0.19/f90nml/fpy.py b/scm/etc/scripts/f90nml-0.19/f90nml/fpy.py deleted file mode 100644 index f42fdac08..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml/fpy.py +++ /dev/null @@ -1,67 +0,0 @@ -"""f90nml.fpy - ============= - - Module for conversion between basic data types and Fortran string - representations. - - :copyright: Copyright 2014 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" -import re - - -def pyfloat(v_str): - """Convert string repr of Fortran floating point to Python double.""" - # NOTE: There is no loss of information from SP to DP floats - - return float(re.sub('(?<=[^eEdD])(?=[+-])', 'e', - v_str.lower().replace('d', 'e'))) - - -def pycomplex(v_str): - """Convert string repr of Fortran complex to Python complex.""" - assert isinstance(v_str, str) - - if v_str[0] == '(' and v_str[-1] == ')' and len(v_str.split(',')) == 2: - v_re, v_im = v_str[1:-1].split(',', 1) - - # NOTE: Failed float(str) will raise ValueError - return complex(pyfloat(v_re), pyfloat(v_im)) - else: - raise ValueError('{0} must be in complex number form (x, y).' - ''.format(v_str)) - - -def pybool(v_str, strict_logical=True): - """Convert string repr of Fortran logical to Python logical.""" - assert isinstance(v_str, str) - assert isinstance(strict_logical, bool) - - if strict_logical: - v_bool = v_str.lower() - else: - try: - if v_str.startswith('.'): - v_bool = v_str[1].lower() - else: - v_bool = v_str[0].lower() - except IndexError: - raise ValueError('{0} is not a valid logical constant.' - ''.format(v_str)) - - if v_bool in ('.true.', '.t.', 'true', 't'): - return True - elif v_bool in ('.false.', '.f.', 'false', 'f'): - return False - else: - raise ValueError('{0} is not a valid logical constant.'.format(v_str)) - - -def pystr(v_str): - """Convert string repr of Fortran string to Python string.""" - assert isinstance(v_str, str) - - if v_str[0] in ("'", '"') and v_str[0] == v_str[-1]: - return v_str[1:-1] - else: - return v_str diff --git a/scm/etc/scripts/f90nml-0.19/f90nml/namelist.py b/scm/etc/scripts/f90nml-0.19/f90nml/namelist.py deleted file mode 100644 index a5f06f72f..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml/namelist.py +++ /dev/null @@ -1,377 +0,0 @@ -"""f90nml.namelist - =============== - - Tools for creating Fortran namelist files from Python ``dict``s. - - :copyright: Copyright 2014 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" -from __future__ import print_function - -import numbers -import os -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict - - -class Namelist(OrderedDict): - """Case-insensitive Python dict""" - - def __init__(self, *args, **kwds): - - # If using (unordered) dict, then resort the keys for reproducibility - s_args = list(args) - if (args and not isinstance(args[0], OrderedDict) and - isinstance(args[0], dict)): - s_args[0] = sorted(args[0].items()) - - super(Namelist, self).__init__(*s_args, **kwds) - - # Convert any internal dicts to Namelists - for key, val in self.items(): - if isinstance(val, dict): - self[key] = Namelist(val) - - # Formatting properties - self._colwidth = 72 - self._indent = 4 * ' ' - self._end_comma = False - self._uppercase = False - self._floatformat = '' - self._logical_repr = {False: '.false.', True: '.true.'} - - # Namelist group spacing flag - self._newline = False - - def __contains__(self, key): - return super(Namelist, self).__contains__(key.lower()) - - def __delitem__(self, key): - return super(Namelist, self).__delitem__(key.lower()) - - def __getitem__(self, key): - return super(Namelist, self).__getitem__(key.lower()) - - def __setitem__(self, key, value): - super(Namelist, self).__setitem__(key.lower(), value) - - # Format configuration - - # Column width - @property - def colwidth(self): - """Return the target column width of the namelist file.""" - return self._colwidth - - @colwidth.setter - def colwidth(self, width): - """Validate and set the column width.""" - if isinstance(width, int): - if width >= 0: - self._colwidth = width - else: - raise ValueError('Column width must be nonnegative.') - else: - raise TypeError('Column width must be a nonnegative integer.') - - # Variable indent - @property - def indent(self): - """Return the indentation string within namelist group entries.""" - return self._indent - - @indent.setter - def indent(self, value): - """Validate and set the indent width, either as an explicit whitespace - string or by the number of whitespace characters. - """ - - # Explicit indent setting - if isinstance(value, str): - if value.isspace(): - self._indent = value - else: - raise ValueError('String indentation can only contain ' - 'whitespace.') - - # Set indent width - elif isinstance(value, int): - if value >= 0: - self._indent = value * ' ' - else: - raise ValueError('Indentation spacing must be nonnegative.') - - else: - raise TypeError('Indentation must be specified by string or space ' - 'width.') - - # Terminal comma - @property - def end_comma(self): - """Return True if entries are terminated with commas.""" - return self._end_comma - - @end_comma.setter - def end_comma(self, value): - """Validate and set the comma termination flag.""" - if not isinstance(value, bool): - raise TypeError('end_comma attribute must be a logical type.') - self._end_comma = value - - # Uppercase - @property - def uppercase(self): - """Return True if names are displayed in upper case.""" - return self._uppercase - - @uppercase.setter - def uppercase(self, value): - """Validate and set the upper case flag.""" - if not isinstance(value, bool): - raise TypeError('uppercase attribute must be a logical type.') - self._uppercase = value - - # Float format - @property - def floatformat(self): - """Return the current floating point format code.""" - return self._floatformat - - @floatformat.setter - def floatformat(self, value): - """Validate and set the upper case flag.""" - if isinstance(value, str): - # Duck-test the format string; raise ValueError on fail - '{0:{1}}'.format(1.23, value) - - self._floatformat = value - else: - raise TypeError('Floating point format code must be a string.') - - # Logical representation - # NOTE: This presumes that bools and ints are identical as dict keys - @property - def logical_repr(self): - """Return the namelist representations of logical values.""" - return self._logical_repr - - @logical_repr.setter - def logical_repr(self, value): - """Set the namelist representations of logical values.""" - - if not any(isinstance(value, t) for t in (list, tuple)): - raise TypeError("Logical representation must be a tuple with " - "a valid true and false value.") - if not len(value) == 2: - raise ValueError("List must contain two values.") - - self.false_repr = value[0] - self.true_repr = value[1] - - @property - def true_repr(self): - """Return the namelist representation of logical true.""" - return self._logical_repr[1] - - @true_repr.setter - def true_repr(self, value): - """Validate and set the logical true representation.""" - if isinstance(value, str): - if not (value.lower().startswith('t') or - value.lower().startswith('.t')): - raise ValueError("Logical true representation must start with " - "'T' or '.T'.") - else: - self._logical_repr[1] = value - else: - raise TypeError('Logical true representation must be a string.') - - @property - def false_repr(self): - """Return the namelist representation of logical false.""" - return self._logical_repr[0] - - @false_repr.setter - def false_repr(self, value): - """Validate and set the logical false representation.""" - if isinstance(value, str): - if not (value.lower().startswith('f') or - value.lower().startswith('.f')): - raise ValueError("Logical false representation must start " - "with 'F' or '.F'.") - else: - self._logical_repr[0] = value - else: - raise TypeError('Logical false representation must be a string.') - - # File output - - def write(self, nml_path, force=False): - """Output dict to a Fortran 90 namelist file.""" - - # Reset newline flag - self._newline = False - - nml_is_file = hasattr(nml_path, 'read') - if not force and not nml_is_file and os.path.isfile(nml_path): - raise IOError('File {0} already exists.'.format(nml_path)) - - nml_file = nml_path if nml_is_file else open(nml_path, 'w') - try: - for grp_name, grp_vars in self.items(): - # Check for repeated namelist records (saved as lists) - if isinstance(grp_vars, list): - for g_vars in grp_vars: - self.write_nmlgrp(grp_name, g_vars, nml_file) - else: - self.write_nmlgrp(grp_name, grp_vars, nml_file) - finally: - if not nml_is_file: - nml_file.close() - - def write_nmlgrp(self, grp_name, grp_vars, nml_file): - """Write namelist group to target file.""" - - if self._newline: - print(file=nml_file) - self._newline = True - - if self.uppercase: - grp_name = grp_name.upper() - - print('&{0}'.format(grp_name), file=nml_file) - - for v_name, v_val in grp_vars.items(): - - for v_str in self.var_strings(v_name, v_val): - nml_line = self.indent + '{0}'.format(v_str) - print(nml_line, file=nml_file) - - print('/', file=nml_file) - - def var_strings(self, v_name, v_values, v_idx=None): - """Convert namelist variable to list of fixed-width strings.""" - - if self.uppercase: - v_name = v_name.upper() - - var_strs = [] - - # Parse derived type contents - if isinstance(v_values, dict): - for f_name, f_vals in v_values.items(): - v_title = '%'.join([v_name, f_name]) - - v_strs = self.var_strings(v_title, f_vals) - var_strs.extend(v_strs) - - # Parse an array of derived types - elif (isinstance(v_values, list) and - any(isinstance(v, dict) for v in v_values) and - all((isinstance(v, dict) or v is None) for v in v_values)): - for idx, val in enumerate(v_values, start=1): - - if val is None: - continue - - v_title = v_name + '({0})'.format(idx) - - v_strs = self.var_strings(v_title, val) - var_strs.extend(v_strs) - - # Parse a multidimensional array - # TODO: Merge with the array of derived types - elif (isinstance(v_values, list) and - any(isinstance(v, list) for v in v_values) and - all((isinstance(v, list) or v is None) for v in v_values)): - - if not v_idx: - v_idx = [] - - v_title = v_name - for idx, val in enumerate(v_values, start=1): - - v_idx_new = v_idx + [idx] - v_strs = self.var_strings(v_title, val, v_idx_new) - var_strs.extend(v_strs) - - else: - if not isinstance(v_values, list): - v_values = [v_values] - - if v_idx: - v_name += '(:, ' + ', '.join(str(i) for i in v_idx[::-1]) + ')' - - # Split output across multiple lines (if necessary) - val_strs = [] - - val_line = '' - for v_val in v_values: - - v_width = self.colwidth - len(self.indent + v_name + ' = ') - - if len(val_line) < v_width: - val_line += self.f90repr(v_val) + ', ' - - if len(val_line) >= v_width: - val_strs.append(val_line.rstrip()) - val_line = '' - - # Append any remaining values - if val_line: - if self.end_comma or v_values[-1] is None: - val_strs.append(val_line) - else: - val_strs.append(val_line[:-2]) - - # Complete the set of values - if val_strs: - var_strs.append('{0} = {1}' - ''.format(v_name, val_strs[0]).strip()) - - for v_str in val_strs[1:]: - var_strs.append(' ' * (len(v_name + ' = ')) + v_str) - - return var_strs - - def f90repr(self, value): - """Convert primitive Python types to equivalent Fortran strings.""" - - if isinstance(value, bool): - return self.f90bool(value) - elif isinstance(value, numbers.Integral): - return self.f90int(value) - elif isinstance(value, numbers.Real): - return self.f90float(value) - elif isinstance(value, numbers.Complex): - return self.f90complex(value) - elif isinstance(value, str): - return self.f90str(value) - elif value is None: - return '' - else: - raise ValueError('Type {0} of {1} cannot be converted to a Fortran' - ' type.'.format(type(value), value)) - - def f90bool(self, value): - """Return a Fortran 90 representation of a logical value.""" - return self.logical_repr[value] - - def f90int(self, value): - """Return a Fortran 90 representation of an integer.""" - return str(value) - - def f90float(self, value): - """Return a Fortran 90 representation of a floating point number.""" - return '{0:{fmt}}'.format(value, fmt=self.floatformat) - - def f90complex(self, value): - """Return a Fortran 90 representation of a complex number.""" - return '({0:{fmt}}, {1:{fmt}})'.format(value.real, value.imag, - fmt=self.floatformat) - - def f90str(self, value): - """Return a Fortran 90 representation of a string.""" - return repr(value).replace("\\'", "''").replace('\\"', '""').replace('\\\\', '\\') diff --git a/scm/etc/scripts/f90nml-0.19/f90nml/parser.py b/scm/etc/scripts/f90nml-0.19/f90nml/parser.py deleted file mode 100644 index 9c45981c3..000000000 --- a/scm/etc/scripts/f90nml-0.19/f90nml/parser.py +++ /dev/null @@ -1,573 +0,0 @@ -"""f90nml.parser - ============= - - Fortran namelist parser and tokenizer to convert contents into a hierarchy - of dicts containing intrinsic Python data types. - - :copyright: Copyright 2014 Marshall Ward, see AUTHORS for details. - :license: Apache License, Version 2.0, see LICENSE for details. -""" -import copy -import shlex -from string import whitespace - -from f90nml.fpy import pyfloat, pycomplex, pybool, pystr -from f90nml.namelist import Namelist -from f90nml.findex import FIndex - - -class Parser(object): - """shlex-based Fortran namelist parser.""" - - def __init__(self): - - # Token management - self.tokens = None - self.token = None - self.prior_token = None - - # Patching - self.pfile = None - - # Control flags - self._row_major = False - self._strict_logical = True - - # Configuration - self.comment_tokens = '!' - - @property - def row_major(self): - """Return true if multidimensional arrays are in row-major format.""" - return self._row_major - - @row_major.setter - def row_major(self, value): - """Validate and set row-major format for multidimensional arrays.""" - - if value is not None: - if not isinstance(value, bool): - raise ValueError( - 'f90nml: error: row_major must be a logical value.') - else: - self._row_major = value - - @property - def strict_logical(self): - """Return true for strict logical value parsing.""" - return self._strict_logical - - @strict_logical.setter - def strict_logical(self, value): - """Validate and set the strict logical flag.""" - - if value is not None: - if not isinstance(value, bool): - raise ValueError( - 'f90nml: error: strict_logical must be a logical value.') - else: - self._strict_logical = value - - def read(self, nml_fname, nml_patch_in=None, patch_fname=None): - """Parse a Fortran namelist file and store the contents. - - >>> from f90nml.parser import Parser - >>> parser = Parser() - >>> data_nml = parser.read('data.nml')""" - - # For switching based on files versus paths - nml_is_path = not hasattr(nml_fname, 'read') - patch_is_path = not hasattr(patch_fname, 'read') - - # Convert patch data to a Namelist object - if nml_patch_in: - if not isinstance(nml_patch_in, dict): - raise ValueError('Input patch must be a dict or a Namelist.') - - nml_patch = copy.deepcopy(Namelist(nml_patch_in)) - - if not patch_fname and nml_is_path: - patch_fname = nml_fname + '~' - elif not patch_fname: - raise ValueError('f90nml: error: No output file for patch.') - elif nml_fname == patch_fname: - raise ValueError('f90nml: error: Patch filepath cannot be the ' - 'same as the original filepath.') - if patch_is_path: - self.pfile = open(patch_fname, 'w') - else: - self.pfile = patch_fname - else: - nml_patch = Namelist() - - try: - nml_file = open(nml_fname, 'r') if nml_is_path else nml_fname - try: - return self.readstream(nml_file, nml_patch) - - # Close the files we opened on any exceptions within readstream - finally: - if nml_is_path: - nml_file.close() - finally: - if self.pfile and patch_is_path: - self.pfile.close() - - def readstream(self, nml_file, nml_patch): - """Parse an input stream containing a Fortran namelist.""" - - f90lex = shlex.shlex(nml_file) - f90lex.whitespace = '' - f90lex.wordchars += '.-+' # Include floating point tokens - if nml_patch: - f90lex.commenters = '' - else: - f90lex.commenters = self.comment_tokens - - self.tokens = iter(f90lex) - - nmls = Namelist() - - # TODO: Replace "while True" with an update_token() iterator - self.update_tokens(write_token=False) - while True: - try: - # Check for classic group terminator - if self.token == 'end': - self.update_tokens() - - # Ignore tokens outside of namelist groups - while self.token not in ('&', '$'): - self.update_tokens() - - except StopIteration: - break - - # Create the next namelist - self.update_tokens() - g_name = self.token - - g_vars = Namelist() - v_name = None - - # TODO: Edit `Namelist` to support case-insensitive `get` calls - grp_patch = nml_patch.get(g_name.lower(), {}) - - # Populate the namelist group - while g_name: - - if self.token not in ('=', '%', '('): - self.update_tokens() - - # Set the next active variable - if self.token in ('=', '(', '%'): - - v_name, v_values = self.parse_variable(g_vars, - patch_nml=grp_patch) - - if v_name in g_vars: - v_prior_values = g_vars[v_name] - v_values = merge_values(v_prior_values, v_values) - - if v_name in g_vars and isinstance(g_vars[v_name], dict): - g_vars[v_name].update(v_values) - else: - g_vars[v_name] = v_values - - # Deselect variable - v_name = None - v_values = [] - - # Finalise namelist group - if self.token in ('/', '&', '$'): - - # Append any remaining patched variables - for v_name, v_val in grp_patch.items(): - g_vars[v_name] = v_val - v_strs = nmls.var_strings(v_name, v_val) - for v_str in v_strs: - self.pfile.write(' {0}\n'.format(v_str)) - - # Append the grouplist to the namelist - if g_name in nmls: - g_update = nmls[g_name] - - # Update to list of groups - if not isinstance(g_update, list): - g_update = [g_update] - - g_update.append(g_vars) - - else: - g_update = g_vars - - nmls[g_name] = g_update - - # Reset state - g_name, g_vars = None, None - - try: - self.update_tokens() - except StopIteration: - break - - return nmls - - def parse_variable(self, parent, patch_nml=None): - """Parse a variable and return its name and values.""" - - if not patch_nml: - patch_nml = Namelist() - - v_name = self.prior_token - v_values = [] - - # Patch state - patch_values = None - - if self.token == '(': - - v_idx_bounds = self.parse_indices() - v_idx = FIndex(v_idx_bounds) - - self.update_tokens() - else: - v_idx = None - - if self.token == '%': - - # Resolve the derived type - - if parent and v_name in parent: - v_parent = parent[v_name] - else: - v_parent = [] - - self.update_tokens() - self.update_tokens() - - v_att, v_att_vals = self.parse_variable(v_parent) - - next_value = Namelist() - next_value[v_att] = v_att_vals - self.append_value(v_values, next_value, v_idx) - - else: - # Construct the variable array - - assert self.token == '=' - n_vals = None - prior_ws_sep = ws_sep = False - - self.update_tokens() - - # Check if value is in the namelist patch - # TODO: Edit `Namelist` to support case-insensitive `pop` calls - # (Currently only a problem in PyPy2) - if v_name in patch_nml: - patch_values = patch_nml.pop(v_name.lower()) - - if not isinstance(patch_values, list): - patch_values = [patch_values] - - p_idx = 0 - - # Add variables until next variable trigger - while (self.token not in ('=', '(', '%') or - (self.prior_token, self.token) == ('=', '(')): - - # Check for repeated values - if self.token == '*': - n_vals = self.parse_value() - assert isinstance(n_vals, int) - self.update_tokens() - elif not n_vals: - n_vals = 1 - - # First check for implicit null values - if self.prior_token in ('=', '%', ','): - if (self.token in (',', '/', '&', '$') and - not (self.prior_token == ',' and - self.token in ('/', '&', '$'))): - self.append_value(v_values, None, v_idx, n_vals) - - elif self.prior_token == '*': - - if self.token not in ('/', '&', '$'): - self.update_tokens() - - if (self.token == '=' or (self.token in ('/', '&', '$') and - self.prior_token == '*')): - next_value = None - else: - next_value = self.parse_value() - - self.append_value(v_values, next_value, v_idx, n_vals) - - else: - next_value = self.parse_value() - - # Check for escaped strings - if (v_values and isinstance(v_values[-1], str) and - isinstance(next_value, str) and not prior_ws_sep): - - quote_char = self.prior_token[0] - v_values[-1] = quote_char.join([v_values[-1], - next_value]) - else: - self.append_value(v_values, next_value, v_idx, n_vals) - - # Exit for end of nml group (/, &, $) or null broadcast (=) - if self.token in ('/', '&', '$', '='): - break - else: - prior_ws_sep = ws_sep - if (patch_values and p_idx < len(patch_values) and - len(patch_values) > 0 and self.token != ','): - p_val = patch_values[p_idx] - p_repr = patch_nml.f90repr(patch_values[p_idx]) - p_idx += 1 - ws_sep = self.update_tokens(override=p_repr) - if isinstance(p_val, complex): - # Skip over the complex content - # NOTE: Assumes input and patch are complex - self.update_tokens(write_token=False) - self.update_tokens(write_token=False) - self.update_tokens(write_token=False) - self.update_tokens(write_token=False) - else: - ws_sep = self.update_tokens() - - if patch_values: - v_values = patch_values - - if not v_idx: - v_values = delist(v_values) - - return v_name, v_values - - def parse_indices(self): - """Parse a sequence of Fortran vector indices as a list of tuples.""" - - v_name = self.prior_token - v_indices = [] - - while self.token in (',', '('): - v_indices.append(self.parse_index(v_name)) - - return v_indices - - def parse_index(self, v_name): - """Parse Fortran vector indices into a tuple of Python indices.""" - - i_start = i_end = i_stride = None - - # Start index - self.update_tokens() - try: - i_start = int(self.token) - self.update_tokens() - except ValueError: - if self.token in (',', ')'): - raise ValueError('{0} index cannot be empty.'.format(v_name)) - elif not self.token == ':': - raise - - # End index - if self.token == ':': - self.update_tokens() - try: - i_end = 1 + int(self.token) - self.update_tokens() - except ValueError: - if self.token == ':': - raise ValueError('{0} end index cannot be implicit ' - 'when using stride.'.format(v_name)) - elif self.token not in (',', ')'): - raise - elif self.token in (',', ')'): - # Replace index with single-index range - if i_start: - i_end = 1 + i_start - - # Stride index - if self.token == ':': - self.update_tokens() - try: - i_stride = int(self.token) - except ValueError: - if self.token == ')': - raise ValueError('{0} stride index cannot be ' - 'implicit.'.format(v_name)) - else: - raise - - if i_stride == 0: - raise ValueError('{0} stride index cannot be zero.' - ''.format(v_name)) - - self.update_tokens() - - if self.token not in (',', ')'): - raise ValueError('{0} index did not terminate ' - 'correctly.'.format(v_name)) - - idx_triplet = (i_start, i_end, i_stride) - return idx_triplet - - def parse_value(self, write_token=True, override=None): - """Convert string repr of Fortran type to equivalent Python type.""" - v_str = self.prior_token - - # Construct the complex string - if v_str == '(': - v_re = self.token - - self.update_tokens(write_token) - assert self.token == ',' - - self.update_tokens(write_token) - v_im = self.token - - self.update_tokens(write_token) - assert self.token == ')' - - self.update_tokens(write_token, override) - v_str = '({0}, {1})'.format(v_re, v_im) - - recast_funcs = [int, pyfloat, pycomplex, pybool, pystr] - - for f90type in recast_funcs: - try: - # Unclever hack.. integrate this better - if f90type == pybool: - value = pybool(v_str, self.strict_logical) - else: - value = f90type(v_str) - return value - except ValueError: - continue - - def update_tokens(self, write_token=True, override=None): - """Update tokens to the next available values.""" - - ws_sep = False - next_token = next(self.tokens) - - if self.pfile and write_token: - token = override if override else self.token - self.pfile.write(token) - - # Commas between values are interpreted as whitespace - if self.token == ',': - ws_sep = True - - while next_token in tuple(whitespace + '!'): - - if self.pfile: - if next_token == '!': - while not next_token == '\n': - self.pfile.write(next_token) - next_token = next(self.tokens) - self.pfile.write(next_token) - - ws_sep = True - next_token = next(self.tokens) - - self.token, self.prior_token = next_token, self.token - - return ws_sep - - def append_value(self, v_values, next_value, v_idx=None, n_vals=1): - """Update a list of parsed values with a new value.""" - - for _ in range(n_vals): - if v_idx: - v_i = next(v_idx) - - if not self.row_major: - v_i = v_i[::-1] - - # Multidimensional arrays - # TODO: support both row and column ordering in Python - - v_tmp = v_values - for idx in v_i[:-1]: - try: - v_tmp = v_tmp[idx - 1] - except IndexError: - size = len(v_tmp) - v_tmp.extend([] for i in range(size, idx)) - v_tmp = v_tmp[idx - 1] - - try: - v_tmp[v_i[-1] - 1] = next_value - except IndexError: - size = len(v_tmp) - v_tmp.extend(None for i in range(size, v_i[-1])) - v_tmp[v_i[-1] - 1] = next_value - else: - v_values.append(next_value) - - -# Support functions - -def merge_values(src, new): - """Merge two lists or dicts into a single element.""" - - if isinstance(src, dict) and isinstance(new, dict): - return merge_dicts(src, new) - else: - if not isinstance(src, list): - src = [src] - if not isinstance(new, list): - new = [new] - - return merge_lists(src, new) - - -def merge_lists(src, new): - """Update a value list with a list of new or updated values.""" - - l_min, l_max = (src, new) if len(src) < len(new) else (new, src) - - l_min.extend(None for i in range(len(l_min), len(l_max))) - - for i, val in enumerate(new): - if isinstance(val, dict) and isinstance(src[i], dict): - new[i] = merge_dicts(src[i], val) - elif isinstance(val, list) and isinstance(src[i], list): - new[i] = merge_lists(src[i], val) - elif val is not None: - new[i] = val - else: - new[i] = src[i] - - return new - - -def merge_dicts(src, patch): - """Merge contents of dict `patch` into `src`.""" - - for key in patch: - if key in src: - if isinstance(src[key], dict) and isinstance(patch[key], dict): - merge_dicts(src[key], patch[key]) - else: - src[key] = merge_values(src[key], patch[key]) - else: - src[key] = patch[key] - - return src - - -def delist(values): - """Reduce lists of zero or one elements to individual values.""" - assert isinstance(values, list) - - if not values: - return None - elif len(values) == 1: - return values[0] - else: - return values diff --git a/scm/etc/scripts/f90nml-0.19/setup.cfg b/scm/etc/scripts/f90nml-0.19/setup.cfg deleted file mode 100644 index 6f08d0e3e..000000000 --- a/scm/etc/scripts/f90nml-0.19/setup.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[bdist_wheel] -universal = 1 - -[egg_info] -tag_build = -tag_date = 0 -tag_svn_revision = 0 - diff --git a/scm/etc/scripts/f90nml-0.19/setup.py b/scm/etc/scripts/f90nml-0.19/setup.py deleted file mode 100644 index 04b69097d..000000000 --- a/scm/etc/scripts/f90nml-0.19/setup.py +++ /dev/null @@ -1,45 +0,0 @@ -"""setup.py - ======== - Installation script for f90nml - - Additional configuration settings are in ``setup.cfg``. -""" - -try: - from setuptools import setup -except ImportError: - from distutils.core import setup - -project_name = 'f90nml' -project_version = __import__(project_name).__version__ -project_readme_fname = 'README.rst' - -with open(project_readme_fname) as f: - project_readme = f.read() - -setup( - name = project_name, - version = project_version, - description = 'Fortran 90 namelist parser', - long_description = project_readme, - author = 'Marshall Ward', - author_email = 'f90nml@marshallward.org', - url = 'http://github.com/marshallward/f90nml', - - packages = ['f90nml'], - - classifiers = [ - 'Development Status :: 4 - Beta', - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Topic :: Utilities', - ] -) diff --git a/scm/etc/scripts/f90nml-0.19/test/bcast.nml b/scm/etc/scripts/f90nml-0.19/test/bcast.nml deleted file mode 100644 index 8347d8979..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/bcast.nml +++ /dev/null @@ -1,10 +0,0 @@ -&bcast_nml - x = 2*2.0 - y = 3* - z = 4*.true. -/ - -&bcast_endnull_nml - x = 2*2.0 - y = 3* -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/bcast_target.nml b/scm/etc/scripts/f90nml-0.19/test/bcast_target.nml deleted file mode 100644 index a06f1d8fc..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/bcast_target.nml +++ /dev/null @@ -1,10 +0,0 @@ -&bcast_nml - x = 2.0, 2.0 - y = , , , - z = .true., .true., .true., .true. -/ - -&bcast_endnull_nml - x = 2.0, 2.0 - y = , , , -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/comment.nml b/scm/etc/scripts/f90nml-0.19/test/comment.nml deleted file mode 100644 index e87c77b0b..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/comment.nml +++ /dev/null @@ -1,8 +0,0 @@ -! This is an external comment -&comment_nml - v_cmt_inline = 123 ! This is an inline comment - ! This is a separate comment - v_cmt_in_str = 'This token ! is not a comment' - v_cmt_after_str = 'This ! is not a comment' ! But this is -/ -! This is a post-namelist comment diff --git a/scm/etc/scripts/f90nml-0.19/test/comment_alt.nml b/scm/etc/scripts/f90nml-0.19/test/comment_alt.nml deleted file mode 100644 index 77efaad0c..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/comment_alt.nml +++ /dev/null @@ -1,5 +0,0 @@ -&comment_alt_nml - x = 1 - #y = 2 - z = 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/comment_patch.nml b/scm/etc/scripts/f90nml-0.19/test/comment_patch.nml deleted file mode 100644 index 4104304e8..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/comment_patch.nml +++ /dev/null @@ -1,8 +0,0 @@ -! This is an external comment -&comment_nml - v_cmt_inline = 456 ! This is an inline comment - ! This is a separate comment - v_cmt_in_str = 'This token ! is not a comment' - v_cmt_after_str = 'This ! is not a comment' ! But this is -/ -! This is a post-namelist comment diff --git a/scm/etc/scripts/f90nml-0.19/test/comment_target.nml b/scm/etc/scripts/f90nml-0.19/test/comment_target.nml deleted file mode 100644 index 5510920e1..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/comment_target.nml +++ /dev/null @@ -1,5 +0,0 @@ -&comment_nml - v_cmt_inline = 123 - v_cmt_in_str = 'This token ! is not a comment' - v_cmt_after_str = 'This ! is not a comment' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/dollar.nml b/scm/etc/scripts/f90nml-0.19/test/dollar.nml deleted file mode 100644 index 693c206f6..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/dollar.nml +++ /dev/null @@ -1,3 +0,0 @@ -$dollar_nml - v = 1.00 -$ diff --git a/scm/etc/scripts/f90nml-0.19/test/dollar_target.nml b/scm/etc/scripts/f90nml-0.19/test/dollar_target.nml deleted file mode 100644 index 16b369405..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/dollar_target.nml +++ /dev/null @@ -1,3 +0,0 @@ -&dollar_nml - v = 1.0 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/dtype.nml b/scm/etc/scripts/f90nml-0.19/test/dtype.nml deleted file mode 100644 index f490df31d..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/dtype.nml +++ /dev/null @@ -1,45 +0,0 @@ -&dtype_nml - dt_scalar%val = 1 - dt_stack%outer%inner = 2 - dt_vector%vec = 1, 2, 3 -/ - -&dtype_multi_nml - dt%x = 1 - dt%y = 2 - dt%z = 3 -/ - -&dtype_nested_nml - f%g%x = 1 - f%g%y = 2 - f%g%z = 3 -/ - -&dtype_field_idx_nml - f%x(1) = 1 - f%x(2) = 2 - f%x(3) = 3 -/ - -&dtype_vec_nml - a%b(1)%c = 1 - a%b(1)%d = 2 - a%b(2)%c = 3 - a%b(2)%d = 4 - a%b(3)%c = 5 - a%b(3)%d = 6 -/ - -&dtype_sparse_vec_nml - a%b(2)%c = 2 -/ - -&dtype_single_value_vec_nml - a(1)%b = 1 -/ - -&dtype_single_vec_merge_nml - a%b(1)%c = 1 - a%b(1)%d = 2 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/dtype_target.nml b/scm/etc/scripts/f90nml-0.19/test/dtype_target.nml deleted file mode 100644 index 2231c71a2..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/dtype_target.nml +++ /dev/null @@ -1,43 +0,0 @@ -&dtype_nml - dt_scalar%val = 1 - dt_stack%outer%inner = 2 - dt_vector%vec = 1, 2, 3 -/ - -&dtype_multi_nml - dt%x = 1 - dt%y = 2 - dt%z = 3 -/ - -&dtype_nested_nml - f%g%x = 1 - f%g%y = 2 - f%g%z = 3 -/ - -&dtype_field_idx_nml - f%x = 1, 2, 3 -/ - -&dtype_vec_nml - a%b(1)%c = 1 - a%b(1)%d = 2 - a%b(2)%c = 3 - a%b(2)%d = 4 - a%b(3)%c = 5 - a%b(3)%d = 6 -/ - -&dtype_sparse_vec_nml - a%b(2)%c = 2 -/ - -&dtype_single_value_vec_nml - a(1)%b = 1 -/ - -&dtype_single_vec_merge_nml - a%b(1)%c = 1 - a%b(1)%d = 2 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/empty.nml b/scm/etc/scripts/f90nml-0.19/test/empty.nml deleted file mode 100644 index 0a4f8893a..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/empty.nml +++ /dev/null @@ -1,2 +0,0 @@ -&empty_nml -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/ext_token.nml b/scm/etc/scripts/f90nml-0.19/test/ext_token.nml deleted file mode 100644 index 02b8460ee..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/ext_token.nml +++ /dev/null @@ -1,7 +0,0 @@ -a -123 -&ext_token_nml - x = 1 -/ -456 -z diff --git a/scm/etc/scripts/f90nml-0.19/test/f77.nml b/scm/etc/scripts/f90nml-0.19/test/f77.nml deleted file mode 100644 index d79575999..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/f77.nml +++ /dev/null @@ -1,7 +0,0 @@ -&f77_nml - x = 123 -&end - -&next_f77_nml - y = 'abc' -&end diff --git a/scm/etc/scripts/f90nml-0.19/test/f77_target.nml b/scm/etc/scripts/f90nml-0.19/test/f77_target.nml deleted file mode 100644 index b7e90d70d..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/f77_target.nml +++ /dev/null @@ -1,7 +0,0 @@ -&f77_nml - x = 123 -/ - -&next_f77_nml - y = 'abc' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/float.nml b/scm/etc/scripts/f90nml-0.19/test/float.nml deleted file mode 100644 index 832f063bf..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/float.nml +++ /dev/null @@ -1,21 +0,0 @@ -&float_nml - v_float = 1.0 - v_decimal_end = 1. - v_negative = -1. - - v_single = 1.0e0 - v_double = 1.0d0 - - v_single_upper = 1.0E0 - v_double_upper = 1.0D0 - - v_positive_index = 1.0e+01 - v_negative_index = 1.0e-01 - - v_no_exp_pos = 1+0 - v_no_exp_neg = 1-0 - v_no_exp_pos_dot = 1.+0 - v_no_exp_neg_dot = 1.-0 - v_neg_no_exp_pos = -1+0 - v_neg_no_exp_neg = -1-0 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/float_format.nml b/scm/etc/scripts/f90nml-0.19/test/float_format.nml deleted file mode 100644 index 3b34eac97..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/float_format.nml +++ /dev/null @@ -1,17 +0,0 @@ -&float_nml - v_float = 1.000 - v_decimal_end = 1.000 - v_negative = -1.000 - v_single = 1.000 - v_double = 1.000 - v_single_upper = 1.000 - v_double_upper = 1.000 - v_positive_index = 10.000 - v_negative_index = 0.100 - v_no_exp_pos = 1.000 - v_no_exp_neg = 1.000 - v_no_exp_pos_dot = 1.000 - v_no_exp_neg_dot = 1.000 - v_neg_no_exp_pos = -1.000 - v_neg_no_exp_neg = -1.000 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/float_target.nml b/scm/etc/scripts/f90nml-0.19/test/float_target.nml deleted file mode 100644 index 8a448fcde..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/float_target.nml +++ /dev/null @@ -1,17 +0,0 @@ -&float_nml - v_float = 1.0 - v_decimal_end = 1.0 - v_negative = -1.0 - v_single = 1.0 - v_double = 1.0 - v_single_upper = 1.0 - v_double_upper = 1.0 - v_positive_index = 10.0 - v_negative_index = 0.1 - v_no_exp_pos = 1.0 - v_no_exp_neg = 1.0 - v_no_exp_pos_dot = 1.0 - v_no_exp_neg_dot = 1.0 - v_neg_no_exp_pos = -1.0 - v_neg_no_exp_neg = -1.0 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/grp_repeat.nml b/scm/etc/scripts/f90nml-0.19/test/grp_repeat.nml deleted file mode 100644 index c831cbfac..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/grp_repeat.nml +++ /dev/null @@ -1,12 +0,0 @@ -&grp_repeat_nml - x = 1 -/ -&grp_repeat_nml - x = 2 -/ -&CASE_CHECK_nml - y = 1 -/ -&CASE_CHECK_nml - y = 2 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/grp_repeat_target.nml b/scm/etc/scripts/f90nml-0.19/test/grp_repeat_target.nml deleted file mode 100644 index 7119512d5..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/grp_repeat_target.nml +++ /dev/null @@ -1,15 +0,0 @@ -&grp_repeat_nml - x = 1 -/ - -&grp_repeat_nml - x = 2 -/ - -&case_check_nml - y = 1 -/ - -&case_check_nml - y = 2 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/index_bad.nml b/scm/etc/scripts/f90nml-0.19/test/index_bad.nml deleted file mode 100644 index 94a844ca7..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/index_bad.nml +++ /dev/null @@ -1,3 +0,0 @@ -&bad_index_nml - y(~) = 1, 2, 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/index_bad_end.nml b/scm/etc/scripts/f90nml-0.19/test/index_bad_end.nml deleted file mode 100644 index 23638d80e..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/index_bad_end.nml +++ /dev/null @@ -1,3 +0,0 @@ -&bad_index_nml - y(1:~) = 1, 2, 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/index_bad_start.nml b/scm/etc/scripts/f90nml-0.19/test/index_bad_start.nml deleted file mode 100644 index 4f085facb..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/index_bad_start.nml +++ /dev/null @@ -1,3 +0,0 @@ -&bad_index_nml - y(1~) = 1, 2, 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/index_bad_stride.nml b/scm/etc/scripts/f90nml-0.19/test/index_bad_stride.nml deleted file mode 100644 index 444c43e28..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/index_bad_stride.nml +++ /dev/null @@ -1,3 +0,0 @@ -&bad_index_nml - y(1:3:~) = 1, 2, 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/index_empty.nml b/scm/etc/scripts/f90nml-0.19/test/index_empty.nml deleted file mode 100644 index bc99ae9b7..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/index_empty.nml +++ /dev/null @@ -1,3 +0,0 @@ -&empty_index_nml - x() = 1, 2, 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/index_empty_end.nml b/scm/etc/scripts/f90nml-0.19/test/index_empty_end.nml deleted file mode 100644 index 00f8980d4..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/index_empty_end.nml +++ /dev/null @@ -1,3 +0,0 @@ -&empty_index_nml - x(1::2) = 1, 2, 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/index_empty_stride.nml b/scm/etc/scripts/f90nml-0.19/test/index_empty_stride.nml deleted file mode 100644 index c51d94510..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/index_empty_stride.nml +++ /dev/null @@ -1,3 +0,0 @@ -&empty_index_nml - x(1:3:) = 1, 2, 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/index_zero_stride.nml b/scm/etc/scripts/f90nml-0.19/test/index_zero_stride.nml deleted file mode 100644 index d7967d746..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/index_zero_stride.nml +++ /dev/null @@ -1,3 +0,0 @@ -&bad_index_nml - y(1:3:0) = 1, 2, 3 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/logical.nml b/scm/etc/scripts/f90nml-0.19/test/logical.nml deleted file mode 100644 index 6efdbc61c..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/logical.nml +++ /dev/null @@ -1,8 +0,0 @@ -&logical_nml - a = .true. - b = .false. - c = t - d = f - e = .t - f = .f -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/logical_repr.nml b/scm/etc/scripts/f90nml-0.19/test/logical_repr.nml deleted file mode 100644 index 6654535f6..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/logical_repr.nml +++ /dev/null @@ -1,8 +0,0 @@ -&logical_nml - a = T - b = F - c = T - d = F - e = T - f = F -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/multidim.nml b/scm/etc/scripts/f90nml-0.19/test/multidim.nml deleted file mode 100644 index 96053b1e7..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/multidim.nml +++ /dev/null @@ -1,19 +0,0 @@ -&multidim_nml - v2d(1:2, 1:2) = 1, 2, 3, 4 - - v3d(1:2, 1:2, 1:2) = 1, 2, 3, 4, 5, 6, 7, 8 - - w3d(1:4, 1:3, 1:2) = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 - - v2d_explicit(1,1) = 1 - v2d_explicit(2,1) = 2 - v2d_explicit(1,2) = 3 - v2d_explicit(2,2) = 4 - - v2d_outer(1, :) = 1, 2, 3, 4 - v2d_inner(:, 1) = 1, 2, 3, 4 - - v2d_sparse(:,1) = 1, 2 - v2d_sparse(:,3) = 5, 6 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/multidim_target.nml b/scm/etc/scripts/f90nml-0.19/test/multidim_target.nml deleted file mode 100644 index f7cf017b0..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/multidim_target.nml +++ /dev/null @@ -1,23 +0,0 @@ -&multidim_nml - v2d(:, 1) = 1, 2 - v2d(:, 2) = 3, 4 - v3d(:, 1, 1) = 1, 2 - v3d(:, 2, 1) = 3, 4 - v3d(:, 1, 2) = 5, 6 - v3d(:, 2, 2) = 7, 8 - w3d(:, 1, 1) = 1, 2, 3, 4 - w3d(:, 2, 1) = 5, 6, 7, 8 - w3d(:, 3, 1) = 9, 10, 11, 12 - w3d(:, 1, 2) = 13, 14, 15, 16 - w3d(:, 2, 2) = 17, 18, 19, 20 - w3d(:, 3, 2) = 21, 22, 23, 24 - v2d_explicit(:, 1) = 1, 2 - v2d_explicit(:, 2) = 3, 4 - v2d_outer(:, 1) = 1 - v2d_outer(:, 2) = 2 - v2d_outer(:, 3) = 3 - v2d_outer(:, 4) = 4 - v2d_inner(:, 1) = 1, 2, 3, 4 - v2d_sparse(:, 1) = 1, 2 - v2d_sparse(:, 3) = 5, 6 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/multiline.nml b/scm/etc/scripts/f90nml-0.19/test/multiline.nml deleted file mode 100644 index a0217b8a6..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/multiline.nml +++ /dev/null @@ -1,5 +0,0 @@ -&multiline_nml - x = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/multiline_colwidth.nml b/scm/etc/scripts/f90nml-0.19/test/multiline_colwidth.nml deleted file mode 100644 index 32e6a7242..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/multiline_colwidth.nml +++ /dev/null @@ -1,7 +0,0 @@ -&multiline_nml - x = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/null.nml b/scm/etc/scripts/f90nml-0.19/test/null.nml deleted file mode 100644 index 7db1d6d0f..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/null.nml +++ /dev/null @@ -1,12 +0,0 @@ -&null_nml - null_value = -/ - -&null_comma_nml - null_comma = , -/ - -&null_nocomma_rpt_nml - null_one = - null_two = -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/null_target.nml b/scm/etc/scripts/f90nml-0.19/test/null_target.nml deleted file mode 100644 index bd739e817..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/null_target.nml +++ /dev/null @@ -1,12 +0,0 @@ -&null_nml - null_value = , -/ - -&null_comma_nml - null_comma = , -/ - -&null_nocomma_rpt_nml - null_one = , - null_two = , -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/numpy_types.nml b/scm/etc/scripts/f90nml-0.19/test/numpy_types.nml deleted file mode 100644 index 571f14778..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/numpy_types.nml +++ /dev/null @@ -1,5 +0,0 @@ -&numpy_nml - np_integer = 1 - np_float = 1.0 - np_complex = (1.0, 2.0) -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/requirements_test.txt b/scm/etc/scripts/f90nml-0.19/test/requirements_test.txt deleted file mode 100644 index 79e3a4ee0..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/requirements_test.txt +++ /dev/null @@ -1,3 +0,0 @@ -coverage == 3.7.1 ; python_version == '3.2' -coverage ; python_version != '3.2' -coveralls diff --git a/scm/etc/scripts/f90nml-0.19/test/string.nml b/scm/etc/scripts/f90nml-0.19/test/string.nml deleted file mode 100644 index 70d5b06fb..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/string.nml +++ /dev/null @@ -1,12 +0,0 @@ -&string_nml - str_basic = 'hello' - str_no_delim = hello - str_no_delim_no_esc = a''b - single_esc_delim = 'a ''single'' delimiter' - double_esc_delim = "a ""double"" delimiter" - double_nested = "''x'' ""y""" - str_list = 'a', 'b', 'c' - slist_no_space = 'a','b','c' - slist_no_quote = a,b,c - slash = 'back\slash' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/string_target.nml b/scm/etc/scripts/f90nml-0.19/test/string_target.nml deleted file mode 100644 index 63c06ec43..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/string_target.nml +++ /dev/null @@ -1,12 +0,0 @@ -&string_nml - str_basic = 'hello' - str_no_delim = 'hello' - str_no_delim_no_esc = "a''b" - single_esc_delim = "a 'single' delimiter" - double_esc_delim = 'a "double" delimiter' - double_nested = '''''x'''' "y"' - str_list = 'a', 'b', 'c' - slist_no_space = 'a', 'b', 'c' - slist_no_quote = 'a', 'b', 'c' - slash = 'back\slash' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/test_f90nml.py b/scm/etc/scripts/f90nml-0.19/test/test_f90nml.py deleted file mode 100644 index 71316abc4..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/test_f90nml.py +++ /dev/null @@ -1,575 +0,0 @@ -import os -import sys -import unittest - -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict -try: - import numpy - has_numpy = True -except ImportError: - has_numpy = False - -sys.path.insert(1, '../') -import f90nml -from f90nml.fpy import pybool -from f90nml.namelist import Namelist -from f90nml.findex import FIndex - - -class Test(unittest.TestCase): - - def setUp(self): - self.empty_nml = {'empty_nml': {}} - - self.null_nml = { - 'null_nml': {'null_value': None}, - 'null_comma_nml': {'null_comma': None}, - 'null_nocomma_rpt_nml': { - 'null_one': None, - 'null_two': None, - } - } - - self.unset_nml = { - 'unset_nml': { - 'x': None, - 'y': None - } - } - - self.types_nml = { - 'types_nml': { - 'v_integer': 1, - 'v_float': 1.0, - 'v_complex': 1+2j, - 'v_logical': True, - 'v_string': 'Hello', - } - } - - self.vector_nml = { - 'vector_nml': { - 'v': [1, 2, 3, 4, 5], - 'v_idx': [1, 2, 3, 4], - 'v_idx_ooo': [1, 2, 3, 4], - 'v_range': [1, 2, 3, 4], - 'v_implicit_start': [1, 2, 3, 4], - 'v_implicit_end': [1, 2, 3, 4], - 'v_implicit_all': [1, 2, 3, 4], - 'v_null_start': [None, 2, 3, 4], - 'v_null_interior': [1, 2, None, 4], - 'v_null_end': [1, 2, 3, None], - 'v_zero': [1, 0, 3], - 'v_stride': [1, None, 3, None, 5, None, 7], - 'v_single': [1], - 'v_implicit_merge': [1, 2], - 'v_explicit_merge': [1, 2], - } - } - - self.multidim_nml = { - 'multidim_nml': { - 'v2d': [[1, 2], [3, 4]], - 'v3d': [[[1, 2], [3, 4]], [[5, 6], [7, 8]]], - 'w3d': [[[1, 2, 3, 4], - [5, 6, 7, 8], - [9, 10, 11, 12]], - [[13, 14, 15, 16], - [17, 18, 19, 20], - [21, 22, 23, 24]]], - 'v2d_explicit': [[1, 2], [3, 4]], - 'v2d_outer': [[1], [2], [3], [4]], - 'v2d_inner': [[1, 2, 3, 4]], - 'v2d_sparse': [[1, 2], [], [5, 6]] - } - } - - self.md_rowmaj_nml = { - 'multidim_nml': { - 'v2d': [[1, 3], [2, 4]], - 'v3d': [[[1, 5], [3, 7]], [[2, 6], [4, 8]]], - 'w3d': [[[1, 13], [5, 17], [9, 21]], - [[2, 14], [6, 18], [10, 22]], - [[3, 15], [7, 19], [11, 23]], - [[4, 16], [8, 20], [12, 24]]], - 'v2d_explicit': [[1, 3], [2, 4]], - 'v2d_outer': [[1, 2, 3, 4]], - 'v2d_inner': [[1], [2], [3], [4]], - 'v2d_sparse': [[1, None, 5], [2, None, 6]] - } - } - - self.float_nml = { - 'float_nml': { - 'v_float': 1., - 'v_decimal_end': 1., - 'v_negative': -1., - 'v_single': 1., - 'v_double': 1., - 'v_single_upper': 1., - 'v_double_upper': 1., - 'v_positive_index': 10., - 'v_negative_index': 0.1, - 'v_no_exp_pos': 1., - 'v_no_exp_neg': 1., - 'v_no_exp_pos_dot': 1., - 'v_no_exp_neg_dot': 1., - 'v_neg_no_exp_pos': -1., - 'v_neg_no_exp_neg': -1., - } - } - - self.string_nml = { - 'string_nml': { - 'str_basic': 'hello', - 'str_no_delim': 'hello', - 'str_no_delim_no_esc': "a''b", - 'single_esc_delim': "a 'single' delimiter", - 'double_esc_delim': 'a "double" delimiter', - 'double_nested': "''x'' \"y\"", - 'str_list': ['a', 'b', 'c'], - 'slist_no_space': ['a', 'b', 'c'], - 'slist_no_quote': ['a', 'b', 'c'], - 'slash': 'back\\slash', - } - } - - self.dtype_nml = { - 'dtype_nml': { - 'dt_scalar': {'val': 1}, - 'dt_stack': {'outer': {'inner': 2}}, - 'dt_vector': {'vec': [1, 2, 3]} - }, - 'dtype_multi_nml': { - 'dt': { - 'x': 1, - 'y': 2, - 'z': 3, - } - }, - 'dtype_nested_nml': { - 'f': { - 'g': { - 'x': 1, - 'y': 2, - 'z': 3, - } - } - }, - 'dtype_field_idx_nml': { - 'f': { - 'x': [1, 2, 3]} - }, - 'dtype_vec_nml': { - 'a': { - 'b': [ - {'c': 1, 'd': 2}, - {'c': 3, 'd': 4}, - {'c': 5, 'd': 6} - ] - } - }, - 'dtype_sparse_vec_nml': { - 'a': { - 'b': [None, {'c': 2}] - } - }, - 'dtype_single_value_vec_nml': { - 'a': [{'b': 1}] - }, - 'dtype_single_vec_merge_nml': { - 'a': { - 'b': [{'c': 1, 'd': 2}] - } - } - } - - self.bcast_nml = { - 'bcast_nml': { - 'x': [2.0, 2.0], - 'y': [None, None, None], - 'z': [True, True, True, True], - }, - 'bcast_endnull_nml': { - 'x': [2.0, 2.0], - 'y': [None, None, None], - } - } - - self.comment_nml = { - 'comment_nml': { - 'v_cmt_inline': 123, - 'v_cmt_in_str': 'This token ! is not a comment', - 'v_cmt_after_str': 'This ! is not a comment', - } - } - - self.comment_alt_nml = { - 'comment_alt_nml': { - 'x': 1, - 'z': 3} - } - - self.grp_repeat_nml = { - 'grp_repeat_nml': [{'x': 1}, {'x': 2}], - 'case_check_nml': [{'y': 1}, {'y': 2}], - } - - self.f77_nml = { - 'f77_nml': {'x': 123}, - 'next_f77_nml': {'y': 'abc'}, - } - - self.dollar_nml = {'dollar_nml': {'v': 1.}} - - self.multiline_nml = { - 'multiline_nml': { - 'x': [ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 - ] - } - } - - self.ext_token_nml = {'ext_token_nml': {'x': 1}} - - if has_numpy: - self.numpy_nml = { - 'numpy_nml': OrderedDict(( - ('np_integer', numpy.int64(1)), - ('np_float', numpy.float64(1.0)), - ('np_complex', numpy.complex128(1+2j)), - ) - ) - } - - # Support functions - def assert_file_equal(self, source_fname, target_fname): - with open(source_fname) as source: - with open(target_fname) as target: - source_str = source.read() - target_str = target.read() - self.assertEqual(source_str, target_str) - - def assert_write(self, nml, target_fname): - self.assert_write_path(nml, target_fname) - self.assert_write_file(nml, target_fname) - - def assert_write_path(self, nml, target_fname): - tmp_fname = 'tmp.nml' - f90nml.write(nml, tmp_fname) - try: - self.assert_file_equal(tmp_fname, target_fname) - finally: - os.remove(tmp_fname) - - def assert_write_file(self, nml, target_fname): - tmp_fname = 'tmp.nml' - with open(tmp_fname, 'w') as tmp_file: - f90nml.write(nml, tmp_file) - self.assertFalse(tmp_file.closed) - try: - self.assert_file_equal(tmp_fname, target_fname) - finally: - os.remove(tmp_fname) - - # Tests - def test_empty(self): - test_nml = f90nml.read('empty.nml') - self.assertEqual(self.empty_nml, test_nml) - self.assert_write(test_nml, 'empty.nml') - - def test_null(self): - test_nml = f90nml.read('null.nml') - self.assertEqual(self.null_nml, test_nml) - self.assert_write(test_nml, 'null_target.nml') - - def test_unset(self): - test_nml = f90nml.read('unset.nml') - self.assertEqual(self.unset_nml, test_nml) - self.assert_write(test_nml, 'unset.nml') - - def test_types(self): - test_nml = f90nml.read('types.nml') - self.assertEqual(self.types_nml, test_nml) - self.assert_write(test_nml, 'types.nml') - - def test_vector(self): - test_nml = f90nml.read('vector.nml') - self.assertEqual(self.vector_nml, test_nml) - self.assert_write(test_nml, 'vector_target.nml') - - def test_multidim(self): - test_nml = f90nml.read('multidim.nml') - self.assertEqual(self.multidim_nml, test_nml) - self.assert_write(test_nml, 'multidim_target.nml') - - def test_rowmaj_multidim(self): - test_nml = f90nml.read('multidim.nml', row_major=True) - self.assertEqual(self.md_rowmaj_nml, test_nml) - - def test_flag_syntax(self): - self.assertRaises(ValueError, f90nml.read, 'index_empty.nml', - row_major='abc') - self.assertRaises(ValueError, f90nml.read, 'index_empty.nml', - strict_logical='abc') - - def test_float(self): - test_nml = f90nml.read('float.nml') - self.assertEqual(self.float_nml, test_nml) - self.assert_write(test_nml, 'float_target.nml') - - def test_string(self): - test_nml = f90nml.read('string.nml') - self.assertEqual(self.string_nml, test_nml) - self.assert_write(test_nml, 'string_target.nml') - - def test_dtype(self): - test_nml = f90nml.read('dtype.nml') - self.assertEqual(self.dtype_nml, test_nml) - self.assert_write(test_nml, 'dtype_target.nml') - - def test_bcast(self): - test_nml = f90nml.read('bcast.nml') - self.assertEqual(self.bcast_nml, test_nml) - self.assert_write(test_nml, 'bcast_target.nml') - - def test_comment(self): - test_nml = f90nml.read('comment.nml') - self.assertEqual(self.comment_nml, test_nml) - self.assert_write(test_nml, 'comment_target.nml') - - def test_comment_alt(self): - parser = f90nml.Parser() - parser.comment_tokens = '#' - test_nml = parser.read('comment_alt.nml') - self.assertEqual(self.comment_alt_nml, test_nml) - - def test_grp_repeat(self): - test_nml = f90nml.read('grp_repeat.nml') - self.assertEqual(self.grp_repeat_nml, test_nml) - self.assert_write(test_nml, 'grp_repeat_target.nml') - - def test_f77(self): - test_nml = f90nml.read('f77.nml') - self.assertEqual(self.f77_nml, test_nml) - self.assert_write(test_nml, 'f77_target.nml') - - def test_dollar(self): - test_nml = f90nml.read('dollar.nml') - self.assertEqual(self.dollar_nml, test_nml) - self.assert_write(test_nml, 'dollar_target.nml') - - def test_multiline(self): - test_nml = f90nml.read('multiline.nml') - self.assertEqual(self.multiline_nml, test_nml) - self.assert_write(test_nml, 'multiline.nml') - - def test_ext_token(self): - test_nml = f90nml.read('ext_token.nml') - self.assertEqual(self.ext_token_nml, test_nml) - - def test_write_existing_file(self): - tmp_fname = 'tmp.nml' - open(tmp_fname, 'w').close() - test_nml = f90nml.read('empty.nml') - self.assertRaises(IOError, test_nml.write, tmp_fname) - os.remove(tmp_fname) - - def test_pop_key(self): - test_nml = f90nml.read('empty.nml') - test_nml.pop('empty_nml') - self.assertEqual(test_nml, f90nml.namelist.Namelist()) - - def test_patch_paths(self): - patch_nml = f90nml.read('types_patch.nml') - f90nml.patch('types.nml', patch_nml, 'tmp.nml') - test_nml = f90nml.read('tmp.nml') - try: - self.assertEqual(test_nml, patch_nml) - finally: - os.remove('tmp.nml') - - def test_patch_files(self): - patch_nml = f90nml.read('types_patch.nml') - with open('types.nml') as f_in: - with open('tmp.nml', 'w') as f_out: - f90nml.patch(f_in, patch_nml, f_out) - self.assertFalse(f_in.closed) - self.assertFalse(f_out.closed) - try: - test_nml = f90nml.read('tmp.nml') - self.assertEqual(test_nml, patch_nml) - finally: - os.remove('tmp.nml') - - def test_patch_case(self): - patch_nml = f90nml.read('types_patch.nml') - f90nml.patch('types_uppercase.nml', patch_nml, 'tmp.nml') - test_nml = f90nml.read('tmp.nml') - try: - self.assertEqual(test_nml, patch_nml) - finally: - os.remove('tmp.nml') - - def test_patch_valueerror(self): - self.assertRaises(ValueError, f90nml.patch, 'types.nml', 'xyz', - 'tmp.nml') - - def test_default_patch(self): - patch_nml = f90nml.read('types_patch.nml') - f90nml.patch('types.nml', patch_nml) - test_nml = f90nml.read('types.nml~') - try: - self.assertEqual(test_nml, patch_nml) - finally: - os.remove('types.nml~') - - # The above behavior is only for paths, not files - with open('types.nml') as nml_file: - self.assertRaises(ValueError, f90nml.patch, nml_file, patch_nml) - - def test_no_selfpatch(self): - patch_nml = f90nml.read('types_patch.nml') - self.assertRaises(ValueError, f90nml.patch, - 'types.nml', patch_nml, 'types.nml') - - def test_comment_patch(self): - nml = {'comment_nml': {'v_cmt_inline': 456}} - try: - f90nml.patch('comment.nml', nml, 'tmp.nml') - self.assert_file_equal('comment_patch.nml', 'tmp.nml') - finally: - os.remove('tmp.nml') - - def test_index_syntax(self): - self.assertRaises(ValueError, f90nml.read, 'index_empty.nml') - self.assertRaises(ValueError, f90nml.read, 'index_bad.nml') - self.assertRaises(ValueError, f90nml.read, 'index_bad_start.nml') - self.assertRaises(ValueError, f90nml.read, 'index_empty_end.nml') - self.assertRaises(ValueError, f90nml.read, 'index_bad_end.nml') - self.assertRaises(ValueError, f90nml.read, 'index_empty_stride.nml') - self.assertRaises(ValueError, f90nml.read, 'index_bad_stride.nml') - self.assertRaises(ValueError, f90nml.read, 'index_zero_stride.nml') - - def test_f90repr(self): - nml = Namelist() - self.assertEqual(nml.f90repr(1), '1') - self.assertEqual(nml.f90repr(1.), '1.0') - self.assertEqual(nml.f90repr(1+2j), '(1.0, 2.0)') - self.assertEqual(nml.f90repr(True), '.true.') - self.assertEqual(nml.f90repr(False), '.false.') - self.assertEqual(nml.f90repr('abc'), "'abc'") - - for ptype in ({}, [], set()): - self.assertRaises(ValueError, nml.f90repr, ptype) - - def test_pybool(self): - for fstr_true in ('true', '.true.', 't', '.t.'): - self.assertEqual(pybool(fstr_true), True) - - for fstr_false in ('false', '.false.', 'f', '.f.'): - self.assertEqual(pybool(fstr_false), False) - - for fstr_true in ('ture', '.t'): - self.assertEqual(pybool(fstr_true, strict_logical=False), True) - - for fstr_false in ('flase', '.f'): - self.assertEqual(pybool(fstr_false, strict_logical=False), False) - - for fstr in ('ture', '.t', 'flase', '.f'): - self.assertRaises(ValueError, pybool, fstr) - - for fstr in ('g', '.', 'xyz'): - self.assertRaises(ValueError, pybool, fstr, strict_logical=False) - - def test_close_patch_on_error(self): - patch = {'tmp_nml': {'tmp_val': 0}} - self.assertRaises(ValueError, f90nml.patch, 'index_empty.nml', patch, - 'tmp.nml') - os.remove('tmp.nml') - - def test_indent(self): - test_nml = f90nml.read('types.nml') - - test_nml.indent = 2 - self.assert_write(test_nml, 'types_indent_2.nml') - - test_nml.indent = '\t' - self.assert_write(test_nml, 'types_indent_tab.nml') - - self.assertRaises(ValueError, setattr, test_nml, 'indent', -4) - self.assertRaises(ValueError, setattr, test_nml, 'indent', 'xyz') - self.assertRaises(TypeError, setattr, test_nml, 'indent', [1, 2, 3]) - - def test_colwidth(self): - test_nml = f90nml.read('multiline.nml') - test_nml.colwidth = 40 - self.assert_write(test_nml, 'multiline_colwidth.nml') - - self.assertRaises(ValueError, setattr, test_nml, 'colwidth', -1) - self.assertRaises(TypeError, setattr, test_nml, 'colwidth', 'xyz') - - def test_end_comma(self): - test_nml = f90nml.read('types.nml') - test_nml.end_comma = True - self.assert_write(test_nml, 'types_end_comma.nml') - - self.assertRaises(TypeError, setattr, test_nml, 'end_comma', 'xyz') - - def test_uppercase(self): - test_nml = f90nml.read('types.nml') - test_nml.uppercase = True - self.assert_write(test_nml, 'types_uppercase.nml') - - self.assertRaises(TypeError, setattr, test_nml, 'uppercase', 'xyz') - - def test_floatformat(self): - test_nml = f90nml.read('float.nml') - test_nml.floatformat = '.3f' - self.assert_write(test_nml, 'float_format.nml') - - self.assertRaises(TypeError, setattr, test_nml, 'floatformat', 123) - - def test_logical_repr(self): - test_nml = f90nml.read('logical.nml', strict_logical=False) - test_nml.true_repr = 'T' - test_nml.false_repr = 'F' - - self.assertEqual(test_nml.false_repr, test_nml.logical_repr[0]) - self.assertEqual(test_nml.true_repr, test_nml.logical_repr[1]) - self.assert_write(test_nml, 'logical_repr.nml') - - test_nml.logical_repr = 'F', 'T' - self.assert_write(test_nml, 'logical_repr.nml') - - self.assertRaises(TypeError, setattr, test_nml, 'true_repr', 123) - self.assertRaises(TypeError, setattr, test_nml, 'false_repr', 123) - self.assertRaises(ValueError, setattr, test_nml, 'true_repr', 'xyz') - self.assertRaises(ValueError, setattr, test_nml, 'false_repr', 'xyz') - self.assertRaises(TypeError, setattr, test_nml, 'logical_repr', 'xyz') - self.assertRaises(ValueError, setattr, test_nml, 'logical_repr', []) - - def test_findex_iteration(self): - rng = [(None, 5, None)] - fidx = iter(FIndex(rng)) - - for i, j in enumerate(fidx, start=1): - self.assertEqual(i, j[0]) - - def test_dict_write(self): - self.assert_write(self.types_nml, 'types_dict.nml') - - if has_numpy: - def test_numpy_write(self): - self.assert_write(self.numpy_nml, 'numpy_types.nml') - -if __name__ == '__main__': - if os.path.isfile('tmp.nml'): - os.remove('tmp.nml') - unittest.main() diff --git a/scm/etc/scripts/f90nml-0.19/test/types.nml b/scm/etc/scripts/f90nml-0.19/test/types.nml deleted file mode 100644 index 9746e44ae..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/types.nml +++ /dev/null @@ -1,7 +0,0 @@ -&types_nml - v_integer = 1 - v_float = 1.0 - v_complex = (1.0, 2.0) - v_logical = .true. - v_string = 'Hello' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/types_dict.nml b/scm/etc/scripts/f90nml-0.19/test/types_dict.nml deleted file mode 100644 index 81f787ab2..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/types_dict.nml +++ /dev/null @@ -1,7 +0,0 @@ -&types_nml - v_complex = (1.0, 2.0) - v_float = 1.0 - v_integer = 1 - v_logical = .true. - v_string = 'Hello' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/types_end_comma.nml b/scm/etc/scripts/f90nml-0.19/test/types_end_comma.nml deleted file mode 100644 index 21fef60e8..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/types_end_comma.nml +++ /dev/null @@ -1,7 +0,0 @@ -&types_nml - v_integer = 1, - v_float = 1.0, - v_complex = (1.0, 2.0), - v_logical = .true., - v_string = 'Hello', -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/types_indent_2.nml b/scm/etc/scripts/f90nml-0.19/test/types_indent_2.nml deleted file mode 100644 index cf62c6a24..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/types_indent_2.nml +++ /dev/null @@ -1,7 +0,0 @@ -&types_nml - v_integer = 1 - v_float = 1.0 - v_complex = (1.0, 2.0) - v_logical = .true. - v_string = 'Hello' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/types_indent_tab.nml b/scm/etc/scripts/f90nml-0.19/test/types_indent_tab.nml deleted file mode 100644 index f69931afb..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/types_indent_tab.nml +++ /dev/null @@ -1,7 +0,0 @@ -&types_nml - v_integer = 1 - v_float = 1.0 - v_complex = (1.0, 2.0) - v_logical = .true. - v_string = 'Hello' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/types_patch.nml b/scm/etc/scripts/f90nml-0.19/test/types_patch.nml deleted file mode 100644 index 6393cdfed..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/types_patch.nml +++ /dev/null @@ -1,8 +0,0 @@ -&types_nml - v_integer = 2 - v_float = 2.0 - v_complex = (2.0, 3.0) - v_logical = .false. - v_string = 'Goodbye' - v_new = 123 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/types_uppercase.nml b/scm/etc/scripts/f90nml-0.19/test/types_uppercase.nml deleted file mode 100644 index 4b590f184..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/types_uppercase.nml +++ /dev/null @@ -1,7 +0,0 @@ -&TYPES_NML - V_INTEGER = 1 - V_FLOAT = 1.0 - V_COMPLEX = (1.0, 2.0) - V_LOGICAL = .true. - V_STRING = 'Hello' -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/unset.nml b/scm/etc/scripts/f90nml-0.19/test/unset.nml deleted file mode 100644 index 5e6413047..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/unset.nml +++ /dev/null @@ -1,4 +0,0 @@ -&unset_nml - x = , - y = , -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/vector.nml b/scm/etc/scripts/f90nml-0.19/test/vector.nml deleted file mode 100644 index 31c910a78..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/vector.nml +++ /dev/null @@ -1,49 +0,0 @@ -&vector_nml - - ! Standard vector - v = 1,2,3,4,5 - - ! Component test - v_idx(1) = 1 - v_idx(2) = 2 - v_idx(3) = 3 - v_idx(4) = 4 - - ! Out-of-order test - v_idx_ooo(2) = 2 - v_idx_ooo(4) = 4 - v_idx_ooo(3) = 3 - v_idx_ooo(1) = 1 - - ! Range test - v_range(1:4) = 1,2,3,4 - - ! Implicit range test - v_implicit_start(1:) = 1,2,3,4 - v_implicit_end(:4) = 1,2,3,4 - v_implicit_all(:) = 1,2,3,4, - - ! Null vector component - v_null_start = ,2,3,4 - v_null_end = 1,2,3,, - v_null_interior = 1,2,,4 - - ! Zero merge_list check - v_zero(1) = 1 - v_zero(2) = 0 - v_zero(3) = 3 - - ! Stride check - v_stride(1:7:2) = 1, 3, 5, 7 - - ! Single element check - v_single(1) = 1 - - ! Implicit merge - v_implicit_merge(2) = 2 - v_implicit_merge = 1 - - ! Explicit merge - v_explicit_merge = 1 - v_explicit_merge(2) = 2 -/ diff --git a/scm/etc/scripts/f90nml-0.19/test/vector_target.nml b/scm/etc/scripts/f90nml-0.19/test/vector_target.nml deleted file mode 100644 index 5c06a133d..000000000 --- a/scm/etc/scripts/f90nml-0.19/test/vector_target.nml +++ /dev/null @@ -1,17 +0,0 @@ -&vector_nml - v = 1, 2, 3, 4, 5 - v_idx = 1, 2, 3, 4 - v_idx_ooo = 1, 2, 3, 4 - v_range = 1, 2, 3, 4 - v_implicit_start = 1, 2, 3, 4 - v_implicit_end = 1, 2, 3, 4 - v_implicit_all = 1, 2, 3, 4 - v_null_start = , 2, 3, 4 - v_null_end = 1, 2, 3, , - v_null_interior = 1, 2, , 4 - v_zero = 1, 0, 3 - v_stride = 1, , 3, , 5, , 7 - v_single = 1 - v_implicit_merge = 1, 2 - v_explicit_merge = 1, 2 -/ diff --git a/scm/etc/scripts/gmtb_scm_analysis.py b/scm/etc/scripts/gmtb_scm_analysis.py index 1bd31e6b5..a1a84887f 100755 --- a/scm/etc/scripts/gmtb_scm_analysis.py +++ b/scm/etc/scripts/gmtb_scm_analysis.py @@ -18,12 +18,15 @@ Rv = 461.0 g = 9.81 -plot_ext = '.png' #.pdf, .eps, .ps, .png (.png is fastest, but raster) +plot_ext = '.pdf' #.pdf, .eps, .ps, .png (.png is fastest, but raster) reload(gspr) reload(gsro) -pd.plotting.register_matplotlib_converters() +try: + pd.plotting.register_matplotlib_converters() +except (AttributeError): + print "Warning: The version of the pandas package you are using may lead to Future Warnings being generated. These can be ignored for now." #subroutine for printing progress to the command line def print_progress(n_complete, n_total): @@ -32,6 +35,7 @@ def print_progress(n_complete, n_total): #set up command line argument parser to read in name of config file to use parser = argparse.ArgumentParser() parser.add_argument('config', help='configuration file for GMTB SCM analysis', nargs=1) +parser.add_argument('-d', '--docker', help='include if scm is being run in a docker container to mount volumes', action='store_true', default=False) args = parser.parse_args() @@ -87,6 +91,13 @@ def print_progress(n_complete, n_total): print 'gmtb_scm_datasets_labels = ',gmtb_scm_datasets_labels quit() +#if running in a Docker container, the output is being copied to a different directory within the container +#and the plots should go into that same (home) directory in order for the volume to be correctly mounted and the host to see them. +if args.docker: + plot_dir = '/home/'+plot_dir + for f in gmtb_scm_datasets: + f = '/home/'+f + #read in the case name from the case_config namelist (just use first dataset dir namelist) i = gmtb_scm_datasets[0].rfind('/') dir = gmtb_scm_datasets[0][:i] diff --git a/scm/etc/scripts/gmtb_scm_plotting_routines.py b/scm/etc/scripts/gmtb_scm_plotting_routines.py index 9f2c911ad..22125bd4d 100755 --- a/scm/etc/scripts/gmtb_scm_plotting_routines.py +++ b/scm/etc/scripts/gmtb_scm_plotting_routines.py @@ -14,6 +14,7 @@ mpl.rcParams['savefig.dpi'] = 150 mpl.rcParams['legend.handlelength'] = 5 +latex_labels = False def calc_skill_score(data, experiment, R_0, k): sigma_data = np.std(data) @@ -25,7 +26,7 @@ def calc_skill_score(data, experiment, R_0, k): def plot_profile(z, values, x_label, y_label, filename, xticks=[], yticks=[], y_inverted = False, y_log = False, y_lim = []): #xticks = [x_start, x_end, x_num] - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) fig = plt.figure() @@ -52,7 +53,7 @@ def plot_profile(z, values, x_label, y_label, filename, xticks=[], yticks=[], y_ def plot_profile_multi(z, values, labels, x_label, y_label, filename, obs_z=None, obs_values=None, xticks=[], yticks=[], y_inverted = False, y_log = False, y_lim = [], conversion_factor=1.0, freeze_axis=None, line_type=None, color_index=None, skill_scores=False, zero_line=False): #xticks = [x_start, x_end, x_num] - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) if np.count_nonzero(values) == 0: print 'The plot for {} will not be created due to all zero values'.format(x_label) @@ -226,7 +227,7 @@ def plot_profile_multi(z, values, labels, x_label, y_label, filename, obs_z=None def plot_profile_compare(z, values, LES_values, LES_z, x_label, y_label, filename, xticks=[], yticks=[], y_inverted = False, y_log = False, x_lim = [], y_lim = []): #xticks = [x_start, x_end, x_num] - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) fig = plt.figure() @@ -260,7 +261,7 @@ def plot_profile_compare(z, values, LES_values, LES_z, x_label, y_label, filenam plt.close() def plot_time_series(time, values, x_label, y_label, filename): - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) fig = plt.figure() @@ -272,7 +273,7 @@ def plot_time_series(time, values, x_label, y_label, filename): plt.close() def plot_time_series_compare(time, values, LES_time, LES_values, x_label, y_label, filename): - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) fig = plt.figure() @@ -291,7 +292,7 @@ def plot_time_series_compare(time, values, LES_time, LES_values, x_label, y_labe plt.close() def plot_time_series_multi(time, values, labels, x_label, y_label, filename, obs_time=None, obs_values=None, obs_label=None, line_type=None, color_index=None, skill_scores=False, conversion_factor=1.0): - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) if np.count_nonzero(values) == 0: print 'The plot for {} will not be created due to all zero values'.format(y_label) @@ -405,7 +406,7 @@ def plot_time_series_multi(time, values, labels, x_label, y_label, filename, obs def contour_plot_firl(x_dim, y_dim, values, min_val, max_val, title, x_label, y_label, filename, xticks=[], yticks=[], plot_mean = 0, annotation = 0, y_inverted = 0, y_log = False, y_lim = [], conversion_factor=1.0): #os.environ['PATH'] = os.environ['PATH'] + ':/usr/texbin' #plt.rc('ps', usedistiller='xpdf') - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) if np.count_nonzero(values) == 0: print 'The plot for {} will not be created due to all zero values'.format(title) @@ -485,7 +486,7 @@ def contour_plot_firl(x_dim, y_dim, values, min_val, max_val, title, x_label, y_ def plot_profile_multi_ens(z, values, labels, x_label, y_label, filename, obs_z=None, obs_values=None, xticks=[], yticks=[], y_inverted = False, y_log = False, y_lim = [], freeze_axis=None, line_type=None, color_index=None, skill_scores=False): #xticks = [x_start, x_end, x_num] - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) #ensemble data processing values_ens_processed = [] @@ -661,7 +662,7 @@ def plot_profile_multi_ens(z, values, labels, x_label, y_label, filename, obs_z= plt.close() def plot_time_series_multi_ens(time, values, labels, x_label, y_label, filename, obs_time=None, obs_values=None, obs_label=None, line_type=None, color_index=None, skill_scores=False): - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) fig = plt.figure() @@ -806,7 +807,7 @@ def plot_time_series_multi_ens(time, values, labels, x_label, y_label, filename, plt.close() def plot_scatter_multi(x, y, x_label, y_label, filename, x_lim=[], y_lim=[], color_index=None): - plt.rc('text', usetex=True) + plt.rc('text', usetex=latex_labels) colors = ['#e41a1c','#4daf4a','#377eb8','#984ea3','#ff7f00','#a65628','#f781bf','#ffff33'] if color_index is None: diff --git a/scm/etc/scripts/plot_configs/twpice_RRTMG_vs_P.ini b/scm/etc/scripts/plot_configs/twpice_RRTMG_vs_P.ini new file mode 100644 index 000000000..ed14edf0d --- /dev/null +++ b/scm/etc/scripts/plot_configs/twpice_RRTMG_vs_P.ini @@ -0,0 +1,57 @@ +gmtb_scm_datasets = output_twpice_SCM_GFS_v15p2/output.nc, output_twpice_SCM_GFS_v15p2_RRTMGP_input_GFS_v15p2_RRTMGP/output.nc, +gmtb_scm_datasets_labels = GFSv15.2, GFSv15.2P +plot_dir = plots_twpice_g_vs_p/ +obs_file = ../data/raw_case_input/twp180iopsndgvarana_v2.1_C3.c1.20060117.000000.cdf +obs_compare = True +plot_ind_datasets = False +time_series_resample = True + +[time_slices] + [[active]] + start = 2006, 1, 20, 0 + end = 2006, 1, 25, 12 + +[time_snapshots] + +[plots] + [[profiles_mean]] + vars = qc, qv, T, dT_dt_PBL, dT_dt_conv, dT_dt_micro, dT_dt_lwrad, dT_dt_swrad + vars_labels = 'cloud water mixing ratio ($g$ $kg^{-1}$)', 'specific humidity ($g$ $kg^{-1}$)', 'T (K)', 'PBL tendency (K/day)', 'conv. tendency (K/day)', 'microphysics tendency (K/day)', 'LW tendency (K/day)', 'SW tendency (K/day)' + vert_axis = pres_l + vert_axis_label = 'average pressure (Pa)' + y_inverted = True + y_log = False + y_min_option = min #min, max, val (if val, add y_min = float value) + y_max_option = max #min, max, val (if val, add y_max = float value) + conversion_factor = 1000.0, 1000.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 + + [[profiles_mean_multi]] + [[[T_forcing]]] + vars = T_force_tend, dT_dt_PBL, dT_dt_conv, dT_dt_micro, dT_dt_lwrad, dT_dt_swrad + vars_labels = 'force', 'PBL', 'Conv', 'MP', 'LW', 'SW' + x_label = 'K/day' + [[[conv_tendencies]]] + vars = dT_dt_deepconv, dT_dt_shalconv + vars_labels = 'deep', 'shallow' + x_label = 'K/day' + + [[profiles_instant]] + + [[time_series]] + vars = 'pres_s','lhf','shf','rain' + vars_labels = 'surface pressure (Pa)','latent heat flux ($W$ $m^{-2}$)','sensible heat flux ($W$ $m^{-2}$)','surface rainfall rate ($mm$ $hr{-1}$)' + + [[contours]] + vars = qv, + vars_labels = 'Water Vapor ($g$ $kg^{-1}$)', + vert_axis = pres_l + vert_axis_label = 'p (Pa)' + y_inverted = True + y_log = False + y_min_option = val #min, max, val (if val, add y_min = float value) + y_min = 10000.0 + y_max_option = val #min, max, val (if val, add y_max = float value) + y_max = 100000.0 + x_ticks_num = 10 + y_ticks_num = 10 + conversion_factor = 1000.0, diff --git a/scm/etc/scripts/plot_configs/twpice_all_suites.ini b/scm/etc/scripts/plot_configs/twpice_all_suites.ini new file mode 100644 index 000000000..bf44e285a --- /dev/null +++ b/scm/etc/scripts/plot_configs/twpice_all_suites.ini @@ -0,0 +1,57 @@ +gmtb_scm_datasets = output_twpice_SCM_GFS_v15p2/output.nc, output_twpice_SCM_GFS_v15p2_no_nsst/output.nc, output_twpice_SCM_GFS_v16beta/output.nc, output_twpice_SCM_GFS_v16beta_no_nsst/output.nc, output_twpice_SCM_GSD_v1/output.nc, output_twpice_SCM_csawmg/output.nc, +gmtb_scm_datasets_labels = GFSv15.2, GFSv15.2-, GFSv16b, GFSv16b-, GSDv1, csawmg, +plot_dir = plots_twpice_all_suites/ +obs_file = ../data/raw_case_input/twp180iopsndgvarana_v2.1_C3.c1.20060117.000000.cdf +obs_compare = True +plot_ind_datasets = False +time_series_resample = True + +[time_slices] + [[active]] + start = 2006, 1, 20, 0 + end = 2006, 1, 25, 12 + +[time_snapshots] + +[plots] + [[profiles_mean]] + vars = qc, qv, T, dT_dt_PBL, dT_dt_conv, dT_dt_micro, dT_dt_lwrad, dT_dt_swrad + vars_labels = 'cloud water mixing ratio ($g$ $kg^{-1}$)', 'specific humidity ($g$ $kg^{-1}$)', 'T (K)', 'PBL tendency (K/day)', 'conv. tendency (K/day)', 'microphysics tendency (K/day)', 'LW tendency (K/day)', 'SW tendency (K/day)' + vert_axis = pres_l + vert_axis_label = 'average pressure (Pa)' + y_inverted = True + y_log = False + y_min_option = min #min, max, val (if val, add y_min = float value) + y_max_option = max #min, max, val (if val, add y_max = float value) + conversion_factor = 1000.0, 1000.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 + + [[profiles_mean_multi]] + [[[T_forcing]]] + vars = T_force_tend, dT_dt_PBL, dT_dt_conv, dT_dt_micro, dT_dt_lwrad, dT_dt_swrad + vars_labels = 'force', 'PBL', 'Conv', 'MP', 'LW', 'SW' + x_label = 'K/day' + [[[conv_tendencies]]] + vars = dT_dt_deepconv, dT_dt_shalconv + vars_labels = 'deep', 'shallow' + x_label = 'K/day' + + [[profiles_instant]] + + [[time_series]] + vars = 'pres_s','lhf','shf','rain' + vars_labels = 'surface pressure (Pa)','latent heat flux ($W$ $m^{-2}$)','sensible heat flux ($W$ $m^{-2}$)','surface rainfall rate ($mm$ $hr{-1}$)' + + [[contours]] + vars = qv, + vars_labels = 'Water Vapor ($g$ $kg^{-1}$)', + vert_axis = pres_l + vert_axis_label = 'p (Pa)' + y_inverted = True + y_log = False + y_min_option = val #min, max, val (if val, add y_min = float value) + y_min = 10000.0 + y_max_option = val #min, max, val (if val, add y_max = float value) + y_max = 100000.0 + x_ticks_num = 10 + y_ticks_num = 10 + conversion_factor = 1000.0, diff --git a/scm/src/CMakeLists.txt b/scm/src/CMakeLists.txt index beaa07ee9..1b7745a22 100644 --- a/scm/src/CMakeLists.txt +++ b/scm/src/CMakeLists.txt @@ -5,47 +5,36 @@ set(PROJECT "CCPP-SCM") #################################################################### # Begin CCPP prebuild step # #################################################################### -if(STATIC) - # Start with empty list of suites - message (STATUS "Generating list of suites to compile for static CCPP") - set(SUITES "") - # Get list of all suite definition files (with full path) - file(GLOB SUITE_DEFINITION_FILES - "${CMAKE_CURRENT_SOURCE_DIR}/../../ccpp/suites/suite_*.xml" - ) - # Extract file name and suite name and append to SUITES - foreach(suite_definition_filepath IN LISTS SUITE_DEFINITION_FILES) - get_filename_component(suite_definition_filename ${suite_definition_filepath} NAME) - string(REGEX REPLACE "^suite_(.+)\\.xml$" "\\1" suite_name ${suite_definition_filename}) - set(SUITES ${SUITES}${suite_name},) - message (STATUS " adding suite ${suite_name}") - endforeach(suite_definition_filepath IN LISTS SUITE_DEFINITION_FILES) - # Abort if no suites found - if ("${SUITES}" STREQUAL "") - message(FATAL_ERROR "No suites found to compile for static CCPP") - endif("${SUITES}" STREQUAL "") - # Remove trailing comma from list of suites - string(REGEX REPLACE "(.+),$" "\\1" SUITES ${SUITES}) - # Run CCPP prebuild.py - message (STATUS "Running ccpp_prebuild.py for static CCPP") - execute_process( - COMMAND ccpp/framework/scripts/ccpp_prebuild.py --config=ccpp/config/ccpp_prebuild_config.py --static --suites=${SUITES} --builddir=${CMAKE_CURRENT_BINARY_DIR}/.. - OUTPUT_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.out - ERROR_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.err - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../.. - RESULT_VARIABLE return_code - ) -else(STATIC) - # Run CCPP prebuild.py - message (STATUS "Running ccpp_prebuild.py for dynamic CCPP") - execute_process( - COMMAND ccpp/framework/scripts/ccpp_prebuild.py --config=ccpp/config/ccpp_prebuild_config.py --builddir=${CMAKE_CURRENT_BINARY_DIR}/.. - OUTPUT_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.out - ERROR_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.err - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../.. - RESULT_VARIABLE return_code - ) -endif(STATIC) +# Start with empty list of suites +message (STATUS "Generating list of suites to compile for CCPP") +set(SUITES "") +# Get list of all suite definition files (with full path) +file(GLOB SUITE_DEFINITION_FILES + "${CMAKE_CURRENT_SOURCE_DIR}/../../ccpp/suites/suite_*.xml" +) +# Extract file name and suite name and append to SUITES +foreach(suite_definition_filepath IN LISTS SUITE_DEFINITION_FILES) + get_filename_component(suite_definition_filename ${suite_definition_filepath} NAME) + string(REGEX REPLACE "^suite_(.+)\\.xml$" "\\1" suite_name ${suite_definition_filename}) + set(SUITES ${SUITES}${suite_name},) + message (STATUS " adding suite ${suite_name}") +endforeach(suite_definition_filepath IN LISTS SUITE_DEFINITION_FILES) +# Abort if no suites found +if ("${SUITES}" STREQUAL "") + message(FATAL_ERROR "No suites found to compile for CCPP") +endif("${SUITES}" STREQUAL "") +# Remove trailing comma from list of suites +string(REGEX REPLACE "(.+),$" "\\1" SUITES ${SUITES}) +# Run CCPP prebuild.py +message (STATUS "Running ccpp_prebuild.py for CCPP") +execute_process( + COMMAND ccpp/framework/scripts/ccpp_prebuild.py --config=ccpp/config/ccpp_prebuild_config.py --suites=${SUITES} --builddir=${CMAKE_CURRENT_BINARY_DIR}/.. + OUTPUT_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.out + ERROR_FILE ${PROJECT_BINARY_DIR}/ccpp_prebuild.err + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../.. + RESULT_VARIABLE return_code +) + # Check return code from CCPP prebuild.py if(return_code EQUAL 0) message (STATUS "CCPP prebuild step completed successfully") @@ -69,20 +58,29 @@ ELSE(DEFINED ENV{NETCDF}) MESSAGE(FATAL_ERROR "The NETCDF environement variable must be set to point to your NetCDF installation before building. Stopping...") ENDIF(DEFINED ENV{NETCDF}) -IF(DEFINED ENV{NCEPLIBS_DIR}) - MESSAGE(STATUS "The NCEPLIBS_DIR environment variable is $ENV{NCEPLIBS_DIR}") - set(NCEPLIBS_DIR $ENV{NCEPLIBS_DIR}) -ELSE(DEFINED ENV{NCEPLIBS_DIR}) - MESSAGE(FATAL_ERROR "The NCEPLIBS_DIR environment variable must be set to point to your NCEPlibs installation before building. Stopping...") -ENDIF(DEFINED ENV{NCEPLIBS_DIR}) +IF(DEFINED ENV{BACIO_LIB4}) + MESSAGE(STATUS "The BACIO_LIB4 environment variable is $ENV{BACIO_LIB4}") + SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{BACIO_LIB4}) + SET(BACIO_LIB4 $ENV{BACIO_LIB4}) +ELSE(DEFINED ENV{BACIO_LIB4}) + MESSAGE(FATAL_ERROR "The BACIO_LIB4 environment variable must be set to point to your BACIO installation (part of NCEPLIBS) before building. Stopping...") +ENDIF(DEFINED ENV{BACIO_LIB4}) -set(BACIO_LIB4 ${NCEPLIBS_DIR}/lib/libbacio_4.a) -set(SP_LIBd ${NCEPLIBS_DIR}/lib/libsp_v2.0.2_d.a) -set(W3NCO_LIBd ${NCEPLIBS_DIR}/lib/libw3nco_d.a) +IF(DEFINED ENV{SP_LIBd}) + MESSAGE(STATUS "The SP_LIBd environment variable is $ENV{SP_LIBd}") + SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{SP_LIBd}) + SET(SP_LIBd $ENV{SP_LIBd}) +ELSE(DEFINED ENV{SP_LIBd}) + MESSAGE(FATAL_ERROR "The SP_LIBd environment variable must be set to point to your SP installation (part of NCEPLIBS) before building. Stopping...") +ENDIF(DEFINED ENV{SP_LIBd}) -if(STATIC) - ADD_DEFINITIONS(-DSTATIC) -endif(STATIC) +IF(DEFINED ENV{W3NCO_LIBd}) + MESSAGE(STATUS "The W3NCO_LIBd environment variable is $ENV{W3NCO_LIBd}") + SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{W3NCO_LIBd}) + SET(W3NCO_LIBd $ENV{W3NCO_LIBd}) +ELSE(DEFINED ENV{W3NCO_LIBd}) + MESSAGE(FATAL_ERROR "The W3NCO_LIBd environment variable must be set to point to your W3NCO installation (part of NCEPLIBS) before building. Stopping...") +ENDIF(DEFINED ENV{W3NCO_LIBd}) SET(CCPP_SRC ${CMAKE_SOURCE_DIR}/../../ccpp/framework) SET(GFSPHYSICS_SRC ${CMAKE_SOURCE_DIR}/../../ccpp/physics) @@ -261,6 +259,10 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../ccpp/framework/ #------------------------------------------------------------------------------ # Set OpenMP flags for C/C++/Fortran if (OPENMP) + # OpenMP broken for clang compiler + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang*") + message(FATAL_ERROR "OpenMP not supported for the LLVM Clang compiler") + endif() include(detect_openmp) detect_openmp() set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") @@ -278,25 +280,18 @@ ADD_SUBDIRECTORY(${GFSPHYSICS_SRC} ${CMAKE_BINARY_DIR}/ccpp/physics) ADD_DEPENDENCIES(ccppphys ccpp) SET(scm_source_files gmtb_scm.F90 - gmtb_scm_input.f90 - gmtb_scm_utils.f90 + gmtb_scm_input.F90 + gmtb_scm_utils.F90 gmtb_scm_vgrid.F90 - gmtb_scm_setup.f90 - gmtb_scm_forcing.f90 - gmtb_scm_time_integration.f90 - gmtb_scm_output.f90 - gmtb_scm_kinds.f90 - gmtb_scm_physical_constants.f90 - gmtb_scm_type_defs.f90 + gmtb_scm_setup.F90 + gmtb_scm_forcing.F90 + gmtb_scm_time_integration.F90 + gmtb_scm_output.F90 ) -if(STATIC) - ADD_EXECUTABLE(gmtb_scm ${scm_source_files} ccpp_static_api.F90) - TARGET_LINK_LIBRARIES(gmtb_scm ccppphys ccpp ${BACIO_LIB4} ${SP_LIBd} ${W3NCO_LIBd}) -else(STATIC) - ADD_EXECUTABLE(gmtb_scm ${scm_source_files}) - TARGET_LINK_LIBRARIES(gmtb_scm ccppphys ccpp) -endif(STATIC) +ADD_EXECUTABLE(gmtb_scm ${scm_source_files} ccpp_static_api.F90) +TARGET_LINK_LIBRARIES(gmtb_scm ccppphys ccpp ${BACIO_LIB4} ${SP_LIBd} ${W3NCO_LIBd}) + set_target_properties(gmtb_scm PROPERTIES COMPILE_FLAGS "${CMAKE_Fortran_FLAGS}" diff --git a/scm/src/GFS_typedefs.F90 b/scm/src/GFS_typedefs.F90 index 2b8187880..bbca9cac2 100644 --- a/scm/src/GFS_typedefs.F90 +++ b/scm/src/GFS_typedefs.F90 @@ -3,8 +3,13 @@ module GFS_typedefs use machine, only: kind_phys - use module_radlw_parameters, only: sfcflw_type, topflw_type, NBDLW - use module_radsw_parameters, only: cmpfsw_type, sfcfsw_type, topfsw_type, NBDSW + use module_radlw_parameters, only: sfcflw_type, topflw_type, NBDLW, proflw_type + use module_radsw_parameters, only: cmpfsw_type, sfcfsw_type, topfsw_type, NBDSW, profsw_type + use mo_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp + use mo_optical_props, only: ty_optical_props_1scl,ty_optical_props_2str + use mo_cloud_optics, only: ty_cloud_optics + use mo_gas_concentrations, only: ty_gas_concs + use mo_source_functions, only: ty_source_func_lw implicit none @@ -30,11 +35,9 @@ module GFS_typedefs private :: levozp, oz_coeff, levh2o, h2o_coeff, ntrcaer integer :: levozp, oz_coeff, levh2o, h2o_coeff, ntrcaer -#if 0 !> \section arg_table_GFS_typedefs !! \htmlinclude GFS_typedefs.html !! -#endif !--- version of physics character(len=64) :: phys_version = 'v2018 FV3GFS BETA VERSION PHYSICS' @@ -77,17 +80,15 @@ module GFS_typedefs ! GFS_diag_type !< fields targetted for diagnostic output ! GFS_interstitial_type !< fields required to replace interstitial code in GFS_{physics,radiation}_driver.F90 in CCPP -#if 0 -!> \section arg_table_GFS_init_type -!! \htmlinclude GFS_init_type.html -!! -#endif !-------------------------------------------------------------------------------- ! GFS_init_type !-------------------------------------------------------------------------------- ! This container is the minimum set of data required from the dycore/atmosphere ! component to allow proper initialization of the GFS physics !-------------------------------------------------------------------------------- +!! \section arg_table_GFS_init_type +!! \htmlinclude GFS_init_type.html +!! type GFS_init_type integer :: me !< my MPI-rank integer :: master !< master MPI-rank @@ -132,15 +133,14 @@ module GFS_typedefs !< for use with internal file reads end type GFS_init_type -#if 0 -!> \section arg_table_GFS_statein_type -!! \htmlinclude GFS_statein_type.html -!! -#endif + !---------------------------------------------------------------- ! GFS_statein_type ! prognostic state variables with layer and level specific data !---------------------------------------------------------------- +!! \section arg_table_GFS_statein_type +!! \htmlinclude GFS_statein_type.html +!! type GFS_statein_type !--- level geopotential and pressures @@ -171,15 +171,14 @@ module GFS_typedefs procedure :: create => statein_create !< allocate array data end type GFS_statein_type -#if 0 -!> \section arg_table_GFS_stateout_type -!! \htmlinclude GFS_stateout_type.html -!! -#endif + !------------------------------------------------------------------ ! GFS_stateout_type ! prognostic state or tendencies after physical parameterizations !------------------------------------------------------------------ +!! \section arg_table_GFS_stateout_type +!! \htmlinclude GFS_stateout_type.html +!! type GFS_stateout_type !-- Out (physics only) @@ -192,15 +191,14 @@ module GFS_typedefs procedure :: create => stateout_create !< allocate array data end type GFS_stateout_type -#if 0 -!> \section arg_table_GFS_sfcprop_type -!! \htmlinclude GFS_sfcprop_type.html -!! -#endif + !--------------------------------------------------------------------------------------- ! GFS_sfcprop_type ! surface properties that may be read in and/or updated by climatology or observations !--------------------------------------------------------------------------------------- +!! \section arg_table_GFS_sfcprop_type +!! \htmlinclude GFS_sfcprop_type.html +!! type GFS_sfcprop_type !--- In (radiation and physics) @@ -212,12 +210,12 @@ module GFS_typedefs !< [tsea in gbphys.f] real (kind=kind_phys), pointer :: tsfco (:) => null() !< sst in K real (kind=kind_phys), pointer :: tsfcl (:) => null() !< surface land temperature in K - real (kind=kind_phys), pointer :: tisfc (:) => null() !< surface temperature over ice fraction + real (kind=kind_phys), pointer :: tisfc (:) => null() !< surface temperature over ice fraction real (kind=kind_phys), pointer :: snowd (:) => null() !< snow depth water equivalent in mm ; same as snwdph - real (kind=kind_phys), pointer :: zorl (:) => null() !< composite surface roughness in cm - real (kind=kind_phys), pointer :: zorlo (:) => null() !< ocean surface roughness in cm - real (kind=kind_phys), pointer :: zorll (:) => null() !< land surface roughness in cm - real (kind=kind_phys), pointer :: fice (:) => null() !< ice fraction over open water grid + real (kind=kind_phys), pointer :: zorl (:) => null() !< composite surface roughness in cm + real (kind=kind_phys), pointer :: zorlo (:) => null() !< ocean surface roughness in cm + real (kind=kind_phys), pointer :: zorll (:) => null() !< land surface roughness in cm + real (kind=kind_phys), pointer :: fice (:) => null() !< ice fraction over open water grid ! real (kind=kind_phys), pointer :: hprim (:) => null() !< topographic standard deviation in m real (kind=kind_phys), pointer :: hprime (:,:) => null() !< orographic metrics @@ -266,7 +264,7 @@ module GFS_typedefs real (kind=kind_phys), pointer :: q2m (:) => null() !< 2 meter humidity ! -- In/Out for Noah MP - real (kind=kind_phys), pointer :: snowxy (:) => null() ! + real (kind=kind_phys), pointer :: snowxy (:) => null() !< real (kind=kind_phys), pointer :: tvxy (:) => null() !< veg temp real (kind=kind_phys), pointer :: tgxy (:) => null() !< ground temp real (kind=kind_phys), pointer :: canicexy(:) => null() !< @@ -352,7 +350,7 @@ module GFS_typedefs real (kind=kind_phys), pointer :: cqs2(:) => null() !exch coeff for moisture at 2m real (kind=kind_phys), pointer :: lh(:) => null() !latent heating at the surface - !---- precipitation amounts from previous time step for RUC LSM + !---- precipitation amounts from previous time step for RUC LSM/NoahMP LSM real (kind=kind_phys), pointer :: raincprv (:) => null() !< explicit rainfall from previous timestep real (kind=kind_phys), pointer :: rainncprv (:) => null() !< convective_precipitation_amount from previous timestep real (kind=kind_phys), pointer :: iceprv (:) => null() !< ice amount from previous timestep @@ -365,20 +363,19 @@ module GFS_typedefs real (kind=kind_phys), pointer :: diceprv (:) => null() !< ice precipitation rate from previous timestep real (kind=kind_phys), pointer :: dsnowprv (:) => null() !< snow precipitation rate from previous timestep real (kind=kind_phys), pointer :: dgraupelprv(:) => null() !< graupel precipitation rate from previous timestep - + contains procedure :: create => sfcprop_create !< allocate array data end type GFS_sfcprop_type -#if 0 -!> \section arg_table_GFS_coupling_type -!! \htmlinclude GFS_coupling_type.html -!! -#endif + !--------------------------------------------------------------------- ! GFS_coupling_type ! fields to/from other coupled components (e.g. land/ice/ocean/etc.) !--------------------------------------------------------------------- +!! \section arg_table_GFS_coupling_type +!! \htmlinclude GFS_coupling_type.html +!! type GFS_coupling_type !--- Out (radiation only) @@ -410,7 +407,8 @@ module GFS_typedefs real (kind=kind_phys), pointer :: ficein_cpl(:) => null() !< aoi_fld%ficein(item,lan) real (kind=kind_phys), pointer :: hicein_cpl(:) => null() !< aoi_fld%hicein(item,lan) real (kind=kind_phys), pointer :: hsnoin_cpl(:) => null() !< aoi_fld%hsnoin(item,lan) - !--- only variable needed for cplwav=.TRUE. + !--- only variable needed for cplwav2atm=.TRUE. + real (kind=kind_phys), pointer :: zorlwav_cpl(:) => null() !< roughness length from wave model !--- also needed for ice/ocn coupling - Xingren real (kind=kind_phys), pointer :: slimskin_cpl(:)=> null() !< aoi_fld%slimskin(item,lan) @@ -464,18 +462,16 @@ module GFS_typedefs real (kind=kind_phys), pointer :: slmsk_cpl (:) => null() !< Land/Sea/Ice mask (slmsk from GFS_sfcprop_type) !--- cellular automata - real (kind=kind_phys), pointer :: tconvtend(:,:) => null() - real (kind=kind_phys), pointer :: qconvtend(:,:) => null() - real (kind=kind_phys), pointer :: uconvtend(:,:) => null() - real (kind=kind_phys), pointer :: vconvtend(:,:) => null() - real (kind=kind_phys), pointer :: ca_out (:) => null() ! + real (kind=kind_phys), pointer :: ca1 (:) => null() ! + real (kind=kind_phys), pointer :: ca2 (:) => null() ! + real (kind=kind_phys), pointer :: ca3 (:) => null() ! real (kind=kind_phys), pointer :: ca_deep (:) => null() ! real (kind=kind_phys), pointer :: ca_turb (:) => null() ! real (kind=kind_phys), pointer :: ca_shal (:) => null() ! real (kind=kind_phys), pointer :: ca_rad (:) => null() ! real (kind=kind_phys), pointer :: ca_micro (:) => null() ! - real (kind=kind_phys), pointer :: cape (:) => null() ! - + real (kind=kind_phys), pointer :: condition(:) => null() ! + real (kind=kind_phys), pointer :: vfact_ca(:) => null() ! !--- stochastic physics real (kind=kind_phys), pointer :: shum_wts (:,:) => null() ! real (kind=kind_phys), pointer :: sppt_wts (:,:) => null() ! @@ -497,16 +493,15 @@ module GFS_typedefs procedure :: create => coupling_create !< allocate array data end type GFS_coupling_type -#if 0 -!> \section arg_table_GFS_control_type -!! \htmlinclude GFS_control_type.html -!! -#endif + !---------------------------------------------------------------------------------- ! GFS_control_type ! model control parameters input from a namelist and/or derived from others ! list of those that can be modified during the run are at the bottom of the list !---------------------------------------------------------------------------------- +!! \section arg_table_GFS_control_type +!! \htmlinclude GFS_control_type.html +!! type GFS_control_type integer :: me !< MPI rank designator @@ -551,10 +546,11 @@ module GFS_typedefs !--- coupling parameters logical :: cplflx !< default no cplflx collection logical :: cplwav !< default no cplwav collection + logical :: cplwav2atm !< default no wav->atm coupling logical :: cplchm !< default no cplchm collection !--- integrated dynamics through earth's atmosphere - logical :: lsidea + logical :: lsidea !vay 2018 GW physics switches @@ -581,7 +577,7 @@ module GFS_typedefs integer :: levr !< number of vertical levels for radiation calculations integer :: levrp1 !< number of vertical levels for radiation calculations plus one integer :: nfxr !< second dimension for fluxr diagnostic variable (radiation) - logical :: aero_in !< flag for initializing aerosol data + logical :: iaerclm !< flag for initializing aerosol data integer :: ntrcaer !< number of aerosol tracers for Morrison-Gettelman microphysics logical :: lmfshal !< parameter for radiation logical :: lmfdeep2 !< parameter for radiation @@ -618,7 +614,27 @@ module GFS_typedefs logical :: norad_precip !< radiation precip flag for Ferrier/Moorthi logical :: lwhtr !< flag to output lw heating rate (Radtend%lwhc) logical :: swhtr !< flag to output sw heating rate (Radtend%swhc) - + ! RRTMGP + logical :: do_RRTMGP !< Use RRTMGP + character(len=128) :: active_gases !< Character list of active gases used in RRTMGP + integer :: nGases !< Number of active gases + character(len=128) :: rrtmgp_root !< Directory of rte+rrtmgp source code + character(len=128) :: lw_file_gas !< RRTMGP K-distribution file, coefficients to compute optics for gaseous atmosphere + character(len=128) :: lw_file_clouds !< RRTMGP file containing coefficients used to compute clouds optical properties + integer :: rrtmgp_nBandsLW !< Number of RRTMGP LW bands. + integer :: rrtmgp_nGptsLW !< Number of RRTMGP LW spectral points. + character(len=128) :: sw_file_gas !< RRTMGP K-distribution file, coefficients to compute optics for gaseous atmosphere + character(len=128) :: sw_file_clouds !< RRTMGP file containing coefficients used to compute clouds optical properties + integer :: rrtmgp_nBandsSW !< Number of RRTMGP SW bands. + integer :: rrtmgp_nGptsSW !< Number of RRTMGP SW spectral points. + integer :: rrtmgp_cld_optics !< Flag to control which RRTMGP routine to compute cloud-optics. + !< = 0 ; Use RRTMG implementation + !< = 1 ; Use RRTMGP (pade) + !< = 2 ; USE RRTMGP (LUT) + integer :: rrtmgp_nrghice !< Number of ice-roughness categories + integer :: rrtmgp_nGauss_ang !< Number of angles used in Gaussian quadrature + logical :: do_GPsw_Glw ! If set to true use rrtmgp for SW calculation, rrtmg for LW. + character(len=128) :: active_gases_array(100) !< character array for each trace gas name !--- microphysical switch integer :: ncld !< choice of cloud scheme !--- new microphysical switch @@ -651,7 +667,6 @@ module GFS_typedefs real(kind=kind_phys) :: mg_alf !< tuning factor for alphs in MG macrophysics real(kind=kind_phys) :: mg_qcmin(2) !< min liquid and ice mixing ratio in Mg macro clouds character(len=16) :: mg_precip_frac_method ! type of precipitation fraction method - real(kind=kind_phys) :: tf real(kind=kind_phys) :: tcr real(kind=kind_phys) :: tcrf @@ -677,12 +692,16 @@ module GFS_typedefs !--- Thompson's microphysical parameters logical :: ltaerosol !< flag for aerosol version - logical :: lradar !< flag for radar reflectivity + logical :: lradar !< flag for radar reflectivity + real(kind=kind_phys) :: nsradar_reset !< seconds between resetting radar reflectivity calculation real(kind=kind_phys) :: ttendlim !< temperature tendency limiter per time step in K/s !--- GFDL microphysical paramters logical :: lgfdlmprad !< flag for GFDL mp scheme and radiation consistency + !--- Thompson,GFDL mp parameter + logical :: lrefres !< flag for radar reflectivity in restart file + !--- land/surface model parameters integer :: lsm !< flag for land surface model lsm=1 for noah lsm integer :: lsm_noah=1 !< flag for NOAH land surface model @@ -779,7 +798,7 @@ module GFS_typedefs integer :: imfdeepcnv_samf = 2 !< flag for SAMF scale- & aerosol-aware mass-flux deep convection scheme integer :: imfdeepcnv_gf = 3 !< flag for scale- & aerosol-aware Grell-Freitas scheme (GSD) integer :: imfdeepcnv_ntiedtke = 4 !< flag for new Tiedtke scheme (CAPS) - integer :: isatmedmf !< flag for scale-aware TKE-based moist edmf scheme + integer :: isatmedmf !< flag for scale-aware TKE-based moist edmf scheme !< 0: initial version of satmedmf (Nov. 2018) !< 1: updated version of satmedmf (as of May 2019) integer :: isatmedmf_vdif = 0 !< flag for initial version of satmedmf (Nov. 2018) @@ -860,7 +879,7 @@ module GFS_typedefs !< cx = min([-0.7 ln(Nccn) + 24]*1.e-4, c0s) !< Nccn: CCN number concentration in cm^(-3) !< Until a realistic Nccn is provided, Nccns are assumed - !< as Nccn=100 for sea and Nccn=1000 for land + !< as Nccn=100 for sea and Nccn=1000 for land !--- near surface temperature model logical :: nst_anl !< flag for NSSTM analysis in gcycle/sfcsub @@ -875,17 +894,20 @@ module GFS_typedefs !< nstf_name(5) : zsea2 in mm !--- fractional grid logical :: frac_grid !< flag for fractional grid + logical :: frac_grid_off !< flag for using fractional grid + logical :: ignore_lake !< flag for ignoring lakes real(kind=kind_phys) :: min_lakeice !< minimum lake ice value real(kind=kind_phys) :: min_seaice !< minimum sea ice value + real(kind=kind_phys) :: min_lake_height !< minimum lake height value real(kind=kind_phys) :: rho_h2o !< density of fresh water !--- surface layer z0 scheme - integer :: sfc_z0_type !< surface roughness options over ocean: + integer :: sfc_z0_type !< surface roughness options over ocean: !< 0=no change !< 6=areodynamical roughness over water with input 10-m wind !< 7=slightly decrease Cd for higher wind speed compare to 6 -!--- background vertical diffusion +!--- vertical diffusion real(kind=kind_phys) :: xkzm_m !< [in] bkgd_vdif_m background vertical diffusion for momentum real(kind=kind_phys) :: xkzm_h !< [in] bkgd_vdif_h background vertical diffusion for heat q real(kind=kind_phys) :: xkzm_s !< [in] bkgd_vdif_s sigma threshold for background mom. diffusion @@ -895,20 +917,34 @@ module GFS_typedefs real(kind=kind_phys) :: bl_upfr !< updraft fraction in boundary layer mass flux scheme real(kind=kind_phys) :: bl_dnfr !< downdraft fraction in boundary layer mass flux scheme - !---cellular automata control parameters +!--- parameters for canopy heat storage (CHS) parameterization + real(kind=kind_phys) :: z0fac !< surface roughness fraction factor + real(kind=kind_phys) :: e0fac !< latent heat flux fraction factor relative to sensible heat flux + !< e.g., e0fac=0.5 indicates that CHS for latent heat flux is 50% of that for + !< sensible heat flux + +!---cellular automata control parameters integer :: nca !< number of independent cellular automata integer :: nlives !< cellular automata lifetime integer :: ncells !< cellular automata finer grid - real(kind=kind_phys) :: nfracseed !< cellular automata seed probability + integer :: nca_g !< number of independent cellular automata + integer :: nlives_g !< cellular automata lifetime + integer :: ncells_g !< cellular automata finer grid + real(kind=kind_phys) :: nfracseed !< cellular automata seed probability integer :: nseed !< cellular automata seed frequency + integer :: nseed_g !< cellular automata seed frequency logical :: do_ca !< cellular automata main switch logical :: ca_sgs !< switch for sgs ca logical :: ca_global !< switch for global ca logical :: ca_smooth !< switch for gaussian spatial filter - logical :: isppt_deep !< switch for combination with isppt_deep. OBS! Switches off SPPT on other tendencies! integer :: iseed_ca !< seed for random number generation in ca scheme integer :: nspinup !< number of iterations to spin up the ca real(kind=kind_phys) :: nthresh !< threshold used for perturbed vertical velocity + real :: ca_amplitude !< amplitude of ca trigger perturbation + integer :: nsmooth !< number of passes through smoother + logical :: ca_closure !< logical switch for ca on closure + logical :: ca_entr !< logical switch for ca on entrainment + logical :: ca_trigger !< logical switch for ca on trigger !--- stochastic physics control parameters logical :: do_sppt @@ -945,7 +981,7 @@ module GFS_typedefs integer :: ntke !< tracer index for kinetic energy integer :: nto !< tracer index for oxygen ion integer :: nto2 !< tracer index for oxygen - integer :: ntwa !< tracer index for water friendly aerosol + integer :: ntwa !< tracer index for water friendly aerosol integer :: ntia !< tracer index for ice friendly aerosol integer :: ntchm !< number of chemical tracers integer :: ntchs !< tracer index for first chemical tracer @@ -999,10 +1035,10 @@ module GFS_typedefs logical :: hydrostatic !< flag whether this is a hydrostatic or non-hydrostatic run integer :: jdat(1:8) !< current forecast date and time !< (yr, mon, day, t-zone, hr, min, sec, mil-sec) - real(kind=kind_phys) :: julian !< current forecast julian date - integer :: yearlen !< current length of the year + real(kind=kind_phys) :: julian !< julian day using midnight of January 1 of forecast year as initial epoch + integer :: yearlen !< length of the current forecast year in days ! - logical :: iccn !< using IN CCN forcing for MG2/3 + integer :: iccn !< using IN CCN forcing for MG2/3 real(kind=kind_phys) :: sec !< seconds since model initialization real(kind=kind_phys), pointer :: si(:) !< vertical sigma coordinate for model initialization @@ -1011,7 +1047,7 @@ module GFS_typedefs real(kind=kind_phys) :: iau_delthrs ! iau time interval (to scale increments) in hours character(len=240) :: iau_inc_files(7)! list of increment files real(kind=kind_phys) :: iaufhrs(7) ! forecast hours associated with increment files - logical :: iau_filter_increments + logical :: iau_filter_increments, iau_drymassfixer ! From physcons.F90, updated/set in control_initialize real(kind=kind_phys) :: dxinv ! inverse scaling factor for critical relative humidity, replaces dxinv in physcons.F90 @@ -1024,15 +1060,14 @@ module GFS_typedefs procedure :: print => control_print end type GFS_control_type -#if 0 -!> \section arg_table_GFS_grid_type -!! \htmlinclude GFS_grid_type.html -!! -#endif + !-------------------------------------------------------------------- ! GFS_grid_type ! grid data needed for interpolations and length-scale calculations !-------------------------------------------------------------------- +!! \section arg_table_GFS_grid_type +!! \htmlinclude GFS_grid_type.html +!! type GFS_grid_type real (kind=kind_phys), pointer :: xlon (:) => null() !< grid longitude in radians, ok for both 0->2pi @@ -1077,15 +1112,14 @@ module GFS_typedefs procedure :: create => grid_create !< allocate array data end type GFS_grid_type -#if 0 -!> \section arg_table_GFS_tbd_type -!! \htmlinclude GFS_tbd_type.html -!! -#endif + !----------------------------------------------- ! GFS_tbd_type ! data not yet assigned to a defined container !----------------------------------------------- +!! \section arg_table_GFS_tbd_type +!! \htmlinclude GFS_tbd_type.html +!! type GFS_tbd_type !--- radiation random seeds @@ -1123,12 +1157,6 @@ module GFS_typedefs real (kind=kind_phys), pointer :: phy_f2d (:,:) => null() !< 2d arrays saved for restart real (kind=kind_phys), pointer :: phy_f3d (:,:,:) => null() !< 3d arrays saved for restart - !--- radiation variables that need to be carried over from radiation to physics - real (kind=kind_phys), pointer :: htlwc(:,:) => null() !< - real (kind=kind_phys), pointer :: htlw0(:,:) => null() !< - real (kind=kind_phys), pointer :: htswc(:,:) => null() !< - real (kind=kind_phys), pointer :: htsw0(:,:) => null() !< - !--- dynamical forcing variables for Grell-Freitas convection real (kind=kind_phys), pointer :: forcet (:,:) => null() !< real (kind=kind_phys), pointer :: forceq (:,:) => null() !< @@ -1165,15 +1193,14 @@ module GFS_typedefs procedure :: create => tbd_create !< allocate array data end type GFS_tbd_type -#if 0 -!> \section arg_table_GFS_cldprop_type -!! \htmlinclude GFS_cldprop_type.html -!! -#endif + !------------------------------------------------------------------ ! GFS_cldprop_type ! cloud properties and tendencies needed by radiation from physics !------------------------------------------------------------------ +!! \section arg_table_GFS_cldprop_type +!! \htmlinclude GFS_cldprop_type.html +!! type GFS_cldprop_type !--- In (radiation) @@ -1186,15 +1213,14 @@ module GFS_typedefs procedure :: create => cldprop_create !< allocate array data end type GFS_cldprop_type -#if 0 -!> \section arg_table_GFS_radtend_type -!! \htmlinclude GFS_radtend_type.html -!! -#endif + !----------------------------------------- ! GFS_radtend_type ! radiation tendencies needed by physics !----------------------------------------- +!! \section arg_table_GFS_radtend_type +!! \htmlinclude GFS_radtend_type.html +!! type GFS_radtend_type type (sfcfsw_type), pointer :: sfcfsw(:) => null() !< sw radiation fluxes at sfc @@ -1234,15 +1260,13 @@ module GFS_typedefs procedure :: create => radtend_create !< allocate array data end type GFS_radtend_type -#if 0 -!> \section arg_table_GFS_diag_type -!! \htmlinclude GFS_diag_type.html -!! -#endif !---------------------------------------------------------------- ! GFS_diag_type ! internal diagnostic type used as arguments to gbphys and grrad !---------------------------------------------------------------- +!! \section arg_table_GFS_diag_type +!! \htmlinclude GFS_diag_type.html +!! type GFS_diag_type !! Input/Output only in radiation @@ -1370,7 +1394,9 @@ module GFS_typedefs real (kind=kind_phys), pointer :: tdomip (:) => null() !< dominant accumulated sleet type real (kind=kind_phys), pointer :: tdoms (:) => null() !< dominant accumulated snow type - real (kind=kind_phys), pointer :: ca_out (:) => null() !< cellular automata fraction + real (kind=kind_phys), pointer :: ca1 (:) => null() ! + real (kind=kind_phys), pointer :: ca2 (:) => null() ! + real (kind=kind_phys), pointer :: ca3 (:) => null() ! real (kind=kind_phys), pointer :: ca_deep (:) => null() !< cellular automata fraction real (kind=kind_phys), pointer :: ca_turb (:) => null() !< cellular automata fraction real (kind=kind_phys), pointer :: ca_shal (:) => null() !< cellular automata fraction @@ -1397,7 +1423,6 @@ module GFS_typedefs real (kind=kind_phys), pointer :: dwn_mf (:,:) => null() !< instantaneous convective downdraft mass flux real (kind=kind_phys), pointer :: det_mf (:,:) => null() !< instantaneous convective detrainment mass flux real (kind=kind_phys), pointer :: cldcov (:,:) => null() !< instantaneous 3D cloud fraction - !--- F-A MP scheme real (kind=kind_phys), pointer :: TRAIN (:,:) => null() !< accumulated stratiform T tendency (K s-1) @@ -1498,16 +1523,14 @@ module GFS_typedefs procedure :: chem_init => diag_chem_init end type GFS_diag_type -#if 0 -!> \section arg_table_GFS_interstitial_type -!! \htmlinclude GFS_interstitial_type.html -!! -#endif !--------------------------------------------------------------------- ! GFS_interstitial_type ! fields required for interstitial code in CCPP schemes, previously ! in GFS_{physics,radiation}_driver.F90 !--------------------------------------------------------------------- +!! \section arg_table_GFS_interstitial_type +!! \htmlinclude GFS_interstitial_type.html +!! type GFS_interstitial_type real (kind=kind_phys), pointer :: adjsfculw_land(:) => null() !< @@ -1589,6 +1612,7 @@ module GFS_typedefs real (kind=kind_phys), pointer :: ep1d_land(:) => null() !< real (kind=kind_phys), pointer :: ep1d_ocean(:) => null() !< real (kind=kind_phys), pointer :: evap(:) => null() !< + real (kind=kind_phys), pointer :: evapq(:) => null() !< real (kind=kind_phys), pointer :: evap_ice(:) => null() !< real (kind=kind_phys), pointer :: evap_land(:) => null() !< real (kind=kind_phys), pointer :: evap_ocean(:) => null() !< @@ -1634,10 +1658,19 @@ module GFS_typedefs real (kind=kind_phys), pointer :: gwdcv(:,:) => null() !< integer :: h2o_coeff !< real (kind=kind_phys), pointer :: h2o_pres(:) => null() !< + real (kind=kind_phys), pointer :: hefac(:) => null() !< + real (kind=kind_phys), pointer :: hffac(:) => null() !< real (kind=kind_phys), pointer :: hflx(:) => null() !< + real (kind=kind_phys), pointer :: hflxq(:) => null() !< real (kind=kind_phys), pointer :: hflx_ice(:) => null() !< real (kind=kind_phys), pointer :: hflx_land(:) => null() !< real (kind=kind_phys), pointer :: hflx_ocean(:) => null() !< + !--- radiation variables that need to be carried over from radiation to physics + real (kind=kind_phys), pointer :: htlwc(:,:) => null() !< + real (kind=kind_phys), pointer :: htlw0(:,:) => null() !< + real (kind=kind_phys), pointer :: htswc(:,:) => null() !< + real (kind=kind_phys), pointer :: htsw0(:,:) => null() !< + ! real (kind=kind_phys), pointer :: icemp(:) => null() !< logical, pointer :: dry(:) => null() !< integer, pointer :: idxday(:) => null() !< @@ -1709,6 +1742,7 @@ module GFS_typedefs real (kind=kind_phys), pointer :: qss_ice(:) => null() !< real (kind=kind_phys), pointer :: qss_land(:) => null() !< real (kind=kind_phys), pointer :: qss_ocean(:) => null() !< + logical :: radar_reset !< real (kind=kind_phys) :: raddt !< real (kind=kind_phys), pointer :: rainmp(:) => null() !< real (kind=kind_phys), pointer :: raincd(:) => null() !< @@ -1775,11 +1809,6 @@ module GFS_typedefs real (kind=kind_phys), pointer :: tsurf_land(:) => null() !< real (kind=kind_phys), pointer :: tsurf_ocean(:) => null() !< real (kind=kind_phys), pointer :: ud_mf(:,:) => null() !< - real (kind=kind_phys), pointer :: ulwsfc_cice(:) => null() !< - real (kind=kind_phys), pointer :: dusfc_cice(:) => null() !< - real (kind=kind_phys), pointer :: dvsfc_cice(:) => null() !< - real (kind=kind_phys), pointer :: dqsfc_cice(:) => null() !< - real (kind=kind_phys), pointer :: dtsfc_cice(:) => null() !< real (kind=kind_phys), pointer :: uustar_ice(:) => null() !< real (kind=kind_phys), pointer :: uustar_land(:) => null() !< real (kind=kind_phys), pointer :: uustar_ocean(:) => null() !< @@ -1803,7 +1832,6 @@ module GFS_typedefs real (kind=kind_phys), pointer :: zorl_land(:) => null() !< real (kind=kind_phys), pointer :: zorl_ocean(:) => null() !< real (kind=kind_phys), pointer :: zt1d(:) => null() !< -! CIRES UGWP v0 real (kind=kind_phys), pointer :: gw_dudt(:,:) => null() !< real (kind=kind_phys), pointer :: gw_dvdt(:,:) => null() !< real (kind=kind_phys), pointer :: gw_dtdt(:,:) => null() !< @@ -1819,6 +1847,69 @@ module GFS_typedefs real (kind=kind_phys), pointer :: dudt_ogw(:,:) => null() !< daily aver u-wind tend due to orographic gravity wave drag real (kind=kind_phys), pointer :: dudt_tms(:,:) => null() !< daily aver u-wind tend due to TMS + ! RRTMGP + integer :: ipsdlw0 !< + integer :: ipsdsw0 !< + real (kind=kind_phys), pointer :: p_lay(:,:) => null() !< + real (kind=kind_phys), pointer :: p_lev(:,:) => null() !< + real (kind=kind_phys), pointer :: t_lev(:,:) => null() !< + real (kind=kind_phys), pointer :: t_lay(:,:) => null() !< + real (kind=kind_phys), pointer :: relhum(:,:) => null() !< + real (kind=kind_phys), pointer :: tv_lay(:,:) => null() !< + real (kind=kind_phys), pointer :: tracer(:,:,:) => null() !< + real (kind=kind_phys), pointer :: aerosolslw(:,:,:,:) => null() !< Aerosol radiative properties in each LW band. + real (kind=kind_phys), pointer :: aerosolssw(:,:,:,:) => null() !< Aerosol radiative properties in each SW band. + real (kind=kind_phys), pointer :: cld_frac(:,:) => null() !< Total cloud fraction + real (kind=kind_phys), pointer :: cld_lwp(:,:) => null() !< Cloud liquid water path + real (kind=kind_phys), pointer :: cld_reliq(:,:) => null() !< Cloud liquid effective radius + real (kind=kind_phys), pointer :: cld_iwp(:,:) => null() !< Cloud ice water path + real (kind=kind_phys), pointer :: cld_reice(:,:) => null() !< Cloud ice effecive radius + real (kind=kind_phys), pointer :: cld_swp(:,:) => null() !< Cloud snow water path + real (kind=kind_phys), pointer :: cld_resnow(:,:) => null() !< Cloud snow effective radius + real (kind=kind_phys), pointer :: cld_rwp(:,:) => null() !< Cloud rain water path + real (kind=kind_phys), pointer :: cld_rerain(:,:) => null() !< Cloud rain effective radius + real (kind=kind_phys), pointer :: hsw0(:,:) => null() !< RRTMGP shortwave heating-rate (clear-sky) + real (kind=kind_phys), pointer :: hswc(:,:) => null() !< RRTMGP shortwave heating-rate (all-sky) + real (kind=kind_phys), pointer :: hswb(:,:,:) => null() !< RRTMGP shortwave heating-rate (all-sky), by band + real (kind=kind_phys), pointer :: hlw0(:,:) => null() !< RRTMGP longwave heating-rate (clear-sky) + real (kind=kind_phys), pointer :: hlwc(:,:) => null() !< RRTMGP longwave heating-rate (all-sky) + real (kind=kind_phys), pointer :: hlwb(:,:,:) => null() !< RRTMGP longwave heating-rate (all-sky), by band + real (kind=kind_phys), pointer :: fluxlwUP_allsky(:,:) => null() !< RRTMGP upward longwave all-sky flux profile + real (kind=kind_phys), pointer :: fluxlwDOWN_allsky(:,:) => null() !< RRTMGP downward longwave all-sky flux profile + real (kind=kind_phys), pointer :: fluxlwUP_clrsky(:,:) => null() !< RRTMGP upward longwave clr-sky flux profile + real (kind=kind_phys), pointer :: fluxlwDOWN_clrsky(:,:) => null() !< RRTMGP downward longwave clr-sky flux profile + real (kind=kind_phys), pointer :: fluxswUP_allsky(:,:) => null() !< RRTMGP upward shortwave all-sky flux profile + real (kind=kind_phys), pointer :: fluxswDOWN_allsky(:,:) => null() !< RRTMGP downward shortwave all-sky flux profile + real (kind=kind_phys), pointer :: fluxswUP_clrsky(:,:) => null() !< RRTMGP upward shortwave clr-sky flux profile + real (kind=kind_phys), pointer :: fluxswDOWN_clrsky(:,:) => null() !< RRTMGP downward shortwave clr-sky flux profile + real (kind=kind_phys), pointer :: sfc_emiss_byband(:,:) => null() !< + real (kind=kind_phys), pointer :: sec_diff_byband(:,:) => null() !< + real (kind=kind_phys), pointer :: sfc_alb_nir_dir(:,:) => null() !< + real (kind=kind_phys), pointer :: sfc_alb_nir_dif(:,:) => null() !< + real (kind=kind_phys), pointer :: sfc_alb_uvvis_dir(:,:) => null() !< + real (kind=kind_phys), pointer :: sfc_alb_uvvis_dif(:,:) => null() !< + real (kind=kind_phys), pointer :: toa_src_lw(:,:) => null() !< + real (kind=kind_phys), pointer :: toa_src_sw(:,:) => null() !< + character(len=128), pointer :: active_gases_array(:) => null() !< Character array for each trace gas name + integer, pointer :: icseed_lw(:) => null() !< RRTMGP seed for RNG for longwave radiation + integer, pointer :: icseed_sw(:) => null() !< RRTMGP seed for RNG for shortwave radiation + type(proflw_type), pointer :: flxprf_lw(:,:) => null() !< DDT containing RRTMGP longwave fluxes + type(profsw_type), pointer :: flxprf_sw(:,:) => null() !< DDT containing RRTMGP shortwave fluxes + type(ty_gas_optics_rrtmgp) :: lw_gas_props !< RRTMGP DDT + type(ty_gas_optics_rrtmgp) :: sw_gas_props !< RRTMGP DDT + type(ty_cloud_optics) :: lw_cloud_props !< RRTMGP DDT + type(ty_cloud_optics) :: sw_cloud_props !< RRTMGP DDT + type(ty_optical_props_1scl) :: lw_optical_props_cloudsByBand !< RRTMGP DDT + type(ty_optical_props_1scl) :: lw_optical_props_clouds !< RRTMGP DDT + type(ty_optical_props_1scl) :: lw_optical_props_clrsky !< RRTMGP DDT + type(ty_optical_props_1scl) :: lw_optical_props_aerosol !< RRTMGP DDT + type(ty_optical_props_2str) :: sw_optical_props_cloudsByBand !< RRTMGP DDT + type(ty_optical_props_2str) :: sw_optical_props_clouds !< RRTMGP DDT + type(ty_optical_props_2str) :: sw_optical_props_clrsky !< RRTMGP DDT + type(ty_optical_props_2str) :: sw_optical_props_aerosol !< RRTMGP DDT + type(ty_gas_concs) :: gas_concentrations !< RRTMGP DDT + type(ty_source_func_lw) :: sources !< RRTMGP DDT + !-- HWRF physics: dry mixing ratios real (kind=kind_phys), pointer :: qv_r(:,:) => null() !< real (kind=kind_phys), pointer :: qc_r(:,:) => null() !< @@ -2108,18 +2199,17 @@ subroutine sfcprop_create (Sfcprop, IM, Model) Sfcprop%dt_cool = zero Sfcprop%qrain = zero endif - if (Model%lsm == Model%lsm_ruc .or. Model%lsm == Model%lsm_noahmp) then - allocate(Sfcprop%raincprv (IM)) - allocate(Sfcprop%rainncprv (IM)) - allocate(Sfcprop%iceprv (IM)) - allocate(Sfcprop%snowprv (IM)) - allocate(Sfcprop%graupelprv(IM)) - Sfcprop%raincprv = clear_val - Sfcprop%rainncprv = clear_val - Sfcprop%iceprv = clear_val - Sfcprop%snowprv = clear_val - Sfcprop%graupelprv = clear_val + allocate(Sfcprop%raincprv (IM)) + allocate(Sfcprop%rainncprv (IM)) + allocate(Sfcprop%iceprv (IM)) + allocate(Sfcprop%snowprv (IM)) + allocate(Sfcprop%graupelprv(IM)) + Sfcprop%raincprv = clear_val + Sfcprop%rainncprv = clear_val + Sfcprop%iceprv = clear_val + Sfcprop%snowprv = clear_val + Sfcprop%graupelprv = clear_val end if ! Noah MP allocate and init when used ! @@ -2201,7 +2291,7 @@ subroutine sfcprop_create (Sfcprop, IM, Model) allocate(Sfcprop%diceprv (IM)) allocate(Sfcprop%dsnowprv (IM)) allocate(Sfcprop%dgraupelprv(IM)) - + Sfcprop%draincprv = clear_val Sfcprop%drainncprv = clear_val Sfcprop%diceprv = clear_val @@ -2246,6 +2336,7 @@ subroutine sfcprop_create (Sfcprop, IM, Model) allocate (Sfcprop%xlaixy (IM)) Sfcprop%xlaixy = clear_val end if + end if if (Model%do_mynnsfclay) then ! For MYNN surface layer scheme @@ -2318,7 +2409,7 @@ subroutine coupling_create (Coupling, IM, Model) Coupling%sfcnsw = clear_val Coupling%sfcdlw = clear_val - if (Model%cplflx .or. Model%do_sppt .or. Model%cplchm) then + if (Model%cplflx .or. Model%do_sppt .or. Model%cplchm .or. Model%ca_global) then allocate (Coupling%rain_cpl (IM)) allocate (Coupling%snow_cpl (IM)) Coupling%rain_cpl = clear_val @@ -2334,6 +2425,13 @@ subroutine coupling_create (Coupling, IM, Model) Coupling%v10mi_cpl = clear_val endif + if (Model%cplwav2atm) then + !--- incoming quantities + allocate (Coupling%zorlwav_cpl (IM)) + + Coupling%zorlwav_cpl = clear_val + end if + if (Model%cplflx) then !--- incoming quantities allocate (Coupling%slimskin_cpl (IM)) @@ -2444,29 +2542,27 @@ subroutine coupling_create (Coupling, IM, Model) endif !-- cellular automata + allocate (Coupling%condition(IM)) + allocate (Coupling%vfact_ca(Model%levs)) if (Model%do_ca) then - allocate (Coupling%tconvtend (IM,Model%levs)) - allocate (Coupling%qconvtend (IM,Model%levs)) - allocate (Coupling%uconvtend (IM,Model%levs)) - allocate (Coupling%vconvtend (IM,Model%levs)) - allocate (Coupling%cape (IM)) - allocate (Coupling%ca_out (IM)) + allocate (Coupling%ca1 (IM)) + allocate (Coupling%ca2 (IM)) + allocate (Coupling%ca3 (IM)) allocate (Coupling%ca_deep (IM)) allocate (Coupling%ca_turb (IM)) allocate (Coupling%ca_shal (IM)) allocate (Coupling%ca_rad (IM)) allocate (Coupling%ca_micro (IM)) - Coupling%ca_out = clear_val + Coupling%vfact_ca = clear_val + Coupling%ca1 = clear_val + Coupling%ca2 = clear_val + Coupling%ca3 = clear_val Coupling%ca_deep = clear_val Coupling%ca_turb = clear_val Coupling%ca_shal = clear_val Coupling%ca_rad = clear_val Coupling%ca_micro = clear_val - Coupling%cape = clear_val - Coupling%tconvtend = clear_val - Coupling%qconvtend = clear_val - Coupling%uconvtend = clear_val - Coupling%vconvtend = clear_val + Coupling%condition = clear_val endif ! -- GSDCHEM coupling options @@ -2485,7 +2581,7 @@ subroutine coupling_create (Coupling, IM, Model) endif !--- stochastic physics option - if (Model%do_sppt) then + if (Model%do_sppt .or. Model%ca_global)then allocate (Coupling%sppt_wts (IM,Model%levs)) Coupling%sppt_wts = clear_val endif @@ -2512,7 +2608,7 @@ subroutine coupling_create (Coupling, IM, Model) endif !--- needed for Thompson's aerosol option - if(Model%imp_physics == Model%imp_physics_thompson .and. Model%ltaerosol) then + if(Model%imp_physics == Model%imp_physics_thompson .and. Model%ltaerosol) then allocate (Coupling%nwfa2d (IM)) allocate (Coupling%nifa2d (IM)) Coupling%nwfa2d = clear_val @@ -2597,6 +2693,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !--- coupling parameters logical :: cplflx = .false. !< default no cplflx collection logical :: cplwav = .false. !< default no cplwav collection + logical :: cplwav2atm = .false. !< default no cplwav2atm coupling logical :: cplchm = .false. !< default no cplchm collection !--- integrated dynamics through earth's atmosphere @@ -2607,8 +2704,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & real(kind=kind_phys) :: fhlwr = 3600. !< frequency for longwave radiation (secs) integer :: levr = -99 !< number of vertical levels for radiation calculations integer :: nfxr = 39+6 !< second dimension of input/output array fluxr - logical :: aero_in = .false. !< flag for initializing aero data - logical :: iccn = .false. !< logical to use IN CCN forcing for MG2/3 + logical :: iaerclm = .false. !< flag for initializing aero data + integer :: iccn = 0 !< logical to use IN CCN forcing for MG2/3 integer :: iflip = 1 !< iflip - is not the same as flipv integer :: isol = 0 !< use prescribed solar constant integer :: ico2 = 0 !< prescribed global mean value (old opernl) @@ -2641,6 +2738,26 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & logical :: norad_precip = .false. !< radiation precip flag for Ferrier/Moorthi logical :: lwhtr = .true. !< flag to output lw heating rate (Radtend%lwhc) logical :: swhtr = .true. !< flag to output sw heating rate (Radtend%swhc) + ! RRTMGP + logical :: do_RRTMGP = .false. !< Use RRTMGP? + character(len=128) :: active_gases = '' !< Character list of active gases used in RRTMGP + integer :: nGases = 0 !< Number of active gases + character(len=128) :: rrtmgp_root = '' !< Directory of rte+rrtmgp source code + character(len=128) :: lw_file_gas = '' !< RRTMGP K-distribution file, coefficients to compute optics for gaseous atmosphere + character(len=128) :: lw_file_clouds = '' !< RRTMGP file containing coefficients used to compute clouds optical properties + integer :: rrtmgp_nBandsLW = 16 !< Number of RRTMGP LW bands. + integer :: rrtmgp_nGptsLW = 256 !< Number of RRTMGP LW spectral points. + character(len=128) :: sw_file_gas = '' !< RRTMGP K-distribution file, coefficients to compute optics for gaseous atmosphere + character(len=128) :: sw_file_clouds = '' !< RRTMGP file containing coefficients used to compute clouds optical properties + integer :: rrtmgp_nBandsSW = 14 !< Number of RRTMGP SW bands. + integer :: rrtmgp_nGptsSW = 224 !< Number of RRTMGP SW spectral points. + integer :: rrtmgp_cld_optics = 0 !< Flag to control which RRTMGP routine to compute cloud-optics. + !< = 0 ; Use RRTMGP implementation + !< = 1 ; Use RRTMGP (pade) + !< = 2 ; USE RRTMGP (LUT) + integer :: rrtmgp_nrghice = 0 !< Number of ice-roughness categories + integer :: rrtmgp_nGauss_ang=1 !< Number of angles used in Gaussian quadrature + logical :: do_GPsw_Glw = .false. !--- Z-C microphysical parameters integer :: ncld = 1 !< choice of cloud scheme @@ -2650,10 +2767,10 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & real(kind=kind_phys) :: evpco = 2.0d-5 !< [in] coeff for evaporation of largescale rain real(kind=kind_phys) :: wminco(2) = (/1.0d-5,1.0d-5/) !< [in] water and ice minimum threshold for Zhao !---Max hourly - real(kind=kind_phys) :: avg_max_length = 3600. !< reset value in seconds for max hourly. + real(kind=kind_phys) :: avg_max_length = 3600. !< reset value in seconds for max hourly !--- Ferrier-Aligo microphysical parameters - real(kind=kind_phys) :: rhgrd = 0.98 !< fer_hires microphysics only - logical :: spec_adv = .true. !< Individual cloud species advected + real(kind=kind_phys) :: rhgrd = 0.98 !< fer_hires microphysics only + logical :: spec_adv = .true. !< Individual cloud species advected !--- M-G microphysical parameters integer :: fprcp = 0 !< no prognostic rain and snow (MG) integer :: pdfflag = 4 !< pdf flag for MG macro physics @@ -2690,11 +2807,15 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !--- Thompson microphysical parameters logical :: ltaerosol = .false. !< flag for aerosol version logical :: lradar = .false. !< flag for radar reflectivity + real(kind=kind_phys) :: nsradar_reset = -999.0 !< seconds between resetting radar reflectivity calculation, set to <0 for every time step real(kind=kind_phys) :: ttendlim = -999.0 !< temperature tendency limiter, set to <0 to deactivate !--- GFDL microphysical parameters logical :: lgfdlmprad = .false. !< flag for GFDLMP radiation interaction + !--- Thompson,GFDL microphysical parameter + logical :: lrefres = .false. !< flag for radar reflectivity in restart file + !--- land/surface model parameters integer :: lsm = 1 !< flag for land surface model to use =0 for osu lsm; =1 for noah lsm; =2 for noah mp lsm; =3 for RUC lsm integer :: lsoil = 4 !< number of soil layers @@ -2804,7 +2925,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & integer :: icloud_bl = 1 logical :: do_myjsfc = .false. !< flag for MYJ surface layer scheme logical :: do_myjpbl = .false. !< flag for MYJ PBL scheme - + integer :: nmtvr = 14 !< number of topographic variables such as variance etc !< used in the GWD parameterization integer :: jcap = 1 !< number of spectral wave trancation used only by sascnv shalcnv @@ -2826,7 +2947,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & real(kind=kind_phys) :: psauras(2) = (/1.0d-3,1.0d-3/) !< [in] auto conversion coeff from ice to snow in ras real(kind=kind_phys) :: prauras(2) = (/2.0d-3,2.0d-3/) !< [in] auto conversion coeff from cloud to rain in ras real(kind=kind_phys) :: wminras(2) = (/1.0d-5,1.0d-5/) !< [in] water and ice minimum threshold for ras - + integer :: nrcmax = 32 !< number of random numbers used in RAS + real(kind=kind_phys) :: rbcr = 0.25 !< Critical Richardson Number in PBL scheme real(kind=kind_phys) :: shoc_parm(5) = (/7000.0,1.0,4.2857143,0.7,-999.0/) !< some tunable parameters for shoc @@ -2877,49 +2999,66 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !< nstf_name(4) : zsea1 in mm !< nstf_name(5) : zsea2 in mm !--- fractional grid - logical :: frac_grid = .false. !< flag for fractional grid - real(kind=kind_phys) :: min_lakeice = 0.15d0 !< minimum lake ice value - real(kind=kind_phys) :: min_seaice = 1.0d-6 !< minimum sea ice value - real(kind=kind_phys) :: rho_h2o = rhowater !< fresh water density + logical :: frac_grid = .false. !< flag for fractional grid + logical :: frac_grid_off = .true. !< flag for using fractional grid + logical :: ignore_lake = .true. !< flag for ignoring lakes + real(kind=kind_phys) :: min_lakeice = 0.15d0 !< minimum lake ice value + real(kind=kind_phys) :: min_seaice = 1.0d-11 !< minimum sea ice value + real(kind=kind_phys) :: min_lake_height = 250.0 !< minimum lake height value + real(kind=kind_phys) :: rho_h2o = rhowater !< fresh water density !--- surface layer z0 scheme integer :: sfc_z0_type = 0 !< surface roughness options over ocean !< 0=no change !< 6=areodynamical roughness over water with input 10-m wind !< 7=slightly decrease Cd for higher wind speed compare to 6 + !< negative when cplwav2atm=.true. - i.e. two way wave coupling -!--- background vertical diffusion +!--- vertical diffusion real(kind=kind_phys) :: xkzm_m = 1.0d0 !< [in] bkgd_vdif_m background vertical diffusion for momentum real(kind=kind_phys) :: xkzm_h = 1.0d0 !< [in] bkgd_vdif_h background vertical diffusion for heat q real(kind=kind_phys) :: xkzm_s = 1.0d0 !< [in] bkgd_vdif_s sigma threshold for background mom. diffusion real(kind=kind_phys) :: xkzminv = 0.3 !< diffusivity in inversion layers real(kind=kind_phys) :: moninq_fac = 1.0 !< turbulence diffusion coefficient factor real(kind=kind_phys) :: dspfac = 1.0 !< tke dissipative heating factor + real(kind=kind_phys) :: bl_upfr = 0.13 !< updraft fraction in boundary layer mass flux scheme real(kind=kind_phys) :: bl_dnfr = 0.1 !< downdraft fraction in boundary layer mass flux scheme +!--- parameters for canopy heat storage (CHS) parameterization + real(kind=kind_phys) :: z0fac = 0.3 + real(kind=kind_phys) :: e0fac = 0.5 + !---Cellular automaton options integer :: nca = 1 integer :: ncells = 5 - integer :: nlives = 10 + integer :: nlives = 30 + integer :: nca_g = 1 + integer :: ncells_g = 1 + integer :: nlives_g = 100 real(kind=kind_phys) :: nfracseed = 0.5 integer :: nseed = 100000 + integer :: nseed_g = 100 integer :: iseed_ca = 0 integer :: nspinup = 1 logical :: do_ca = .false. - logical :: ca_sgs = .false. + logical :: ca_sgs = .false. logical :: ca_global = .false. logical :: ca_smooth = .false. - logical :: isppt_deep = .false. real(kind=kind_phys) :: nthresh = 0.0 - + real :: ca_amplitude = 500. + integer :: nsmooth = 100 + logical :: ca_closure = .false. + logical :: ca_entr = .false. + logical :: ca_trigger = .false. !--- IAU options real(kind=kind_phys) :: iau_delthrs = 0 !< iau time interval (to scale increments) character(len=240) :: iau_inc_files(7) = '' !< list of increment files real(kind=kind_phys) :: iaufhrs(7) = -1 !< forecast hours associated with increment files logical :: iau_filter_increments = .false. !< filter IAU increments + logical :: iau_drymassfixer = .false. !< IAU dry mass fixer !--- debug flag logical :: debug = .false. @@ -2954,11 +3093,17 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & fhzero, ldiag3d, lssav, fhcyc, & thermodyn_id, sfcpress_id, & !--- coupling parameters - cplflx, cplwav, cplchm, lsidea, & + cplflx, cplwav, cplwav2atm, cplchm, lsidea, & !--- radiation parameters - fhswr, fhlwr, levr, nfxr, aero_in, iflip, isol, ico2, ialb, & + fhswr, fhlwr, levr, nfxr, iaerclm, iflip, isol, ico2, ialb, & isot, iems, iaer, icliq_sw, iovr_sw, iovr_lw, ictm, isubc_sw,& isubc_lw, crick_proof, ccnorm, lwhtr, swhtr, & + ! --- RRTMGP + do_RRTMGP, active_gases, nGases, rrtmgp_root, & + lw_file_gas, lw_file_clouds, rrtmgp_nBandsLW, rrtmgp_nGptsLW,& + sw_file_gas, sw_file_clouds, rrtmgp_nBandsSW, rrtmgp_nGptsSW,& + rrtmgp_cld_optics, rrtmgp_nrghice, rrtmgp_nGauss_ang, & + do_GPsw_Glw, & ! IN CCN forcing iccn, & !--- microphysical parameterizations @@ -2969,7 +3114,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & mg_do_graupel, mg_do_hail, mg_nccons, mg_nicons, mg_ngcons, & mg_ncnst, mg_ninst, mg_ngnst, sed_supersat, do_sb_physics, & mg_alf, mg_qcmin, mg_do_ice_gmao, mg_do_liq_liu, & - ltaerosol, lradar, ttendlim, lgfdlmprad, & + ltaerosol, lradar, nsradar_reset, lrefres, ttendlim, & + lgfdlmprad, & !--- max hourly avg_max_length, & !--- land/surface model control @@ -3006,18 +3152,23 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & clam_shal, c0s_shal, c1_shal, pgcon_shal, asolfac_shal, & !--- near surface sea temperature model nst_anl, lsea, nstf_name, & - frac_grid, min_lakeice, min_seaice, & - frac_grid, & + frac_grid, min_lakeice, min_seaice, min_lake_height, & + frac_grid_off, ignore_lake, & !--- surface layer sfc_z0_type, & - ! background vertical diffusion + ! vertical diffusion xkzm_m, xkzm_h, xkzm_s, xkzminv, moninq_fac, dspfac, & bl_upfr, bl_dnfr, & + !--- canopy heat storage parameterization + z0fac, e0fac, & !--- cellular automata - nca, ncells, nlives, nfracseed,nseed, nthresh, do_ca, & - ca_sgs, ca_global,iseed_ca,ca_smooth,isppt_deep,nspinup, & + nca, ncells, nlives, nca_g, ncells_g, nlives_g, nfracseed, & + nseed, nseed_g, nthresh, do_ca, & + ca_sgs, ca_global,iseed_ca,ca_smooth, & + nspinup,ca_amplitude,nsmooth,ca_closure,ca_entr,ca_trigger, & !--- IAU iau_delthrs,iaufhrs,iau_inc_files,iau_filter_increments, & + iau_drymassfixer, & !--- debug options debug, pre_rad, & !--- parameter range for critical relative humidity @@ -3115,6 +3266,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !--- coupling parameters Model%cplflx = cplflx Model%cplwav = cplwav + Model%cplwav2atm = cplwav2atm Model%cplchm = cplchm !--- integrated dynamics through earth's atmosphere @@ -3145,15 +3297,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & endif Model%levrp1 = Model%levr + 1 Model%nfxr = nfxr - Model%aero_in = aero_in - if (Model%aero_in) then - ntrcaer = ntrcaerm - else - ntrcaer = 1 - endif - Model%ntrcaer = ntrcaer Model%iccn = iccn - if (Model%aero_in) Model%iccn = .false. ! further down: set Model%iccn to .false. ! for all microphysics schemes except ! MG2/3 (these are the only ones using ICCN) @@ -3163,6 +3307,14 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%ialb = ialb Model%iems = iems Model%iaer = iaer + Model%iaerclm = iaerclm + if (iaer/1000 == 1 .or. Model%iccn == 2) then + Model%iaerclm = .true. + ntrcaer = ntrcaerm + else + ntrcaer = 1 + endif + Model%ntrcaer = ntrcaer Model%icliq_sw = icliq_sw Model%iovr_sw = iovr_sw Model%iovr_lw = iovr_lw @@ -3173,6 +3325,29 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%ccnorm = ccnorm Model%lwhtr = lwhtr Model%swhtr = swhtr + ! RRTMGP + Model%do_RRTMGP = do_RRTMGP + Model%rrtmgp_nrghice = rrtmgp_nrghice + Model%rrtmgp_nGauss_ang = rrtmgp_nGauss_ang + Model%do_GPsw_Glw = do_GPsw_Glw + Model%active_gases = active_gases + Model%ngases = nGases + Model%rrtmgp_root = rrtmgp_root + Model%lw_file_gas = lw_file_gas + Model%lw_file_clouds = lw_file_clouds + Model%rrtmgp_nBandsLW = rrtmgp_nBandsLW + Model%rrtmgp_nGptsLW = rrtmgp_nGptsLW + Model%sw_file_gas = sw_file_gas + Model%sw_file_clouds = sw_file_clouds + Model%rrtmgp_nBandsSW = rrtmgp_nBandsSW + Model%rrtmgp_nGptsSW = rrtmgp_nGptsSW + Model%rrtmgp_cld_optics = RRTMGP_CLD_OPTICS + ! RRTMGP incompatible with levr /= levs + if (Model%do_RRTMGP .and. Model%levr /= Model%levs) then + write(0,*) "Logic error, RRTMGP only works with levr = levs" + stop + end if + ! The CCPP versions of the RRTMG lw/sw schemes are configured ! such that lw and sw heating rate are output, i.e. they rely ! on the corresponding arrays to be allocated. @@ -3186,7 +3361,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%ncld = ncld Model%imp_physics = imp_physics ! turn off ICCN interpolation when MG2/3 are not used - if (.not. Model%imp_physics==Model%imp_physics_mg) Model%iccn = .false. + if (.not. Model%imp_physics==Model%imp_physics_mg) Model%iccn = 0 !--- Zhao-Carr MP parameters Model%psautco = psautco Model%prautco = prautco @@ -3228,6 +3403,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !--- Thompson MP parameters Model%ltaerosol = ltaerosol Model%lradar = lradar + Model%nsradar_reset = nsradar_reset Model%ttendlim = ttendlim !--- F-A MP parameters Model%rhgrd = rhgrd @@ -3235,6 +3411,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !--- gfdl MP parameters Model%lgfdlmprad = lgfdlmprad +!--- Thompson,GFDL MP parameter + Model%lrefres = lrefres !--- land/surface model parameters Model%lsm = lsm @@ -3296,10 +3474,10 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%do_aw = do_aw Model%cs_parm = cs_parm Model%do_shoc = do_shoc - if (Model%do_shoc) then - print *, "Error, update of SHOC from May 22 2019 not yet in CCPP" - stop - end if +! if (Model%do_shoc) then +! print *, "Error, update of SHOC from May 22 2019 not yet in CCPP" +! stop +! end if Model%shoc_parm = shoc_parm Model%shocaftcnv = shocaftcnv Model%shoc_cld = shoc_cld @@ -3352,8 +3530,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%wminras = wminras Model%rbcr = rbcr Model%do_gwd = maxval(Model%cdmbgwd) > 0.0 - Model%do_cnvgwd = Model%cnvgwd .and. maxval(Model%cdmbgwd(3:4)) == 0.0 + Model%do_cnvgwd = Model%cnvgwd .and. maxval(Model%cdmbgwd(3:4)) == 0.0 Model%do_mynnedmf = do_mynnedmf Model%do_mynnsfclay = do_mynnsfclay Model%bl_mynn_cloudpdf = bl_mynn_cloudpdf @@ -3367,7 +3545,6 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%bl_mynn_tkeadvect = bl_mynn_tkeadvect Model%grav_settling = grav_settling Model%icloud_bl = icloud_bl - Model%gwd_opt = gwd_opt Model%do_myjsfc = do_myjsfc Model%do_myjpbl = do_myjpbl @@ -3401,16 +3578,20 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & !--- fractional grid Model%frac_grid = frac_grid + Model%frac_grid_off = frac_grid_off + Model%ignore_lake = ignore_lake if (Model%frac_grid) then write(0,*) "ERROR: CCPP has not been tested with fractional landmask turned on" - stop +! stop end if Model%min_lakeice = min_lakeice Model%min_seaice = min_seaice + Model%min_lake_height = min_lake_height Model%rho_h2o = rho_h2o !--- surface layer Model%sfc_z0_type = sfc_z0_type + if (Model%cplwav2atm) Model%sfc_z0_type = -1 !--- backgroud vertical diffusion Model%xkzm_m = xkzm_m @@ -3422,6 +3603,10 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%bl_upfr = bl_upfr Model%bl_dnfr = bl_dnfr +!--- canopy heat storage parametrization + Model%z0fac = z0fac + Model%e0fac = e0fac + !--- stochastic physics options ! do_sppt, do_shum, do_skeb and do_sfcperts are namelist variables in group ! physics that are parsed here and then compared in init_stochastic_physics @@ -3443,16 +3628,24 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%nca = nca Model%ncells = ncells Model%nlives = nlives + Model%nca_g = nca_g + Model%ncells_g = ncells_g + Model%nlives_g = nlives_g Model%nfracseed = nfracseed Model%nseed = nseed + Model%nseed_g = nseed_g Model%ca_global = ca_global Model%do_ca = do_ca Model%ca_sgs = ca_sgs Model%iseed_ca = iseed_ca Model%ca_smooth = ca_smooth - Model%isppt_deep = isppt_deep Model%nspinup = nspinup Model%nthresh = nthresh + Model%ca_amplitude = ca_amplitude + Model%nsmooth = nsmooth + Model%ca_closure = ca_closure + Model%ca_entr = ca_entr + Model%ca_trigger = ca_trigger ! IAU flags !--- iau parameters @@ -3460,6 +3653,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%iau_inc_files = iau_inc_files Model%iau_delthrs = iau_delthrs Model%iau_filter_increments = iau_filter_increments + Model%iau_drymassfixer = iau_drymassfixer if(Model%me==0) print *,' model init,iaufhrs=',Model%iaufhrs !--- debug flag @@ -3603,7 +3797,6 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%yearlen = 365 Model%julian = -9999. endif - ! DH* what happens if LTP>0? Does this have to change? ! A conversation with Yu-Tai suggests that we can probably ! eliminate LTP altogether *DH @@ -3626,7 +3819,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & ' rhc_max=',Model%rhcmax !--- set nrcm - Model%nrcm = 2 + Model%nrcm = 2 !--- cal_pre if (Model%cal_pre) then @@ -3724,8 +3917,10 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & if (Model%imp_physics /= Model%imp_physics_gfdl) stop 'iopt_snf == 4 must use GFDL MP' endif - print *,' nst_anl=',Model%nst_anl,' use_ufo=',Model%use_ufo,' frac_grid=',Model%frac_grid - print *,' min_lakeice=',Model%min_lakeice,' min_seaice=',Model%min_seaice + print *,' nst_anl=',Model%nst_anl,' use_ufo=',Model%use_ufo,' frac_grid=',Model%frac_grid,& + ' frac_grid_off=',frac_grid_off,' ignore_lake=',ignore_lake + print *,' min_lakeice=',Model%min_lakeice,' min_seaice=',Model%min_seaice, & + 'min_lake_height=',Model%min_lake_height if (Model%nstf_name(1) > 0 ) then print *,' NSSTM is active ' print *,' nstf_name(1)=',Model%nstf_name(1) @@ -3815,7 +4010,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & print *,' do_gwd=',Model%do_gwd endif if (Model%do_cnvgwd) then - print *,' Convective GWD parameterization used, do_cnvgwd=',do_cnvgwd + print *,' Convective GWD parameterization used, do_cnvgwd=',Model%do_cnvgwd endif if (Model%crick_proof) print *,' CRICK-Proof cloud water used in radiation ' if (Model%ccnorm) print *,' Cloud condensate normalized by cloud cover for radiation' @@ -3871,9 +4066,9 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%pdfcld = .false. Model%shcnvcw = .false. Model%ncnd = 5 - Model%nleffr = 1 - Model%nieffr = 2 - Model%nseffr = 3 + Model%nleffr = 1 + Model%nieffr = 2 + Model%nseffr = 3 if (Model%me == Model%master) print *,' Using Ferrier-Aligo MP scheme', & ' microphysics', & ' lradar =',Model%lradar @@ -3903,7 +4098,10 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & if (Model%me == Model%master) print *,' Using Thompson double moment', & ' microphysics',' ltaerosol = ',Model%ltaerosol, & ' ttendlim =',Model%ttendlim, & - ' lradar =',Model%lradar,Model%num_p3d,Model%num_p2d + ' lradar =',Model%lradar, & + ' nsradar_reset =',Model%nsradar_reset, & + ' num_p3d =',Model%num_p3d, & + ' num_p2d =',Model%num_p2d else if (Model%imp_physics == Model%imp_physics_mg) then ! Morrison-Gettelman Microphysics Model%npdf3d = 0 @@ -3928,7 +4126,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & endif if (Model%me == Model%master) & print *,' Using Morrison-Gettelman double moment microphysics', & - ' aero_in=', Model%aero_in, ' iccn=', Model%iccn, & + ' iaerclm=', Model%iaerclm, ' iccn=', Model%iccn, & ' mg_dcs=', Model%mg_dcs, ' mg_qcvar=', Model%mg_qcvar, & ' mg_ts_auto_ice=', Model%mg_ts_auto_ice, ' pdfflag=', Model%pdfflag, & ' mg_do_graupel=', Model%mg_do_graupel, ' mg_do_hail=', Model%mg_do_hail, & @@ -4098,6 +4296,7 @@ subroutine control_print(Model) print *, 'coupling parameters' print *, ' cplflx : ', Model%cplflx print *, ' cplwav : ', Model%cplwav + print *, ' cplwav2atm : ', Model%cplwav2atm print *, ' cplchm : ', Model%cplchm print *, ' ' print *, 'integrated dynamics through earth atmosphere' @@ -4118,7 +4317,6 @@ subroutine control_print(Model) print *, ' nslwr : ', Model%nslwr print *, ' levr : ', Model%levr print *, ' nfxr : ', Model%nfxr - print *, ' aero_in : ', Model%aero_in print *, ' ntrcaer : ', Model%ntrcaer print *, ' lmfshal : ', Model%lmfshal print *, ' lmfdeep2 : ', Model%lmfdeep2 @@ -4140,6 +4338,23 @@ subroutine control_print(Model) print *, ' norad_precip : ', Model%norad_precip print *, ' lwhtr : ', Model%lwhtr print *, ' swhtr : ', Model%swhtr + if (Model%do_RRTMGP) then + print *, ' rrtmgp_nrghice : ', Model%rrtmgp_nrghice + print *, ' rrtmgp_nrghice : ', Model%rrtmgp_nrghice + print *, ' do_GPsw_Glw : ', Model%do_GPsw_Glw + print *, ' active_gases : ', Model%active_gases + print *, ' nGases : ', Model%ngases + print *, ' rrtmgp_root : ', Model%rrtmgp_root + print *, ' lw_file_gas : ', Model%lw_file_gas + print *, ' lw_file_clouds : ', Model%lw_file_clouds + print *, ' rrtmgp_nBandsLW : ', Model%rrtmgp_nBandsLW + print *, ' rrtmgp_nGptsLW : ', Model%rrtmgp_nGptsLW + print *, ' sw_file_gas : ', Model%sw_file_gas + print *, ' sw_file_clouds : ', Model%sw_file_clouds + print *, ' rrtmgp_nBandsSW : ', Model%rrtmgp_nBandsSW + print *, ' rrtmgp_nGptsSW : ', Model%rrtmgp_nGptsSW + print *, ' rrtmgp_cld_optics : ', Model%rrtmgp_cld_optics + endif print *, ' ' print *, 'microphysical switch' print *, ' ncld : ', Model%ncld @@ -4158,6 +4373,8 @@ subroutine control_print(Model) print *, ' Thompson microphysical parameters' print *, ' ltaerosol : ', Model%ltaerosol print *, ' lradar : ', Model%lradar + print *, ' nsradar_reset : ', Model%nsradar_reset + print *, ' lrefres : ', Model%lrefres print *, ' ttendlim : ', Model%ttendlim print *, ' ' endif @@ -4169,12 +4386,14 @@ subroutine control_print(Model) print *, ' mg_ts_auto_ice : ', Model%mg_ts_auto_ice print *, ' mg_alf : ', Model%mg_alf print *, ' mg_qcmin : ', Model%mg_qcmin + print *, ' mg_rhmini : ', Model%mg_rhmini print *, ' pdfflag : ', Model%pdfflag print *, ' ' endif if (Model%imp_physics == Model%imp_physics_gfdl) then print *, ' GFDL microphysical parameters' print *, ' GFDL MP radiation inter: ', Model%lgfdlmprad + print *, ' lrefres : ', Model%lrefres print *, ' ' endif @@ -4209,6 +4428,7 @@ subroutine control_print(Model) print *, ' iopt_tbot : ', Model%iopt_tbot print *, ' iopt_stc : ', Model%iopt_stc endif + print *, ' use_ufo : ', Model%use_ufo print *, ' ' print *, 'tuning parameters for physical parameterizations' @@ -4305,7 +4525,7 @@ subroutine control_print(Model) print *, 'surface layer options' print *, ' sfc_z0_type : ', Model%sfc_z0_type print *, ' ' - print *, 'background vertical diffusion coefficients' + print *, 'vertical diffusion coefficients' print *, ' xkzm_m : ', Model%xkzm_m print *, ' xkzm_h : ', Model%xkzm_h print *, ' xkzm_s : ', Model%xkzm_s @@ -4315,6 +4535,10 @@ subroutine control_print(Model) print *, ' bl_upfr : ', Model%bl_upfr print *, ' bl_dnfr : ', Model%bl_dnfr print *, ' ' + print *, 'parameters for canopy heat storage parametrization' + print *, ' z0fac : ', Model%z0fac + print *, ' e0fac : ', Model%e0fac + print *, ' ' print *, 'stochastic physics' print *, ' do_sppt : ', Model%do_sppt print *, ' do_shum : ', Model%do_shum @@ -4322,19 +4546,27 @@ subroutine control_print(Model) print *, ' do_sfcperts : ', Model%do_sfcperts print *, ' ' print *, 'cellular automata' - print *, ' nca : ', Model%ncells + print *, ' nca : ', Model%nca print *, ' ncells : ', Model%ncells print *, ' nlives : ', Model%nlives + print *, ' nca_g : ', Model%nca_g + print *, ' ncells_g : ', Model%ncells_g + print *, ' nlives_g : ', Model%nlives_g print *, ' nfracseed : ', Model%nfracseed + print *, ' nseed_g : ', Model%nseed_g print *, ' nseed : ', Model%nseed print *, ' ca_global : ', Model%ca_global print *, ' ca_sgs : ', Model%ca_sgs print *, ' do_ca : ', Model%do_ca print *, ' iseed_ca : ', Model%iseed_ca print *, ' ca_smooth : ', Model%ca_smooth - print *, ' isppt_deep : ', Model%isppt_deep print *, ' nspinup : ', Model%nspinup print *, ' nthresh : ', Model%nthresh + print *, ' ca_amplitude : ', Model%ca_amplitude + print *, ' nsmooth : ', Model%nsmooth + print *, ' ca_closure : ', Model%ca_closure + print *, ' ca_entr : ', Model%ca_entr + print *, ' ca_trigger : ', Model%ca_trigger print *, ' ' print *, 'tracers' print *, ' tracer_names : ', Model%tracer_names @@ -4450,7 +4682,7 @@ subroutine grid_create (Grid, IM, Model) endif !--- iccn active - if ( Model%iccn ) then + if ( Model%iccn == 1) then allocate (Grid%ddy_ci (IM)) allocate (Grid%jindx1_ci (IM)) allocate (Grid%jindx2_ci (IM)) @@ -4460,7 +4692,7 @@ subroutine grid_create (Grid, IM, Model) endif !--- iaerclm active - if ( Model%aero_in ) then + if ( Model%iaerclm ) then allocate (Grid%ddy_aer (IM)) allocate (Grid%jindx1_aer(IM)) allocate (Grid%jindx2_aer(IM)) @@ -4487,6 +4719,8 @@ subroutine tbd_create (Tbd, IM, Model) if ( Model%isubc_lw == 2 .or. Model%isubc_sw == 2 ) then allocate (Tbd%icsdsw (IM)) allocate (Tbd%icsdlw (IM)) + Tbd%icsdsw = zero + Tbd%icsdlw = zero endif !--- ozone and stratosphere h2o needs @@ -4529,18 +4763,20 @@ subroutine tbd_create (Tbd, IM, Model) Tbd%acvb = clear_val Tbd%acvt = clear_val - if (Model%do_sppt) then - allocate (Tbd%dtdtr (IM,Model%levs)) - allocate (Tbd%dtotprcp (IM)) - allocate (Tbd%dcnvprcp (IM)) + if (Model%cplflx .or. Model%cplchm) then allocate (Tbd%drain_cpl (IM)) allocate (Tbd%dsnow_cpl (IM)) + Tbd%drain_cpl = clear_val + Tbd%dsnow_cpl = clear_val + endif + if (Model%do_sppt .or. Model%ca_global) then + allocate (Tbd%dtdtr (IM,Model%levs)) + allocate (Tbd%dtotprcp (IM)) + allocate (Tbd%dcnvprcp (IM)) Tbd%dtdtr = clear_val Tbd%dtotprcp = clear_val Tbd%dcnvprcp = clear_val - Tbd%drain_cpl = clear_val - Tbd%dsnow_cpl = clear_val endif allocate (Tbd%phy_f2d (IM,Model%ntot2d)) @@ -4556,16 +4792,6 @@ subroutine tbd_create (Tbd, IM, Model) ! if (Model%do_shoc) Tbd%phy_f3d(:,1,Model%ntot3d-1) = 3.0 ! if (Model%do_shoc) Tbd%phy_f3d(:,:,Model%ntot3d-1) = 1.0 - allocate (Tbd%htlwc (IM,Model%levr+LTP)) - allocate (Tbd%htlw0 (IM,Model%levr+LTP)) - allocate (Tbd%htswc (IM,Model%levr+LTP)) - allocate (Tbd%htsw0 (IM,Model%levr+LTP)) - - Tbd%htlwc = clear_val - Tbd%htlw0 = clear_val - Tbd%htswc = clear_val - Tbd%htsw0 = clear_val - if (Model%imfdeepcnv == Model%imfdeepcnv_gf .or. Model%imfdeepcnv == Model%imfdeepcnv_ntiedtke) then allocate(Tbd%forcet(IM, Model%levs)) allocate(Tbd%forceq(IM, Model%levs)) @@ -4603,7 +4829,7 @@ subroutine tbd_create (Tbd, IM, Model) Tbd%qsq = clear_val Tbd%cov = clear_val end if - + ! MYJ variables if (Model%do_myjsfc.or.Model%do_myjpbl) then !print*,"Allocating all MYJ surface variables:" @@ -4819,13 +5045,15 @@ subroutine diag_create (Diag, IM, Model) allocate (Diag%sppt_wts(IM,Model%levs)) allocate (Diag%shum_wts(IM,Model%levs)) allocate (Diag%zmtnblck(IM)) + allocate (Diag%ca1 (IM)) + allocate (Diag%ca2 (IM)) + allocate (Diag%ca3 (IM)) ! F-A MP scheme if (Model%imp_physics == Model%imp_physics_fer_hires) then allocate (Diag%TRAIN (IM,Model%levs)) end if - allocate (Diag%ca_out (IM)) allocate (Diag%ca_deep (IM)) allocate (Diag%ca_turb (IM)) allocate (Diag%ca_shal (IM)) @@ -5113,7 +5341,7 @@ subroutine diag_phys_zero (Diag, Model, linit, iauwindow_center) Diag%sppt_wts = zero Diag%shum_wts = zero Diag%zmtnblck = zero - + if (Model%imp_physics == Model%imp_physics_fer_hires) then Diag%TRAIN = zero end if @@ -5125,7 +5353,9 @@ subroutine diag_phys_zero (Diag, Model, linit, iauwindow_center) Diag%totgrpb = zero ! if (Model%do_ca) then - Diag%ca_out = zero + Diag%ca1 = zero + Diag%ca2 = zero + Diag%ca3 = zero Diag%ca_deep = zero Diag%ca_turb = zero Diag%ca_shal = zero @@ -5412,6 +5642,7 @@ subroutine interstitial_create (Interstitial, IM, Model) allocate (Interstitial%ep1d_land (IM)) allocate (Interstitial%ep1d_ocean (IM)) allocate (Interstitial%evap (IM)) + allocate (Interstitial%evapq (IM)) allocate (Interstitial%evap_ice (IM)) allocate (Interstitial%evap_land (IM)) allocate (Interstitial%evap_ocean (IM)) @@ -5454,10 +5685,17 @@ subroutine interstitial_create (Interstitial, IM, Model) allocate (Interstitial%gwdcu (IM,Model%levs)) allocate (Interstitial%gwdcv (IM,Model%levs)) allocate (Interstitial%h2o_pres (levh2o)) + allocate (Interstitial%hefac (IM)) + allocate (Interstitial%hffac (IM)) allocate (Interstitial%hflx (IM)) + allocate (Interstitial%hflxq (IM)) allocate (Interstitial%hflx_ice (IM)) allocate (Interstitial%hflx_land (IM)) allocate (Interstitial%hflx_ocean (IM)) + allocate (Interstitial%htlwc (IM,Model%levr+LTP)) + allocate (Interstitial%htlw0 (IM,Model%levr+LTP)) + allocate (Interstitial%htswc (IM,Model%levr+LTP)) + allocate (Interstitial%htsw0 (IM,Model%levr+LTP)) allocate (Interstitial%dry (IM)) allocate (Interstitial%idxday (IM)) allocate (Interstitial%icy (IM)) @@ -5541,11 +5779,6 @@ subroutine interstitial_create (Interstitial, IM, Model) allocate (Interstitial%tsurf_land (IM)) allocate (Interstitial%tsurf_ocean (IM)) allocate (Interstitial%ud_mf (IM,Model%levs)) - allocate (Interstitial%ulwsfc_cice (IM)) - allocate (Interstitial%dusfc_cice (IM)) - allocate (Interstitial%dvsfc_cice (IM)) - allocate (Interstitial%dtsfc_cice (IM)) - allocate (Interstitial%dqsfc_cice (IM)) allocate (Interstitial%uustar_ice (IM)) allocate (Interstitial%uustar_land (IM)) allocate (Interstitial%uustar_ocean (IM)) @@ -5568,6 +5801,54 @@ subroutine interstitial_create (Interstitial, IM, Model) allocate (Interstitial%zorl_land (IM)) allocate (Interstitial%zorl_ocean (IM)) allocate (Interstitial%zt1d (IM)) + ! RRTMGP + if (Model%do_RRTMGP) then + allocate (Interstitial%tracer (IM, Model%levs,Model%ntrac)) + allocate (Interstitial%tv_lay (IM, Model%levs)) + allocate (Interstitial%relhum (IM, Model%levs)) + allocate (Interstitial%p_lev (IM, Model%levs+1)) + allocate (Interstitial%p_lay (IM, Model%levs)) + allocate (Interstitial%t_lev (IM, Model%levs+1)) + allocate (Interstitial%t_lay (IM, Model%levs)) + allocate (Interstitial%fluxlwUP_allsky (IM, Model%levs+1)) + allocate (Interstitial%fluxlwDOWN_allsky (IM, Model%levs+1)) + allocate (Interstitial%fluxlwUP_clrsky (IM, Model%levs+1)) + allocate (Interstitial%fluxlwDOWN_clrsky (IM, Model%levs+1)) + allocate (Interstitial%fluxswUP_allsky (IM, Model%levs+1)) + allocate (Interstitial%fluxswDOWN_allsky (IM, Model%levs+1)) + allocate (Interstitial%fluxswUP_clrsky (IM, Model%levs+1)) + allocate (Interstitial%fluxswDOWN_clrsky (IM, Model%levs+1)) + allocate (Interstitial%aerosolslw (IM, Model%levs, Model%rrtmgp_nBandsLW, NF_AELW)) + allocate (Interstitial%aerosolssw (IM, Model%levs, Model%rrtmgp_nBandsSW, NF_AESW)) + allocate (Interstitial%cld_frac (IM, Model%levs)) + allocate (Interstitial%cld_lwp (IM, Model%levs)) + allocate (Interstitial%cld_reliq (IM, Model%levs)) + allocate (Interstitial%cld_iwp (IM, Model%levs)) + allocate (Interstitial%cld_reice (IM, Model%levs)) + allocate (Interstitial%cld_swp (IM, Model%levs)) + allocate (Interstitial%cld_resnow (IM, Model%levs)) + allocate (Interstitial%cld_rwp (IM, Model%levs)) + allocate (Interstitial%cld_rerain (IM, Model%levs)) + allocate (Interstitial%hsw0 (IM, Model%levs)) + allocate (Interstitial%hswc (IM, Model%levs)) + allocate (Interstitial%hswb (IM, Model%levs, Model%rrtmgp_nGptsSW)) + allocate (Interstitial%hlw0 (IM, Model%levs)) + allocate (Interstitial%hlwc (IM, Model%levs)) + allocate (Interstitial%hlwb (IM, Model%levs, Model%rrtmgp_nGptsLW)) + allocate (Interstitial%icseed_lw (IM)) + allocate (Interstitial%icseed_sw (IM)) + allocate (Interstitial%flxprf_lw (IM, Model%levs+1)) + allocate (Interstitial%flxprf_sw (IM, Model%levs+1)) + allocate (Interstitial%sfc_emiss_byband (Model%rrtmgp_nBandsLW,IM)) + allocate (Interstitial%sec_diff_byband (Model%rrtmgp_nBandsLW,IM)) + allocate (Interstitial%sfc_alb_nir_dir (Model%rrtmgp_nBandsSW,IM)) + allocate (Interstitial%sfc_alb_nir_dif (Model%rrtmgp_nBandsSW,IM)) + allocate (Interstitial%sfc_alb_uvvis_dir (Model%rrtmgp_nBandsSW,IM)) + allocate (Interstitial%sfc_alb_uvvis_dif (Model%rrtmgp_nBandsSW,IM)) + allocate (Interstitial%toa_src_sw (IM,Model%rrtmgp_nGptsSW)) + allocate (Interstitial%toa_src_lw (IM,Model%rrtmgp_nGptsLW)) + allocate (Interstitial%active_gases_array(Model%nGases)) + end if ! CIRES UGWP v0 allocate (Interstitial%gw_dudt (IM,Model%levs)) allocate (Interstitial%gw_dvdt (IM,Model%levs)) @@ -5746,6 +6027,7 @@ subroutine interstitial_setup_tracers(Interstitial, Model) endif elseif (Model%imp_physics == Model%imp_physics_gfdl) then Interstitial%ntiwx = 3 + ! F-A MP scheme elseif (Model%imp_physics == Model%imp_physics_fer_hires) then Interstitial%ntiwx = 3 ! total ice or total condensate elseif (Model%imp_physics == Model%imp_physics_mg) then @@ -5799,6 +6081,7 @@ subroutine interstitial_setup_tracers(Interstitial, Model) do n=2,Model%ntrac if ( n /= Model%ntcw .and. n /= Model%ntiw .and. n /= Model%ntclamt .and. & n /= Model%ntrw .and. n /= Model%ntsw .and. n /= Model%ntrnc .and. & +! n /= Model%ntlnc .and. n /= Model%ntinc .and. & n /= Model%ntsnc .and. n /= Model%ntgl .and. n /= Model%ntgnc) then tracers = tracers + 1 if (Model%ntke == n ) then @@ -5814,7 +6097,8 @@ subroutine interstitial_setup_tracers(Interstitial, Model) enddo Interstitial%tracers_total = tracers - 2 endif ! end if_ras or cfscnv or samf - if(.not. Model%satmedmf .and. .not. Model%trans_trac) then + if (.not. Model%satmedmf .and. .not. Model%trans_trac .and. & + .not. Model%ras .and. .not. Model%do_shoc) then Interstitial%nsamftrac = 0 else Interstitial%nsamftrac = Interstitial%tracers_total @@ -5842,6 +6126,10 @@ subroutine interstitial_rad_reset (Interstitial, Model) Interstitial%faerlw = clear_val Interstitial%faersw = clear_val Interstitial%gasvmr = clear_val + Interstitial%htlwc = clear_val + Interstitial%htlw0 = clear_val + Interstitial%htswc = clear_val + Interstitial%htsw0 = clear_val Interstitial%idxday = 0 Interstitial%kb = 0 Interstitial%kd = 0 @@ -5867,7 +6155,7 @@ subroutine interstitial_rad_reset (Interstitial, Model) Interstitial%tsfg = clear_val ! F-A scheme - if (Model%imp_physics == Model%imp_physics_fer_hires ) then + if (Model%imp_physics == Model%imp_physics_fer_hires) then Interstitial%qv_r = clear_val Interstitial%qc_r = clear_val Interstitial%qi_r = clear_val @@ -5881,6 +6169,51 @@ subroutine interstitial_rad_reset (Interstitial, Model) Interstitial%cwm = clear_val end if end if + + if (Model%do_RRTMGP) then + Interstitial%tracer = clear_val + Interstitial%tv_lay = clear_val + Interstitial%relhum = clear_val + Interstitial%p_lev = clear_val + Interstitial%p_lay = clear_val + Interstitial%t_lev = clear_val + Interstitial%t_lay = clear_val + Interstitial%fluxlwUP_allsky = clear_val + Interstitial%fluxlwDOWN_allsky = clear_val + Interstitial%fluxlwUP_clrsky = clear_val + Interstitial%fluxlwDOWN_clrsky = clear_val + Interstitial%fluxswUP_allsky = clear_val + Interstitial%fluxswDOWN_allsky = clear_val + Interstitial%fluxswUP_clrsky = clear_val + Interstitial%fluxswDOWN_clrsky = clear_val + Interstitial%aerosolslw = clear_val + Interstitial%aerosolssw = clear_val + Interstitial%cld_frac = clear_val + Interstitial%cld_lwp = clear_val + Interstitial%cld_reliq = clear_val + Interstitial%cld_iwp = clear_val + Interstitial%cld_reice = clear_val + Interstitial%cld_swp = clear_val + Interstitial%cld_resnow = clear_val + Interstitial%cld_rwp = clear_val + Interstitial%cld_rerain = clear_val + Interstitial%hsw0 = clear_val + Interstitial%hswc = clear_val + Interstitial%hswb = clear_val + Interstitial%hlw0 = clear_val + Interstitial%hlwc = clear_val + Interstitial%hlwb = clear_val + Interstitial%icseed_lw = clear_val + Interstitial%icseed_sw = clear_val + Interstitial%sfc_emiss_byband = clear_val + Interstitial%sec_diff_byband = clear_val + Interstitial%sfc_alb_nir_dir = clear_val + Interstitial%sfc_alb_nir_dif = clear_val + Interstitial%sfc_alb_uvvis_dir = clear_val + Interstitial%sfc_alb_uvvis_dif = clear_val + Interstitial%toa_src_sw = clear_val + Interstitial%toa_src_lw = clear_val + end if ! end subroutine interstitial_rad_reset @@ -5953,6 +6286,7 @@ subroutine interstitial_phys_reset (Interstitial, Model) Interstitial%ep1d_land = huge Interstitial%ep1d_ocean = huge Interstitial%evap = clear_val + Interstitial%evapq = clear_val Interstitial%evap_ice = huge Interstitial%evap_land = huge Interstitial%evap_ocean = huge @@ -5986,12 +6320,15 @@ subroutine interstitial_phys_reset (Interstitial, Model) Interstitial%gamq = clear_val Interstitial%gamt = clear_val Interstitial%gflx = clear_val - Interstitial%gflx_ice = zero - Interstitial%gflx_land = zero - Interstitial%gflx_ocean = zero + Interstitial%gflx_ice = clear_val + Interstitial%gflx_land = clear_val + Interstitial%gflx_ocean = clear_val Interstitial%gwdcu = clear_val Interstitial%gwdcv = clear_val + Interstitial%hefac = clear_val + Interstitial%hffac = clear_val Interstitial%hflx = clear_val + Interstitial%hflxq = clear_val Interstitial%hflx_ice = huge Interstitial%hflx_land = huge Interstitial%hflx_ocean = huge @@ -6064,11 +6401,6 @@ subroutine interstitial_phys_reset (Interstitial, Model) Interstitial%tsurf_land = huge Interstitial%tsurf_ocean = huge Interstitial%ud_mf = clear_val - Interstitial%ulwsfc_cice = clear_val - Interstitial%dusfc_cice = clear_val - Interstitial%dvsfc_cice = clear_val - Interstitial%dtsfc_cice = clear_val - Interstitial%dqsfc_cice = clear_val Interstitial%uustar_ice = huge Interstitial%uustar_land = huge Interstitial%uustar_ocean = huge @@ -6153,6 +6485,12 @@ subroutine interstitial_phys_reset (Interstitial, Model) ! ! Set flag for resetting maximum hourly output fields Interstitial%reset = mod(Model%kdt-1, nint(Model%avg_max_length/Model%dtp)) == 0 + ! Set flag for resetting radar reflectivity calculation + if (Model%nsradar_reset<0) then + Interstitial%radar_reset = .true. + else + Interstitial%radar_reset = mod(Model%kdt-1, nint(Model%nsradar_reset/Model%dtp)) == 0 + end if ! end subroutine interstitial_phys_reset @@ -6263,6 +6601,7 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) write (0,*) 'sum(Interstitial%ep1d_land ) = ', sum(Interstitial%ep1d_land ) write (0,*) 'sum(Interstitial%ep1d_ocean ) = ', sum(Interstitial%ep1d_ocean ) write (0,*) 'sum(Interstitial%evap ) = ', sum(Interstitial%evap ) + write (0,*) 'sum(Interstitial%evapq ) = ', sum(Interstitial%evapq ) write (0,*) 'sum(Interstitial%evap_ice ) = ', sum(Interstitial%evap_ice ) write (0,*) 'sum(Interstitial%evap_land ) = ', sum(Interstitial%evap_land ) write (0,*) 'sum(Interstitial%evap_ocean ) = ', sum(Interstitial%evap_ocean ) @@ -6305,10 +6644,17 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) write (0,*) 'sum(Interstitial%gflx_ocean ) = ', sum(Interstitial%gflx_ocean ) write (0,*) 'sum(Interstitial%gwdcu ) = ', sum(Interstitial%gwdcu ) write (0,*) 'sum(Interstitial%gwdcv ) = ', sum(Interstitial%gwdcv ) + write (0,*) 'sum(Interstitial%hefac ) = ', sum(Interstitial%hefac ) + write (0,*) 'sum(Interstitial%hffac ) = ', sum(Interstitial%hffac ) write (0,*) 'sum(Interstitial%hflx ) = ', sum(Interstitial%hflx ) + write (0,*) 'sum(Interstitial%hflxq ) = ', sum(Interstitial%hflxq ) write (0,*) 'sum(Interstitial%hflx_ice ) = ', sum(Interstitial%hflx_ice ) write (0,*) 'sum(Interstitial%hflx_land ) = ', sum(Interstitial%hflx_land ) write (0,*) 'sum(Interstitial%hflx_ocean ) = ', sum(Interstitial%hflx_ocean ) + write (0,*) 'sum(Interstitial%htlwc ) = ', sum(Interstitial%htlwc ) + write (0,*) 'sum(Interstitial%htlw0 ) = ', sum(Interstitial%htlw0 ) + write (0,*) 'sum(Interstitial%htswc ) = ', sum(Interstitial%htswc ) + write (0,*) 'sum(Interstitial%htsw0 ) = ', sum(Interstitial%htsw0 ) write (0,*) 'Interstitial%dry(:)==.true. = ', count(Interstitial%dry(:) ) write (0,*) 'sum(Interstitial%idxday ) = ', sum(Interstitial%idxday ) write (0,*) 'Interstitial%icy(:)==.true. = ', count(Interstitial%icy(:) ) @@ -6340,6 +6686,7 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) write (0,*) 'sum(Interstitial%qss_ice ) = ', sum(Interstitial%qss_ice ) write (0,*) 'sum(Interstitial%qss_land ) = ', sum(Interstitial%qss_land ) write (0,*) 'sum(Interstitial%qss_ocean ) = ', sum(Interstitial%qss_ocean ) + write (0,*) 'Interstitial%radar_reset = ', Interstitial%radar_reset write (0,*) 'Interstitial%raddt = ', Interstitial%raddt write (0,*) 'sum(Interstitial%raincd ) = ', sum(Interstitial%raincd ) write (0,*) 'sum(Interstitial%raincs ) = ', sum(Interstitial%raincs ) @@ -6402,11 +6749,6 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) write (0,*) 'sum(Interstitial%tsurf_land ) = ', sum(Interstitial%tsurf_land ) write (0,*) 'sum(Interstitial%tsurf_ocean ) = ', sum(Interstitial%tsurf_ocean ) write (0,*) 'sum(Interstitial%ud_mf ) = ', sum(Interstitial%ud_mf ) - write (0,*) 'sum(Interstitial%ulwsfc_cice ) = ', sum(Interstitial%ulwsfc_cice ) - write (0,*) 'sum(Interstitial%dusfc_cice ) = ', sum(Interstitial%dusfc_cice ) - write (0,*) 'sum(Interstitial%dvsfc_cice ) = ', sum(Interstitial%dvsfc_cice ) - write (0,*) 'sum(Interstitial%dtsfc_cice ) = ', sum(Interstitial%dtsfc_cice ) - write (0,*) 'sum(Interstitial%dqsfc_cice ) = ', sum(Interstitial%dqsfc_cice ) write (0,*) 'sum(Interstitial%uustar_ice ) = ', sum(Interstitial%uustar_ice ) write (0,*) 'sum(Interstitial%uustar_land ) = ', sum(Interstitial%uustar_land ) write (0,*) 'sum(Interstitial%uustar_ocean ) = ', sum(Interstitial%uustar_ocean ) @@ -6445,6 +6787,41 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) write (0,*) 'sum(Interstitial%dudt_ogw ) = ', sum(Interstitial%dudt_ogw ) write (0,*) 'sum(Interstitial%dudt_tms ) = ', sum(Interstitial%dudt_tms ) ! + ! RRTMGP fields + write (0,*) 'sum(Interstitial%aerosolslw ) = ', sum(Interstitial%aerosolslw ) + write (0,*) 'sum(Interstitial%aerosolssw ) = ', sum(Interstitial%aerosolssw ) + write (0,*) 'sum(Interstitial%cld_frac ) = ', sum(Interstitial%cld_frac ) + write (0,*) 'sum(Interstitial%cld_lwp ) = ', sum(Interstitial%cld_lwp ) + write (0,*) 'sum(Interstitial%cld_reliq ) = ', sum(Interstitial%cld_reliq ) + write (0,*) 'sum(Interstitial%cld_iwp ) = ', sum(Interstitial%cld_iwp ) + write (0,*) 'sum(Interstitial%cld_reice ) = ', sum(Interstitial%cld_reice ) + write (0,*) 'sum(Interstitial%cld_swp ) = ', sum(Interstitial%cld_swp ) + write (0,*) 'sum(Interstitial%cld_resnow ) = ', sum(Interstitial%cld_resnow ) + write (0,*) 'sum(Interstitial%cld_rwp ) = ', sum(Interstitial%cld_rwp ) + write (0,*) 'sum(Interstitial%cld_rerain ) = ', sum(Interstitial%cld_rerain ) + write (0,*) 'sum(Interstitial%hsw0 ) = ', sum(Interstitial%hsw0 ) + write (0,*) 'sum(Interstitial%hswc ) = ', sum(Interstitial%hswc ) + write (0,*) 'sum(Interstitial%hswb ) = ', sum(Interstitial%hswb ) + write (0,*) 'sum(Interstitial%hlw0 ) = ', sum(Interstitial%hlw0 ) + write (0,*) 'sum(Interstitial%hlwc ) = ', sum(Interstitial%hlwc ) + write (0,*) 'sum(Interstitial%hlwb ) = ', sum(Interstitial%hlwb ) + write (0,*) 'sum(Interstitial%icseed_lw ) = ', sum(Interstitial%icseed_lw ) + write (0,*) 'sum(Interstitial%icseed_sw ) = ', sum(Interstitial%icseed_sw ) + write (0,*) 'sum(Interstitial%fluxlwUP_allsky ) = ', sum(Interstitial%fluxlwUP_allsky ) + write (0,*) 'sum(Interstitial%fluxlwDOWN_allsky) = ', sum(Interstitial%fluxlwDOWN_allsky) + write (0,*) 'sum(Interstitial%fluxlwUP_clrsky ) = ', sum(Interstitial%fluxlwUP_clrsky ) + write (0,*) 'sum(Interstitial%fluxlwDOWN_clrsky) = ', sum(Interstitial%fluxlwDOWN_clrsky) + write (0,*) 'sum(Interstitial%fluxswUP_allsky ) = ', sum(Interstitial%fluxswUP_allsky ) + write (0,*) 'sum(Interstitial%fluxswDOWN_allsky) = ', sum(Interstitial%fluxswDOWN_allsky) + write (0,*) 'sum(Interstitial%fluxswUP_clrsky ) = ', sum(Interstitial%fluxswUP_clrsky ) + write (0,*) 'sum(Interstitial%fluxswDOWN_clrsky) = ', sum(Interstitial%fluxswDOWN_clrsky) + write (0,*) 'sum(Interstitial%relhum ) = ', sum(Interstitial%relhum ) + write (0,*) 'sum(Interstitial%p_lay ) = ', sum(Interstitial%p_lay ) + write (0,*) 'sum(Interstitial%p_lev ) = ', sum(Interstitial%p_lev ) + write (0,*) 'sum(Interstitial%t_lay ) = ', sum(Interstitial%t_lay ) + write (0,*) 'sum(Interstitial%t_lev ) = ', sum(Interstitial%t_lev ) + write (0,*) 'sum(Interstitial%tv_lay ) = ', sum(Interstitial%tv_lay ) + ! Print arrays that are conditional on physics choices if (Model%imp_physics == Model%imp_physics_gfdl .or. Model%imp_physics == Model%imp_physics_thompson) then write (0,*) 'Interstitial_print: values specific to GFDL/Thompson microphysics' @@ -6452,6 +6829,7 @@ subroutine interstitial_print(Interstitial, Model, mpirank, omprank, blkno) write (0,*) 'sum(Interstitial%icemp ) = ', sum(Interstitial%icemp ) write (0,*) 'sum(Interstitial%rainmp ) = ', sum(Interstitial%rainmp ) write (0,*) 'sum(Interstitial%snowmp ) = ', sum(Interstitial%snowmp ) + !F-A scheme else if (Model%imp_physics == Model%imp_physics_fer_hires) then write (0,*) 'Interstitial_print: values specific to F-A microphysics' write (0,*) 'sum(Interstitial%f_ice ) = ', sum(Interstitial%f_ice ) diff --git a/scm/src/GFS_typedefs.meta b/scm/src/GFS_typedefs.meta index b5e0502a8..bd0106859 100644 --- a/scm/src/GFS_typedefs.meta +++ b/scm/src/GFS_typedefs.meta @@ -148,42 +148,42 @@ kind = kind_phys [qgrs(:,:,index_for_liquid_cloud_condensate)] standard_name = cloud_condensed_water_mixing_ratio - long_name = moist (dry+vapor, no condensates) mixing ratio of cloud water (condensate) + long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [qgrs(:,1,index_for_liquid_cloud_condensate)] standard_name = cloud_condensed_water_mixing_ratio_at_lowest_model_layer - long_name = moist (dry+vapor, no condensates) mixing ratio of cloud water at lowest model layer + long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) at lowest model layer units = kg kg-1 dimensions = (horizontal_dimension) type = real kind = kind_phys [qgrs(:,:,index_for_ice_cloud_condensate)] standard_name = ice_water_mixing_ratio - long_name = moist (dry+vapor, no condensates) mixing ratio of ice water + long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [qgrs(:,:,index_for_rain_water)] standard_name = rain_water_mixing_ratio - long_name = moist (dry+vapor, no condensates) mixing ratio of rain water + long_name = ratio of mass of rain water to mass of dry air plus vapor (without condensates) units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [qgrs(:,:,index_for_snow_water)] standard_name = snow_water_mixing_ratio - long_name = moist (dry+vapor, no condensates) mixing ratio of snow water + long_name = ratio of mass of snow water to mass of dry air plus vapor (without condensates) units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [qgrs(:,:,index_for_graupel)] standard_name = graupel_mixing_ratio - long_name = moist (dry+vapor, no condensates) mixing ratio of graupel + long_name = ratio of mass of graupel to mass of dry air plus vapor (without condensates) units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real @@ -335,35 +335,35 @@ kind = kind_phys [gq0(:,:,index_for_liquid_cloud_condensate)] standard_name = cloud_condensed_water_mixing_ratio_updated_by_physics - long_name = moist (dry+vapor, no condensates) mixing ratio of cloud condensed water updated by physics + long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) updated by physics units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [gq0(:,:,index_for_ice_cloud_condensate)] standard_name = ice_water_mixing_ratio_updated_by_physics - long_name = moist (dry+vapor, no condensates) mixing ratio of ice water updated by physics + long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) updated by physics units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [gq0(:,:,index_for_rain_water)] standard_name = rain_water_mixing_ratio_updated_by_physics - long_name = moist (dry+vapor, no condensates) mixing ratio of rain water updated by physics + long_name = ratio of mass of rain water to mass of dry air plus vapor (without condensates) updated by physics units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [gq0(:,:,index_for_snow_water)] standard_name = snow_water_mixing_ratio_updated_by_physics - long_name = moist (dry+vapor, no condensates) mixing ratio of snow water updated by physics + long_name = ratio of mass of snow water to mass of dry air plus vapor (without condensates) updated by physics units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [gq0(:,:,index_for_graupel)] standard_name = graupel_mixing_ratio_updated_by_physics - long_name = moist (dry+vapor, no condensates) mixing ratio of graupel updated by physics + long_name = ratio of mass of graupel to mass of dry air plus vapor (without condensates) updated by physics units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real @@ -1353,6 +1353,34 @@ dimensions = (horizontal_dimension) type = real kind = kind_phys +[alvsf] + standard_name = mean_vis_albedo_with_strong_cosz_dependency + long_name = mean vis albedo with strong cosz dependency + units = frac + dimensions = (horizontal_dimension) + type = real + kind = kind_phys +[alnsf] + standard_name = mean_nir_albedo_with_strong_cosz_dependency + long_name = mean nir albedo with strong cosz dependency + units = frac + dimensions = (horizontal_dimension) + type = real + kind = kind_phys +[facsf] + standard_name =fractional_coverage_with_strong_cosz_dependency + long_name = fractional coverage with strong cosz dependency + units = frac + dimensions = (horizontal_dimension) + type = real + kind = kind_phys +[facwf] + standard_name = fractional_coverage_with_weak_cosz_dependency + long_name = fractional coverage with weak cosz dependency + units = frac + dimensions = (horizontal_dimension) + type = real + kind = kind_phys ######################################################################## [ccpp-arg-table] @@ -1764,34 +1792,6 @@ dimensions = (horizontal_dimension) type = real kind = kind_phys -[tconvtend] - standard_name = tendency_of_air_temperature_due_to_deep_convection_for_coupling_on_physics_timestep - long_name = tendency of air temperature due to deep convection - units = K - dimensions = (horizontal_dimension,vertical_dimension) - type = real - kind = kind_phys -[qconvtend] - standard_name = tendency_of_water_vapor_specific_humidity_due_to_deep_convection_for_coupling_on_physics_timestep - long_name = tendency of specific humidity due to deep convection - units = kg kg-1 - dimensions = (horizontal_dimension,vertical_dimension) - type = real - kind = kind_phys -[uconvtend] - standard_name = tendency_of_x_wind_due_to_deep_convection_for_coupling_on_physics_timestep - long_name = tendency_of_x_wind_due_to_deep_convection - units = m s-1 - dimensions = (horizontal_dimension,vertical_dimension) - type = real - kind = kind_phys -[vconvtend] - standard_name = tendency_of_y_wind_due_to_deep_convection_for_coupling_on_physics_timestep - long_name = tendency_of_y_wind_due_to_deep_convection - units = m s-1 - dimensions = (horizontal_dimension,vertical_dimension) - type = real - kind = kind_phys [ca_deep] standard_name = fraction_of_cellular_automata_for_deep_convection long_name = fraction of cellular automata for deep convection @@ -1799,9 +1799,23 @@ dimensions = (horizontal_dimension) type = real kind = kind_phys -[cape] - standard_name = convective_available_potential_energy_for_coupling - long_name = convective available potential energy for coupling +[vfact_ca] + standard_name = vertical_weight_for_ca + long_name = vertical weight for ca + units = frac + dimensions = (vertical_dimension) + type = real + kind = kind_phys +[ca1] + standard_name = cellular_automata_global_pattern + long_name = cellular automata global pattern + units = flag + dimensions = (horizontal_dimension) + type = real + kind = kind_phys +[condition] + standard_name = physics_field_for_coupling + long_name = physics_field_for_coupling units = m2 s-2 dimensions = (horizontal_dimension) type = real @@ -2039,6 +2053,12 @@ units = flag dimensions = () type = logical +[cplwav2atm] + standard_name = flag_for_wave_coupling_to_atm + long_name = flag controlling ocean wave coupling to the atmosphere (default off) + units = flag + dimensions = () + type = logical [cplchm] standard_name = flag_for_chemistry_coupling long_name = flag controlling cplchm collection (default off) @@ -2121,9 +2141,9 @@ units = count dimensions = () type = integer -[aero_in] - standard_name = flag_for_aerosol_input_MG - long_name = flag for using aerosols in Morrison-Gettelman MP +[iaerclm] + standard_name = flag_for_aerosol_input_MG_radiation + long_name = flag for using aerosols in Morrison-Gettelman MP_radiation units = flag dimensions = () type = logical @@ -2241,6 +2261,108 @@ units = flag dimensions = () type = logical +[active_gases] + standard_name = active_gases_used_by_RRTMGP + long_name = active gases used by RRTMGP + units = none + dimensions = () + type = character + kind = len=128 +[nGases] + standard_name = number_of_active_gases_used_by_RRTMGP + long_name = number of gases available used by RRTMGP (Model%nGases) + units = count + dimensions = () + type = integer +[rrtmgp_root] + standard_name = directory_for_rte_rrtmgp_source_code + long_name = directory for rte+rrtmgp source code (Model%rrtmgp_root) + units = none + dimensions = () + type = character + kind = len=128 +[lw_file_gas] + standard_name = rrtmgp_kdistribution_lw + long_name = file containing RRTMGP LW k-distribution (Model%lw_file_gas) + units = none + dimensions = () + type = character + kind = len=128 +[lw_file_clouds] + standard_name = rrtmgp_coeff_lw_cloud_optics + long_name = file containing coefficients for RRTMGP LW cloud optics (Model%lw_file_clouds) + units = none + dimensions = () + type = character + kind = len=128 +[rrtmgp_nBandsLW] + standard_name = number_of_lw_bands_rrtmgp + long_name = number of lw bands used in RRTMGP (Model%rrtmgp_nBandsLW) + units = count + dimensions = () + type = integer +[rrtmgp_nGptsLW] + standard_name = number_of_lw_spectral_points_rrtmgp + long_name = number of spectral points in RRTMGP LW calculation (model%rrtmgp_nGptsLW) + units = count + dimensions = () + type = integer +[sw_file_gas] + standard_name = rrtmgp_kdistribution_sw + long_name = file containing RRTMGP SW k-distribution (Model%sw_file_gas) + units = none + dimensions = () + type = character + kind = len=128 +[sw_file_clouds] + standard_name = rrtmgp_coeff_sw_cloud_optics + long_name = file containing coefficients for RRTMGP SW cloud optics (Model%sw_file_clouds) + units = none + dimensions = () + type = character + kind = len=128 +[rrtmgp_nBandsSW] + standard_name = number_of_sw_bands_rrtmgp + long_name = number of sw bands used in RRTMGP (Model%rrtmgp_nBandsSW) + units = count + dimensions = () + type = integer +[rrtmgp_nGptsSW] + standard_name = number_of_sw_spectral_points_rrtmgp + long_name = number of spectral points in RRTMGP SW calculation (model%rrtmgp_nGptsSW) + units = count + dimensions = () + type = integer +[rrtmgp_cld_optics] + standard_name = rrtmgp_cloud_optics_flag + long_name = Flag to control which RRTMGP cloud-optics scheme (Model%rrtmgp_cld_optics) + units = flag + dimensions = () + type = integer +[rrtmgp_nrghice] + standard_name = number_of_rrtmgp_ice_roughness + long_name = number of ice-roughness categories in RRTMGP calculation (Model%rrtmgp_nrghice) + units = count + dimensions = () + type = integer +[rrtmgp_nGauss_ang] + standard_name = number_of_angles_used_in_gaussian_quadrature + long_name = Number of angles used in Gaussian quadrature + units = count + dimensions = () + type = integer +[do_RRTMGP] + standard_name = flag_for_rrtmgp_radiation_scheme + long_name = flag for RRTMGP scheme + units = flag + dimensions = () + type = logical +[do_GPsw_Glw] + standard_name = scheme_flag + long_name = When true GP is used for SW calculation and G is used for LW calculation + units = flag + dimensions = () + type = logical [ncld] standard_name = number_of_hydrometeors long_name = choice of cloud scheme / number of hydrometeors @@ -2309,6 +2431,20 @@ dimensions = (2) type = real kind = kind_phys +[psauras] + standard_name = coefficient_from_cloud_ice_to_snow_ras + long_name = conversion coefficient from cloud ice to snow in ras + units = none + dimensions = (2) + type = real + kind = kind_phys +[prauras] + standard_name = coefficient_from_cloud_water_to_rain_ras + long_name = conversion coefficient from cloud water to rain in ras + units = none + dimensions = (2) + type = real + kind = kind_phys [evpco] standard_name = coefficient_for_evaporation_of_rainfall long_name = coeff for evaporation of largescale rain @@ -2323,6 +2459,20 @@ dimensions = (2) type = real kind = kind_phys +[wminras] + standard_name = cloud_condensed_water_ice_conversion_threshold_ras + long_name = conversion coefficient from cloud liquid and ice to precipitation in ras + units = none + dimensions = (2) + type = real + kind = kind_phys +[dlqf] + standard_name = condensate_fraction_detrained_in_updraft_layers + long_name = condensate fraction detrained with in a updraft layers + units = none + dimensions = (2) + type = real + kind = kind_phys [avg_max_length] standard_name = time_interval_for_maximum_hourly_fields long_name = reset time interval for maximum hourly fields @@ -2743,12 +2893,6 @@ units = index dimensions = () type = integer -[mom4ice] - standard_name = flag_for_mom4_coupling - long_name = flag controls mom4 sea ice - units = flag - dimensions = () - type = logical [ras] standard_name = flag_for_ras_deep_convection long_name = flag for ras convection scheme @@ -3033,6 +3177,13 @@ dimensions = (4) type = real kind = kind_phys +[ccwf] + standard_name = multiplication_factor_for_critical_cloud_workfunction + long_name = multiplication factor for tical_cloud_workfunction + units = none + dimensions = (2) + type = real + kind = kind_phys [sup] standard_name = ice_supersaturation_threshold long_name = ice supersaturation parameter for PDF clouds @@ -3287,6 +3438,20 @@ dimensions = () type = real kind = kind_phys +[z0fac] + standard_name = surface_roughness_fraction_factor + long_name = surface roughness fraction for canopy heat storage parameterization + units = none + dimensions = () + type = real + kind = kind_phys +[e0fac] + standard_name = latent_heat_flux_fraction_factor_relative_to_sensible_heat_flux + long_name = latent heat flux fraction relative to sensible heat flux for canopy heat storage parameterization + units = none + dimensions = () + type = real + kind = kind_phys [nca] standard_name = number_of_independent_cellular_automata long_name = number of independent cellular automata @@ -3336,15 +3501,27 @@ units = flag dimensions = () type = logical -[ca_smooth] - standard_name = flag_for_gaussian_spatial_filter - long_name = switch for gaussian spatial filter +[ca_closure] + standard_name = flag_for_global_cellular_automata_closure + long_name = switch for ca on closure + units = flag + dimensions = () + type = logical +[ca_entr] + standard_name = flag_for_global_cellular_automata_entr + long_name = switch for ca on entr units = flag dimensions = () type = logical -[isppt_deep] - standard_name = flag_for_combination_of_sppt_with_isppt_deep - long_name = switch for combination with isppt_deep. +[ca_trigger] + standard_name = flag_for_global_cellular_automata_trigger + long_name = switch for ca on trigger + units = flag + dimensions = () + type = logical +[ca_smooth] + standard_name = flag_for_gaussian_spatial_filter + long_name = switch for gaussian spatial filter units = flag dimensions = () type = logical @@ -3831,9 +4008,9 @@ [iccn] standard_name = flag_for_in_ccn_forcing_for_morrison_gettelman_microphysics long_name = flag for IN and CCN forcing for morrison gettelman microphysics - units = flag + units = none dimensions = () - type = logical + type = integer [sec] standard_name = seconds_elapsed_since_model_initialization long_name = seconds elapsed since model initialization @@ -4308,34 +4485,6 @@ dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys -[htlwc] - standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_time_step - long_name = total sky heating rate due to longwave radiation - units = K s-1 - dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) - type = real - kind = kind_phys -[htlw0] - standard_name = tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_time_step - long_name = clear sky heating rate due to longwave radiation - units = K s-1 - dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) - type = real - kind = kind_phys -[htswc] - standard_name = tendency_of_air_temperature_due_to_shortwave_heating_on_radiation_time_step - long_name = total sky heating rate due to shortwave radiation - units = K s-1 - dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) - type = real - kind = kind_phys -[htsw0] - standard_name = tendency_of_air_temperature_due_to_shortwave_heating_assuming_clear_sky_on_radiation_time_step - long_name = clear sky heating rates due to shortwave radiation - units = K s-1 - dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) - type = real - kind = kind_phys [forcet] standard_name = temperature_tendency_due_to_dynamics long_name = temperature tendency due to dynamics only @@ -4561,14 +4710,14 @@ dimensions = (horizontal_dimension) type = sfcflw_type [htrsw] - standard_name = tendency_of_air_temperature_due_to_shortwave_heating_on_radiation_timestep + standard_name = tendency_of_air_temperature_due_to_shortwave_heating_on_radiation_time_step long_name = total sky sw heating rate units = K s-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [htrlw] - standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_timestep + standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_time_step long_name = total sky lw heating rate units = K s-1 dimensions = (horizontal_dimension,vertical_dimension) @@ -4588,6 +4737,13 @@ dimensions = (horizontal_dimension) type = real kind = kind_phys +[coszdg] + standard_name = daytime_mean_cosz_over_rad_call_period + long_name = daytime mean cosz over rad call period + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys [tsflw] standard_name = surface_midlayer_air_temperature_in_longwave_radiation long_name = surface air temp during lw calculation @@ -4603,14 +4759,14 @@ type = real kind = kind_phys [swhc] - standard_name = tendency_of_air_temperature_due_to_shortwave_heating_assuming_clear_sky_on_radiation_timestep + standard_name = tendency_of_air_temperature_due_to_shortwave_heating_assuming_clear_sky_on_radiation_time_step long_name = clear sky sw heating rates units = K s-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [lwhc] - standard_name = tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_timestep + standard_name = tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_time_step long_name = clear sky lw heating rates units = K s-1 dimensions = (horizontal_dimension,vertical_dimension) @@ -6189,14 +6345,14 @@ kind = kind_phys [clw(:,:,1)] standard_name = ice_water_mixing_ratio_convective_transport_tracer - long_name = moist (dry+vapor, no condensates) mixing ratio of ice water in the convectively transported tracer array + long_name = ratio of mass of ice water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [clw(:,:,2)] standard_name = cloud_condensed_water_mixing_ratio_convective_transport_tracer - long_name = moist (dry+vapor, no condensates) mixing ratio of cloud water (condensate) in the convectively transported tracer array + long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) in the convectively transported tracer array units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real @@ -6420,21 +6576,21 @@ kind = kind_phys [dqdt(:,:,index_for_rain_water)] standard_name = tendency_of_rain_water_mixing_ratio_due_to_model_physics - long_name = moist (dry+vapor, no condensates) mixing ratio of rain water tendency due to model physics + long_name = ratio of mass of rain water tendency to mass of dry air plus vapor (without condensates) due to model physics units = kg kg-1 s-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [dqdt(:,:,index_for_snow_water)] standard_name = tendency_of_snow_water_mixing_ratio_due_to_model_physics - long_name = moist (dry+vapor, no condensates) mixing ratio of snow water tendency due to model physics + long_name = ratio of mass of snow water tendency to mass of dry air plus vapor (without condensates) due to model physics units = kg kg-1 s-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [dqdt(:,:,index_for_graupel)] standard_name = tendency_of_graupel_mixing_ratio_due_to_model_physics - long_name = moist (dry+vapor, no condensates) mixing ratio of graupel tendency due to model physics + long_name = ratio of mass of graupel tendency to mass of dry air plus vapor (without condensates) due to model physics units = kg kg-1 s-1 dimensions = (horizontal_dimension,vertical_dimension) type = real @@ -6551,34 +6707,6 @@ dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) type = real kind = kind_phys -[dusfc_cice] - standard_name = surface_x_momentum_flux_for_coupling_interstitial - long_name = sfc x momentum flux for coupling interstitial - units = Pa - dimensions = (horizontal_dimension) - type = real - kind = kind_phys -[dvsfc_cice] - standard_name = surface_y_momentum_flux_for_coupling_interstitial - long_name = sfc y momentum flux for coupling interstitial - units = Pa - dimensions = (horizontal_dimension) - type = real - kind = kind_phys -[dtsfc_cice] - standard_name = surface_upward_sensible_heat_flux_for_coupling_interstitial - long_name = sfc sensible heat flux for coupling interstitial - units = W m-2 - dimensions = (horizontal_dimension) - type = real - kind = kind_phys -[dqsfc_cice] - standard_name = surface_upward_latent_heat_flux_for_coupling_interstitial - long_name= surface latent heat flux for coupling interstitial - units = W m-2 - dimensions = (horizontal_dimension) - type = real - kind = kind_phys [elvmax] standard_name = maximum_subgrid_orography long_name = maximum of subgrid orography @@ -6642,6 +6770,13 @@ dimensions = (horizontal_dimension) type = real kind = kind_phys +[evapq] + standard_name = kinematic_surface_upward_latent_heat_flux_reduced_by_surface_roughness + long_name = kinematic surface upward latent heat flux reduced by surface roughness + units = kg kg-1 m s-1 + dimensions = (horizontal_dimension) + type = real + kind = kind_phys [evap_ocean] standard_name = kinematic_surface_upward_latent_heat_flux_over_ocean long_name = kinematic surface upward latent heat flux over ocean @@ -7058,6 +7193,20 @@ dimensions = (vertical_dimension_of_h2o_forcing_data) type = real kind = kind_phys +[hefac] + standard_name = surface_upward_latent_heat_flux_reduction_factor + long_name = surface upward latent heat flux reduction factor from canopy heat storage + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys +[hffac] + standard_name = surface_upward_sensible_heat_flux_reduction_factor + long_name = surface upward sensible heat flux reduction factor from canopy heat storage + units = none + dimensions = (horizontal_dimension) + type = real + kind = kind_phys [hflx] standard_name = kinematic_surface_upward_sensible_heat_flux long_name = kinematic surface upward sensible heat flux @@ -7065,6 +7214,13 @@ dimensions = (horizontal_dimension) type = real kind = kind_phys +[hflxq] + standard_name = kinematic_surface_upward_sensible_heat_flux_reduced_by_surface_roughness + long_name = kinematic surface upward sensible heat flux reduced by surface roughness + units = K m s-1 + dimensions = (horizontal_dimension) + type = real + kind = kind_phys [hflx_ocean] standard_name = kinematic_surface_upward_sensible_heat_flux_over_ocean long_name = kinematic surface upward sensible heat flux over ocean @@ -7086,6 +7242,34 @@ dimensions = (horizontal_dimension) type = real kind = kind_phys +[htlwc] + standard_name = tendency_of_air_temperature_due_to_longwave_heating_on_radiation_time_step_and_radiation_levels + long_name = total sky heating rate due to longwave radiation + units = K s-1 + dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) + type = real + kind = kind_phys +[htlw0] + standard_name = tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_time_step_and_radiation_levels + long_name = clear sky heating rate due to longwave radiation + units = K s-1 + dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) + type = real + kind = kind_phys +[htswc] + standard_name = tendency_of_air_temperature_due_to_shortwave_heating_on_radiation_time_step_and_radiation_levels + long_name = total sky heating rate due to shortwave radiation + units = K s-1 + dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) + type = real + kind = kind_phys +[htsw0] + standard_name = tendency_of_air_temperature_due_to_shortwave_heating_assuming_clear_sky_on_radiation_time_step_and_radiation_levels + long_name = clear sky heating rates due to shortwave radiation + units = K s-1 + dimensions = (horizontal_dimension,adjusted_vertical_layer_dimension_for_radiation) + type = real + kind = kind_phys [icemp] standard_name = lwe_thickness_of_ice_amount long_name = explicit ice fall on physics timestep @@ -7462,7 +7646,7 @@ kind = kind_phys [qgl] standard_name = local_graupel_mixing_ratio - long_name = moist (dry+vapor, no condensates) mixing ratio of graupel local to physics + long_name = ratio of mass of graupel to mass of dry air plus vapor (without condensates) local to physics units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real @@ -7490,14 +7674,14 @@ kind = kind_phys [qrn] standard_name = local_rain_water_mixing_ratio - long_name = moist (dry+vapor, no condensates) mixing ratio of rain water local to physics + long_name = ratio of mass of rain water to mass of dry air plus vapor (without condensates) local to physics units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys [qsnw] standard_name = local_snow_water_mixing_ratio - long_name = moist (dry+vapor, no condensates) mixing ratio of snow water local to physics + long_name = ratio of mass of snow water to mass of dry air plus vapor (without condensates) local to physics units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real @@ -7537,6 +7721,12 @@ dimensions = (horizontal_dimension) type = real kind = kind_phys +[radar_reset] + standard_name = flag_for_resetting_radar_reflectivity_calculation + long_name = flag for resetting radar reflectivity calculation + units = flag + dimensions = () + type = logical [raddt] standard_name = time_step_for_radiation long_name = radiation time step @@ -7629,7 +7819,7 @@ kind = kind_phys [save_q(:,:,index_for_liquid_cloud_condensate)] standard_name = cloud_condensed_water_mixing_ratio_save - long_name = moist (dry+vapor, no condensates) mixing ratio of cloud water (condensate) before entering a physics scheme + long_name = ratio of mass of cloud water to mass of dry air plus vapor (without condensates) before entering a physics scheme units = kg kg-1 dimensions = (horizontal_dimension,vertical_dimension) type = real @@ -8004,13 +8194,6 @@ dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys -[ulwsfc_cice] - standard_name = surface_upwelling_longwave_flux_for_coupling_interstitial - long_name = surface upwelling longwave flux for coupling_interstitial - units = W m-2 - dimensions = (horizontal_dimension) - type = real - kind = kind_phys [uustar_ocean] standard_name = surface_friction_velocity_over_ocean long_name = surface friction velocity over ocean @@ -8269,6 +8452,510 @@ dimensions = (horizontal_dimension,vertical_dimension) type = real kind = kind_phys +[p_lay] + standard_name = air_pressure_at_layer_for_RRTMGP_in_hPa + long_name = air pressure layer + units = hPa + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = F +[p_lev] + standard_name = air_pressure_at_interface_for_RRTMGP_in_hPa + long_name = air pressure level + units = hPa + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[t_lay] + standard_name = air_temperature_at_layer_for_RRTMGP + long_name = air temperature layer + units = K + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = F +[t_lev] + standard_name = air_temperature_at_interface_for_RRTMGP + long_name = air temperature layer + units = K + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[tv_lay] + standard_name = virtual_temperature + long_name = layer virtual temperature + units = K + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = F +[relhum] + standard_name = relative_humidity + long_name = layer relative humidity + units = frac + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = F +[tracer] + standard_name = chemical_tracers + long_name = chemical tracers + units = g g-1 + dimensions = (horizontal_dimension,vertical_dimension,number_of_tracers) + type = real + kind = kind_phys + optional = F +[hsw0] + standard_name = RRTMGP_sw_heating_rate_clear_sky + long_name = RRTMGP shortwave clear sky heating rate + units = K s-1 + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = T +[hswc] + standard_name = RRTMGP_sw_heating_rate_all_sky + long_name = RRTMGP shortwave all sky heating rate + units = K s-1 + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = F +[hswb] + standard_name = RRTMGP_sw_heating_rate_spectral + long_name = RRTMGP shortwave total sky heating rate (spectral) + units = K s-1 + dimensions = (horizontal_dimension,vertical_dimension,number_of_sw_spectral_points_rrtmgp) + type = real + kind = kind_phys + optional = T +[hlw0] + standard_name = RRTMGP_lw_heating_rate_clear_sky + long_name = RRTMGP longwave clear sky heating rate + units = K s-1 + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = T +[hlwc] + standard_name = RRTMGP_lw_heating_rate_all_sky + long_name = RRTMGP longwave all sky heating rate + units = K s-1 + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = F +[hlwb] + standard_name = RRTMGP_lw_heating_rate_spectral + long_name = RRTMGP longwave total sky heating rate (spectral) + units = K s-1 + dimensions = (horizontal_dimension,vertical_dimension,number_of_lw_spectral_points_rrtmgp) + type = real + kind = kind_phys + optional = T +[ipsdsw0] + standard_name = initial_permutation_seed_sw + long_name = initial seed for McICA SW + units = none + dimensions = () + type = integer + optional = F +[ipsdlw0] + standard_name = initial_permutation_seed_lw + long_name = initial seed for McICA LW + units = none + dimensions = () + type = integer + optional = F +[cld_frac] + standard_name = RRTMGP_total_cloud_fraction + long_name = layer total cloud fraction + units = frac + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cld_lwp] + standard_name = RRTMGP_cloud_liquid_water_path + long_name = layer cloud liquid water path + units = g m-2 + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cld_reliq] + standard_name = RRTMGP_mean_effective_radius_for_liquid_cloud + long_name = mean effective radius for liquid cloud + units = micron + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cld_iwp] + standard_name = RRTMGP_cloud_ice_water_path + long_name = layer cloud ice water path + units = g m-2 + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cld_reice] + standard_name = RRTMGP_mean_effective_radius_for_ice_cloud + long_name = mean effective radius for ice cloud + units = micron + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cld_rwp] + standard_name = RRTMGP_cloud_rain_water_path + long_name = cloud rain water path + units = g m-2 + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cld_rerain] + standard_name = RRTMGP_mean_effective_radius_for_rain_drop + long_name = mean effective radius for rain drop + units = micron + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cld_swp] + standard_name = RRTMGP_cloud_snow_water_path + long_name = cloud snow water path + units = g m-2 + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cld_resnow] + standard_name = RRTMGP_mean_effective_radius_for_snow_flake + long_name = mean effective radius for snow flake + units = micron + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[cldtausw] + standard_name = RRTMGP_cloud_optical_depth_layers_at_0_55mu_band + long_name = approx .55mu band layer cloud optical depth + units = none + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys + optional = F +[cldtaulw] + standard_name = RRTMGP_cloud_optical_depth_layers_at_10mu_band + long_name = approx 10mu band layer cloud optical depth + units = none + dimensions = (horizontal_dimension,vertical_dimension) + type = real + kind = kind_phys +[fluxlwUP_allsky] + standard_name = RRTMGP_lw_flux_profile_upward_allsky + long_name = RRTMGP upward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[fluxlwDOWN_allsky] + standard_name = RRTMGP_lw_flux_profile_downward_allsky + long_name = RRTMGP downward longwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[fluxlwUP_clrsky] + standard_name = RRTMGP_lw_flux_profile_upward_clrsky + long_name = RRTMGP upward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[fluxlwDOWN_clrsky] + standard_name = RRTMGP_lw_flux_profile_downward_clrsky + long_name = RRTMGP downward longwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[fluxswUP_allsky] + standard_name = RRTMGP_sw_flux_profile_upward_allsky + long_name = RRTMGP upward shortwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[fluxswDOWN_allsky] + standard_name = RRTMGP_sw_flux_profile_downward_allsky + long_name = RRTMGP downward shortwave all-sky flux profile + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[fluxswUP_clrsky] + standard_name = RRTMGP_sw_flux_profile_upward_clrsky + long_name = RRTMGP upward shortwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[fluxswDOWN_clrsky] + standard_name = RRTMGP_sw_flux_profile_downward_clrsky + long_name = RRTMGP downward shortwave clr-sky flux profile + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = real + kind = kind_phys + optional = F +[flxprf_lw] + standard_name = RRTMGP_lw_fluxes + long_name = lw fluxes total sky / csk and up / down at levels + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = proflw_type + optional = T +[flxprf_sw] + standard_name = RRTMGP_sw_fluxes + long_name = sw fluxes total sky / csk and up / down at levels + units = W m-2 + dimensions = (horizontal_dimension,vertical_dimension_plus_one) + type = profsw_type + optional = T +[aerosolslw] + standard_name = RRTMGP_aerosol_optical_properties_for_longwave_bands_01_16 + long_name = aerosol optical properties for longwave bands 01-16 + units = various + dimensions = (horizontal_dimension,vertical_dimension, number_of_lw_bands_rrtmgp,number_of_aerosol_output_fields_for_longwave_radiation) + type = real + kind = kind_phys + optional = F +[aerosolslw(:,:,:,1)] + standard_name = RRTMGP_aerosol_optical_depth_for_longwave_bands_01_16 + long_name = aerosol optical depth for longwave bands 01-16 + units = none + dimensions = (horizontal_dimension,vertical_dimension, number_of_lw_bands_rrtmgp) + type = real + kind = kind_phys +[aerosolslw(:,:,:,2)] + standard_name = RRTMGP_aerosol_single_scattering_albedo_for_longwave_bands_01_16 + long_name = aerosol single scattering albedo for longwave bands 01-16 + units = frac + dimensions = (horizontal_dimension,vertical_dimension, number_of_lw_bands_rrtmgp) + type = real + kind = kind_phys +[aerosolslw(:,:,:,3)] + standard_name = RRTMGP_aerosol_asymmetry_parameter_for_longwave_bands_01_16 + long_name = aerosol asymmetry parameter for longwave bands 01-16 + units = none + dimensions = (horizontal_dimension,vertical_dimension, number_of_lw_bands_rrtmgp) + type = real + kind = kind_phys +[aerosolssw] + standard_name = RRTMGP_aerosol_optical_properties_for_shortwave_bands_01_16 + long_name = aerosol optical properties for shortwave bands 01-16 + units = various + dimensions = (horizontal_dimension,vertical_dimension, number_of_sw_bands_rrtmgp, number_of_aerosol_output_fields_for_shortwave_radiation) + type = real + kind = kind_phys +[aerosolssw(:,:,:,1)] + standard_name = RRTMGP_aerosol_optical_depth_for_shortwave_bands_01_16 + long_name = aerosol optical depth for shortwave bands 01-16 + units = none + dimensions = (horizontal_dimension,vertical_dimension, number_of_sw_bands_rrtmgp) + type = real + kind = kind_phys +[aerosolssw(:,:,:,2)] + standard_name = RRTMGP_aerosol_single_scattering_albedo_for_shortwave_bands_01_16 + long_name = aerosol single scattering albedo for shortwave bands 01-16 + units = frac + dimensions = (horizontal_dimension,vertical_dimension, number_of_sw_bands_rrtmgp) + type = real + kind = kind_phys +[aerosolssw(:,:,:,3)] + standard_name = RRTMGP_aerosol_asymmetry_parameter_for_shortwave_bands_01_16 + long_name = aerosol asymmetry parameter for shortwave bands 01-16 + units = none + dimensions = (horizontal_dimension,vertical_dimension, number_of_sw_bands_rrtmgp) + type = real + kind = kind_phys +[icseed_lw] + standard_name = seed_random_numbers_lw_for_RRTMGP + long_name = seed for random number generation for longwave radiation + units = none + dimensions = (horizontal_dimension) + type = integer + optional = F +[icseed_sw] + standard_name = seed_random_numbers_sw_for_RRTMGP + long_name = seed for random number generation for shortwave radiation + units = none + dimensions = (horizontal_dimension) + type = integer + optional = F +[sw_gas_props] + standard_name = coefficients_for_sw_gas_optics + long_name = DDT containing spectral information for RRTMGP SW radiation scheme + units = DDT + dimensions = () + type = ty_gas_optics_rrtmgp + optional = F +[sw_cloud_props] + standard_name = coefficients_for_sw_cloud_optics + long_name = DDT containing spectral information for RRTMGP SW radiation scheme + units = DDT + dimensions = () + type = ty_cloud_optics + optional = F +[sw_optical_props_clrsky] + standard_name = shortwave_optical_properties_for_clear_sky + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + optional = F +[sw_optical_props_cloudsByBand] + standard_name = shortwave_optical_properties_for_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str +[sw_optical_props_clouds] + standard_name = shortwave_optical_properties_for_cloudy_atmosphere + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + optional = F +[sw_optical_props_aerosol] + standard_name = shortwave_optical_properties_for_aerosols + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_2str + optional = F +[gas_concentrations] + standard_name = Gas_concentrations_for_RRTMGP_suite + long_name = DDT containing gas concentrations for RRTMGP radiation scheme + units = DDT + dimensions = () + type = ty_gas_concs + optional = F +[sources] + standard_name = longwave_source_function + long_name = Fortran DDT containing RRTMGP source functions + units = DDT + dimensions = () + type = ty_source_func_lw + optional = F +[lw_gas_props] + standard_name = coefficients_for_lw_gas_optics + long_name = DDT containing spectral information for RRTMGP LW radiation scheme + units = DDT + dimensions = () + type = ty_gas_optics_rrtmgp + optional = F +[lw_cloud_props] + standard_name = coefficients_for_lw_cloud_optics + long_name = DDT containing spectral information for RRTMGP LW radiation scheme + units = DDT + dimensions = () + type = ty_cloud_optics + optional = F +[lw_optical_props_clrsky] + standard_name = longwave_optical_properties_for_clear_sky + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_1scl + optional = F +[lw_optical_props_clouds] + standard_name = longwave_optical_properties_for_cloudy_atmosphere + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_1scl + optional = F +[lw_optical_props_cloudsByBand] + standard_name = longwave_optical_properties_for_cloudy_atmosphere_by_band + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_1scl +[lw_optical_props_aerosol] + standard_name = longwave_optical_properties_for_aerosols + long_name = Fortran DDT containing RRTMGP optical properties + units = DDT + dimensions = () + type = ty_optical_props_1scl + optional = F +[sfc_emiss_byband] + standard_name = surface_emissivity_in_each_RRTMGP_LW_band + long_name = surface emissivity in each RRTMGP LW band + units = none + dimensions = (number_of_lw_bands_rrtmgp,horizontal_dimension) + type = real + kind = kind_phys +[sec_diff_byband] + standard_name = secant_of_diffusivity_angle_each_RRTMGP_LW_band + long_name = secant of diffusivity angle in each RRTMGP LW band + units = none + dimensions = (number_of_lw_bands_rrtmgp,horizontal_dimension) + type = real + kind = kind_phys +[sfc_alb_nir_dir] + standard_name = surface_albedo_nearIR_direct + long_name = near-IR (direct) surface albedo (sfc_alb_nir_dir) + units = none + dimensions = (number_of_sw_bands_rrtmgp,horizontal_dimension) + type = real + kind = kind_phys +[sfc_alb_nir_dif] + standard_name = surface_albedo_nearIR_diffuse + long_name = near-IR (diffuse) surface albedo (sfc_alb_nir_dif) + units = none + dimensions = (number_of_sw_bands_rrtmgp,horizontal_dimension) + type = real + kind = kind_phys +[sfc_alb_uvvis_dir] + standard_name = surface_albedo_uvvis_dir + long_name = UVVIS (direct) surface albedo (sfc_alb_uvvis_dir) + units = none + dimensions = (number_of_sw_bands_rrtmgp,horizontal_dimension) + type = real + kind = kind_phys +[sfc_alb_uvvis_dif] + standard_name = surface_albedo_uvvis_dif + long_name = UVVIS (diffuse) surface albedo (sfc_alb_uvvis_dif) + units = none + dimensions = (number_of_sw_bands_rrtmgp,horizontal_dimension) + type = real + kind = kind_phys +[toa_src_lw] + standard_name = toa_incident_lw_flux_by_spectral_point + long_name = TOA longwave incident flux at each spectral points + units = W m-2 + dimensions = (horizontal_dimension,number_of_lw_spectral_points_rrtmgp) + type = real + kind = kind_phys +[toa_src_sw] + standard_name = toa_incident_sw_flux_by_spectral_point + long_name = TOA shortwave incident flux at each spectral points + units = W m-2 + dimensions = (horizontal_dimension,number_of_sw_spectral_points_rrtmgp) + type = real + kind = kind_phys +[active_gases_array] + standard_name = list_of_active_gases_used_by_RRTMGP + long_name = list of active gases used by RRTMGP + units = none + dimensions = (number_of_active_gases_used_by_RRTMGP) + type = character + kind = len=128 ######################################################################## [ccpp-arg-table] diff --git a/scm/src/default_namelists.py b/scm/src/default_namelists.py index 5adff214c..41a0299a9 100644 --- a/scm/src/default_namelists.py +++ b/scm/src/default_namelists.py @@ -1,8 +1,10 @@ -default_physics_namelists = {"SCM_GFS_v15":"input_GFS_v15.nml", - "SCM_GFS_v15plus":"input_GFS_v15plus.nml", - "SCM_csawmg":"input_csawmg.nml", +default_physics_namelists = {"SCM_csawmg":"input_csawmg.nml", "SCM_GSD_v1":"input_GSD_v1.nml", - "SCM_GFS_v15_noahmp":"input_GFS_v15_noahmp.nml", "SCM_GFS_v15p2":"input_GFS_v15p2.nml", - "SCM_GFS_v16beta":"input_GFS_v16beta.nml" + "SCM_GFS_v16beta":"input_GFS_v16beta.nml", + "SCM_GFS_v15p2_no_nsst":"input_GFS_v15p2.nml", + "SCM_GFS_v16beta_no_nsst":"input_GFS_v16beta.nml", + "SCM_GFS_v15p2_noahmp":"input_GFS_v15p2_noahmp.nml", + "SCM_GFS_v15p2_MYJ":"input_GFS_v15p2_MYJ.nml", + "SCM_GFS_v15p2_FA":"input_GFS_v15p2_FA.nml" } \ No newline at end of file diff --git a/scm/src/example_multi_run.py b/scm/src/example_multi_run.py index 65d3173fe..b2746af1f 100644 --- a/scm/src/example_multi_run.py +++ b/scm/src/example_multi_run.py @@ -1,3 +1,3 @@ cases = ["bomex"] -suites = ["SCM_GFS_v15","SCM_GFS_v15plus"] -namelists = ["input_GFS_v15.nml","input_GFS_v15plus.nml"] \ No newline at end of file +suites = ["SCM_GFS_v15p2","SCM_GFS_v16beta"] +namelists = ["input_GFS_v15p2.nml","input_GFS_v16beta.nml"] \ No newline at end of file diff --git a/scm/src/gmtb_scm.F90 b/scm/src/gmtb_scm.F90 index 0b9ac864e..35c57c054 100644 --- a/scm/src/gmtb_scm.F90 +++ b/scm/src/gmtb_scm.F90 @@ -15,29 +15,12 @@ subroutine gmtb_scm_main_sub() use gmtb_scm_time_integration use gmtb_scm_output use gmtb_scm_type_defs - -#ifdef STATIC - use :: ccpp_api, & - only: ccpp_init, & - ccpp_finalize + use :: ccpp_static_api, & only: ccpp_physics_init, & ccpp_physics_run, & ccpp_physics_finalize -#else - use :: ccpp_api, & - only: ccpp_init, & - ccpp_finalize, & - ccpp_physics_init, & - ccpp_physics_run, & - ccpp_physics_finalize, & - ccpp_field_add, & - ccpp_initialized, & - ccpp_error - use :: iso_c_binding, only: c_loc -#include "ccpp_modules.inc" -#endif implicit none @@ -112,11 +95,11 @@ subroutine gmtb_scm_main_sub() do i = 1, scm_state%n_cols !set up each column's physics suite (which may be different) - call ccpp_init(trim(adjustl(scm_state%physics_suite_name(i))), cdata_cols(i), ierr) - if (ierr/=0) then - write(*,'(a,i0,a)') 'An error occurred in ccpp_init for column ', i, '. Exiting...' - stop - end if + ! call ccpp_init(trim(adjustl(scm_state%physics_suite_name(i))), cdata_cols(i), ierr) + ! if (ierr/=0) then + ! write(*,'(a,i0,a)') 'An error occurred in ccpp_init for column ', i, '. Exiting...' + ! stop + ! end if !open a logfile for each column if (physics%Init_parm(i)%me == physics%Init_parm(i)%master .and. physics%Init_parm(i)%logunit>=0) then @@ -156,23 +139,11 @@ subroutine gmtb_scm_main_sub() call physics%associate(scm_state, i) -#ifndef STATIC -! use ccpp_fields.inc to call ccpp_field_add for all variables to add -! (this is auto-generated from ccpp/scripts/ccpp_prebuild.py, -! the script parses tables in gmtb_scm_type_defs.f90) - associate_column: associate (cdata => cdata_cols(i)) -#include "ccpp_fields.inc" - end associate associate_column -#endif - !initialize each column's physics -#ifdef STATIC + write(0,'(a,i0,a)') "Calling ccpp_physics_init for column ", i, " with suite '" // trim(trim(adjustl(scm_state%physics_suite_name(i)))) // "'" call ccpp_physics_init(cdata_cols(i), suite_name=trim(trim(adjustl(scm_state%physics_suite_name(i)))), ierr=ierr) write(0,'(a,i0,a,i0)') "Called ccpp_physics_init for column ", i, " with suite '" // trim(trim(adjustl(scm_state%physics_suite_name(i)))) // "', ierr=", ierr -#else - call ccpp_physics_init(cdata_cols(i), ierr=ierr) -#endif if (ierr/=0) then write(*,'(a,i0,a)') 'An error occurred in ccpp_physics_init for column ', i, ': ' // trim(cdata_cols(i)%errmsg) // '. Exiting...' stop @@ -220,11 +191,7 @@ subroutine gmtb_scm_main_sub() scm_state%state_v(:,:,:,2) = scm_state%state_v(:,:,:,1) do i=1, scm_state%n_cols -#ifdef STATIC call ccpp_physics_run(cdata_cols(i), suite_name=trim(trim(adjustl(scm_state%physics_suite_name(i)))), ierr=ierr) -#else - call ccpp_physics_run(cdata_cols(i), ierr=ierr) -#endif if (ierr/=0) then write(*,'(a,i0,a)') 'An error occurred in ccpp_physics_run for column ', i, ': ' // trim(cdata_cols(i)%errmsg) // '. Exiting...' stop @@ -328,21 +295,10 @@ subroutine gmtb_scm_main_sub() end do do i=1, scm_state%n_cols -#ifdef STATIC call ccpp_physics_finalize(cdata_cols(i), suite_name=trim(trim(adjustl(scm_state%physics_suite_name(i)))), ierr=ierr) -#else - call ccpp_physics_finalize(cdata_cols(i), ierr=ierr) -#endif - if (ierr/=0) then - write(*,'(a,i0,a)') 'An error occurred in ccpp_physics_finalize for column ', i, ': ' // trim(cdata_cols(i)%errmsg) // '. Exiting...' - stop - end if - end do - do i=1, scm_state%n_cols - call ccpp_finalize(cdata_cols(i), ierr) if (ierr/=0) then - write(*,'(a,i0,a)') 'An error occurred in ccpp_finalize for column ', i, '. Exiting...' + write(*,'(a,i0,a)') 'An error occurred in ccpp_physics_finalize for column ', i, ': ' // trim(cdata_cols(i)%errmsg) // '. Exiting...' stop end if end do diff --git a/scm/src/gmtb_scm_forcing.f90 b/scm/src/gmtb_scm_forcing.F90 similarity index 100% rename from scm/src/gmtb_scm_forcing.f90 rename to scm/src/gmtb_scm_forcing.F90 diff --git a/scm/src/gmtb_scm_input.f90 b/scm/src/gmtb_scm_input.F90 similarity index 100% rename from scm/src/gmtb_scm_input.f90 rename to scm/src/gmtb_scm_input.F90 diff --git a/scm/src/gmtb_scm_kinds.F90 b/scm/src/gmtb_scm_kinds.F90 new file mode 100644 index 000000000..2e0397810 --- /dev/null +++ b/scm/src/gmtb_scm_kinds.F90 @@ -0,0 +1,14 @@ +!> \file gmtb_scm_kinds.f90 +!! Contains definition of kinds used in the GMTB SCM. + +module gmtb_scm_kinds + +!! \section arg_table_gmtb_scm_kinds +!! \htmlinclude gmtb_scm_kinds.html +!! + + integer, parameter :: sp = selected_real_kind(P= 6,R=37) + integer, parameter :: dp = selected_real_kind(P=13,R=300) + integer, parameter :: qp = selected_real_kind(P=27,R=2400) + +end module gmtb_scm_kinds diff --git a/scm/src/gmtb_scm_kinds.f90 b/scm/src/gmtb_scm_kinds.f90 deleted file mode 100644 index 46d01cafb..000000000 --- a/scm/src/gmtb_scm_kinds.f90 +++ /dev/null @@ -1,10 +0,0 @@ -!> \file gmtb_scm_kinds.f90 -!! Contains definition of kinds used in the GMTB SCM. - -module gmtb_scm_kinds - - integer, parameter :: sp = selected_real_kind(P= 6,R=37) - integer, parameter :: dp = selected_real_kind(P=13,R=300) - integer, parameter :: qp = selected_real_kind(P=27,R=2400) - -end module gmtb_scm_kinds diff --git a/scm/src/gmtb_scm_kinds.meta b/scm/src/gmtb_scm_kinds.meta new file mode 100644 index 000000000..23807f0c4 --- /dev/null +++ b/scm/src/gmtb_scm_kinds.meta @@ -0,0 +1,21 @@ +[ccpp-arg-table] + name = gmtb_scm_kinds + type = module +[kind_sp] + standard_name = kind_sp + long_name = definition of kind_sp + units = none + dimensions = () + type = integer +[kind_dp] + standard_name = kind_dp + long_name = definition of kind_dp + units = none + dimensions = () + type = integer +[kind_qp] + standard_name = kind_qp + long_name = definition of kind_qp + units = none + dimensions = () + type = integer diff --git a/scm/src/gmtb_scm_output.f90 b/scm/src/gmtb_scm_output.F90 similarity index 89% rename from scm/src/gmtb_scm_output.f90 rename to scm/src/gmtb_scm_output.F90 index 29166d39d..76465db6a 100644 --- a/scm/src/gmtb_scm_output.f90 +++ b/scm/src/gmtb_scm_output.F90 @@ -292,19 +292,19 @@ subroutine output_init(scm_state) CALL CHECK(NF90_PUT_ATT(NCID=ncid,VARID=dummy_id,NAME="description",VALUES="detrainment mass flux")) CALL CHECK(NF90_PUT_ATT(NCID=ncid,VARID=dummy_id,NAME="units",VALUES="kg m-2 s-1")) ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='PBL_height',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_up_TOA_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_dn_TOA_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_up_TOA_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_up_sfc_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_dn_sfc_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_up_sfc_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_dn_sfc_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_up_TOA_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_up_TOA_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_up_sfc_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_up_sfc_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_dn_sfc_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) - ! CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_dn_sfc_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_up_TOA_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_dn_TOA_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_up_TOA_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_up_sfc_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_dn_sfc_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_up_sfc_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='sw_dn_sfc_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_up_TOA_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_up_TOA_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_up_sfc_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_up_sfc_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_dn_sfc_tot',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) + CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='lw_dn_sfc_clr',XTYPE=NF90_FLOAT,DIMIDS= (/ hor_dim_id, time_id /), VARID=dummy_id)) CALL CHECK(NF90_DEF_VAR(NCID=ncid,NAME='init_year',XTYPE=NF90_FLOAT,VARID=year_id)) CALL CHECK(NF90_PUT_ATT(NCID=ncid,VARID=year_id,NAME="description",VALUES="model initialization year")) @@ -636,6 +636,86 @@ subroutine output_append(scm_state, physics) ! CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="lw_dn_sfc_clr",VARID=var_id)) ! CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=lw_dn_sfc_clr(:),START=(/1,scm_state%itt_out /))) + ! TOA/SFC fluxes + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Diag(i)%topfsw(1)%upfxc + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="sw_up_TOA_tot",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Diag(i)%topfsw(1)%dnfxc + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="sw_dn_TOA_tot",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Diag(i)%topfsw(1)%upfx0 + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="sw_up_TOA_clr",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Radtend(i)%sfcfsw(1)%upfxc + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="sw_up_sfc_tot",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Radtend(i)%sfcfsw(1)%dnfxc + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="sw_dn_sfc_tot",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Radtend(i)%sfcfsw(1)%upfx0 + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="sw_up_sfc_clr",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Radtend(i)%sfcfsw(1)%dnfx0 + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="sw_dn_sfc_clr",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Diag(i)%topflw(1)%upfxc + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="lw_up_TOA_tot",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Diag(i)%topflw(1)%upfx0 + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="lw_up_TOA_clr",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Radtend(i)%sfcflw(1)%upfxc + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="lw_up_sfc_tot",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Radtend(i)%sfcflw(1)%dnfxc + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="lw_dn_sfc_tot",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Radtend(i)%sfcflw(1)%upfx0 + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="lw_up_sfc_clr",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + ! + do i=1, scm_state%n_cols + dummy_1D(i) = physics%Radtend(i)%sfcflw(1)%upfx0 + end do + CALL CHECK(NF90_INQ_VARID(NCID=ncid,NAME="lw_dn_sfc_clr",VARID=var_id)) + CALL CHECK(NF90_PUT_VAR(NCID=ncid,VARID=var_id,VALUES=dummy_1D,START=(/1,scm_state%itt_out /))) + + !> - Close the file. CALL CHECK(NF90_CLOSE(ncid)) diff --git a/scm/src/gmtb_scm_physical_constants.f90 b/scm/src/gmtb_scm_physical_constants.F90 similarity index 100% rename from scm/src/gmtb_scm_physical_constants.f90 rename to scm/src/gmtb_scm_physical_constants.F90 diff --git a/scm/src/gmtb_scm_setup.f90 b/scm/src/gmtb_scm_setup.F90 similarity index 100% rename from scm/src/gmtb_scm_setup.f90 rename to scm/src/gmtb_scm_setup.F90 diff --git a/scm/src/gmtb_scm_time_integration.f90 b/scm/src/gmtb_scm_time_integration.F90 similarity index 96% rename from scm/src/gmtb_scm_time_integration.f90 rename to scm/src/gmtb_scm_time_integration.F90 index 6aa224f69..3ccc14529 100644 --- a/scm/src/gmtb_scm_time_integration.f90 +++ b/scm/src/gmtb_scm_time_integration.F90 @@ -6,13 +6,8 @@ module gmtb_scm_time_integration use gmtb_scm_kinds, only: sp, dp, qp use gmtb_scm_forcing -#ifdef STATIC use ccpp_api, only: ccpp_t use ccpp_static_api, only: ccpp_physics_run -#else -use ccpp_api, only: ccpp_t, & - ccpp_physics_run -#endif implicit none @@ -84,11 +79,7 @@ subroutine do_time_step(scm_state, cdata_cols) end if do i=1, scm_state%n_cols -#ifdef STATIC call ccpp_physics_run(cdata_cols(i), suite_name=trim(adjustl(scm_state%physics_suite_name(i))), ierr=ierr) -#else - call ccpp_physics_run(cdata_cols(i), ierr=ierr) -#endif if (ierr/=0) then write(*,'(a,i0,a)') 'An error occurred in ccpp_physics_run for column ', i, ': ' // trim(cdata_cols(i)%errmsg) // '. Exiting...' stop diff --git a/scm/src/gmtb_scm_type_defs.f90 b/scm/src/gmtb_scm_type_defs.F90 similarity index 100% rename from scm/src/gmtb_scm_type_defs.f90 rename to scm/src/gmtb_scm_type_defs.F90 diff --git a/scm/src/gmtb_scm_utils.f90 b/scm/src/gmtb_scm_utils.F90 similarity index 100% rename from scm/src/gmtb_scm_utils.f90 rename to scm/src/gmtb_scm_utils.F90 diff --git a/scm/src/multi_run_gmtb_scm.py b/scm/src/multi_run_gmtb_scm.py index 51bceac12..c67bcda1f 100755 --- a/scm/src/multi_run_gmtb_scm.py +++ b/scm/src/multi_run_gmtb_scm.py @@ -1,7 +1,13 @@ #!/usr/bin/env python +import sys +PYTHON2 = sys.version_info[0] < 3 + import argparse -import imp +if PYTHON2: + from imp import load_source +else: + from importlib.machinery import SourceFileLoader import os import logging import subprocess @@ -21,8 +27,12 @@ group.add_argument('-s', '--suite', help='name of suite to use',) group.add_argument('-f', '--file', help='name of file where SCM runs are defined',) parser.add_argument('-v', '--verbose', help='once: set logging level to debug; twice: set logging level to debug '\ - 'and write log to file',action='count') + 'and write log to file', action='count', default=0) parser.add_argument('-t', '--timer', help='set to time each subprocess', action='store_true', default=False) +parser.add_argument('-d', '--docker', help='include if scm is being run in a docker container to mount volumes', action='store_true', default=False) + +# Results are recorded in this global list (to avoid complications with getting return values from the partial functions used below) +RESULTS = [] def setup_logging(verbose): """Sets up the logging module.""" @@ -33,9 +43,9 @@ def setup_logging(verbose): LOG_LEVEL = logging.INFO LOG_FILE = 'multi_run_gmtb_scm.log' LOG_FORMAT = '%(levelname)s: %(message)s' - + logging.basicConfig(format=LOG_FORMAT, level=LOG_LEVEL) - + # write out a log file if verbosity is set twice (-vv) if verbose > 1: fh = logging.FileHandler(LOG_FILE, mode='w') @@ -51,8 +61,8 @@ def spawn_subprocess(command, timer): logging.info('elapsed time: {0} s'.format(elapsed_time/timer_iterations)) else: subprocess_work(command) - -# function to actually do the work of executing a subprocess and adding the stderr and stdout to the log + +# function to actually do the work of executing a subprocess and adding the stderr and stdout to the log # at the DEBUG level def subprocess_work(command): p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) @@ -61,69 +71,84 @@ def subprocess_work(command): logging.debug(output) exit_code = p.returncode if not exit_code == 0: - message = '####### The subprocess started using the command ({0}) exited with code {1}. #######\n'\ - 'Run the command ({0}) by itself again or use the -v or -vv options for more details.'.format(command, exit_code) - logging.critical(message) - #raise Exception(message) + message = '####### The subprocess started using the command ({0}) exited with code {1}. #######\n'\ + 'Run the command ({0}) by itself again or use the -v or -vv options for more details.'.format(command, exit_code) + logging.critical(message) + #raise Exception(message) + RESULTS.append([command, exit_code]) def main(): args = parser.parse_args() - + setup_logging(args.verbose) - + # if the case argument is specified, run through all supported suites with the specified case if args.case: logging.info('Running all supported suites with case {0}'.format(args.case)) for i, suite in enumerate(suites,1): command = RUN_SCRIPT + ' -c ' + args.case + ' -s ' + suite + if args.docker: + command = command + ' -d' logging.info('Executing process {0} of {1} ({2})'.format(i, len(suites), command)) spawn_subprocess(command, args.timer) - + # if the suite argument is specified, run through all supported cases with the specified suite if args.suite: logging.info('Running all supported cases with suite {0}'.format(args.suite)) for i, case in enumerate(cases,1): command = RUN_SCRIPT + ' -c ' + case + ' -s ' + args.suite + if args.docker: + command = command + ' -d' logging.info('Executing process {0} of {1} ({2})'.format(i, len(cases), command)) spawn_subprocess(command, args.timer) - + # For maximum flexibility, run the SCM as specified from an external file where cases, suites, and physics namelists - # are all specified. This file must contain python lists called 'cases','suites', and 'namelists'. The suites and + # are all specified. This file must contain python lists called 'cases','suites', and 'namelists'. The suites and # namelists lists can be empty ([]) if necessary. #The following rules apply: # 1. The case list in the file must not be empty. - # 2. If only a case list is specified, the cases are run with the default suite specified in run_gmtb_scm.py with + # 2. If only a case list is specified, the cases are run with the default suite specified in run_gmtb_scm.py with # the default namelists specified in default_namelists.py. - # 3. If a case list and suite list is provided without a namelist list, all permutations of cases and suites will + # 3. If a case list and suite list is provided without a namelist list, all permutations of cases and suites will # be run using default namelists specified in default_namelists.py. # 4. If a case list and suite list is provided with a namelist: # 4a. If only one suite is specified, it can be run with any number of namelists. - # 4b. If more than one suite is specified, the number of namelists must match, and each case is run with each + # 4b. If more than one suite is specified, the number of namelists must match, and each case is run with each # (suite,namelist) pair, by order specified in the lists. - # 5. If a case list and namelist list are specified without a suite list, each case is run with the default suite + # 5. If a case list and namelist list are specified without a suite list, each case is run with the default suite # specified in run_gmtb_scm.py using the supplied namelists. if args.file: logging.info('Importing {0} to run requested combinations'.format(args.file)) - try: - scm_runs = imp.load_source(os.path.splitext(args.file)[0], args.file) - except ImportError: - message = 'There was a problem loading {0}. Please check that the path exists.'.format(args.file) - logging.critical(message) - raise - + if PYTHON2: + try: + scm_runs = load_source(os.path.splitext(args.file)[0], args.file) + except (IOError, ImportError): + message = 'There was a problem loading {0}. Please check that the path exists.'.format(args.file) + logging.critical(message) + raise Exception(message) + else: + try: + scm_runs = SourceFileLoader(os.path.splitext(args.file)[0], args.file).load_module() + except FileNotFoundError: + message = 'There was a problem loading {0}. Please check that the path exists.'.format(args.file) + logging.critical(message) + raise Exception(message) + if not scm_runs.cases: message = 'The cases list in {0} must not be empty'.format(args.file) logging.critical(message) raise Exception(message) - + if scm_runs.cases and not scm_runs.suites and not scm_runs.namelists: logging.info( 'Only cases were specified in {0}, so running all cases with the default suite'.format(args.file)) for i, case in enumerate(scm_runs.cases,1): command = RUN_SCRIPT + ' -c ' + case + if args.docker: + command = command + ' -d' logging.info('Executing process {0} of {1} ({2})'.format(i, len(scm_runs.cases), command)) spawn_subprocess(command, args.timer) - + if scm_runs.cases and scm_runs.suites: if scm_runs.namelists: if len(scm_runs.suites) == 1: @@ -132,6 +157,8 @@ def main(): for i, case in enumerate(scm_runs.cases): for j, namelist in enumerate(scm_runs.namelists,1): command = RUN_SCRIPT + ' -c ' + case + ' -s ' + scm_runs.suites[0] + ' -n ' + namelist + if args.docker: + command = command + ' -d' logging.info('Executing process {0} of {1} ({2})'.format( len(scm_runs.namelists)*i+j, len(scm_runs.cases)*len(scm_runs.namelists), command)) spawn_subprocess(command, args.timer) @@ -141,6 +168,8 @@ def main(): for i, case in enumerate(scm_runs.cases): for j, suite in enumerate(scm_runs.suites,1): command = RUN_SCRIPT + ' -c ' + case + ' -s ' + suite + ' -n ' + scm_runs.namelists[j-1] + if args.docker: + command = command + ' -d' logging.info('Executing process {0} of {1} ({2})'.format( len(scm_runs.suites)*i+j, len(scm_runs.cases)*len(scm_runs.suites), command)) spawn_subprocess(command, args.timer) @@ -156,20 +185,24 @@ def main(): for i, case in enumerate(scm_runs.cases): for j, suite in enumerate(scm_runs.suites,1): command = RUN_SCRIPT + ' -c ' + case + ' -s ' + suite + if args.docker: + command = command + ' -d' logging.info('Executing process {0} of {1} ({2})'.format( len(scm_runs.suites)*i+j, len(scm_runs.cases)*len(scm_runs.suites), command)) spawn_subprocess(command, args.timer) - + if scm_runs.cases and not scm_runs.suites and scm_runs.namelists: logging.info('Cases and namelists were specified in {0}, so running all cases with the default suite '\ 'using the list of namelists'.format(args.file)) for i, case in enumerate(scm_runs.cases): for j, namelist in enumerate(scm_runs.namelists,1): command = RUN_SCRIPT + ' -c ' + case + ' -n ' + namelist + if args.docker: + command = command + ' -d' logging.info('Executing process {0} of {1} ({2})'.format( len(scm_runs.namelists)*i+j, len(scm_runs.cases)*len(scm_runs.namelists), command)) spawn_subprocess(command, args.timer) - + # If running the script with no arguments, run all supported (case,suite) permutations. if not args.case and not args.suite and not args.file: logging.info('Since no arguments were specified, running through all permuatations of supported cases and '\ @@ -177,9 +210,19 @@ def main(): for i, case in enumerate(cases): for j, suite in enumerate(suites,1): command = RUN_SCRIPT + ' -c ' + case + ' -s ' + suite + if args.docker: + command = command + ' -d' logging.info('Executing process {0} of {1} ({2})'.format( len(suites)*i+j, len(cases)*len(suites), command)) spawn_subprocess(command, args.timer) - + + # Generate report at the end of the log file when verbose flag is set + if args.verbose > 0: + for (command, exit_code) in RESULTS: + if exit_code == 0: + logging.info('Process "{}" completed successfully'.format(command)) + else: + logging.error('Process "{}" exited with code {}'.format(command, exit_code)) + if __name__ == '__main__': main() diff --git a/scm/src/rrtmgp_multi_run.py b/scm/src/rrtmgp_multi_run.py new file mode 100644 index 000000000..e1db31f51 --- /dev/null +++ b/scm/src/rrtmgp_multi_run.py @@ -0,0 +1,3 @@ +cases = ["arm_sgp_summer_1997_A","astex","bomex","LASSO_2016051812","twpice"] +suites = ["SCM_GFS_v15p2_RRTMGP"] +namelists = ["input_GFS_v15p2_RRTMGP.nml"] \ No newline at end of file diff --git a/scm/src/run_gmtb_scm.py b/scm/src/run_gmtb_scm.py index 33ed59486..5bd5ea0fd 100755 --- a/scm/src/run_gmtb_scm.py +++ b/scm/src/run_gmtb_scm.py @@ -31,7 +31,7 @@ PHYSICS_SUITE_DIR = '../../ccpp/suites' # Default suite to use if none is specified -DEFAULT_SUITE = 'SCM_GFS_v15' +DEFAULT_SUITE = 'SCM_GFS_v15p2' # Path to physics data files PHYSICS_DATA_DIR = '../data/physics_input_data' @@ -63,6 +63,7 @@ parser.add_argument('-g', '--gdb', help='invoke gmtb_scm through gdb', action='store_true', default=False) parser.add_argument('-s', '--suite', help='name of suite to use', default=DEFAULT_SUITE) parser.add_argument('-n', '--namelist', help='physics namelist to use') +parser.add_argument('-d', '--docker', help='include if scm is being run in a docker container to mount volumes', action='store_true', default=False) ############################################################################### # Functions and subroutines # @@ -82,15 +83,15 @@ def execute(cmd): status = p.returncode if status == 0: message = 'Execution of "{0}" returned with exit code {1}\n'.format(cmd, status) - message += ' stdout: "{0}"\n'.format(stdout.rstrip('\n')) - message += ' stderr: "{0}"'.format(stderr.rstrip('\n')) + message += ' stdout: "{0}"\n'.format(stdout.rstrip('\n'.encode())) + message += ' stderr: "{0}"'.format(stderr.rstrip('\n'.encode())) logging.debug(message) else: message = 'Execution of command "{0}" failed, exit code {1}\n'.format(cmd, status) - message += ' stdout: "{0}"\n'.format(stdout.rstrip('\n')) - message += ' stderr: "{0}"'.format(stderr.rstrip('\n')) + message += ' stdout: "{0}"\n'.format(stdout.rstrip('\n'.encode())) + message += ' stderr: "{0}"'.format(stderr.rstrip('\n'.encode())) logging.debug(message) - return (status, stdout.rstrip('\n'), stderr.rstrip('\n')) + return (status, stdout.rstrip('\n'.encode()), stderr.rstrip('\n'.encode())) def parse_arguments(): """Parse command line arguments""" @@ -99,7 +100,8 @@ def parse_arguments(): gdb = args.gdb suite = args.suite namelist = args.namelist - return (case, gdb, suite, namelist) + docker = args.docker + return (case, gdb, suite, namelist, docker) def find_gdb(): """Detect gdb, abort if not found""" @@ -229,8 +231,8 @@ def setup_rundir(self): # If surface fluxes are specified for this case, use the SDF modified to use them if surface_flux_spec: - logging.info('Specified surface fluxes are used for case {0}. Switching to SDF {1} from {2}'.format(self._case,'suite_' + self._suite + '_prescribed_surface' + '.xml','suite_' + self._suite + '.xml')) - self._suite = self._suite + '_prescribed_surface' + logging.info('Specified surface fluxes are used for case {0}. Switching to SDF {1} from {2}'.format(self._case,'suite_' + self._suite + '_ps' + '.xml','suite_' + self._suite + '.xml')) + self._suite = self._suite + '_ps' # Create physics_config namelist for experiment configuration file physics_config = {"physics_suite":self._suite, @@ -348,6 +350,8 @@ def setup_rundir(self): logging.info('Writing experiment configuration {0}.nml to output directory'.format(self._name)) cmd = 'cp {0} {1}'.format(STANDARD_EXPERIMENT_NAMELIST, os.path.join(output_dir,self._name + '.nml')) execute(cmd) + + return output_dir def launch_executable(use_gdb, gdb): """Configure model run command and pass control to shell/gdb""" @@ -358,9 +362,16 @@ def launch_executable(use_gdb, gdb): logging.info('Passing control to "{0}"'.format(cmd)) time.sleep(2) sys.exit(os.system(cmd)) + +def copy_outdir(exp_dir): + """Copy output directory to /home for this experiment.""" + home_output_dir = '/home/'+exp_dir + if os.path.isdir(home_output_dir): + shutil.rmtree(home_output_dir) + shutil.copytree(exp_dir, home_output_dir) def main(): - (case, use_gdb, suite, namelist) = parse_arguments() + (case, use_gdb, suite, namelist, docker) = parse_arguments() setup_logging() @@ -370,14 +381,18 @@ def main(): else: logging.info('Setting up experiment {0} with suite {1} using the default namelist for the suite'.format(case,suite)) exp = Experiment(case, suite, namelist) - exp.setup_rundir() + exp_dir = exp.setup_rundir() # Debugger if use_gdb: gdb = find_gdb() else: gdb = None # Launch model on exit + if docker: + #registering this function first should mean that it executes last, which is what we want + atexit.register(copy_outdir, exp_dir) atexit.register(launch_executable, use_gdb, gdb) + if __name__ == '__main__': main() diff --git a/scm/src/supported_suites.py b/scm/src/supported_suites.py index cdcfe58fe..06dcbca4c 100644 --- a/scm/src/supported_suites.py +++ b/scm/src/supported_suites.py @@ -1 +1 @@ -suites = ["SCM_GFS_v15p2","SCM_GFS_v16beta","SCM_csawmg","SCM_GSD_v1"] \ No newline at end of file +suites = ["SCM_GFS_v15p2","SCM_GFS_v15p2_no_nsst","SCM_GFS_v16beta","SCM_GFS_v16beta_no_nsst","SCM_csawmg","SCM_GSD_v1"] \ No newline at end of file