From 16afaa963f0cd27eb74f81749e7af7bb63b4b55d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Thu, 17 Jun 2021 15:48:40 +0200
Subject: [PATCH] Plug SLEPc library to compute eigenvalues

---
 CMakeLists.txt               | 39 ++++++++++++++++++++++++++++++++++++
 src/utils/BuildInfo.cpp      | 15 ++++++++++++++
 src/utils/BuildInfo.hpp      |  1 +
 src/utils/PugsUtils.cpp      |  1 +
 src/utils/pugs_config.hpp.in |  1 +
 tests/test_PugsUtils.cpp     |  1 +
 6 files changed, 58 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a4aa863b2..e9255bff6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -187,6 +187,34 @@ else()
   endif()
 endif()
 
+#------------------------------------------------------
+# Check for SLEPc
+# defaults use SLEPc
+set(PUGS_ENABLE_SLEPC AUTO CACHE STRING
+  "Choose one of: AUTO ON OFF")
+
+if (PUGS_ENABLE_SLEPC MATCHES "^(AUTO|ON)$")
+  if (PETSC_FOUND)
+    # SLEPc support is deactivated if PETSc is not found
+    pkg_check_modules(SLEPC SLEPc)
+  else()
+    message(STATUS "SLEPc support is deactivated since pugs will not be build with PETSc support")
+    set(SLEPc_FOUND FALSE)
+    unset(PUGS_HAS_SLEPC)
+  endif()
+  set(PUGS_HAS_SLEPC ${SLEPC_FOUND})
+else()
+  unset(PUGS_HAS_SLEPC)
+endif()
+
+if (${SLEPC_FOUND})
+  include_directories(SYSTEM ${SLEPC_INCLUDE_DIRS})
+else()
+  if (PUGS_ENABLE_SLEPC MATCHES "^ON$")
+    message(FATAL_ERROR "Could not find SLEPc!")
+  endif()
+endif()
+
 # -----------------------------------------------------
 
 if (${MPI_FOUND})
@@ -558,6 +586,7 @@ target_link_libraries(
   PugsLanguageUtils
   kokkos
   ${PETSC_LIBRARIES}
+  ${SLEPC_LIBRARIES}
   ${PARMETIS_LIBRARIES}
   ${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES}
   ${KOKKOS_CXX_FLAGS}
@@ -615,6 +644,16 @@ else()
   endif()
 endif()
 
+if (SLEPC_FOUND)
+  message(" SLEPc: ${SLEPC_VERSION}")
+else()
+  if (PUGS_ENABLE_SLEPC MATCHES "^(AUTO|ON)$")
+    message(" SLEPc: not found!")
+  else()
+      message(" SLEPc: explicitly deactivated!")
+  endif()
+endif()
+
 if(CLANG_FORMAT)
   message(" clang-format: ${CLANG_FORMAT}")
 else()
diff --git a/src/utils/BuildInfo.cpp b/src/utils/BuildInfo.cpp
index 38d46007e..71d702c99 100644
--- a/src/utils/BuildInfo.cpp
+++ b/src/utils/BuildInfo.cpp
@@ -12,6 +12,10 @@
 #include <petsc.h>
 #endif   // PUGS_HAS_PETSC
 
+#ifdef PUGS_HAS_SLEPC
+#include <slepc.h>
+#endif   // PUGS_HAS_PETSC
+
 std::string
 BuildInfo::type()
 {
@@ -57,3 +61,14 @@ BuildInfo::petscLibrary()
   return "none";
 #endif   // PUGS_HAS_PETSC
 }
+
+std::string
+BuildInfo::slepcLibrary()
+{
+#ifdef PUGS_HAS_SLEPC
+  return std::to_string(SLEPC_VERSION_MAJOR) + "." + std::to_string(SLEPC_VERSION_MINOR) + "." +
+         std::to_string(SLEPC_VERSION_SUBMINOR);
+#else
+  return "none";
+#endif   // PUGS_HAS_SLEPC
+}
diff --git a/src/utils/BuildInfo.hpp b/src/utils/BuildInfo.hpp
index 67134a782..bc83cf3f1 100644
--- a/src/utils/BuildInfo.hpp
+++ b/src/utils/BuildInfo.hpp
@@ -10,6 +10,7 @@ struct BuildInfo
   static std::string kokkosDevices();
   static std::string mpiLibrary();
   static std::string petscLibrary();
+  static std::string slepcLibrary();
 };
 
 #endif   // BUILD_INFO_HPP
diff --git a/src/utils/PugsUtils.cpp b/src/utils/PugsUtils.cpp
index ad9e12e7e..4c16444b3 100644
--- a/src/utils/PugsUtils.cpp
+++ b/src/utils/PugsUtils.cpp
@@ -55,6 +55,7 @@ pugsBuildInfo()
   os << "kokkos:   " << rang::style::bold << BuildInfo::kokkosDevices() << rang::style::reset << '\n';
   os << "MPI:      " << rang::style::bold << BuildInfo::mpiLibrary() << rang::style::reset << '\n';
   os << "PETSc:    " << rang::style::bold << BuildInfo::petscLibrary() << rang::style::reset << '\n';
+  os << "SLEPc:    " << rang::style::bold << BuildInfo::slepcLibrary() << rang::style::reset << '\n';
   os << "-------------------------------------------------------";
 
   return os.str();
diff --git a/src/utils/pugs_config.hpp.in b/src/utils/pugs_config.hpp.in
index 84a6d8fa0..0736003b9 100644
--- a/src/utils/pugs_config.hpp.in
+++ b/src/utils/pugs_config.hpp.in
@@ -4,6 +4,7 @@
 #cmakedefine PUGS_HAS_FENV_H
 #cmakedefine PUGS_HAS_MPI
 #cmakedefine PUGS_HAS_PETSC
+#cmakedefine PUGS_HAS_SLEPC
 
 #cmakedefine SYSTEM_IS_LINUX
 #cmakedefine SYSTEM_IS_DARWIN
diff --git a/tests/test_PugsUtils.cpp b/tests/test_PugsUtils.cpp
index f32e8014a..4632ae825 100644
--- a/tests/test_PugsUtils.cpp
+++ b/tests/test_PugsUtils.cpp
@@ -50,6 +50,7 @@ TEST_CASE("PugsUtils", "[utils]")
       os << "kokkos:   " << rang::style::bold << BuildInfo::kokkosDevices() << rang::style::reset << '\n';
       os << "MPI:      " << rang::style::bold << BuildInfo::mpiLibrary() << rang::style::reset << '\n';
       os << "PETSc:    " << rang::style::bold << BuildInfo::petscLibrary() << rang::style::reset << '\n';
+      os << "SLEPc:    " << rang::style::bold << BuildInfo::slepcLibrary() << rang::style::reset << '\n';
       os << "-------------------------------------------------------";
 
       return os.str();
-- 
GitLab