From 56db8f2c20d2138ee01263826386cac80fa373e6 Mon Sep 17 00:00:00 2001
From: Sebastian Westerheide <sebastian.westerheide@uni-muenster.de>
Date: Mon, 3 Aug 2015 01:49:45 +0200
Subject: [PATCH] [istl][eigenvalue] add cmake support for ARPACK++

Check for the ARPACK++ library (needed for the new Dune::ArPackPlusPlus_Algorithms class template)
---
 cmake/modules/AddARPACKPPFlags.cmake |  20 ++++
 cmake/modules/DuneIstlMacros.cmake   |   2 +
 cmake/modules/FindARPACK.cmake       |  77 +++++++++++++++
 cmake/modules/FindARPACKPP.cmake     | 143 +++++++++++++++++++++++++++
 config.h.cmake                       |   3 +
 5 files changed, 245 insertions(+)
 create mode 100644 cmake/modules/AddARPACKPPFlags.cmake
 create mode 100644 cmake/modules/FindARPACK.cmake
 create mode 100644 cmake/modules/FindARPACKPP.cmake

diff --git a/cmake/modules/AddARPACKPPFlags.cmake b/cmake/modules/AddARPACKPPFlags.cmake
new file mode 100644
index 00000000..651ce079
--- /dev/null
+++ b/cmake/modules/AddARPACKPPFlags.cmake
@@ -0,0 +1,20 @@
+#
+# Module providing convenience methods for compile binaries with ARPACK++ support.
+#
+# Provides the following functions:
+#
+# add_dune_arpackpp_flags(target1 target2 ...)
+#
+# adds ARPACK++ flags to the targets for compilation and linking
+#
+function(add_dune_arpackpp_flags _targets)
+  if(ARPACKPP_FOUND)
+    foreach(_target ${_targets})
+      target_link_libraries(${_target} ${ARPACKPP_DUNE_LIBRARIES})
+      get_target_property(_props ${_target} COMPILE_FLAGS)
+      string(REPLACE "_props-NOTFOUND" "" _props "${_props}")
+      set_target_properties(${_target} PROPERTIES COMPILE_FLAGS
+        "${_props} ${ARPACKPP_DUNE_COMPILE_FLAGS} -DENABLE_ARPACKPP=1")
+    endforeach(_target ${_targets})
+  endif(ARPACKPP_FOUND)
+endfunction(add_dune_arpackpp_flags)
diff --git a/cmake/modules/DuneIstlMacros.cmake b/cmake/modules/DuneIstlMacros.cmake
index 6b5a48e8..65414e59 100644
--- a/cmake/modules/DuneIstlMacros.cmake
+++ b/cmake/modules/DuneIstlMacros.cmake
@@ -7,3 +7,5 @@ find_package(SuperLU)
 include(AddSuperLUFlags)
 find_package(UMFPack)
 include(AddUMFPackFlags)
+find_package(ARPACKPP)
+include(AddARPACKPPFlags)
diff --git a/cmake/modules/FindARPACK.cmake b/cmake/modules/FindARPACK.cmake
new file mode 100644
index 00000000..09c3eb4a
--- /dev/null
+++ b/cmake/modules/FindARPACK.cmake
@@ -0,0 +1,77 @@
+#
+# Module that checks whether ARPACK is available and usable.
+#
+# Variables used by this module which you may want to set:
+# ARPACK_ROOT           Path list to search for ARPACK.
+#
+# Sets the following variables:
+# ARPACK_FOUND          True if ARPACK available.
+# ARPACK_LIBRARIES      Link against these libraries to use ARPACK.
+#
+
+# check for Fortran support which is required by ARPACK
+if(NOT(Fortran_Works))
+  message(WARNING "Fortran doesn't seem to be supported, skipping search for ARPACK.")
+  # log errornous result
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Determing location of ARPACK failed:\n"
+    "Fortran support is required but could not be detected\n\n")
+  return()
+endif(NOT(Fortran_Works))
+
+# look for library, only at positions given by the user
+find_library(ARPACK_LIBRARY
+  NAMES "arpack"
+  PATHS ${ARPACK_PREFIX} ${ARPACK_ROOT}
+  PATH_SUFFIXES "lib" "lib32" "lib64"
+  NO_DEFAULT_PATH
+)
+
+# look for library files, including default paths
+find_library(ARPACK_LIBRARY
+  NAMES "arpack"
+  PATH_SUFFIXES "lib" "lib32" "lib64"
+)
+
+# check header usability
+include(CMakePushCheckState)
+cmake_push_check_state()
+
+# we need if clauses here because variable is set variable-NOTFOUND if the
+# searches above were not successful; without them CMake print errors like:
+# "CMake Error: The following variables are used in this project, but they
+# are set to NOTFOUND. Please set them or make sure they are set and tested
+# correctly in the CMake files."
+if(ARPACK_LIBRARY)
+  set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${ARPACK_LIBRARY})
+endif(ARPACK_LIBRARY)
+
+# end of header usability check
+cmake_pop_check_state()
+
+# behave like a CMake module is supposed to behave
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+  "ARPACK"
+  DEFAULT_MSG
+  ARPACK_LIBRARY
+)
+
+# hide the introduced cmake cached variables in cmake GUIs
+mark_as_advanced(ARPACK_LIBRARY)
+
+# if headers are found, store results
+if(ARPACK_FOUND)
+  set(ARPACK_LIBRARIES ${ARPACK_LIBRARY})
+  # log result
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Determing location of ARPACK succeded:\n"
+    "Libraries to link against: ${ARPACK_LIBRARIES}\n\n")
+  set(ARPACK_DUNE_LIBRARIES ${ARPACK_LIBRARIES}
+    CACHE STRING "Libraries used by DUNE when linking ARPACK programs")
+else(ARPACK_FOUND)
+  # log errornous result
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Determing location of ARPACK failed:\n"
+    "Libraries to link against: ${ARPACK_LIBRARIES}\n\n")
+endif(ARPACK_FOUND)
diff --git a/cmake/modules/FindARPACKPP.cmake b/cmake/modules/FindARPACKPP.cmake
new file mode 100644
index 00000000..286ad7f0
--- /dev/null
+++ b/cmake/modules/FindARPACKPP.cmake
@@ -0,0 +1,143 @@
+#
+# Module that checks whether ARPACK++ is available and usable.
+#
+# Variables used by this module which you may want to set:
+# ARPACKPP_ROOT           Path list to search for ARPACK++.
+#
+# Sets the following variables:
+# ARPACKPP_FOUND          True if ARPACK++ available.
+# ARPACKPP_INCLUDE_DIRS   Path to the ARPACK++ include directories.
+# ARPACKPP_LIBRARIES      Link against these libraries to use ARPACK++.
+#
+
+# find ARPACK which is required by ARPACK++
+find_package(ARPACK)
+if(NOT(ARPACK_FOUND))
+  message(WARNING "ARPACK not found, skipping search for ARPACK++.")
+  # log errornous result
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Determing location of ARPACK++ failed:\n"
+    "ARPACK is required but could not be found\n\n")
+  return()
+endif(NOT(ARPACK_FOUND))
+
+# # find BLAS which is required by ARPACK++
+# # (not needed for the ARPACK++ classes that we currently use)
+# find_package(BLAS QUIET)
+# if(NOT(BLAS_FOUND))
+#   message(WARNING "BLAS not found, skipping search for ARPACK++.")
+#   # log errornous result
+#   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+#     "Determing location of ARPACK++ failed:\n"
+#     "BLAS is required but could not be found\n\n")
+#   return()
+# endif(NOT(BLAS_FOUND))
+
+# # find LAPACK which is required by ARPACK++
+# # (not needed for the ARPACK++ classes that we currently use)
+# find_package(LAPACK QUIET)
+# if(NOT(LAPACK_FOUND))
+#   message(WARNING "LAPACK not found, skipping search for ARPACK++.")
+#   # log errornous result
+#   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+#     "Determing location of ARPACK++ failed:\n"
+#     "LAPACK is required but could not be found\n\n")
+#   return()
+# endif(NOT(LAPACK_FOUND))
+
+# # find UMFPACK which is required by ARPACK++
+# # (not needed for the ARPACK++ classes that we currently use)
+# find_package(UMFPack QUIET)
+# if(NOT(UMFPACK_FOUND))
+#   message(WARNING "UMFPACK not found, skipping search for ARPACK++.")
+#   # log errornous result
+#   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+#     "Determing location of ARPACK++ failed:\n"
+#     "UMFPACK is required but could not be found\n\n")
+#   return()
+# endif(NOT(UMFPACK_FOUND))
+
+# # find SuperLU which is required by ARPACK++
+# # (not needed for the ARPACK++ classes that we currently use)
+# find_package(SuperLU QUIET)
+# if(NOT(SUPERLU_FOUND))
+#   message(WARNING "SuperLU not found, skipping search for ARPACK++.")
+#   # log errornous result
+#   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+#     "Determing location of ARPACK++ failed:\n"
+#     "SuperLU is required but could not be found\n\n")
+#   return()
+# endif(NOT(SUPERLU_FOUND))
+
+# look for header files, only at positions given by the user
+find_path(ARPACKPP_INCLUDE_DIR
+  NAMES "arssym.h"
+  PATHS ${ARPACKPP_PREFIX} ${ARPACKPP_ROOT}
+  PATH_SUFFIXES "include" "include/arpack++"
+  NO_DEFAULT_PATH
+)
+
+# look for header files, including default paths
+find_path(ARPACKPP_INCLUDE_DIR
+  NAMES "arssym.h"
+  PATH_SUFFIXES "include" "include/arpack++"
+)
+
+# check header usability
+include(CMakePushCheckState)
+cmake_push_check_state()
+
+# we need if clauses here because variable is set variable-NOTFOUND if the
+# searches above were not successful; without them CMake print errors like:
+# "CMake Error: The following variables are used in this project, but they
+# are set to NOTFOUND. Please set them or make sure they are set and tested
+# correctly in the CMake files."
+if(ARPACKPP_INCLUDE_DIR)
+  set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${ARPACKPP_INCLUDE_DIR})
+  set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${ARPACK_LIBRARIES}) #${BLAS_LIBRARIES} ${LAPACK_LIBRARIES} ${UMFPACK_LIBRARIES} ${SUPERLU_LIBRARIES}
+endif(ARPACKPP_INCLUDE_DIR)
+
+# end of header usability check
+cmake_pop_check_state()
+
+# behave like a CMake module is supposed to behave
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+  "ARPACKPP"
+  DEFAULT_MSG
+  ARPACKPP_INCLUDE_DIR
+)
+
+# hide the introduced cmake cached variables in cmake GUIs
+mark_as_advanced(ARPACKPP_INCLUDE_DIR)
+
+# if headers are found, store results
+if(ARPACKPP_FOUND)
+  set(ARPACKPP_INCLUDE_DIRS ${ARPACKPP_INCLUDE_DIR})
+  set(ARPACKPP_LIBRARIES ${ARPACK_LIBRARIES}) #${BLAS_LIBRARIES} ${LAPACK_LIBRARIES} ${UMFPACK_LIBRARIES} ${SUPERLU_LIBRARIES}
+  # log result
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Determing location of ARPACK++ succeded:\n"
+    "Include directory: ${ARPACKPP_INCLUDE_DIRS}\n"
+    "Libraries to link against: ${ARPACKPP_LIBRARIES}\n\n")
+  set(ARPACKPP_DUNE_COMPILE_FLAGS "-I${ARPACKPP_INCLUDE_DIRS}"
+    CACHE STRING "Compile flags used by DUNE when compiling ARPACK++ programs")
+  set(ARPACKPP_DUNE_LIBRARIES ${ARPACKPP_LIBRARIES}
+    CACHE STRING "Libraries used by DUNE when linking ARPACK++ programs")
+else(ARPACKPP_FOUND)
+  # log errornous result
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Determing location of ARPACK++ failed:\n"
+    "Include directory: ${ARPACKPP_INCLUDE_DIRS}\n"
+    "Libraries to link against: ${ARPACKPP_LIBRARIES}\n\n")
+endif(ARPACKPP_FOUND)
+
+# set HAVE_ARPACKPP for config.h
+set(HAVE_ARPACKPP ${ARPACKPP_FOUND})
+
+# register all ARPACK++ related flags
+if(ARPACKPP_FOUND)
+  dune_register_package_flags(COMPILE_DEFINITIONS "ENABLE_ARPACKPP=1"
+                              LIBRARIES "${ARPACKPP_LIBRARIES}"
+                              INCLUDE_DIRS "${ARPACKPP_INCLUDE_DIRS}")
+endif(ARPACKPP_FOUND)
diff --git a/config.h.cmake b/config.h.cmake
index e533d7f1..30043b2b 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -37,6 +37,9 @@
 /* Define to ENABLE_SUPERLU if the SuperLU library is available */
 #cmakedefine HAVE_SUPERLU ENABLE_SUPERLU
 
+/* Define to ENABLE_ARPACKPP if the ARPACK++ library is available */
+#cmakedefine HAVE_ARPACKPP ENABLE_ARPACKPP
+
 /* define to 1 because older versions of SuperLU are no longer supported*/
 #define SUPERLU_POST_2005_VERSION 1
 
-- 
GitLab