1# Copyright (c) 2020 - 2025 David Guibert
2# Copyright (c) 2024 - 2025 Niclas Schroeter
3# Copyright (c) 2024 Antoine Morvan
6# SPDX-License-Identifier: Apache-2.0
10set_property(GLOBAL PROPERTY ecrad_can_use_system TRUE)
11set_property(GLOBAL PROPERTY ecrad_depends netcdf cdo)
13set(ecrad_build_args "" CACHE STRING "Custom Make arguments for ecRad")
15option(ecrad_custom_profile "Use a custom Make profile" OFF)
16set(ecrad_opt_flags "" CACHE STRING "Optimization flags for custom profile")
17set(ecrad_ld_flags "" CACHE STRING "Linker flags for custom profile")
18set(ecrad_basic_flags "" CACHE STRING "Basic flags for custom profile")
20set(test_cases small medium big)
21list(TRANSFORM test_cases PREPEND "<BINARY_DIR>/" OUTPUT_VARIABLE required_dirs)
25 message(STATUS "ecrad: enabled (system installed)")
26 find_program(ECRAD_EXE ecrad REQUIRED)
28 get_filename_component(ECRAD_EXE_DIR "${ECRAD_EXE}" DIRECTORY)
29 set_if_not_present(ENV{PATH} "$ENV{PATH}" "${ECRAD_EXE_DIR}")
31 # dummy ecrad external project to get tests
32 ExternalProject_Data_Add(
37 INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${required_dirs})
39 ExternalProject_Get_Property(ecrad BINARY_DIR)
40 set(ecrad_BIN_DIR ${BINARY_DIR})
43 message(STATUS "ecrad: enabled (internally built)")
45 # Check compiler to set the PROFILE argument of make command
47 if(ecrad_custom_profile)
48 set(ECRAD_COMPILER_PROFILE "custom")
49 message(STATUS "Building a custom Make profile...")
50 find_package(OpenMP REQUIRED)
51 set(custom_profile_path "${CMAKE_CURRENT_BINARY_DIR}/Makefile_include.custom")
52 set(copy_cmd "cp ${custom_profile_path} <SOURCE_DIR>")
54 file(GENERATE OUTPUT ${custom_profile_path} CONTENT "
55FC = ${CMAKE_Fortran_COMPILER}
56CC = ${CMAKE_C_COMPILER}
57OPTFLAGS = ${ecrad_opt_flags}
58LDFLAGS = ${ecrad_ld_flags}
59BASICFLAGS = ${CMAKE_Fortran_MODDIR_FLAG}../mod ${ecrad_basic_flags}
60OMPFLAG = ${OpenMP_Fortran_FLAGS}"
62 elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
63 set(ECRAD_COMPILER_PROFILE "gfortran")
64 elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^Intel(LLVM)?$")
65 set(ECRAD_COMPILER_PROFILE "intel")
69 "ecrad: compiler profile not supported (${CMAKE_Fortran_COMPILER_ID}). Provide a custom profile instead!"
73 ExternalProject_Data_Add(
75 DEPENDS netcdf::Fortran ${ecrad_revision}
76 CONFIGURE_COMMAND bash -c ${copy_cmd}
78 PATH=$ENV{PATH} CPATH=$ENV{CPATH}
79 C_INCLUDE_PATH=$ENV{C_INCLUDE_PATH}
80 LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
81 ${CMAKE_MAKE_PROGRAM} -j 1 PROFILE=${ECRAD_COMPILER_PROFILE} FC=${CMAKE_Fortran_COMPILER} ${default_build_args} ${ecrad_build_args}
82 INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${required_dirs}
83 COMMAND ${CMAKE_COMMAND} -E make_directory <INSTALL_DIR>
84 COMMAND ${CMAKE_COMMAND} -E copy_directory <BINARY_DIR>/bin
86 COMMAND ${CMAKE_COMMAND} -E copy_directory <BINARY_DIR>/lib
90 ExternalProject_Get_Property(ecrad INSTALL_DIR)
91 set(ecrad_DIR ${INSTALL_DIR})
93 set_if_not_present(ENV{PATH} "$ENV{PATH}" "${ecrad_DIR}/bin")
94 set_if_not_present(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}"
97 ExternalProject_Get_Property(ecrad BINARY_DIR)
98 set(ecrad_BIN_DIR ${BINARY_DIR})
99 set_if_not_present(ENV{PATH} "$ENV{PATH}" "${ecrad_BIN_DIR}/bin")
102 #The large tests require inputs that are NC4 files. ecRad requires setting a parameter in the radiation_driver namelist to
103 #enable reading and writing of this file format. Additionally, the tests are repeated 5 times by adding the other parameter.
104 #For comparability's sake, the small test is also executed with this adjusted namelist.
105 set(awk_add_params "awk '/do_write_double_precision/ { print; print \"do_write_hdf5 = true,\\nnrepeat = 5,\"; next }1'")
106 set(namelist_large_files configLargeFiles.nam)
107 set(namelist_creation "${awk_add_params} config.nam > ${namelist_large_files}")
108 set(append_new_namelist "&& ${namelist_creation}")
110 #Setting up the directories' contents
111 foreach(case IN LISTS test_cases)
113 NAME ecrad-${case}-stage-in
115 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
116 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-${case}-stage-in
119 bash -c "${ecrad_BIN_DIR}/bin/create_practical.sh ${append_new_namelist}"
120 WORKING_DIRECTORY ${ecrad_BIN_DIR}/${case}
127 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
128 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-small
131 ${namelist_large_files} era5slice.nc control.nc
132 WORKING_DIRECTORY ${ecrad_BIN_DIR}/small
135 #The large two tests require input data from outside of ecRad.
136 ExternalData_Add_Test(offline_ecrad_medium
139 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
140 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-medium
143 ${namelist_large_files} DATA{inputs/ecrad/era5sliceConcat1000.nc} control.nc
144 WORKING_DIRECTORY ${ecrad_BIN_DIR}/medium
147 ExternalData_Add_Test(offline_ecrad_big
150 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
151 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-big
154 ${namelist_large_files} DATA{inputs/ecrad/era5sliceConcat2000.nc} control.nc
155 WORKING_DIRECTORY ${ecrad_BIN_DIR}/big
158 ExternalData_Add_Target(offline_ecrad_medium)
159 ExternalData_Add_Target(offline_ecrad_big)
160 add_dependencies(offline offline_ecrad_medium offline_ecrad_big)
162 foreach(case IN LISTS test_cases)
163 ExternalData_Add_Test(offline_ecrad_${case}_validation
164 NAME ecrad-${case}-validation
166 env LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} LIBRARY_PATH=$ENV{LIBRARY_PATH}
167 PATH=$ENV{PATH} $<TARGET_FILE:job_launcher> --name=ecrad-${case}-validation
170 cdo diff,abslim=0.001 DATA{inputs/ecrad/ref-${case}.nc} control.nc
171 WORKING_DIRECTORY ${ecrad_BIN_DIR}/${case}
173 ExternalData_Add_Target(offline_ecrad_${case}_validation)
174 add_dependencies(offline offline_ecrad_${case}_validation)
176 set_tests_properties(ecrad-${case}-stage-in PROPERTIES FIXTURES_SETUP _setup-ecrad-${case})
177 set_tests_properties(ecrad-${case} PROPERTIES FIXTURES_SETUP _run-ecrad-${case})
179 set_tests_properties(ecrad-${case} PROPERTIES FIXTURES_REQUIRED _setup-ecrad-${case})
180 set_tests_properties(ecrad-${case}-validation PROPERTIES FIXTURES_REQUIRED _run-ecrad-${case})