Skip to content

Commit

Permalink
Add option to output subdomain matrices in elliptic solver
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsvu committed Oct 11, 2023
1 parent b1ca770 commit 621cb44
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 14 deletions.
50 changes: 48 additions & 2 deletions src/NumericalAlgorithms/LinearSolver/ExplicitInverse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,26 @@

#include <algorithm>
#include <cstddef>
#include <fstream>
#include <string>
#include <tuple>
#include <vector>

#include "DataStructures/DataBox/DataBox.hpp"
#include "DataStructures/DynamicMatrix.hpp"
#include "DataStructures/DynamicVector.hpp"
#include "NumericalAlgorithms/Convergence/HasConverged.hpp"
#include "NumericalAlgorithms/LinearSolver/BuildMatrix.hpp"
#include "NumericalAlgorithms/LinearSolver/LinearSolver.hpp"
#include "Options/Auto.hpp"
#include "Options/String.hpp"
#include "Parallel/Tags/ArrayIndex.hpp"
#include "Utilities/ErrorHandling/Error.hpp"
#include "Utilities/Gsl.hpp"
#include "Utilities/MakeWithValue.hpp"
#include "Utilities/NoSuchType.hpp"
#include "Utilities/Serialization/CharmPupable.hpp"
#include "Utilities/Serialization/PupStlCpp17.hpp"
#include "Utilities/TMPL.hpp"

namespace LinearSolver::Serial {
Expand Down Expand Up @@ -73,19 +80,32 @@ class ExplicitInverse : public LinearSolver<LinearSolverRegistrars> {
using Base = LinearSolver<LinearSolverRegistrars>;

public:
using options = tmpl::list<>;
struct WriteMatrixToFile {
using type = Options::Auto<std::string, Options::AutoLabel::None>;
static constexpr Options::String help =
"Write the matrix representation of the linear operator to a "
"space-delimited CSV file with this name. A '.txt' extension will be "
"added. Also a suffix with the element ID will be added if this linear "
"solver runs on an array element, so one file per element will be "
"written.";
};

using options = tmpl::list<WriteMatrixToFile>;
static constexpr Options::String help =
"Build a matrix representation of the linear operator and invert it "
"directly. This means that the first solve has a large initialization "
"cost, but all subsequent solves converge immediately.";

ExplicitInverse() = default;
ExplicitInverse(const ExplicitInverse& /*rhs*/) = default;
ExplicitInverse& operator=(const ExplicitInverse& /*rhs*/) = default;
ExplicitInverse(ExplicitInverse&& /*rhs*/) = default;
ExplicitInverse& operator=(ExplicitInverse&& /*rhs*/) = default;
~ExplicitInverse() = default;

explicit ExplicitInverse(
std::optional<std::string> matrix_filename = std::nullopt)
: matrix_filename_(std::move(matrix_filename)) {}

/// \cond
explicit ExplicitInverse(CkMigrateMessage* m) : Base(m) {}
using PUP::able::register_constructor;
Expand Down Expand Up @@ -130,6 +150,7 @@ class ExplicitInverse : public LinearSolver<LinearSolverRegistrars> {

// NOLINTNEXTLINE(google-runtime-references)
void pup(PUP::er& p) override {
p | matrix_filename_;
p | size_;
p | inverse_;
if (p.isUnpacking() and size_ != std::numeric_limits<size_t>::max()) {
Expand All @@ -143,6 +164,7 @@ class ExplicitInverse : public LinearSolver<LinearSolverRegistrars> {
}

private:
std::optional<std::string> matrix_filename_{};
// Caches for successive solves of the same operator
// NOLINTNEXTLINE(spectre-mutable)
mutable size_t size_ = std::numeric_limits<size_t>::max();
Expand Down Expand Up @@ -177,6 +199,30 @@ Convergence::HasConverged ExplicitInverse<LinearSolverRegistrars>::solve(
auto result_buffer = make_with_value<SourceType>(used_for_size, 0.);
build_matrix(make_not_null(&inverse_), make_not_null(&operand_buffer),
make_not_null(&result_buffer), linear_operator, operator_args);
// Write to file before inverting
if (UNLIKELY(matrix_filename_.has_value())) {
const auto filename_suffix =
[&operator_args]() -> std::optional<std::string> {
using DataBoxType =
std::decay_t<tmpl::front<tmpl::list<OperatorArgs..., NoSuchType>>>;
if constexpr (tt::is_a_v<db::DataBox, DataBoxType>) {
if constexpr (db::tag_is_retrievable_v<Parallel::Tags::ArrayIndex,
DataBoxType>) {
const auto& box = get<0>(operator_args);

Check failure on line 211 in src/NumericalAlgorithms/LinearSolver/ExplicitInverse.hpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Debug)

use of function template name with no prior declaration in function call with explicit template arguments is a C++20 extension

Check failure on line 211 in src/NumericalAlgorithms/LinearSolver/ExplicitInverse.hpp

View workflow job for this annotation

GitHub Actions / Clang-tidy (Release)

use of function template name with no prior declaration in function call with explicit template arguments is a C++20 extension
return "_" + get_output(db::get<Parallel::Tags::ArrayIndex>(box));
} else {
(void)operator_args;
return std::nullopt;
}
} else {
(void)operator_args;
return std::nullopt;
}
}();
std::ofstream matrix_file(matrix_filename_.value() +
filename_suffix.value_or("") + ".txt");
write_csv(matrix_file, inverse_, " ");
}
// Directly invert the matrix
try {
blaze::invert(inverse_);
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Elasticity/BentBeam.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ LinearSolver:
Iterations: 3
MaxOverlap: 2
Verbosity: Quiet
SubdomainSolver: ExplicitInverse
SubdomainSolver:
ExplicitInverse:
WriteMatrixToFile: None
ObservePerCoreReductions: False

EventsAndTriggers:
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Elasticity/HalfSpaceMirror.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ LinearSolver:
Restart: None
Preconditioner:
MinusLaplacian:
Solver: ExplicitInverse
Solver:
ExplicitInverse:
WriteMatrixToFile: None
BoundaryConditions: Auto
ObservePerCoreReductions: False

Expand Down
6 changes: 5 additions & 1 deletion tests/InputFiles/Poisson/ProductOfSinusoids1D.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Testing:
ExpectedOutput:
- PoissonProductOfSinusoids1DReductions.h5
- PoissonProductOfSinusoids1DVolume0.h5
- SubdomainMatrix_[B0,(L1I0)].txt
- SubdomainMatrix_[B0,(L1I1)].txt
OutputFileChecks:
- Label: Discretization error
Subfile: /ErrorNorms.dat
Expand Down Expand Up @@ -75,7 +77,9 @@ LinearSolver:
Iterations: 3
MaxOverlap: 2
Verbosity: Quiet
SubdomainSolver: ExplicitInverse
SubdomainSolver:
ExplicitInverse:
WriteMatrixToFile: "SubdomainMatrix"
ObservePerCoreReductions: False

RadiallyCompressedCoordinates: None
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Poisson/ProductOfSinusoids2D.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ LinearSolver:
Iterations: 3
MaxOverlap: 2
Verbosity: Quiet
SubdomainSolver: ExplicitInverse
SubdomainSolver:
ExplicitInverse:
WriteMatrixToFile: None
ObservePerCoreReductions: False

RadiallyCompressedCoordinates: None
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Poisson/ProductOfSinusoids3D.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ LinearSolver:
Iterations: 3
MaxOverlap: 2
Verbosity: Quiet
SubdomainSolver: ExplicitInverse
SubdomainSolver:
ExplicitInverse:
WriteMatrixToFile: None
ObservePerCoreReductions: False

RadiallyCompressedCoordinates: None
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Punctures/MultiplePunctures.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ LinearSolver:
Restart: None
Preconditioner:
MinusLaplacian:
Solver: ExplicitInverse
Solver:
ExplicitInverse:
WriteMatrixToFile: None
BoundaryConditions: Auto
SkipResets: True
ObservePerCoreReductions: False
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Xcts/BinaryBlackHole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ LinearSolver:
Restart: None
Preconditioner:
MinusLaplacian:
Solver: ExplicitInverse
Solver:
ExplicitInverse:
WriteMatrixToFile: None
BoundaryConditions: Auto
SkipResets: True
ObservePerCoreReductions: False
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Xcts/HeadOnBns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ LinearSolver:
Restart: None
Preconditioner:
MinusLaplacian:
Solver: ExplicitInverse
Solver:
ExplicitInverse:
WriteMatrixToFile: None
BoundaryConditions: Auto
SkipResets: True
ObservePerCoreReductions: False
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Xcts/KerrSchild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ LinearSolver:
Restart: None
Preconditioner:
MinusLaplacian:
Solver: ExplicitInverse
Solver:
ExplicitInverse:
WriteMatrixToFile: None
BoundaryConditions: Auto
SkipResets: True
ObservePerCoreReductions: False
Expand Down
4 changes: 3 additions & 1 deletion tests/InputFiles/Xcts/TovStar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ LinearSolver:
Restart: None
Preconditioner:
MinusLaplacian:
Solver: ExplicitInverse
Solver:
ExplicitInverse:
WriteMatrixToFile: None
BoundaryConditions: Auto
SkipResets: True
ObservePerCoreReductions: False
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,16 @@ SPECTRE_TEST_CASE("Unit.LinearSolver.Serial.ExplicitInverse",
const blaze::DynamicVector<double> source{1., 2.};
const blaze::DynamicVector<double> expected_solution{-1., 5.};
blaze::DynamicVector<double> solution(2);
const ExplicitInverse<> solver{};
const ExplicitInverse<> solver{"Matrix"};
const auto has_converged =
solver.solve(make_not_null(&solution), linear_operator, source);
REQUIRE(has_converged);
CHECK_MATRIX_APPROX(solver.matrix_representation(), blaze::inv(matrix));
CHECK_ITERABLE_APPROX(solution, expected_solution);
std::ifstream matrix_file("Matrix.txt");
std::string matrix_csv((std::istreambuf_iterator<char>(matrix_file)),
std::istreambuf_iterator<char>());
CHECK(matrix_csv == "4 1\n3 1\n");
{
INFO("Resetting");
ExplicitInverse<> resetting_solver{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ SchwarzSmoother:
Preconditioner:
# Preconditioning with the explicitly-built inverse matrix, so all
# subdomain solves should converge immediately
ExplicitInverse
ExplicitInverse:
WriteMatrixToFile: None
ObservePerCoreReductions: False

ConvergenceReason: NumIterations
Expand Down

0 comments on commit 621cb44

Please sign in to comment.