# -----------------------------------------------------------------
# Programmer(s): Cody J. Balos @ LLNL
# -----------------------------------------------------------------
# SUNDIALS Copyright Start
# Copyright (c) 2002-2024, Lawrence Livermore National Security
# and Southern Methodist University.
# All rights reserved.
#
# See the top-level LICENSE and NOTICE files for details.
#
# SPDX-License-Identifier: BSD-3-Clause
# SUNDIALS Copyright End
# -----------------------------------------------------------------
# CMakeLists.txt for KINSOL Fortran 2003 serial examples.
#
# This file is generated from a template using variables
# set at configuration time. It can be used as a template for
# other user CMakeLists configuration files.
# -----------------------------------------------------------------

cmake_minimum_required(VERSION 3.31.3)

# Set cache variables for compilers and flags
set(CMAKE_Fortran_COMPILER
  ${CMAKE_CURRENT_LIST_DIR}/../../../../../bin/gfortran.exe
  CACHE FILEPATH "Fortran compiler")

set(CMAKE_Fortran_FLAGS
  ""
  CACHE STRING "Fortran compiler flags")

# Specify project name and languages
project(KINSOL_F2003_examples Fortran)

# Fortran preprocessor must be enabled
set(CMAKE_Fortran_PREPROCESS ON)

# Enable testing
include(CTest)

# ------------------------------------------------------------------------------

# Set cmake variables from template inputsd
set(NVEC_LIB  ""  CACHE STRING "NVECTOR library")
set(NVEC_FLIB  ""  CACHE STRING "NVECTOR library")

set(SUNLS_LIB "" CACHE STRING "SUNLinearSolver library")
set(SUNLS_FLIB "" CACHE STRING "SUNLinearSolver library")

# Specify the path to SUNDIALS Fortran modules
set(SUNDIALS_INCLUDE_DIR
  ${CMAKE_CURRENT_LIST_DIR}/../../../../../include/sundials/fortran
  CACHE PATH "Location of SUNDIALS Fortran module files")

# Specify the path to SUNDIALS libraries
set(SUNDIALS_LIBRARY_DIR
  ${CMAKE_CURRENT_LIST_DIR}/../../../../../lib
  CACHE PATH "Location of SUNDIALS libraries")

find_library(SUNDIALS_CORE_LIB
  sundials_core ${SUNDIALS_LIBRARY_DIR}
  DOC "SUNDIALS core library")

find_library(SUNDIALS_FCORE_LIB
  sundials_fcore_mod ${SUNDIALS_LIBRARY_DIR}
  DOC "SUNDIALS Fortran core library")

find_library(SUNDIALS_SOLVER_LIB
  sundials_kinsol ${SUNDIALS_LIBRARY_DIR}
  DOC "KINSOL library")

find_library(SUNDIALS_SOLVER_FLIB
  sundials_fkinsol_mod ${SUNDIALS_LIBRARY_DIR}
  DOC "KINSOL Fortran-C library")

# Find the NVECTOR library
if("${NVEC_LIB}" STREQUAL "")
  # No additional NVECTOR library necessary
else()
  # Find the additional NVECTOR library
  find_library(SUNDIALS_NVEC_LIB
     ${SUNDIALS_LIBRARY_DIR}
    DOC "NVECTOR library")

  # Find the Fortran NVECTOR library
  find_library(SUNDIALS_NVEC_FLIB
     ${SUNDIALS_LIBRARY_DIR}
    DOC "NVECTOR library")
endif()

if("${SUNLS_LIB}" STREQUAL "")
  # No additional SUNLinearSolver library necessary
else()
  # Find the additional SUNLinearSolver library
  find_library(SUNDIALS_SUNLS_LIB
     ${SUNDIALS_LIBRARY_DIR}
    DOC "SUNLinearSolver library")

  find_library(SUNDIALS_SUNLS_FLIB
     ${SUNDIALS_LIBRARY_DIR}
    DOC "SUNLinearSolver library")
endif()

# Set additional libraries
set(SUNDIALS_EXTRA_LIBS  CACHE STRING "Additional libraries")

# For SUNDIALS module examples the solver library is not needed
if(NOT SUNDIALS_SOLVER_LIB)
  set(SUNDIALS_SOLVER_LIB "")
endif()

# List of SUNDIALS libraries
set(SUNDIALS_LIBRARIES
  -L${SUNDIALS_LIBRARY_DIR}
  ${SUNDIALS_SOLVER_FLIB}
  ${SUNDIALS_NVEC_FLIB}
  ${SUNDIALS_SUNLS_FLIB}
  ${SUNDIALS_SOLVER_LIB}
  ${SUNDIALS_NVEC_LIB}
  ${SUNDIALS_SUNLS_LIB}
  ${SUNDIALS_FCORE_LIB}
  ${SUNDIALS_CORE_LIB}
  ${SUNDIALS_EXTRA_LIBS})

# ------------------------------------------------------------------------------

# Set the names of the examples to be built and their dependencies
set(examples  kinDiagon_kry_f2003 kinRoboKin_dns_f2003 kinLaplace_bnd_f2003 kinLaplace_picard_kry_f2003)
set(examples_dependencies )
if(examples)
  list(REMOVE_DUPLICATES examples)
endif()

# Create targets for each example
foreach(example ${examples})

  # Keep fortran modules to a unique directory to avoid naming collisions
  set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${example}.dir)

  # example source files
  add_executable(${example} ${example}.f90 ${examples_dependencies})

  # directories to include
  target_include_directories(${example} PRIVATE ${SUNDIALS_INCLUDE_DIR})

  # libraries to link against
  target_link_libraries(${example} ${SUNDIALS_LIBRARIES})

  target_compile_definitions(${example} PRIVATE SUNDIALS_INT64_T)

  # add the example to ctest
  add_test(NAME ${example} COMMAND ${example})

endforeach()

# ------------------------------------------------------------------------------

# KLU include directory and libraries
set(KLU_INCLUDE_DIR
  ${CMAKE_CURRENT_LIST_DIR}/../../../../../include/suitesparse
  CACHE PATH "Location of KLU header files")

set(KLU_LIBRARIES
  ${CMAKE_CURRENT_LIST_DIR}/../../../../../lib/libklu.dll.a
  CACHE STRING "KLU libraries")

# Set the names of the examples to be built and their dependencies
set(examples_klu )
set(examples_dependencies_klu )
if(examples_klu)
  list(REMOVE_DUPLICATES examples_klu)
endif()

if(KLU_LIBRARIES AND examples_klu)

  # Create targets for each example
  foreach(example ${examples_klu})

    # Keep fortran modules to a unique directory to avoid naming collisions
    set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${example}.dir)

    # example source files
    add_executable(${example} ${example}.f90)

    # directories to include
    target_include_directories(${example} PRIVATE ${SUNDIALS_INCLUDE_DIR})

    # libraries to link against
    target_link_libraries(${example} ${SUNDIALS_LIBRARIES})
    target_link_libraries(${example} ${KLU_LIBRARIES})

    target_compile_definitions(${example} PRIVATE SUNDIALS_INT64_T)

    # add the example to ctest
    add_test(NAME ${example} COMMAND ${example})

  endforeach()

endif()
