From e3bde25e10cc5ec99245ebd56e210d5777741159 Mon Sep 17 00:00:00 2001 From: Matt Dawson Date: Tue, 5 Mar 2024 10:00:30 -0700 Subject: [PATCH] update to latest TUV-x --- .gitignore | 3 +- Externals_CAM.cfg | 15 +-- cime_config/buildlib | 146 +++++----------------- cime_config/buildnml | 4 +- cime_config/config_component.xml | 2 +- cime_config/tuvx_MOZART_TS1.json | 204 ++++++++++++++++++++++++------- 6 files changed, 199 insertions(+), 175 deletions(-) diff --git a/.gitignore b/.gitignore index 54898a9808..130f252e2c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,7 @@ src/dynamics/fv3/atmos_cubed_sphere libraries/FMS libraries/mct libraries/parallelio -libraries/musica -libraries/json-fortran +libraries/tuv-x src/atmos_phys src/dynamics/mpas/dycore share diff --git a/Externals_CAM.cfg b/Externals_CAM.cfg index e7866ae5af..ec3b2abc0c 100644 --- a/Externals_CAM.cfg +++ b/Externals_CAM.cfg @@ -71,18 +71,11 @@ sparse = ../.mpas_sparse_checkout hash = b8c33daa required = True -[musica] -local_path = libraries/musica +[TUV-x] +local_path = libraries/tuv-x protocol = git -repo_url = https://github.com/NCAR/musica.git -branch = develop-update-tuvx -required = True - -[json-fortran] -local_path = libraries/json-fortran -protocol = git -repo_url = https://github.com/jacobwilliams/json-fortran.git -tag = 8.2.1 +repo_url = https://github.com/NCAR/tuv-x.git +hash = 6930151 required = True [hemco] diff --git a/cime_config/buildlib b/cime_config/buildlib index 9cd718f59f..c07ef02ad9 100755 --- a/cime_config/buildlib +++ b/cime_config/buildlib @@ -151,96 +151,19 @@ def _cmake_default_args(caseroot): return arg_dict ############################################################################### -def _build_json_fortran(caseroot, libroot, bldroot): +def _build_tuvx(caseroot, libroot, bldroot): ############################################################################### -# Builds the json-fortran library and updates the case variables used to set -# the include paths and linked libraries - - with Case(caseroot) as case: - bldpath = os.path.join(bldroot, "json-fortran") - if not os.path.exists(bldpath): - os.makedirs(bldpath) - srcpath = os.path.abspath(os.path.join(case.get_value("COMP_ROOT_DIR_ATM"), \ - "libraries", "json-fortran", "")) - logger.info("Building json-fortran in {} from source in {}\n".format(bldpath, srcpath)) - - arg_dict = _cmake_default_args(caseroot) - cmake_args = "-DCMAKE_Fortran_COMPILER={} ".format(arg_dict["SFC"]) - cmake_args += "-DCMAKE_C_COMPILER_WORKS=1 " - cmake_args += "-DCMAKE_CXX_COMPILER_WORKS=1 " - cmake_args += "-DCMAKE_BUILD_TYPE=Release " - cmake_args += "-DSKIP_DOC_GEN:BOOL=TRUE " - cmake_args += "-DCMAKE_INSTALL_PREFIX='{}' ".format(libroot) - cmake_args += srcpath - - _run_cmd("cmake {}".format(cmake_args), bldpath) - _run_cmd(case.get_value("GMAKE"), bldpath) - _run_cmd("{} install".format(case.get_value("GMAKE")), bldpath) - - # add json-fortran to include paths - incldir = os.environ.get('USER_INCLDIR') - if incldir is None: - incldir = '' - os.environ['USER_INCLDIR'] = incldir + \ - " -I{} ".format(_json_fortran_include_dir(libroot)) - - # create simlink to library in folder CIME expects libraries to be in - dst = os.path.join(libroot, "libjsonfortran.a") - if os.path.isfile(dst): - os.remove(dst) - os.symlink(_json_fortran_lib_path(libroot), dst) - -############################################################################### -def _json_fortran_include_dir(libroot): -############################################################################### -# Returns the path to the json-fortran include directory - - jsoninc = os.path.join(_json_fortran_install_dir(libroot), "lib", "") - expect(os.path.exists(jsoninc), \ - "JSON-Fortran include directory not found at {}".format(jsoninc)) - return jsoninc - -############################################################################### -def _json_fortran_lib_path(libroot): -############################################################################### -# Returns the path to the json-fortran library - - jsonlib = os.path.join(_json_fortran_install_dir(libroot), "lib", "libjsonfortran.a") - expect(os.path.exists(jsonlib), \ - "JSON-Fortran library not found at {}".format(jsonlib)) - return jsonlib - -############################################################################### -def _json_fortran_install_dir(libroot): -############################################################################### -# Returns the path to the json-fortran install directory - - jsonpaths = glob(os.path.join(libroot, "jsonfortran*")) - expect(len(jsonpaths)>0, \ - "JSON-Fortran not found at {}".format(libroot)) - expect(len(jsonpaths)<2, \ - "Multiple JSON-Fortran versions found at {}".format(libroot)) - expect(os.path.exists(jsonpaths[0]), \ - "JSON-Fortran install directory not found at {}".format(jsonpaths[0])) - return jsonpaths[0] - -############################################################################### -def _build_musica(caseroot, libroot, bldroot): -############################################################################### -# Builds the musica library, including TUV-x, musica, and MICM -# and updates the case variables used to set the include paths -# and linked libraries +# Builds the TUV-x library and updates the case variables used to set the +# include paths and linked libraries build = EnvBuild(case_root=caseroot) with Case(caseroot) as case: - bldpath = os.path.join(bldroot, "musica") + bldpath = os.path.join(bldroot, "tuv-x") if not os.path.exists(bldpath): os.makedirs(bldpath) - jsoninc = _json_fortran_include_dir(libroot) - jsonlib = _json_fortran_lib_path(libroot) srcpath = os.path.abspath(os.path.join(case.get_value("COMP_ROOT_DIR_ATM"), \ - "libraries", "musica", "")) - logger.info("Building musica in {} from source in {}\n".format(bldpath, srcpath)) + "libraries", "tuv-x", "")) + logger.info("Building TUV-x in {} from source in {}\n".format(bldpath, srcpath)) arg_dict = _cmake_default_args(caseroot) if build.get_value("MPILIB") == "mpi-serial": @@ -255,12 +178,8 @@ def _build_musica(caseroot, libroot, bldroot): cmake_args += "-DENABLE_UTIL_ONLY=ON " cmake_args += "-DCMAKE_C_COMPILER_WORKS=1 " cmake_args += "-DCMAKE_CXX_COMPILER_WORKS=1 " - cmake_args += "-DENABLE_MICM=OFF " - cmake_args += "-DENABLE_TUVX=ON " cmake_args += "-DENABLE_TESTS=OFF " cmake_args += "-DENABLE_COVERAGE=OFF " - cmake_args += "-DJSON_INCLUDE_DIR={} ".format(jsoninc) - cmake_args += "-DJSON_LIB={} ".format(jsonlib) cmake_args += "-DCMAKE_Fortran_FLAGS='{}' ".format(arg_dict["FFLAGS"]) cmake_args += "-DCMAKE_INSTALL_PREFIX='{}' ".format(libroot) cmake_args += srcpath @@ -269,67 +188,67 @@ def _build_musica(caseroot, libroot, bldroot): _run_cmd(case.get_value("GMAKE"), bldpath) _run_cmd("{} install".format(case.get_value("GMAKE")), bldpath) - # add musica to include paths + # add TUV-x to include paths incldir = os.environ.get('USER_INCLDIR') if incldir is None: incldir = '' os.environ['USER_INCLDIR'] = incldir + \ - " -I{} ".format(_musica_include_dir(libroot)) + " -I{} ".format(_tuvx_include_dir(libroot)) # create simlink to library in folder CIME expects libraries to be in - dst = os.path.join(libroot, "libmusica.a") + dst = os.path.join(libroot, "libtuvx.a") if os.path.isfile(dst): os.remove(dst) - os.symlink(_musica_lib_path(libroot), dst) + os.symlink(_tuvx_lib_path(libroot), dst) ############################################################################### -def _musica_include_dir(libroot): +def _tuvx_include_dir(libroot): ############################################################################### -# Returns the path to the musica include directory +# Returns the path to the TUV-x include directory - coreinc = os.path.join(_musica_install_dir(libroot), "include", "") + coreinc = os.path.join(_tuvx_install_dir(libroot), "include", "") expect(os.path.exists(coreinc), \ - "musica include directory not found at {}".format(coreinc)) + "TUV-x include directory not found at {}".format(coreinc)) return coreinc ############################################################################### -def _musica_lib_path(libroot): +def _tuvx_lib_path(libroot): ############################################################################### -# Returns the path to the musica library +# Returns the path to the TUV-x library - corelib = os.path.join(_musica_install_dir(libroot), "lib64", "libmusica.a") + corelib = os.path.join(_tuvx_install_dir(libroot), "lib64", "libtuvx.a") if not os.path.exists(corelib): - corelib = os.path.join(_musica_install_dir(libroot), "lib", "libmusica.a") + corelib = os.path.join(_tuvx_install_dir(libroot), "lib", "libtuvx.a") expect(os.path.exists(corelib), \ - "musica library not found at {}".format(corelib)) + "TUV-x library not found at {}".format(corelib)) return corelib ############################################################################### -def _musica_install_dir(libroot): +def _tuvx_install_dir(libroot): ############################################################################### -# Returns the path to the musica install directory +# Returns the path to the TUV-x install directory - corepaths = glob(os.path.join(libroot, "musica*")) + corepaths = glob(os.path.join(libroot, "tuvx*")) expect(len(corepaths)>0, \ - "musica not found at {}".format(libroot)) + "TUV-x not found at {}".format(libroot)) expect(len(corepaths)<2, \ - "Multiple musica versions found at {}".format(libroot)) + "Multiple TUV-x versions found at {}".format(libroot)) expect(os.path.exists(corepaths[0]), \ - "musica install directory not found at {}".format(corepaths[0])) + "TUV-x install directory not found at {}".format(corepaths[0])) return corepaths[0] ############################################################################### -def _musica_package_dir(libroot): +def _tuvx_package_dir(libroot): ############################################################################### -# Returns the path to the musica CMake package +# Returns the path to the TUV-x CMake package - paths = glob(os.path.join(libroot, "musica*", "cmake", "musica*" )) + paths = glob(os.path.join(libroot, "tuvx*", "cmake", "tuvx*" )) expect(len(paths)>0, \ - "musica package not found at {}".format(libroot)) + "TUV-x package not found at {}".format(libroot)) expect(len(paths)<2, \ - "Multiple musica versions found at {}".format(libroot)) + "Multiple TUV-x versions found at {}".format(libroot)) expect(os.path.exists(paths[0]), \ - "musica package directory not found at {}".format(paths[0])) + "TUV-x package directory not found at {}".format(paths[0])) return paths[0] ############################################################################### @@ -337,8 +256,7 @@ def _musica_package_dir(libroot): def _main_func(): caseroot, libroot, bldroot = parse_input(sys.argv) - _build_json_fortran(caseroot, libroot, bldroot) - _build_musica(caseroot, libroot, bldroot) + _build_tuvx(caseroot, libroot, bldroot) _build_cam(caseroot, libroot, bldroot) diff --git a/cime_config/buildnml b/cime_config/buildnml index 0e66d457e5..bebcd94426 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -215,8 +215,8 @@ def buildnml(case, caseroot, compname): dest_data = os.path.join(rundir, "data") if os.path.exists(dest_data): shutil.rmtree(dest_data) - shutil.copytree(os.path.join(srcroot, "libraries", "musica", "lib", \ - "tuv-x", "data"), dest_data) + shutil.copytree(os.path.join(srcroot, "libraries", "tuv-x", "data"), \ + dest_data) shutil.copy2(os.path.join(srcroot, "cime_config", "tuvx_MOZART.json"), \ os.path.join(rundir, "tuvx_MOZART.json")) shutil.copy2(os.path.join(srcroot, "cime_config", "tuvx_MOZART_TS1.json"), \ diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 1d0cf001ab..80d39d7510 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -206,7 +206,7 @@ char - -lmusica -ljsonfortran + -ltuvx build_component_cam env_build.xml diff --git a/cime_config/tuvx_MOZART_TS1.json b/cime_config/tuvx_MOZART_TS1.json index 5a37185017..7ece4f5ecf 100644 --- a/cime_config/tuvx_MOZART_TS1.json +++ b/cime_config/tuvx_MOZART_TS1.json @@ -99,6 +99,7 @@ "name": "jo2_b", "__reaction": "O2 + hv -> O + O", "cross section": { + "apply O2 bands": true, "netcdf files": [ { "file path": "data/cross_sections/O2_1.nc", @@ -185,31 +186,121 @@ "name": "jn2o5_a", "__reaction": "N2O5 + hv -> NO2 + NO3", "cross section": { - "netcdf files": [ - { "file path": "data/cross_sections/N2O5_1.nc" }, - { "file path": "data/cross_sections/N2O5_2.nc" } - ], - "type": "N2O5+hv->NO2+NO3" - }, - "quantum yield": { - "type": "base", - "netcdf files": [ "data/quantum_yields/N2O5_NO3_NO2.nc" ] - } + "type":"temperature based", + "netcdf file": "data/cross_sections/N2O5_JPL06.nc", + "parameterization": { + "type": "HARWOOD", + "aa": [ -18.27, -18.42, -18.59, -18.72, -18.84, + -18.90, -18.93, -18.87, -18.77, -18.71, + -18.31, -18.14, -18.01, -18.42, -18.59, + -18.13 ], + "bb": [ -91.0, -104.0, -112.0, -135.0, -170.0, + -226.0, -294.0, -388.0, -492.0, -583.0, + -770.0, -885.0, -992.0, -949.0, -966.0, + -1160.0 ], + "base temperature": 0.0, + "base wavelength": 0.0, + "logarithm": "base 10", + "minimum wavelength": 260.0, + "maximum wavelength": 410.0, + "temperature ranges": [ + { + "maximum": 199.999999999999, + "fixed value": 200 + }, + { + "minimum": 200, + "maximum": 295 + }, + { + "minimum": 295.00000000001, + "fixed value": 295.0 + } + ] + }, + "parameterization wavelength grid": { + "name": "custom wavelengths", + "type": "from config file", + "units": "nm", + "values": [ + 255.0, 265.0, 275.0, 285.0, 295.0, 305.0, + 315.0, 325.0, 335.0, 345.0, 355.0, 365.0, + 375.0, 385.0, 395.0, 405.0, 415.0 + ] + } + }, + "quantum yield": { + "type": "Taylor series", + "constant value": 0.0, + "coefficients": [ -2.832441, 0.012809638 ], + "override bands": [ + { + "band": "range", + "minimum wavelength": 300.0, + "value": 1.0 + } + ] + } }, { "name": "jn2o5_b", "__reaction": "N2O5 + hv -> NO + O + NO3", "cross section": { - "netcdf files": [ - { "file path": "data/cross_sections/N2O5_1.nc" }, - { "file path": "data/cross_sections/N2O5_2.nc" } - ], - "type": "N2O5+hv->NO2+NO3" - }, - "quantum yield": { - "type": "base", - "netcdf files": [ "data/quantum_yields/N2O5_NO3_NO_O.nc" ] - } + "type":"temperature based", + "netcdf file": "data/cross_sections/N2O5_JPL06.nc", + "parameterization": { + "type": "HARWOOD", + "aa": [ -18.27, -18.42, -18.59, -18.72, -18.84, + -18.90, -18.93, -18.87, -18.77, -18.71, + -18.31, -18.14, -18.01, -18.42, -18.59, + -18.13 ], + "bb": [ -91.0, -104.0, -112.0, -135.0, -170.0, + -226.0, -294.0, -388.0, -492.0, -583.0, + -770.0, -885.0, -992.0, -949.0, -966.0, + -1160.0 ], + "base temperature": 0.0, + "base wavelength": 0.0, + "logarithm": "base 10", + "minimum wavelength": 260.0, + "maximum wavelength": 410.0, + "temperature ranges": [ + { + "maximum": 199.999999999999, + "fixed value": 200 + }, + { + "minimum": 200, + "maximum": 295 + }, + { + "minimum": 295.00000000001, + "fixed value": 295.0 + } + ] + }, + "parameterization wavelength grid": { + "name": "custom wavelengths", + "type": "from config file", + "units": "nm", + "values": [ + 255.0, 265.0, 275.0, 285.0, 295.0, 305.0, + 315.0, 325.0, 335.0, 345.0, 355.0, 365.0, + 375.0, 385.0, 395.0, 405.0, 415.0 + ] + } + }, + "quantum yield": { + "type": "Taylor series", + "constant value": 0.0, + "coefficients": [ 3.832441, -0.012809638 ], + "override bands": [ + { + "band": "range", + "minimum wavelength": 300.0, + "value": 0.0 + } + ] + } }, { "name": "jhno3", @@ -375,35 +466,34 @@ "__reaction": "CH3COCH3 + hv -> CH3CO + CH3", "cross section": { "type": "temperature based", - "netcdf file": "data/cross_sections/CH3CL_JPL06.nc", "parameterization": { - "AA": [ -299.80, 5.1047, -3.3630e-2, 9.5805e-5, -1.0135e-7 ], - "BB": [ -7.1727, 1.4837e-1, -1.1463e-3, 3.9188e-6, -4.9994e-9 ], - "lp": [ 0.0, 1.0, 2.0, 3.0, 4.0 ], - "minimum wavelength": 174.1, - "maximum wavelength": 216.0, - "base temperature": 273.0, - "base wavelength": 0.0, - "logarithm": "base 10", + "type": "TAYLOR_SERIES", + "netcdf file": { + "file path": "data/cross_sections/ACETONE_JPL06.nc" + }, + "base temperature": 0.0, "temperature ranges": [ { - "maximum": 209.999999999999, - "fixed value": 210.0 + "maximum": 234.999999999999, + "fixed value": 235.0 }, { - "minimum": 210, - "maximum": 300 + "minimum": 235.0, + "maximum": 298.0 }, { - "minimum": 300.00000000001, - "fixed value": 300.0 + "minimum": 298.00000000001, + "fixed value": 298.0 } ] } }, "quantum yield": { - "type": "base", - "constant value": 1.0 + "type": "CH3COCH3+hv->CH3CO+CH3", + "branch": "CO+CH3CO", + "low wavelength value": 1, + "minimum temperature": 218, + "maximum temperature": 295 } }, { @@ -433,7 +523,7 @@ "constant value": 0.5 } }, - { +{ "name": "jglyoxal", "__reaction": "GLYOXAL + hv -> 2*CO + 2*HO2", "__comments": "TODO the products of this reaction don't exactly match", @@ -859,15 +949,37 @@ "name": "jch3cl", "__reaction": "CH3Cl + hv -> Products", "cross section": { - "netcdf files": [ - { "file path": "data/cross_sections/CH3Cl_1.nc" } - ], - "type": "tint" - }, - "quantum yield": { + "type": "temperature based", + "netcdf file": "data/cross_sections/CH3CL_JPL06.nc", + "parameterization": { + "AA": [ -299.80, 5.1047, -3.3630e-2, 9.5805e-5, -1.0135e-7 ], + "BB": [ -7.1727, 1.4837e-1, -1.1463e-3, 3.9188e-6, -4.9994e-9 ], + "lp": [ 0.0, 1.0, 2.0, 3.0, 4.0 ], + "minimum wavelength": 174.1, + "maximum wavelength": 216.0, + "base temperature": 273.0, + "base wavelength": 0.0, + "logarithm": "base 10", + "temperature ranges": [ + { + "maximum": 209.999999999999, + "fixed value": 210.0 + }, + { + "minimum": 210, + "maximum": 300 + }, + { + "minimum": 300.00000000001, + "fixed value": 300.0 + } + ] + } + }, + "quantum yield": { "type": "base", "constant value": 1.0 - } + } }, { "name": "jchbr3", @@ -1607,6 +1719,8 @@ ] }, "__CAM options": { + "disable clouds": true, + "disable aerosols": true, "aliasing": { "default matching": "backup", "pairs": [