Skip to content

Commit

Permalink
Update NUOPC Cap and CMake build (#546)
Browse files Browse the repository at this point in the history
1. add WRF_HYDRO_NUOPC build option to CMake
2. build wrfhydro_nuopc library
3. fix NUOPC gluecode init
  • Loading branch information
danrosen25 authored and rscabell committed Apr 22, 2021
1 parent 7cf193b commit df784c8
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 12 deletions.
14 changes: 14 additions & 0 deletions trunk/NDHMS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ set (NWM_META $ENV{NWM_META} CACHE STRING "NWM output metadata 0=off 1=on")
set (WRF_HYDRO_NUDGING $ENV{WRF_HYDRO_NUDGING} CACHE STRING "Streamflow nudging 0=off 1=on")
set (OUTPUT_CHAN_CONN $ENV{OUTPUT_CHAN_CONN} CACHE STRING "Output channel connections")
set (PRECIP_DOUBLE $ENV{PRECIP_DOUBLE} CACHE STRING "Precipitation as double")
set (WRF_HYDRO_NUOPC $ENV{WRF_HYDRO_NUOPC} CACHE STRING "NUOPC library 0=off 1=on")

#set default values for env variables
if (WRF_HYDRO STREQUAL "")
Expand Down Expand Up @@ -110,6 +111,9 @@ if (PRECIP_DOUBLE STREQUAL "")
set (PRECIP_DOUBLE "0" CACHE STRING "Precipitation as double" FORCE)
endif (PRECIP_DOUBLE STREQUAL "")

if (WRF_HYDRO_NUOPC STREQUAL "")
set (WRF_HYDRO_NUOPC "0" CACHE STRING "NUOPC library 0=off, 1=on" FORCE)
endif (WRF_HYDRO_NUOPC STREQUAL "")

# add preprocessor defines using env variables

Expand Down Expand Up @@ -179,6 +183,12 @@ if (PRECIP_DOUBLE STREQUAL "1" )
add_definitions(-DPRECIP_DOUBLE)
endif (PRECIP_DOUBLE STREQUAL "1")

#set -DWRF_HYDRO_NUOPC from env
message ("WRF_HYDRO_NUOPC = " ${WRF_HYDRO_NUOPC} )
if (WRF_HYDRO_NUOPC STREQUAL "1" )
add_definitions(-DWRF_HYDRO_NUOPC)
endif (WRF_HYDRO_NUOPC STREQUAL "1")

message("=============================================================")

#set compile flags based on compiler id
Expand Down Expand Up @@ -230,6 +240,10 @@ if (WRF_HYDRO_NUDGING STREQUAL "1")
add_dependencies(hydro_driver hydro_nudging)
endif (WRF_HYDRO_NUDGING STREQUAL "1")

if (WRF_HYDRO_NUOPC STREQUAL "1")
add_subdirectory("CPL/NUOPC_cpl")
endif (WRF_HYDRO_NUOPC STREQUAL "1")

# add module dependencies
add_dependencies(hydro_debug_utils hydro_mpp)
add_dependencies(hydro_utils hydro_mpp)
Expand Down
64 changes: 64 additions & 0 deletions trunk/NDHMS/CPL/NUOPC_cpl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
cmake_minimum_required (VERSION 2.8)

### Library Prerequisites
if (NOT TARGET esmf)
find_package(ESMF MODULE REQUIRED)
endif (NOT TARGET esmf)

### Library Files
list(APPEND wrfhydro_nuopc_files
WRFHydro_NUOPC_Cap.F90
WRFHydro_NUOPC_Gluecode.F90
WRFHydro_ESMF_Extensions.F90
)

### Library Dependencies
list(APPEND wrfhydro_nuopc_deps
hydro_routing
hydro_mpp
hydro_driver
hydro_orchestrator
)

list(APPEND wrfhydro_nuopc_linklibs
hydro_utils
hydro_mpp
hydro_debug_utils
hydro_routing_overland
hydro_routing_subsurface
hydro_data_rec
hydro_routing
hydro_routing_reservoirs_levelpool
hydro_routing_reservoirs_hybrid
hydro_routing_reservoirs_rfc
hydro_routing_reservoirs
hydro_driver
hydro_orchestrator
hydro_netcdf_layer
)
if (WRF_HYDRO_NUDGING STREQUAL "1")
list(APPEND wrfhydro_nuopc_linklibs
hydro_nudging
)
endif (WRF_HYDRO_NUDGING STREQUAL "1")


### New Library: wrfhydro_nuopc
add_library(wrfhydro_nuopc STATIC ${wrfhydro_nuopc_files})
add_dependencies(wrfhydro_nuopc ${wrfhydro_nuopc_deps})
target_link_libraries(wrfhydro_nuopc PUBLIC ${wrfhydro_nuopc_linklibs})
target_link_libraries(wrfhydro_nuopc PUBLIC esmf)
target_link_libraries(wrfhydro_nuopc PUBLIC ${NETCDF_LIBRARIES})

### Library Installation
install(TARGETS wrfhydro_nuopc ${wrfhydro_nuopc_linklibs}
EXPORT wrfhydro-config
LIBRARY DESTINATION lib
)
install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}
DESTINATION ${CMAKE_INSTALL_PREFIX}/WRFHYDRO
)
install(EXPORT wrfhydro-config
DESTINATION lib/cmake
)

16 changes: 4 additions & 12 deletions trunk/NDHMS/CPL/NUOPC_cpl/WRFHydro_NUOPC_Gluecode.F90
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,7 @@ module wrfhydro_nuopc_gluecode
use config_base, only: &
nlst, &
init_namelist_rt_field
! use module_gw_gw2d_data, only: &
! gw2d
! use module_domain, only: &
! domain, &
! domain_clock_get
! use module_configure, only: &
! grid_config_rec_type
! use module_configure, only: &
! config_flags
! use module_configure, only: &
! model_config_rec
use orchestrator_base

implicit none

Expand Down Expand Up @@ -322,6 +312,8 @@ subroutine wrfhydro_nuopc_ini(did,vm,clock,forcingDir,rc)
call WRFHYDRO_TimeToString(startTime,timestr=startTimeStr,rc=rc)
if(ESMF_STDERRORCHECK(rc)) return ! bail out

call orchestrator%init()

! Set default namelist values
read (startTimeStr(1:4),"(I)") nlst(did)%START_YEAR
read (startTimeStr(6:7),"(I)") nlst(did)%START_MONTH
Expand Down Expand Up @@ -366,9 +358,9 @@ subroutine wrfhydro_nuopc_ini(did,vm,clock,forcingDir,rc)
return ! bail out
endif

call MPP_LAND_INIT() ! required before get_file_dimension
call get_file_dimension(fileName=nlst(did)%geo_static_flnm,&
ix=nx_global(1),jx=ny_global(1))
call MPP_LAND_INIT(nx_global(1),ny_global(1))

#ifdef DEBUG
write (logMsg,"(A,2(I0,A))") MODNAME//": Global Dimensions = (", &
Expand Down
2 changes: 2 additions & 0 deletions trunk/NDHMS/HYDRO_drv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ add_library(hydro_driver STATIC

target_link_libraries(hydro_driver PUBLIC hydro_mpp)
target_link_libraries(hydro_driver PUBLIC hydro_data_rec)
target_link_libraries(hydro_driver PUBLIC hydro_routing)
target_link_libraries(hydro_driver PUBLIC hydro_debug_utils)

if (WRF_HYDRO_NUDGING STREQUAL "1")
target_link_libraries(hydro_driver PUBLIC hydro_nudging)
Expand Down
105 changes: 105 additions & 0 deletions trunk/NDHMS/cmake-modules/FindESMF.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# - Try to find ESMF
#
# Requires setting ESMFMKFILE to the filepath of esmf.mk. If this is NOT set,
# then ESMF_FOUND will always be FALSE. If ESMFMKFILE exists, then ESMF_FOUND=TRUE
# and all ESMF makefile variables will be set in the global scope. Optionally,
# set ESMF_MKGLOBALS to a string list to filter makefile variables. For example,
# to globally scope only ESMF_LIBSDIR and ESMF_APPSDIR variables, use this CMake
# command in CMakeLists.txt:
#
# set(ESMF_MKGLOBALS "LIBSDIR" "APPSDIR")


# Add the ESMFMKFILE path to the cache if defined as system env variable
if (DEFINED ENV{ESMFMKFILE} AND NOT DEFINED ESMFMKFILE)
set(ESMFMKFILE $ENV{ESMFMKFILE} CACHE FILEPATH "Path to ESMF mk file")
endif ()

# Found the mk file and ESMF exists on the system
if (EXISTS ${ESMFMKFILE})
set(ESMF_FOUND TRUE CACHE BOOL "ESMF mk file found" FORCE)
# Did not find the ESMF mk file
else()
set(ESMF_FOUND FALSE CACHE BOOL "ESMF mk file NOT found" FORCE)
# Best to warn users that without the mk file there is no way to find ESMF
if (NOT DEFINED ESMFMKFILE)
message(FATAL_ERROR "ESMFMKFILE not defined. This is the path to esmf.mk file. \
Without this filepath, ESMF_FOUND will always be FALSE.")
endif ()
endif()

# Only parse the mk file if it is found
if (ESMF_FOUND)
# Read the mk file
file(STRINGS "${ESMFMKFILE}" esmfmkfile_contents)
# Parse each line in the mk file
foreach(str ${esmfmkfile_contents})
# Only consider uncommented lines
string(REGEX MATCH "^[^#]" def ${str})
# Line is not commented
if (def)
# Extract the variable name
string(REGEX MATCH "^[^=]+" esmf_varname ${str})
# Extract the variable's value
string(REGEX MATCH "=.+$" esmf_vardef ${str})
# Only for variables with a defined value
if (esmf_vardef)
# Get rid of the assignment string
string(SUBSTRING ${esmf_vardef} 1 -1 esmf_vardef)
# Remove whitespace
string(STRIP ${esmf_vardef} esmf_vardef)
# A string or single-valued list
if(NOT DEFINED ESMF_MKGLOBALS)
# Set in global scope
set(${esmf_varname} ${esmf_vardef})
# Don't display by default in GUI
mark_as_advanced(esmf_varname)
else() # Need to filter global promotion
foreach(m ${ESMF_MKGLOBALS})
string(FIND ${esmf_varname} ${m} match)
# Found the string
if(NOT ${match} EQUAL -1)
# Promote to global scope
set(${esmf_varname} ${esmf_vardef})
# Don't display by default in the GUI
mark_as_advanced (esmf_varname)
# No need to search for the current string filter
break()
endif()
endforeach()
endif()
endif()
endif()
endforeach()

separate_arguments(ESMF_F90COMPILEPATHS NATIVE_COMMAND ${ESMF_F90COMPILEPATHS})
foreach (ITEM ${ESMF_F90COMPILEPATHS})
string(REGEX REPLACE "^-I" "" ITEM "${ITEM}")
list(APPEND tmp ${ITEM})
endforeach()
set(ESMF_F90COMPILEPATHS ${tmp})

add_library(esmf UNKNOWN IMPORTED)
# Look for static library, if not found try dynamic library
find_library(esmf_lib NAMES libesmf.a PATHS ${ESMF_LIBSDIR})
if(esmf_lib MATCHES "esmf_lib-NOTFOUND")
message(STATUS "Static ESMF library not found, searching for dynamic library instead")
find_library(esmf_lib NAMES esmf_fullylinked PATHS ${ESMF_LIBSDIR})
if(esmf_lib MATCHES "esmf_lib-NOTFOUND")
message(FATAL_ERROR "Neither the dynamic nor the static ESMF library was found")
else()
message(STATUS "Found ESMF library: ${esmf_lib}")
endif()
set(ESMF_INTERFACE_LINK_LIBRARIES "")
else()
# When linking the static library, also need the ESMF linker flags; strip any leading/trailing whitespaces
string(STRIP "${ESMF_F90ESMFLINKRPATHS} ${ESMF_F90ESMFLINKPATHS} ${ESMF_F90LINKPATHS} ${ESMF_F90LINKLIBS} ${ESMF_F90LINKOPTS}" ESMF_INTERFACE_LINK_LIBRARIES)
message(STATUS "Found ESMF library: ${esmf_lib}")
endif()

set_target_properties(esmf PROPERTIES
IMPORTED_LOCATION ${esmf_lib}
INTERFACE_INCLUDE_DIRECTORIES "${ESMF_F90COMPILEPATHS}"
INTERFACE_LINK_LIBRARIES "${ESMF_INTERFACE_LINK_LIBRARIES}")

endif()

0 comments on commit df784c8

Please sign in to comment.