DDC 0.1.0
Loading...
Searching...
No Matches
splines_linear_problem_maker.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <algorithm>
8#include <cassert>
9#include <cstddef>
10#include <memory>
11#include <optional>
12#include <utility>
13
14#include "splines_linear_problem_2x2_blocks.hpp"
15#include "splines_linear_problem_3x3_blocks.hpp"
16#include "splines_linear_problem_band.hpp"
17#include "splines_linear_problem_dense.hpp"
18#include "splines_linear_problem_pds_band.hpp"
19#include "splines_linear_problem_pds_tridiag.hpp"
20#include "splines_linear_problem_sparse.hpp"
21
22namespace ddc::detail {
23
24/**
25 * @brief A static factory for SplinesLinearProblem classes.
26 */
27class SplinesLinearProblemMaker
28{
29public:
30 /**
31 * @brief Construct a dense matrix
32 *
33 * @tparam the Kokkos::ExecutionSpace on which matrix-related operation will be performed.
34 * @param n The size of one of the dimensions of the square matrix.
35 *
36 * @return The SplinesLinearProblem instance.
37 */
38 template <typename ExecSpace>
39 static std::unique_ptr<SplinesLinearProblem<ExecSpace>> make_new_dense(int const n)
40 {
41 return std::make_unique<SplinesLinearProblemDense<ExecSpace>>(n);
42 }
43
44 /**
45 * @brief Construct a band matrix
46 *
47 * @tparam the Kokkos::ExecutionSpace on which matrix-related operation will be performed.
48 * @param n The size of one of the dimensions of the square matrix.
49 * @param kl The number of subdiagonals.
50 * @param ku The number of superdiagonals.
51 * @param pds A boolean indicating if the matrix is positive-definite symetric or not.
52 *
53 * @return The SplinesLinearProblem instance.
54 */
55 template <typename ExecSpace>
56 static std::unique_ptr<SplinesLinearProblem<ExecSpace>> make_new_band(
57 int const n,
58 int const kl,
59 int const ku,
60 bool const pds)
61 {
62 if (kl == ku && kl == 1 && pds) {
63 return std::make_unique<SplinesLinearProblemPDSTridiag<ExecSpace>>(n);
64 }
65
66 if (kl == ku && pds) {
67 return std::make_unique<SplinesLinearProblemPDSBand<ExecSpace>>(n, kl);
68 }
69
70 if (2 * kl + ku + 1 >= n) {
71 return std::make_unique<SplinesLinearProblemDense<ExecSpace>>(n);
72 }
73
74 return std::make_unique<SplinesLinearProblemBand<ExecSpace>>(n, kl, ku);
75 }
76
77 /**
78 * @brief Construct a 2x2-blocks or 3x3-blocks linear problem with band "main" block (the one called
79 * Q in SplinesLinearProblem2x2Blocks and SplinesLinearProblem3x3Blocks).
80 *
81 * @tparam the Kokkos::ExecutionSpace on which matrix-related operation will be performed.
82 * @param n The size of one of the dimensions of the whole square matrix.
83 * @param kl The number of subdiagonals in the band block.
84 * @param ku The number of superdiagonals in the band block.
85 * @param pds A boolean indicating if the band block is positive-definite symetric or not.
86 * @param bottom_right_size The size of one of the dimensions of the bottom-right square block.
87 * @param top_left_size The size of one of the dimensions of the top-left square block.
88 *
89 * @return The SplinesLinearProblem instance.
90 */
91 template <typename ExecSpace>
92 static std::unique_ptr<SplinesLinearProblem<ExecSpace>>
93 make_new_block_matrix_with_band_main_block(
94 int const n,
95 int const kl,
96 int const ku,
97 bool const pds,
98 int const bottom_right_size,
99 int const top_left_size = 0)
100 {
101 int const main_size = n - top_left_size - bottom_right_size;
102 std::unique_ptr<SplinesLinearProblem<ExecSpace>> main_block
103 = make_new_band<ExecSpace>(main_size, kl, ku, pds);
104 if (top_left_size == 0) {
105 return std::make_unique<
106 SplinesLinearProblem2x2Blocks<ExecSpace>>(n, std::move(main_block));
107 }
108 return std::make_unique<
109 SplinesLinearProblem3x3Blocks<ExecSpace>>(n, top_left_size, std::move(main_block));
110 }
111
112 /**
113 * @brief Construct a 2x2-blocks linear problem with band "main" block (the one called
114 * Q in SplinesLinearProblem2x2Blocks) and other blocks containing the "periodic parts" of
115 * a periodic band matrix.
116 *
117 * It simply calls make_new_block_matrix_with_band_main_block with bottom_size being
118 * max(kl, ku) (except if the allocation would be higher than instantiating a SplinesLinearProblemDense).
119 *
120 * @tparam the Kokkos::ExecutionSpace on which matrix-related operation will be performed.
121 * @param n The size of one of the dimensions of the whole square matrix.
122 * @param kl The number of subdiagonals in the band block.
123 * @param ku The number of superdiagonals in the band block.
124 * @param pds A boolean indicating if the band block is positive-definite symetric or not.
125 *
126 * @return The SplinesLinearProblem instance.
127 */
128 template <typename ExecSpace>
129 static std::unique_ptr<SplinesLinearProblem<ExecSpace>> make_new_periodic_band_matrix(
130 int const n,
131 int const kl,
132 int const ku,
133 bool const pds)
134 {
135 assert(kl < n);
136 assert(ku < n);
137 int const bottom_size = std::max(kl, ku);
138 int const top_size = n - bottom_size;
139
140 if (bottom_size * (n + top_size) + (2 * kl + ku + 1) * top_size >= n * n) {
141 return std::make_unique<SplinesLinearProblemDense<ExecSpace>>(n);
142 }
143
144 return make_new_block_matrix_with_band_main_block<ExecSpace>(n, kl, ku, pds, bottom_size);
145 }
146
147 /**
148 * @brief Construct a sparse matrix
149 *
150 * @tparam the Kokkos::ExecutionSpace on which matrix-related operation will be performed.
151 * @param n The size of one of the dimensions of the square matrix.
152 * @param cols_per_chunk A parameter used by the slicer (internal to the solver) to define the size
153 * of a chunk of right-hand sides of the linear problem to be computed in parallel (chunks are treated
154 * by the linear solver one-after-the-other).
155 * This value is optional. If no value is provided then the default value is chosen by the requested solver.
156 *
157 * @param preconditioner_max_block_size A parameter used by the slicer (internal to the solver) to
158 * define the size of a block used by the Block-Jacobi preconditioner.
159 * This value is optional. If no value is provided then the default value is chosen by the requested solver.
160 *
161 * @return The SplinesLinearProblem instance.
162 */
163 template <typename ExecSpace>
164 static std::unique_ptr<SplinesLinearProblem<ExecSpace>> make_new_sparse(
165 int const n,
166 std::optional<std::size_t> cols_per_chunk = std::nullopt,
167 std::optional<unsigned int> preconditioner_max_block_size = std::nullopt)
168 {
169 return std::make_unique<SplinesLinearProblemSparse<
170 ExecSpace>>(n, cols_per_chunk, preconditioner_max_block_size);
171 }
172};
173
174} // namespace ddc::detail
The top-level namespace of DDC.