DOLFINx 0.10.0.0
DOLFINx C++ interface
Loading...
Searching...
No Matches
petsc.h
1// Copyright (C) 2004-2018 Johan Hoffman, Johan Jansson, Anders Logg and
2// Garth N. Wells
3//
4// This file is part of DOLFINx (https://www.fenicsproject.org)
5//
6// SPDX-License-Identifier: LGPL-3.0-or-later
7
8#pragma once
9
10#ifdef HAS_PETSC
11
12#include "Vector.h"
13#include "utils.h"
14#include <boost/lexical_cast.hpp>
15#include <functional>
16#include <optional>
17#include <petscksp.h>
18#include <petscmat.h>
19#include <petscoptions.h>
20#include <petscvec.h>
21#include <span>
22#include <string>
23#include <vector>
24
25namespace dolfinx::common
26{
27class IndexMap;
28} // namespace dolfinx::common
29
30namespace dolfinx::la
31{
32class SparsityPattern;
33
35namespace petsc
36{
38void error(int error_code, const std::string& filename,
39 const std::string& petsc_function);
40
48std::vector<Vec>
49create_vectors(MPI_Comm comm,
50 const std::vector<std::span<const PetscScalar>>& x);
51
57Vec create_vector(const common::IndexMap& map, int bs);
58
67Vec create_vector(MPI_Comm comm, std::array<std::int64_t, 2> range,
68 std::span<const std::int64_t> ghosts, int bs);
69
79Vec create_vector_wrap(const common::IndexMap& map, int bs,
80 std::span<const PetscScalar> x);
81
85template <class V>
86Vec create_vector_wrap(const la::Vector<V>& x)
87{
88 assert(x.index_map());
89 return create_vector_wrap(*x.index_map(), x.bs(), x.array());
90}
91
104std::vector<IS> create_index_sets(
105 const std::vector<
106 std::pair<std::reference_wrapper<const common::IndexMap>, int>>& maps);
107
109std::vector<std::vector<PetscScalar>> get_local_vectors(
110 const Vec x,
111 const std::vector<
112 std::pair<std::reference_wrapper<const common::IndexMap>, int>>& maps);
113
115void scatter_local_vectors(
116 Vec x, const std::vector<std::span<const PetscScalar>>& x_b,
117 const std::vector<
118 std::pair<std::reference_wrapper<const common::IndexMap>, int>>& maps);
119
122Mat create_matrix(MPI_Comm comm, const SparsityPattern& sp,
123 std::optional<std::string> type = std::nullopt);
124
130MatNullSpace create_nullspace(MPI_Comm comm, std::span<const Vec> basis);
131
137namespace options
138{
140void set(std::string option);
141
143template <typename T>
144void set(std::string option, const T& value)
145{
146 if (option[0] != '-')
147 option = '-' + option;
148
149 PetscErrorCode ierr;
150 ierr = PetscOptionsSetValue(nullptr, option.c_str(),
151 boost::lexical_cast<std::string>(value).c_str());
152 if (ierr != 0)
153 petsc::error(ierr, __FILE__, "PetscOptionsSetValue");
154}
155
157void clear(std::string option);
158
160void clear();
161} // namespace options
162
168class Vector
169{
170public:
175 Vector(const common::IndexMap& map, int bs);
176
177 // Delete copy constructor to avoid accidental copying of 'heavy' data
178 Vector(const Vector& x) = delete;
179
181 Vector(Vector&& x) noexcept;
182
194 Vector(Vec x, bool inc_ref_count);
195
197 virtual ~Vector();
198
199 // Assignment operator (disabled)
200 Vector& operator=(const Vector& x) = delete;
201
203 Vector& operator=(Vector&& x) noexcept;
204
207 Vector copy() const;
208
210 std::int64_t size() const;
211
213 std::int32_t local_size() const;
214
216 std::array<std::int64_t, 2> local_range() const;
217
219 MPI_Comm comm() const;
220
222 void set_options_prefix(const std::string& options_prefix);
223
226 std::string get_options_prefix() const;
227
229 void set_from_options();
230
232 Vec vec() const;
233
234private:
235 // PETSc Vec pointer
236 Vec _x;
237};
238
241class Operator
242{
243public:
245 Operator(Mat A, bool inc_ref_count);
246
247 // Copy constructor (deleted)
248 Operator(const Operator& A) = delete;
249
251 Operator(Operator&& A) noexcept;
252
254 virtual ~Operator();
255
257 Operator& operator=(const Operator& A) = delete;
258
260 Operator& operator=(Operator&& A) noexcept;
261
264 std::array<std::int64_t, 2> size() const;
265
271 Vec create_vector(std::size_t dim) const;
272
274 Mat mat() const;
275
276protected:
277 // PETSc Mat pointer
278 Mat _matA;
279};
280
286class Matrix : public Operator
287{
288public:
293 static auto set_fn(Mat A, InsertMode mode)
294 {
295 return [A, mode, cache = std::vector<PetscInt>()](
296 std::span<const std::int32_t> rows,
297 std::span<const std::int32_t> cols,
298 std::span<const PetscScalar> vals) mutable -> int
299 {
300 PetscErrorCode ierr;
301#ifdef PETSC_USE_64BIT_INDICES
302 cache.resize(rows.size() + cols.size());
303 std::ranges::copy(rows, cache.begin());
304 std::ranges::copy(cols, std::next(cache.begin(), rows.size()));
305 const PetscInt* _rows = cache.data();
306 const PetscInt* _cols = cache.data() + rows.size();
307 ierr = MatSetValuesLocal(A, rows.size(), _rows, cols.size(), _cols,
308 vals.data(), mode);
309#else
310 ierr = MatSetValuesLocal(A, rows.size(), rows.data(), cols.size(),
311 cols.data(), vals.data(), mode);
312#endif
313
314#ifndef NDEBUG
315 if (ierr != 0)
316 petsc::error(ierr, __FILE__, "MatSetValuesLocal");
317#endif
318 return ierr;
319 };
320 }
321
327 static auto set_block_fn(Mat A, InsertMode mode)
328 {
329 return [A, mode, cache = std::vector<PetscInt>()](
330 std::span<const std::int32_t> rows,
331 std::span<const std::int32_t> cols,
332 std::span<const PetscScalar> vals) mutable -> int
333 {
334 PetscErrorCode ierr;
335#ifdef PETSC_USE_64BIT_INDICES
336 cache.resize(rows.size() + cols.size());
337 std::ranges::copy(rows, cache.begin());
338 std::ranges::copy(cols, std::next(cache.begin(), rows.size()));
339 const PetscInt* _rows = cache.data();
340 const PetscInt* _cols = cache.data() + rows.size();
341 ierr = MatSetValuesBlockedLocal(A, rows.size(), _rows, cols.size(), _cols,
342 vals.data(), mode);
343#else
344 ierr = MatSetValuesBlockedLocal(A, rows.size(), rows.data(), cols.size(),
345 cols.data(), vals.data(), mode);
346#endif
347
348#ifndef NDEBUG
349 if (ierr != 0)
350 petsc::error(ierr, __FILE__, "MatSetValuesBlockedLocal");
351#endif
352 return ierr;
353 };
354 }
355
364 static auto set_block_expand_fn(Mat A, int bs0, int bs1, InsertMode mode)
365 {
366 return [A, bs0, bs1, mode, cache0 = std::vector<PetscInt>(),
367 cache1 = std::vector<PetscInt>()](
368 std::span<const std::int32_t> rows,
369 std::span<const std::int32_t> cols,
370 std::span<const PetscScalar> vals) mutable -> int
371 {
372 PetscErrorCode ierr;
373 cache0.resize(bs0 * rows.size());
374 cache1.resize(bs1 * cols.size());
375 for (std::size_t i = 0; i < rows.size(); ++i)
376 for (int k = 0; k < bs0; ++k)
377 cache0[bs0 * i + k] = bs0 * rows[i] + k;
378
379 for (std::size_t i = 0; i < cols.size(); ++i)
380 for (int k = 0; k < bs1; ++k)
381 cache1[bs1 * i + k] = bs1 * cols[i] + k;
382
383 ierr = MatSetValuesLocal(A, cache0.size(), cache0.data(), cache1.size(),
384 cache1.data(), vals.data(), mode);
385#ifndef NDEBUG
386 if (ierr != 0)
387 petsc::error(ierr, __FILE__, "MatSetValuesLocal");
388#endif
389 return ierr;
390 };
391 }
392
394 Matrix(MPI_Comm comm, const SparsityPattern& sp,
395 std::optional<std::string> type = std::nullopt);
396
401 Matrix(Mat A, bool inc_ref_count);
402
403 // Copy constructor (deleted)
404 Matrix(const Matrix& A) = delete;
405
407 Matrix(Matrix&& A) = default;
408
410 ~Matrix() = default;
411
413 Matrix& operator=(const Matrix& A) = delete;
414
416 Matrix& operator=(Matrix&& A) = default;
417
421 enum class AssemblyType : std::int8_t
422 {
423 FINAL,
424 FLUSH
425 };
426
432 void apply(AssemblyType type);
433
435 double norm(Norm norm_type) const;
436
437 //--- Special PETSc Functions ---
438
441 void set_options_prefix(const std::string& options_prefix);
442
445 std::string get_options_prefix() const;
446
448 void set_from_options();
449};
450
453class KrylovSolver
454{
455public:
458 explicit KrylovSolver(MPI_Comm comm);
459
463 KrylovSolver(KSP ksp, bool inc_ref_count);
464
465 // Copy constructor (deleted)
466 KrylovSolver(const KrylovSolver& solver) = delete;
467
469 KrylovSolver(KrylovSolver&& solver) noexcept;
470
472 ~KrylovSolver();
473
474 // Assignment operator (deleted)
475 KrylovSolver& operator=(const KrylovSolver&) = delete;
476
478 KrylovSolver& operator=(KrylovSolver&& solver) noexcept;
479
481 void set_operator(const Mat A);
482
484 void set_operators(const Mat A, const Mat P);
485
488 int solve(Vec x, const Vec b, bool transpose = false) const;
489
492 void set_options_prefix(const std::string& options_prefix);
493
496 std::string get_options_prefix() const;
497
499 void set_from_options() const;
500
502 KSP ksp() const;
503
504private:
505 // PETSc solver pointer
506 KSP _ksp;
507};
508} // namespace petsc
509} // namespace dolfinx::la
510
511#endif
Definition IndexMap.h:96
Definition SparsityPattern.h:26
int size(MPI_Comm comm)
Definition MPI.cpp:72
constexpr std::array< std::int64_t, 2 > local_range(int rank, std::int64_t N, int size)
Return local range for the calling process, partitioning the global [0, N - 1] range across all ranks...
Definition MPI.h:89
Miscellaneous classes, functions and types.
Definition dolfinx_common.h:8
Linear algebra interface.
Definition sparsitybuild.h:15
auto norm(const V &x, Norm type=Norm::l2)
Definition Vector.h:267