Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
buildnmlc
buildcppc

# Ignore ide configs
.vscode

# Ignore editor temporaries and backups
*~
.#*
Expand Down
7 changes: 7 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,10 @@ url = https://github.com/NCAR/CUPiD.git
fxtag = v0.4.0
fxrequired = ToplevelRequired
fxDONOTUSEurl = https://github.com/NCAR/CUPiD.git

[submodule "tuv-x"]
path = libraries/tuv-x
url = https://github.com/NCAR/tuv-x.git
fxtag = ecf768a2b66
fxrequired = ToplevelRequired
fxDONOTUSEurl = https://github.com/NCAR/tuv-x.git
11 changes: 11 additions & 0 deletions bld/namelist_files/namelist_definition.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7672,6 +7672,17 @@ Maximum zenith angle (degrees) used for photolysis.
Default: set by build-namelist.
</entry>

<entry id="tuvx_config_path" type="char*256" input_pathname="abs" category="chemistry"
group="tuvx_opts" valid_values="" >
Filepath of TUV-X configuration specification.
Default: NONE
</entry>

<entry id="tuvx_active" type="logical" category="chemistry"
group="tuvx_opts" valid_values="" >
Switch to turn on TUV-X photolysis.
Default: FALSE
</entry>

<!-- Namelist read by seq_drydep_mod and shared by CAM and CLM -->

Expand Down
157 changes: 154 additions & 3 deletions cime_config/buildlib
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ create the cam library
# pylint: disable=unused-wildcard-import, bad-whitespace, too-many-locals
# pylint: disable=invalid-name
import sys, os, filecmp, shutil

from glob import glob

_CIMEROOT = os.environ.get("CIMEROOT")
if _CIMEROOT is None:
Expand All @@ -22,12 +22,13 @@ from CIME.utils import run_sub_or_cmd, expect, run_cmd
from CIME.utils import import_from_file
from CIME.buildlib import parse_input
from CIME.build import get_standard_makefile_args
from CIME.XML.env_build import EnvBuild

logger = logging.getLogger(__name__)

###############################################################################
def _build_fms(caseroot, libroot, bldroot):
###############################################################################
###############################################################################

with Case(caseroot) as case:

Expand Down Expand Up @@ -71,7 +72,7 @@ def _build_fms(caseroot, libroot, bldroot):

###############################################################################
def _build_cam(caseroot, libroot, bldroot):
###############################################################################
###############################################################################

with Case(caseroot, read_only=False) as case:

Expand Down Expand Up @@ -157,12 +158,162 @@ def _build_cam(caseroot, libroot, bldroot):
logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n", cmd, out, err)
expect(rc == 0, "Command %s failed with rc=%s" % (cmd, rc))

###############################################################################
def _run_cmd(command, working_dir):
###############################################################################

rc, out, err = run_cmd(command, from_dir=working_dir, verbose=True)
expect(rc == 0, f"Command {command} failed with rc={rc} out={out} err={err}")

###############################################################################
def _cmake_default_args(caseroot):
###############################################################################
# Returns a dictionary of CMake variables based on the Macros.cmake file for
# the build.

build = EnvBuild(case_root=caseroot)
with Case(caseroot) as case:
macro_path = os.path.abspath(os.path.join(caseroot, "cmake_macros", ""))
args = "-DCONVERT_TO_MAKE=ON "
args += f"-DCASEROOT={caseroot} "
args += f"-DCOMPILER={build.get_value('COMPILER')} "
args += f"-DOS={build.get_value('OS')} "
args += f"-DMACH={case.get_value('MACH')} "
args += "-DCMAKE_C_COMPILER_WORKS=1 "
args += "-DCMAKE_Fortran_COMPILER_WORKS=1 "
args += "-DCMAKE_CXX_COMPILER_WORKS=1 "
args += f"-DDEBUG={build.get_value('DEBUG')} "
cmd = f"cmake {args} ."
rc, out, err = run_cmd(cmd, combine_output=True, from_dir=macro_path)
expect(rc == 0, f"Command {cmd} failed with rc={rc} out={out} err={err}")

arg_dict = {}
for line in out.splitlines():
if ":=" in line:
key, val = line.split(":=")
arg_dict[key.replace('CIME_SET_MAKEFILE_VAR','').strip()] = val.strip()

return arg_dict

###############################################################################
def _build_tuvx(caseroot, libroot, bldroot):
###############################################################################
# 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, "tuv-x")
if not os.path.exists(bldpath):
os.makedirs(bldpath)
srcpath = os.path.abspath(os.path.join(case.get_value("COMP_ROOT_DIR_ATM"), \
"libraries", "tuv-x", ""))
logger.info("Building TUV-x in {} from source in {}\n".format(bldpath, srcpath))

arg_dict = _cmake_default_args(caseroot)
cmake_args = "-DCMAKE_VERBOSE_MAKEFILE=ON "
if build.get_value("MPILIB") != "mpi-serial":
cmake_args += "-DTUVX_ENABLE_MPI:BOOL=TRUE "
if case.get_value("DEBUG"):
cmake_args += "-DCMAKE_BUILD_TYPE=Debug "
else:
cmake_args += "-DCMAKE_BUILD_TYPE=Release "
cmake_args += "-DCMAKE_Fortran_COMPILER=mpif90 "
cmake_args += "-DCMAKE_C_COMPILER=mpicc "
cmake_args += "-DCMAKE_CXX_COMPILER=mpicxx "
cmake_args += "-DCMAKE_Fortran_COMPILER_WORKS=1 "
cmake_args += "-DCMAKE_C_COMPILER_WORKS=1 "
cmake_args += "-DCMAKE_CXX_COMPILER_WORKS=1 "
if (case.get_value("MACH") == "izumi") :
cmake_args += f"-DCMAKE_PREFIX_PATH={arg_dict['NETCDF_PATH']} "
cmake_args += f"-DCMAKE_IGNORE_PATH={os.environ.get('PYTHONHOME')} "
if (case.get_value("MACH") == "izumi") and (case.get_value('COMPILER') == "nag") :
cmake_args += "-DCMAKE_Fortran_FLAGS='-C=all -g ' "
else :
cmake_args += f"-DCMAKE_Fortran_FLAGS='{arg_dict['FFLAGS']}' "
cmake_args += f"-DCMAKE_INSTALL_PREFIX='{libroot}' "
cmake_args += "-DTUVX_ENABLE_TESTS=OFF "
cmake_args += "-DTUVX_ENABLE_COVERAGE=OFF "
cmake_args += "-DTUVX_BUILD_CLI=OFF "
cmake_args += f"-DTUVX_INSTALL_INCLUDE_DIR='{_tuvx_include_dir(libroot)}' "
cmake_args += f"-DTUVX_INSTALL_MOD_DIR='{_tuvx_include_dir(libroot)}' "
cmake_args += srcpath

_run_cmd(f"cmake {cmake_args}", bldpath)
_run_cmd(case.get_value('GMAKE'), bldpath)
_run_cmd(f"{case.get_value('GMAKE')} install", bldpath)

# add TUV-x to include paths
incldir = os.environ.get('USER_INCLDIR')
if incldir is None:
incldir = ''
os.environ['USER_INCLDIR'] = incldir + \
f" -I{_tuvx_include_dir(libroot)} "

# create symlink to library in folder CIME expects libraries to be in
dst = os.path.join(libroot, "libtuvx.a")
if os.path.isfile(dst):
os.remove(dst)
os.symlink(_tuvx_lib_path(libroot), dst)
dst = os.path.join(libroot, "libyaml-cpp.a")
if os.path.isfile(dst):
os.remove(dst)
os.symlink(_yaml_cpp_lib_path(libroot), dst)

###############################################################################
def _tuvx_include_dir(libroot):
###############################################################################
# Returns the path to the TUV-x include directory

coreinc = os.path.join(libroot, "include")
expect(os.path.exists(coreinc), f"TUV-x include directory not found at {coreinc}")

return coreinc

###############################################################################
def _yaml_cpp_lib_path(libroot):
###############################################################################
# Returns the path to the yaml-cpp library

corelib = os.path.join(libroot, "lib64", "libyaml-cpp.a")
if not os.path.exists(corelib):
corelib = os.path.join(libroot, "lib64", "libyaml-cppd.a")
if not os.path.exists(corelib):
corelib = os.path.join(libroot, "lib", "libyaml-cpp.a")
expect(os.path.exists(corelib), f"yaml-cpp library not found at {corelib}")

return corelib

###############################################################################
def _tuvx_lib_path(libroot):
###############################################################################
# Returns the path to the TUV-x library

corelib = os.path.join(_tuvx_install_dir(libroot), "lib64", "libtuvx.a")
if not os.path.exists(corelib):
corelib = os.path.join(_tuvx_install_dir(libroot), "lib", "libtuvx.a")
expect(os.path.exists(corelib), f"TUV-x library not found at {corelib}")

return corelib

###############################################################################
def _tuvx_install_dir(libroot):
###############################################################################
# Returns the path to the TUV-x install directory

corepaths = glob(os.path.join(libroot, "tuvx*"))
expect(len(corepaths)>0, f"TUV-x not found at {libroot}")
expect(len(corepaths)<2, f"Multiple TUV-x versions found at {libroot}")
expect(os.path.exists(corepaths[0]), f"TUV-x install directory not found at {corepaths[0]}")

return corepaths[0]

###############################################################################


def _main_func():
caseroot, libroot, bldroot = parse_input(sys.argv)
_build_tuvx(caseroot, libroot, bldroot)
_build_fms(caseroot, libroot, bldroot)
_build_cam(caseroot, libroot, bldroot)

Expand Down
7 changes: 7 additions & 0 deletions cime_config/buildnml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ def buildnml(case, caseroot, compname):
logger.info("GEOS-Chem config file copy: file1 %s file2 %s ", file1, file2)
shutil.copy(file1,file2)

# Copy TUV-x data to rundir
dest_data = os.path.join(rundir, "data")
if os.path.exists(dest_data):
shutil.rmtree(dest_data)
shutil.copytree(os.path.join(srcroot, "libraries", "tuv-x", "data"), \
dest_data)

###############################################################################
def _main_func():

Expand Down
12 changes: 12 additions & 0 deletions cime_config/config_component.xml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,18 @@
</desc>
</entry>

<entry id="CAM_LINKED_LIBS">
<type>char</type>
<valid_values></valid_values>
<default_value>-ltuvx -lyaml-cpp -lstdc++</default_value>
<group>build_component_cam</group>
<file>env_build.xml</file>
<desc>
CAM linked libraries. The libraries are built by CAM's buildlib script and should be included
during linking of the model executable.
</desc>
</entry>

<entry id="CAM_NML_USE_CASE">
<type>char</type>
<valid_values></valid_values>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mfilt=1,1,1,1,1,1
ndens=1,1,1,1,1,1
nhtfrq=3,3,3,3,3,3
mfilt=1,1,1,1,1,1,1,1,1,1
ndens=1,1,1,1,1,1,1,1,1,1
nhtfrq=3,3,3,3,3,3,3,3,3,3
inithist='ENDOFRUN'
pbuf_global_allocate=.false.
history_carma=.true.
Expand All @@ -11,3 +11,5 @@ solar_data_type='FIXED'
solar_data_ymd=20000101
carma_maxretries = 40
ubc_specifier = 'T->MSIS', 'Q->2.d-8vmr', 'CH4->2.d-10vmr', 'H->MSIS', 'N->MSIS', 'O->MSIS', 'O2->MSIS', 'H2->TGCM', 'NO->SNOE'
tuvx_active = .true.
tuvx_config_path = '$COMPCOMP_ROOT_DIR_ATM/src/chemistry/pp_waccm_ma_sulfur/tuvx_config.json'
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
./xmlchange ROF_NCPL=\$ATM_NCPL
./xmlchange GLC_NCPL=\$ATM_NCPL
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
mfilt=1,1,1,1,1,1,1,1,1
ndens=1,1,1,1,1,1,1,1,1
nhtfrq=9,9,9,9,9,9,9,9,9
write_nstep0=.true.
inithist='ENDOFRUN'

tuvx_active = .true.
tuvx_config_path = '$COMP_ROOT_DIR_ATM/src/chemistry/pp_waccm_ma_mam5/tuvx_config.json'

fincl2 = 'TUVX_DOSE_RATE_01','TUVX_DOSE_RATE_02','TUVX_DOSE_RATE_03','TUVX_DOSE_RATE_04','TUVX_DOSE_RATE_05',
'TUVX_DOSE_RATE_06','TUVX_DOSE_RATE_07','TUVX_DOSE_RATE_08','TUVX_DOSE_RATE_09','TUVX_DOSE_RATE_10',
'TUVX_DOSE_RATE_11','TUVX_DOSE_RATE_12','TUVX_DOSE_RATE_13','TUVX_DOSE_RATE_14','TUVX_DOSE_RATE_15',
'TUVX_DOSE_RATE_16','TUVX_DOSE_RATE_17','TUVX_DOSE_RATE_18','TUVX_DOSE_RATE_19','TUVX_DOSE_RATE_20',
'TUVX_DOSE_RATE_21','TUVX_DOSE_RATE_22','TUVX_DOSE_RATE_23','TUVX_DOSE_RATE_24',
'TUVX_DOSE_RATE_25','TUVX_DOSE_RATE_26','TUVX_DOSE_RATE_27','TUVX_DOSE_RATE_28'
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
!----------------------------------------------------------------------------------
! Users should add all user specific namelist changes below in the form of
! namelist_var = new_namelist_value
!
! Include namelist variables for drv_flds_in ONLY if -megan and/or -drydep options
! are set in the CLM_NAMELIST_OPTS env variable.
!
! EXCEPTIONS:
! Set use_cndv by the compset you use and the CLM_BLDNML_OPTS -dynamic_vegetation setting
! Set use_vichydro by the compset you use and the CLM_BLDNML_OPTS -vichydro setting
! Set use_cn by the compset you use and CLM_BLDNML_OPTS -bgc setting
! Set use_crop by the compset you use and CLM_BLDNML_OPTS -crop setting
! Set spinup_state by the CLM_BLDNML_OPTS -bgc_spinup setting
! Set irrigate by the CLM_BLDNML_OPTS -irrig setting
! Set dtime with L_NCPL option
! Set fatmlndfrc with LND_DOMAIN_PATH/LND_DOMAIN_FILE options
! Set finidat with RUN_REFCASE/RUN_REFDATE/RUN_REFTOD options for hybrid or branch cases
! (includes $inst_string for multi-ensemble cases)
! Set glc_grid with CISM_GRID option
! Set glc_smb with GLC_SMB option
! Set maxpatch_glcmec with GLC_NEC option
! Set glc_do_dynglacier with GLC_TWO_WAY_COUPLING env variable
!----------------------------------------------------------------------------------
hist_nhtfrq = 9
hist_mfilt = 1
hist_ndens = 1

Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ inithist='ENDOFRUN'
nlte_use_extco2 = .true.
fincl2 = 'QRL_TOT','QRLNLTE','QCO2','QO3','QHC2S','QNO','QO3P',
'QCO2ext','TCO2ext','PCO2ext','CO2_ext','N2_ext','O_ext','O2_ext'

tuvx_active = .true.
tuvx_config_path = '$COMP_ROOT_DIR_ATM/src/chemistry/pp_waccm_ma_mam5/tuvx_config.json'
Loading