DorieCompileInstance.cmake 4.77 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
# Default Dorie model targets
add_custom_target("richards")
add_custom_target("transport")

# Maximum polynomial orders of Richards model for available targets
set(DORIE_MAX_RORDER_2 6)
set(DORIE_MAX_RORDER_3 6)

# Maximum polynomial orders of transport model for available targets
set(DORIE_MAX_TORDER_2 0)
set(DORIE_MAX_TORDER_3 0)

# Maximum polynomial orders of Richards model for default targets
set(DORIE_MAX_DEFAULT_RORDER_2 3)
set(DORIE_MAX_DEFAULT_RORDER_3 1)

# Maximum polynomial orders of transport model for default targets
set(DORIE_MAX_DEFAULT_TORDER_2 0)
set(DORIE_MAX_DEFAULT_TORDER_3 0)

#
# .. cmake_function:: dorie_compile_instance
#
# Adds an executable and library for the specified model.
#
# The parameters specify static settings for the model instance. If these
# settings comply to the limits of the default variables, the instance is
# added to the global "richards" or "transport" targets, depending on which
# MODEL type is built.
#
# In case of "transport", the appropriate "richards" library must be available.
# Otherwise, it is also defined by this function.
#
# A sanity check for the input variables is not performed by CMake, but by
# the C++ code during compile-time.
#
# This function takes the following arguments:
#
#   - MODEL: Name of the model. Accepts "richards" or "transport".
#   - DIMENSION: Spatial dimension.
#   - RORDER: Finite element polynomial order of the Richards module.
#   - TORDER: Finite element polynomial order of the Transport module.
#   - CREATED_LIB: Variable to store the created library target name in.
#
function(dorie_compile_instance)

    # parse the function arguments
    set(SINGLE_ARGS MODEL DIMENSION RORDER TORDER CREATED_LIB)
    cmake_parse_arguments(ARGS "" "${SINGLE_ARGS}" "" ${ARGN})

    if (ARGS_UNPARSED_ARGUMENTS)
        message(WARNING "Unparsed arguments when calling "
                        "'dorie_create_executable: "
                        "${ARGS_UNPARSED_ARGUMENTS}")
    endif ()

    # set dimension string
    set(DIM_STR "d${ARGS_DIMENSION}")

    # set option string
    set(OPTION_STR "r${ARGS_RORDER}")

    # issue warning if transport order is given for 'richards'
    if (ARGS_MODEL STREQUAL "richards")
        set (lib_src ${PROJECT_SOURCE_DIR}/dune/dorie/model/richards/impl/impl.cc)
        if (ARGS_TORDER)
            message(WARNING "Ignoring argument TORDER for MODEL "
                            "'richards'")
        endif ()
    # append transport order to option string
    elseif (ARGS_MODEL STREQUAL "transport")
        set (lib_src ${PROJECT_SOURCE_DIR}/dune/dorie/model/coupling/impl/impl.cc)
        string(APPEND OPTION_STR "_t${ARGS_TORDER}")
    # unknown model
    else ()
        message(SEND_ERROR "Unsupported model: ${ARGS_MODEL}. "
                           "Must be either 'richards' or 'transport'")
    endif ()

    # register the library
    set(lib_name "dorie_${ARGS_MODEL}_${DIM_STR}_${OPTION_STR}")
    if (NOT TARGET ${lib_name})
        add_library(${lib_name} EXCLUDE_FROM_ALL STATIC ${lib_src})

        # link to dependencies
        target_link_libraries(${lib_name}
            PUBLIC
                spdlog
                muparser::muparser
                hdf5
                yaml-cpp
                ${DUNE_LIBS}
        )

        # register the executable
        set(exe_name "${ARGS_MODEL}_${DIM_STR}_${OPTION_STR}")
        set(src_file ${CMAKE_SOURCE_DIR}/dune/dorie/${ARGS_MODEL}.cc)
        add_executable(${exe_name} EXCLUDE_FROM_ALL ${src_file})
        target_link_libraries(${exe_name} PUBLIC ${lib_name})

        # Add the executable to the default targets
        if ((ARGS_RORDER LESS_EQUAL DORIE_MAX_DEFAULT_RORDER_${ARGS_DIMENSION})
            AND ((NOT ARGS_TORDER)
                OR ARGS_TORDER LESS_EQUAL DORIE_MAX_DEFAULT_TORDER_${ARGS_DIMENSION})
        )
            add_dependencies(${ARGS_MODEL} ${exe_name})
        endif()

        # set compile definitions
        target_compile_definitions(${lib_name}
            PUBLIC
                DORIE_DIM=${ARGS_DIMENSION}
                DORIE_RORDER=${ARGS_RORDER})

        if (ARGS_MODEL STREQUAL "transport")
            target_compile_definitions(${lib_name}
                PUBLIC DORIE_TORDER=${ARGS_TORDER})
        endif ()
    endif()

    # If we build a transport model, build the Richards library as well
    if (ARGS_MODEL STREQUAL "transport")
        dorie_compile_instance(MODEL "richards"
                               DIMENSION ${ARGS_DIMENSION}
                               RORDER ${ARGS_RORDER}
                               CREATED_LIB richards_lib
        )
        # ... and link to it!
        target_link_libraries(${exe_name} PUBLIC ${richards_lib})
    endif()

    # Report the library target name
    if (ARGS_CREATED_LIB)
        set(${ARGS_CREATED_LIB} ${lib_name} PARENT_SCOPE)
    endif ()

endfunction()