Skip to content

Commit

Permalink
Properly take into account the effect of the WW3 switches in the list…
Browse files Browse the repository at this point in the history
… of source files. Update the list of swiches.
  • Loading branch information
micaeljtoliveira committed Oct 11, 2023
1 parent 04586b5 commit 0069205
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 56 deletions.
63 changes: 20 additions & 43 deletions WW3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,59 +1,36 @@
# Switch definitions (taken from CESM)
add_compile_definitions(W3_CESMCOUPLED)
add_compile_definitions(W3_NCO)
add_compile_definitions(W3_DIST)
add_compile_definitions(W3_MPI)
add_compile_definitions(W3_PR3)
add_compile_definitions(W3_UQ)
add_compile_definitions(W3_FLX0)
add_compile_definitions(W3_SEED)
add_compile_definitions(W3_ST4)
add_compile_definitions(W3_STAB0)
add_compile_definitions(W3_NL1)
add_compile_definitions(W3_BT1)
add_compile_definitions(W3_DB1)
add_compile_definitions(W3_MLIM)
add_compile_definitions(W3_FLD2)
add_compile_definitions(W3_TR0)
add_compile_definitions(W3_BS0)
add_compile_definitions(W3_RWND)
add_compile_definitions(W3_WNX1)
add_compile_definitions(W3_WNT1)
add_compile_definitions(W3_CRX1)
add_compile_definitions(W3_CRT1)
add_compile_definitions(W3_O0)
add_compile_definitions(W3_O1)
add_compile_definitions(W3_O2)
add_compile_definitions(W3_O3)
add_compile_definitions(W3_O4)
add_compile_definitions(W3_O5)
add_compile_definitions(W3_O6)
add_compile_definitions(W3_O7)
add_compile_definitions(W3_O14)
add_compile_definitions(W3_O15)
add_compile_definitions(W3_IS0)
add_compile_definitions(W3_REF0)
add_compile_definitions(W3_NOGRB)
add_compile_definitions(W3_IC0)
# Commom source files. Too many files to list, so include them via this file
include("ww3_files.cmake")

# List of switches
list(APPEND switches "CESMCOUPLED" "NCO" "DIST" "MPI" "PR3" "UQ" "FLX4" "SEED" "ST6" "STAB0" "NL1" "BT1" "DB1" "MLIM" "TR0" "BS0" "RWND" "WNX1" "WNT1" "CRX1" "CRT1" "O0" "O1" "O2" "O3" "O4" "O5" "O6" "O7" "O14" "O15" "IS0" "REF0" "NOGRB" "IC0")

# Process switches and get list of extra source files
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/check_switches.cmake)
check_switches("${switches}" switch_files)

# Compile definitions
foreach(switch ${switches})
add_compile_definitions(W3_${switch})
endforeach()

add_compile_definitions(ENDIANNESS="big_endian")

set_property(SOURCE WW3/model/src/w3initmd.F90
APPEND
PROPERTY COMPILE_DEFINITIONS
"__WW3_SWITCHES__=\'\'"
)
)

# Too many files to list, so include them via this file
include("ww3_files.cmake")
message(VERBOSE "WW3 common source files : ${ww3_src_files}")
message(VERBOSE "WW# switch files: ${switch_files}")

### Create target library and set PUBLIC interfaces on the library
add_fortran_library(ww3 mod STATIC ${ww3_src_files})
add_fortran_library(ww3 mod STATIC ${ww3_src_files} ${switch_files})
target_link_libraries(ww3 PUBLIC esmf
NetCDF::NetCDF_Fortran)

# WW3 executables
foreach(EXE ww3_grid ww3_strt ww3_ounf ww3_outf ww3_outp)
add_executable(${EXE} WW3/model/src/${EXE}.F90)
target_link_libraries(${EXE} PRIVATE ww3)
add_executable(${EXE} ${${EXE}_src_files})
target_link_libraries(${EXE} PRIVATE ww3)
endforeach()
105 changes: 105 additions & 0 deletions WW3/cmake/check_switches.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
function(check_switches switches switch_files)
# Read JSON file
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/WW3/model/src/cmake/switches.json json_str)
# Get length of top-level array of all switch categories
string(JSON len LENGTH ${json_str})
# CMake's foreach RANGE is inclusive, so subtract 1 when looping
math(EXPR len "${len} - 1")

# Loop over switch categories
set(files "")
foreach(i_category RANGE ${len})
string(JSON category GET ${json_str} ${i_category})
string(JSON num_options LENGTH ${category} valid-options)

# Loop over valid options
math(EXPR num_options "${num_options} - 1")
set(n_switches_in_category 0)
foreach(j_options RANGE ${num_options})
string(JSON valid_opt GET ${category} valid-options ${j_options} name)

# This option is in current switch file
if(valid_opt IN_LIST switches)
math(EXPR n_switches_in_category "${n_switches_in_category} + 1")
string(JSON n_files ERROR_VARIABLE err LENGTH ${category} valid-options ${j_options} build_files)

# Check for conflicting switches
string(JSON n_conflicts ERROR_VARIABLE err LENGTH ${category} valid-options ${j_options} conflicts)
if(n_conflicts)
math(EXPR n_conflicts "${n_conflicts} -1")
# Loop over conflcits
foreach(i_conflict RANGE ${n_conflicts})
string(JSON conflict GET ${category} valid-options ${j_options} conflicts ${i_conflict})
if(conflict IN_LIST switches)
message(FATAL_ERROR "Switch '${valid_opt}' and '${conflict}' conflict")
endif()
endforeach()
endif()

# Check for required dependent switches
string(JSON n_requires ERROR_VARIABLE err LENGTH ${category} valid-options ${j_options} requires)
if(n_requires)
math(EXPR n_requires "${n_requires} - 1")
# Loop over required switches
foreach(i_requires RANGE ${n_requires})

string(JSON json_type TYPE ${category} valid-options ${j_options} requires ${i_requires})

# Can be a string or an array. String values or directly required, while if an array one of the values is required.
if(json_type STREQUAL "STRING")
string(JSON required_switch GET ${category} valid-options ${j_options} requires ${i_requires})
if(NOT required_switch IN_LIST switches)
message(FATAL_ERROR "Switch '${valid_opt}' requires '${required_switch}' to be set")
endif()
elseif(json_type STREQUAL "ARRAY")
string(JSON n_requires_any LENGTH ${vategory} valid-options ${j_options} requries ${i_requires})
math(EXPR n_requires_any "${n_requires_any} - 1")

# Loop over array and check that one of the switches is present
set(found false)
set(possible_values "")
foreach(i_requires_any RANGE ${n_requires_any})
string(JSON required_switch GET ${category} valid-options ${j_options} requires ${i_requires} ${i_requires_any})
list(APPEND possible_values "${required_switch}")

if(required_switch IN_LIST switches)
set(found true)
endif()
endforeach()

if(NOT found)
message(FATAL_ERROR "Switch ${valid_opt} requires one of ${possible_values} to be set")
endif()

endif()
endforeach()
endif()

if(n_files)
# Loop over files associated with switch and add them to build
math(EXPR n_files "${n_files} - 1")
foreach(i_files RANGE ${n_files})
string(JSON file GET ${category} valid-options ${j_options} build_files ${i_files})
list(APPEND files "WW3/model/src/${file}")
endforeach()
endif()
endif()

endforeach()

# Check for the correct number of switches per category
string(JSON num_switches GET ${category} num_switches)
string(JSON category_name GET ${category} name)

if(num_switches STREQUAL "one" AND NOT n_switches_in_category EQUAL 1)
message(FATAL_ERROR "No valid ${category_name} switches found, but one is required")
elseif(num_switches STREQUAL "upto1" AND n_switches_in_category GREATER 1)
message(FATAL_ERROR "Too many ${category_name} switches found (max 1)")
elseif(num_switches STREQUAL "upto2" AND n_switches_in_category GREATER 2)
message(FATAL_ERROR "Too many ${category_name} switches found (max 2)")
endif()

endforeach()

set(${switch_files} ${files} PARENT_SCOPE)
endfunction()
36 changes: 23 additions & 13 deletions WW3/ww3_files.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Common sources
list(APPEND ww3_src_files
# Common sources
WW3/model/src/constants.F90
WW3/model/src/w3adatmd.F90
WW3/model/src/w3arrymd.F90
Expand Down Expand Up @@ -32,7 +32,6 @@ list(APPEND ww3_src_files
WW3/model/src/w3nmltrncmd.F90
WW3/model/src/w3nmluprstrmd.F90
WW3/model/src/w3odatmd.F90
WW3/model/src/w3ounfmetamd.F90
WW3/model/src/w3parall.F90
WW3/model/src/w3partmd.F90
WW3/model/src/w3servmd.F90
Expand All @@ -58,21 +57,32 @@ list(APPEND ww3_src_files
WW3/model/src/w3iogoncdmd.F90
WW3/model/src/wav_shr_flags.F90

# Sources needed for switches
WW3/model/src/w3profsmd.F90
WW3/model/src/w3pro3md.F90
WW3/model/src/w3uqckmd.F90
WW3/model/src/w3fld1md.F90
WW3/model/src/w3fld2md.F90
WW3/model/src/w3src4md.F90
WW3/model/src/w3snl1md.F90
WW3/model/src/w3sbt1md.F90
WW3/model/src/w3sdb1md.F90

# NUOPC cap sources
WW3/model/src/wav_kind_mod.F90
WW3/model/src/wav_shr_mod.F90
WW3/model/src/wav_shel_inp.F90
WW3/model/src/wav_comp_nuopc.F90
WW3/model/src/wav_import_export.F90
)

# Utilities sources
list(APPEND ww3_grid_src_files
WW3/model/src/ww3_grid.F90
)

list(APPEND ww3_strt_src_files
WW3/model/src/ww3_strt.F90
)

list(APPEND ww3_outf_src_files
WW3/model/src/ww3_outf.F90
)

list(APPEND ww3_ounf_src_files
WW3/model/src/ww3_ounf.F90
WW3/model/src/w3ounfmetamd.F90
)

list(APPEND ww3_outp_src_files
WW3/model/src/ww3_outp.F90
)

0 comments on commit 0069205

Please sign in to comment.