Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 107 additions & 26 deletions cmake/FindPETSc.cmake
Original file line number Diff line number Diff line change
@@ -1,47 +1,128 @@
# Find PETSc
# FindPETSc.cmake
#
# Once done this will define
# PETSC_FOUND - System has PETSc
# PETSC_INCLUDE_DIR - The PETSc include directory
# PETSC_LIBRARY - The PETSc library
# PETSC_VERSION - The PETSc version
# SLEPC_FOUND - PETSc has SLEPc
# SLEPC_INCLUDE_DIR - The SLEPc include directory
# SLEPC_LIBRARY - The SLEPc library
# SLEPC_VERSION

find_path(
PETSC_INCLUDE_DIR
petsc.h
PATHS
$ENV{PETSC_DIR}/include
$ENV{PETSC_ROOT}/include
include(FindPackageHandleStandardArgs)

find_package(PETSc CONFIG QUIET
PATHS
$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib/cmake/PETSc
$ENV{PETSC_ROOT}/$ENV{PETSC_ARCH}/lib/cmake/PETSc
)

find_library(
PETSC_LIBRARY
petsc
if (NOT PETSc_FOUND)
find_path(PETSC_INCLUDE_DIR
NAMES petsc.h
PATHS
$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib
$ENV{PETSC_DIR}/lib
$ENV{PETSC_ROOT}/$ENV{PETSC_ARCH}/lib
$ENV{PETSC_ROOT}/lib
)
$ENV{PETSC_DIR}/include
$ENV{PETSC_ROOT}/include
DOC "PETSc include directory"
)

set(PETSC_VERSION "unknown")
find_file(PETSCVERSION_H petscversion.h
find_library(PETSC_LIBRARY
NAMES petsc
PATHS
$ENV{PETSC_DIR}/include
$ENV{PETSC_ROOT}/include
)
mark_as_advanced(PETSCVERSION_H)
if (PETSCVERSION_H)
file(READ ${PETSCVERSION_H} PETSC_VERSION_FILE)
string(REGEX MATCH "define[ ]+PETSC_VERSION_MAJOR[ ]+([0-9]+)" TMP "${PETSC_VERSION_FILE}")
$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib
$ENV{PETSC_DIR}/lib
$ENV{PETSC_ROOT}/$ENV{PETSC_ARCH}/lib
$ENV{PETSC_ROOT}/lib
DOC "PETSc library"
)

set(PETSc_FOUND
${PETSC_INCLUDE_DIR}
AND
${PETSC_LIBRARY}
)
endif()

if (TARGET PETSc::PETSc)
get_target_property(_petsc_version PETSc::PETSc INTERFACE_VERSION)
set(PETSC_VERSION ${_petsc_version})
endif()

if(NOT DEFINED PETSC_VERSION)
set(PETSC_VERSION "unknown")
find_file(PETSCVERSION_H
NAMES petscversion.h
PATHS
$ENV{PETSC_DIR}/include
$ENV{PETSC_ROOT}/include
)
if(PETSCVERSION_H)
file(READ ${PETSCVERSION_H} _petscver)
string(REGEX MATCH "define[ ]+PETSC_VERSION_MAJOR[ ]+([0-9]+)" _ "${_petscver}")
set(PETSC_VERSION_MAJOR ${CMAKE_MATCH_1})
string(REGEX MATCH "define[ ]+PETSC_VERSION_MINOR[ ]+([0-9]+)" TMP "${PETSC_VERSION_FILE}")
string(REGEX MATCH "define[ ]+PETSC_VERSION_MINOR[ ]+([0-9]+)" _ "${_petscver}")
set(PETSC_VERSION_MINOR ${CMAKE_MATCH_1})
string(REGEX MATCH "define[ ]+PETSC_VERSION_SUBMINOR[ ]+([0-9]+)" TMP "${PETSC_VERSION_FILE}")
string(REGEX MATCH "define[ ]+PETSC_VERSION_SUBMINOR[ ]+([0-9]+)" _ "${_petscver}")
set(PETSC_VERSION_PATCH ${CMAKE_MATCH_1})
set(PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_PATCH}")
endif()
endif()

find_path(SLEPC_INCLUDE_DIR
NAMES slepc.h
PATHS
$ENV{PETSC_DIR}/include/slepc
$ENV{PETSC_ROOT}/include/slepc
$ENV{SLEPC_DIR}/include
$ENV{SLEPC_ROOT}/include
DOC "SLEPc include directory"
)

find_library(SLEPC_LIBRARY
NAMES slepc
PATHS
$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib
$ENV{PETSC_DIR}/lib
$ENV{PETSC_ROOT}/$ENV{PETSC_ARCH}/lib
$ENV{PETSC_ROOT}/lib
$ENV{SLEPC_DIR}/$ENV{SLEPC_ARCH}/lib
$ENV{SLEPC_ROOT}/$ENV{SLEPC_ARCH}/lib
$ENV{SLEPC_DIR}/lib
$ENV{SLEPC_ROOT}/lib
DOC "SLEPc library"
)

set(SLEPC_VERSION "unknown")
find_file(SLEPCVERSION_H
NAMES slepcversion.h
PATHS
$ENV{PETSC_DIR}/include/slepc
$ENV{PETSC_ROOT}/include/slepc
$ENV{SLEPC_DIR}/include
$ENV{SLEPC_ROOT}/include
)
if(SLEPCVERSION_H)
file(READ ${SLEPCVERSION_H} _slepcver)
string(REGEX MATCH "define[ ]+SLEPC_VERSION_MAJOR[ ]+([0-9]+)" _ "${_slepcver}")
set(SLEPC_VERSION_MAJOR ${CMAKE_MATCH_1})
string(REGEX MATCH "define[ ]+SLEPC_VERSION_MINOR[ ]+([0-9]+)" _ "${_slepcver}")
set(SLEPC_VERSION_MINOR ${CMAKE_MATCH_1})
string(REGEX MATCH "define[ ]+SLEPC_VERSION_SUBMINOR[ ]+([0-9]+)" _ "${_slepcver}")
set(SLEPC_VERSION_PATCH ${CMAKE_MATCH_1})
set(SLEPC_VERSION "${SLEPC_VERSION_MAJOR}.${SLEPC_VERSION_MINOR}.${SLEPC_VERSION_PATCH}")
endif()

if (NOT SLEPC_INCLUDE_DIR)
message(FATAL_ERROR "PETSc has not been configured with SLEPc support.")
endif()
if (NOT SLEPC_LIBRARY)
message(FATAL_ERROR "PETSc has not been configured with SLEPc support.")
endif()
set(SLEPc_FOUND TRUE)

list(APPEND PETSC_LIBRARY ${SLEPC_LIBRARY})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
PETSc
Expand Down
11 changes: 10 additions & 1 deletion framework/math/linear_solver/linear_eigen_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ class LinearEigenSolver : public LinearSolver
public:
enum class IterativeMethod : int
{
POWER
KRYLOV_SCHUR,
POWER,
ARNOLDI,
SUBSPACE
};

LinearEigenSolver(IterativeMethod method, std::shared_ptr<LinearEigenContext> ctx)
Expand All @@ -26,8 +29,14 @@ class LinearEigenSolver : public LinearSolver
{
switch (method_)
{
case IterativeMethod::KRYLOV_SCHUR:
return "KRYLOV-SCHUR";
case IterativeMethod::POWER:
return "POWER ITERATION";
case IterativeMethod::ARNOLDI:
return "ARNOLDI";
case IterativeMethod::SUBSPACE:
return "SUBSPACE";
default:
return "UNKNOWN ITERATIVE METHOD";
}
Expand Down
102 changes: 102 additions & 0 deletions framework/math/linear_solver/slepc_linear_eigen_solver.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-FileCopyrightText: 2025 The OpenSn Authors <https://open-sn.github.io/opensn/>
// SPDX-License-Identifier: MIT

#include "framework/math/linear_solver/slepc_linear_eigen_solver.h"
#include "framework/runtime.h"

namespace opensn
{

SLEPcLinearEigenSolver::SLEPcLinearEigenSolver(IterativeMethod method,
std::shared_ptr<LinearEigenContext> context_ptr)
: LinearEigenSolver(method, context_ptr),
A_(nullptr),
x_(nullptr),
eps_(nullptr),
eps_type_("krylovschur"),
num_local_dofs_(0),
num_global_dofs_(0),
system_set_(false)
{
}

SLEPcLinearEigenSolver::~SLEPcLinearEigenSolver()
{
VecDestroy(&x_);
EPSDestroy(&eps_);
}

void
SLEPcLinearEigenSolver::PreSetupCallback()
{
}

void
SLEPcLinearEigenSolver::SetOptions()
{
}

void
SLEPcLinearEigenSolver::SetSolverContext()
{
}

void
SLEPcLinearEigenSolver::SetConvergenceTest()
{
}

void
SLEPcLinearEigenSolver::SetMonitor()
{
}

void
SLEPcLinearEigenSolver::SetPreconditioner()
{
}

void
SLEPcLinearEigenSolver::PostSetupCallback()
{
}

void
SLEPcLinearEigenSolver::Setup()
{
if (IsSystemSet())
return;

PreSetupCallback();
EPSCreate(opensn::mpi_comm, &eps_);
SetOptions();
SetSolverContext();
SetConvergenceTest();
SetMonitor();
SetSystemSize();
SetSystem();
SetPreconditioner();
PostSetupCallback();

system_set_ = true;
}

void
SLEPcLinearEigenSolver::PreSolveCallback()
{
}

void
SLEPcLinearEigenSolver::PostSolveCallback()
{
}

void
SLEPcLinearEigenSolver::Solve()
{
PreSolveCallback();
SetInitialGuess();
PostSolveCallback();
}

} // namespace opensn
82 changes: 82 additions & 0 deletions framework/math/linear_solver/slepc_linear_eigen_solver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-FileCopyrightText: 2024 The OpenSn Authors <https://open-sn.github.io/opensn/>
// SPDX-License-Identifier: MIT

#pragma once

#include "framework/math/linear_solver/linear_eigen_solver.h"
#include "framework/math/linear_solver/linear_solver_context.h"
#include <string>
#include <utility>
#include <memory>
#include <slepceps.h>

namespace opensn
{

class SLEPcLinearEigenSolver : public LinearEigenSolver
{
public:
struct ToleranceOptions
{
double residual_absolute = 1.0e-6;
int maximum_iterations = 100;
} tolerance_options;

SLEPcLinearEigenSolver(IterativeMethod method, std::shared_ptr<LinearEigenContext> context_ptr);

virtual ~SLEPcLinearEigenSolver();

ToleranceOptions& GetToleranceOptions() { return tolerance_options; }

std::string GetEPSType() { return eps_type_; }

void SetEPSType(std::string& type)
{
eps_type_ = type;
if (type == "power")
method_ = IterativeMethod::POWER;
else if (type == "subspace")
method_ = IterativeMethod::SUBSPACE;
else if (type == "arnolidi")
method_ = IterativeMethod::ARNOLDI;
else if (type == "krylovschur")
method_ = IterativeMethod::KRYLOV_SCHUR;
else
throw std::runtime_error("Invalid iterative method type for linear eigen solver");
}

void ApplyToleranceOptions();

/// Set up the linaer solver
virtual void Setup();

/// Solve the system
virtual void Solve();

protected:
bool IsSystemSet() const { return system_set_; }
virtual void PreSetupCallback();
virtual void SetOptions();
virtual void SetSolverContext();
virtual void SetConvergenceTest();
virtual void SetMonitor();
virtual void SetPreconditioner();
virtual void SetSystemSize() = 0;
virtual void SetSystem() = 0;
virtual void PostSetupCallback();
virtual void PreSolveCallback();
virtual void SetInitialGuess() = 0;
virtual void PostSolveCallback();

Mat A_;
Vec x_;
EPS eps_;
std::string eps_type_;
int64_t num_local_dofs_;
int64_t num_global_dofs_;

private:
bool system_set_;
};

} // namespace opensn
Loading