Skip to content

Commit 9ff0203

Browse files
Unify PETSc matrix and vector factory functions (#3667)
* Create singelton constructors for PETSc matrix and vectors * Modify docs * Fix type hint * Simplification * Simplification * Small fix * Remove default arg in low level function * Small update --------- Co-authored-by: Garth N. Wells <[email protected]>
1 parent 9b3f4c5 commit 9ff0203

File tree

8 files changed

+164
-290
lines changed

8 files changed

+164
-290
lines changed

cpp/dolfinx/fem/petsc.h

+22-20
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <functional>
1717
#include <map>
1818
#include <memory>
19+
#include <optional>
1920
#include <petscmat.h>
2021
#include <petscvec.h>
2122
#include <span>
@@ -43,7 +44,7 @@ namespace petsc
4344
/// object.
4445
template <std::floating_point T>
4546
Mat create_matrix(const Form<PetscScalar, T>& a,
46-
std::string type = std::string())
47+
std::optional<std::string> type = std::nullopt)
4748
{
4849
la::SparsityPattern pattern = fem::create_sparsity_pattern(a);
4950
pattern.finalize();
@@ -52,6 +53,7 @@ Mat create_matrix(const Form<PetscScalar, T>& a,
5253

5354
/// @brief Initialise a monolithic matrix for an array of bilinear
5455
/// forms.
56+
///
5557
/// @param[in] a Rectangular array of bilinear forms. The `a(i, j)` form
5658
/// will correspond to the `(i, j)` block in the returned matrix
5759
/// @param[in] type The type of PETSc Mat. If empty the PETSc default is
@@ -62,7 +64,7 @@ Mat create_matrix(const Form<PetscScalar, T>& a,
6264
template <std::floating_point T>
6365
Mat create_matrix_block(
6466
const std::vector<std::vector<const Form<PetscScalar, T>*>>& a,
65-
std::string type = std::string())
67+
std::optional<std::string> type = std::nullopt)
6668
{
6769
// Extract and check row/column ranges
6870
std::array<std::vector<std::shared_ptr<const FunctionSpace<T>>>, 2> V
@@ -191,16 +193,11 @@ Mat create_matrix_block(
191193
template <std::floating_point T>
192194
Mat create_matrix_nest(
193195
const std::vector<std::vector<const Form<PetscScalar, T>*>>& a,
194-
const std::vector<std::vector<std::string>>& types)
196+
std::optional<std::vector<std::vector<std::optional<std::string>>>> types)
195197
{
196198
// Extract and check row/column ranges
197199
auto V = fem::common_function_spaces(extract_function_spaces(a));
198200

199-
std::vector<std::vector<std::string>> _types(
200-
a.size(), std::vector<std::string>(a.front().size()));
201-
if (!types.empty())
202-
_types = types;
203-
204201
// Loop over each form and create matrix
205202
int rows = a.size();
206203
int cols = a.front().size();
@@ -212,7 +209,10 @@ Mat create_matrix_nest(
212209
{
213210
if (const Form<PetscScalar, T>* form = a[i][j]; form)
214211
{
215-
mats[i * cols + j] = create_matrix(*form, _types[i][j]);
212+
if (types)
213+
mats[i * cols + j] = create_matrix(*form, types->at(i).at(j));
214+
else
215+
mats[i * cols + j] = create_matrix(*form, std::nullopt);
216216
mesh = form->mesh();
217217
}
218218
}
@@ -238,14 +238,14 @@ Mat create_matrix_nest(
238238
return A;
239239
}
240240

241-
/// Initialise monolithic vector. Vector is not zeroed.
241+
/// @brief Initialise monolithic vector. Vector is not zeroed.
242242
///
243243
/// The caller is responsible for destroying the Mat object
244244
Vec create_vector_block(
245245
const std::vector<
246246
std::pair<std::reference_wrapper<const common::IndexMap>, int>>& maps);
247247

248-
/// Create nested (VecNest) vector. Vector is not zeroed.
248+
/// @brief Create nested (VecNest) vector. Vector is not zeroed.
249249
Vec create_vector_nest(
250250
const std::vector<
251251
std::pair<std::reference_wrapper<const common::IndexMap>, int>>& maps);
@@ -283,15 +283,16 @@ void assemble_vector(
283283
VecGhostRestoreLocalForm(b, &b_local);
284284
}
285285

286-
/// Assemble linear form into an already allocated PETSc vector. Ghost
287-
/// contributions are not accumulated (not sent to owner). Caller is
288-
/// responsible for calling VecGhostUpdateBegin/End.
286+
/// @brief Assemble linear form into an already allocated PETSc vector.
289287
///
290-
/// @param[in,out] b The PETsc vector to assemble the form into. The
291-
/// vector must already be initialised with the correct size. The
292-
/// process-local contribution of the form is assembled into this
293-
/// vector. It is not zeroed before assembly.
294-
/// @param[in] L The linear form to assemble
288+
/// Ghost contributions are not accumulated (not sent to owner). Caller
289+
/// is responsible for calling `VecGhostUpdateBegin`/`End`.
290+
///
291+
/// @param[in,out] b Vector to assemble the form into. The vector must
292+
/// already be initialised with the correct size. The process-local
293+
/// contribution of the form is assembled into this vector. It is not
294+
/// zeroed before assembly.
295+
/// @param[in] L Linear form to assemble.
295296
template <std::floating_point T>
296297
void assemble_vector(Vec b, const Form<PetscScalar, T>& L)
297298
{
@@ -462,7 +463,8 @@ void apply_lifting(
462463
template <std::floating_point T>
463464
void set_bc(
464465
Vec b,
465-
const std::vector<std::reference_wrapper<const DirichletBC<PetscScalar, T>>> bcs,
466+
const std::vector<std::reference_wrapper<const DirichletBC<PetscScalar, T>>>
467+
bcs,
466468
const Vec x0, PetscScalar alpha = 1)
467469
{
468470
PetscInt n = 0;

cpp/dolfinx/la/petsc.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ void la::petsc::scatter_local_vectors(
231231
}
232232
//-----------------------------------------------------------------------------
233233
Mat la::petsc::create_matrix(MPI_Comm comm, const SparsityPattern& sp,
234-
std::string type)
234+
std::optional<std::string> type)
235235
{
236236
PetscErrorCode ierr;
237237
Mat A;
@@ -243,8 +243,8 @@ Mat la::petsc::create_matrix(MPI_Comm comm, const SparsityPattern& sp,
243243
std::array maps = {sp.index_map(0), sp.index_map(1)};
244244
const std::array bs = {sp.block_size(0), sp.block_size(1)};
245245

246-
if (!type.empty())
247-
MatSetType(A, type.c_str());
246+
if (type)
247+
MatSetType(A, type->c_str());
248248

249249
// Get global and local dimensions
250250
const std::int64_t M = bs[0] * maps[0]->size_global();
@@ -561,7 +561,7 @@ Mat petsc::Operator::mat() const { return _matA; }
561561
//-----------------------------------------------------------------------------
562562
//-----------------------------------------------------------------------------
563563
petsc::Matrix::Matrix(MPI_Comm comm, const SparsityPattern& sp,
564-
std::string type)
564+
std::optional<std::string> type)
565565
: Operator(petsc::create_matrix(comm, sp, type), false)
566566
{
567567
// Do nothing

cpp/dolfinx/la/petsc.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "utils.h"
1414
#include <boost/lexical_cast.hpp>
1515
#include <functional>
16+
#include <optional>
1617
#include <petscksp.h>
1718
#include <petscmat.h>
1819
#include <petscoptions.h>
@@ -118,7 +119,7 @@ void scatter_local_vectors(
118119
/// Create a PETSc Mat. Caller is responsible for destroying the
119120
/// returned object.
120121
Mat create_matrix(MPI_Comm comm, const SparsityPattern& sp,
121-
std::string type = std::string());
122+
std::optional<std::string> type = std::nullopt);
122123

123124
/// Create PETSc MatNullSpace. Caller is responsible for destruction
124125
/// returned object.
@@ -390,7 +391,7 @@ class Matrix : public Operator
390391

391392
/// Create holder for a PETSc Mat object from a sparsity pattern
392393
Matrix(MPI_Comm comm, const SparsityPattern& sp,
393-
std::string type = std::string());
394+
std::optional<std::string> type = std::nullopt);
394395

395396
/// Create holder of a PETSc Mat object/pointer. The Mat A object
396397
/// should already be created. If inc_ref_count is true, the reference

python/demo/demo_stokes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def nested_iterative_solver():
249249
# a vector that spans the nullspace to the solver, and any component
250250
# of the solution in this direction will be eliminated during the
251251
# solution process.
252-
null_vec = fem.petsc.create_vector_nest(L)
252+
null_vec = fem.petsc.create_vector(L, "nest")
253253

254254
# Set velocity part to zero and the pressure part to a non-zero
255255
# constant

0 commit comments

Comments
 (0)