DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
petsc.h
1// Copyright (C) 2018-2026 Garth N. Wells and Jack S. Hale
2//
3// This file is part of DOLFINx (https://www.fenicsproject.org)
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6
7#pragma once
8
9#ifdef HAS_PETSC
10
11#include "Form.h"
12#include "Function.h"
13#include "assembler.h"
14#include "utils.h"
15#include <cassert>
16#include <concepts>
17#include <cstdint>
18#include <dolfinx/la/petsc.h>
19#include <format>
20#include <functional>
21#include <map>
22#include <memory>
23#include <numeric>
24#include <optional>
25#include <petscmat.h>
26#include <petscvec.h>
27#include <ranges>
28#include <span>
29#include <stdexcept>
30#include <utility>
31#include <vector>
32
33namespace dolfinx::common
34{
35class IndexMap;
36}
37
38namespace dolfinx::fem
39{
40template <dolfinx::scalar T, std::floating_point U>
41class DirichletBC;
42
44namespace petsc
45{
52template <std::floating_point T>
54 std::optional<std::string> type = std::nullopt)
55{
57 pattern.finalize();
58 return la::petsc::create_matrix(a.mesh()->comm(), pattern, type);
59}
60
71template <std::floating_point T>
73 const std::vector<std::vector<const Form<PetscScalar, T>*>>& a,
74 std::optional<std::string> type = std::nullopt)
75{
76 // Extract and check row/column ranges
77 std::array<std::vector<std::shared_ptr<const FunctionSpace<T>>>, 2> V
79 std::array<std::vector<int>, 2> bs_dofs;
80 for (std::size_t i = 0; i < 2; ++i)
81 {
82 for (auto& _V : V[i])
83 bs_dofs[i].push_back(_V->dofmap()->bs());
84 }
85
86 // Build sparsity pattern for each block
87 std::shared_ptr<const mesh::Mesh<T>> mesh;
88 std::vector<std::vector<std::unique_ptr<la::SparsityPattern>>> patterns(
89 V[0].size());
90 for (std::size_t row = 0; row < V[0].size(); ++row)
91 {
92 for (std::size_t col = 0; col < V[1].size(); ++col)
93 {
94 if (const Form<PetscScalar, T>* form = a[row][col]; form)
95 {
96 patterns[row].push_back(std::make_unique<la::SparsityPattern>(
98 if (!mesh)
99 mesh = form->mesh();
100 }
101 else
102 patterns[row].push_back(nullptr);
103 }
104 }
105
106 if (!mesh)
107 throw std::invalid_argument("Could not find a Mesh.");
108
109 // Compute offsets for the fields
110 std::array<std::vector<std::pair<
111 std::reference_wrapper<const common::IndexMap>, int>>,
112 2>
113 maps;
114 for (std::size_t d = 0; d < 2; ++d)
115 {
116 for (auto& space : V[d])
117 {
118 maps[d].emplace_back(*space->dofmap()->index_map,
119 space->dofmap()->index_map_bs());
120 }
121 }
122
123 // Create merged sparsity pattern
124 std::vector<std::vector<const la::SparsityPattern*>> p(V[0].size());
125 for (std::size_t row = 0; row < V[0].size(); ++row)
126 for (std::size_t col = 0; col < V[1].size(); ++col)
127 p[row].push_back(patterns[row][col].get());
128
129 la::SparsityPattern pattern(mesh->comm(), p, maps, bs_dofs);
130 pattern.finalize();
131
132 // FIXME: Add option to pass customised local-to-global map to PETSc
133 // Mat constructor
134
135 // TODO: Index map concatenation has already been computed inside
136 // the SparsityPattern constructor, but we also need it here to
137 // build the PETSc local-to-global map. Compute outside and pass
138 // into SparsityPattern constructor.
139
140 // Initialise matrix
141 Mat A = la::petsc::create_matrix(mesh->comm(), pattern, type);
142
143 // Create row and column local-to-global maps (field0, field1, field2,
144 // etc), i.e. ghosts of field0 appear before owned indices of field1
145 std::array<std::vector<PetscInt>, 2> _maps;
146 for (int d = 0; d < 2; ++d)
147 {
148 if (d == 1 and V[0] == V[1])
149 {
150 // Row and column spaces are identical, so the concatenated
151 // index map for d=1 is identical to the one already computed
152 // for d=0 -- reuse it rather than paying for a second,
153 // communication-heavy call to stack_index_maps.
154 _maps[1] = _maps[0];
155 continue;
156 }
157
158 const std::vector<
159 std::pair<std::reference_wrapper<const common::IndexMap>, int>>& map
160 = maps[d];
161 std::vector<PetscInt>& _map = _maps[d];
162
163 // Concatenate the block index map in the row and column directions
164 const auto [rank_offset, local_offset, ghosts, _]
166 const std::size_t num_ghosts
167 = std::accumulate(ghosts.begin(), ghosts.end(), std::size_t(0),
168 [](std::size_t n, auto& g) { return n + g.size(); });
169 _map.reserve(local_offset.back() + num_ghosts);
170 for (std::size_t f = 0; f < map.size(); ++f)
171 {
172 auto offset = local_offset[f];
173 const common::IndexMap& imap = map[f].first.get();
174 int bs = map[f].second;
175 auto owned
176 = std::views::iota(std::int32_t(0), bs * imap.size_local())
177 | std::views::transform([offset, rank_offset](std::int32_t i)
178 { return i + rank_offset + offset; });
179 _map.insert(_map.end(), owned.begin(), owned.end());
180 _map.insert(_map.end(), ghosts[f].begin(), ghosts[f].end());
181 }
182 }
183
184 // Create PETSc local-to-global map/index sets and attach to matrix
185 ISLocalToGlobalMapping petsc_local_to_global0;
186 common::petsc::check(ISLocalToGlobalMappingCreate(
187 MPI_COMM_SELF, 1, _maps[0].size(), _maps[0].data(),
188 PETSC_COPY_VALUES, &petsc_local_to_global0),
189 "ISLocalToGlobalMappingCreate");
190 if (V[0] == V[1])
191 {
192 common::petsc::check(MatSetLocalToGlobalMapping(A, petsc_local_to_global0,
193 petsc_local_to_global0),
194 "MatSetLocalToGlobalMapping");
195 common::petsc::check(ISLocalToGlobalMappingDestroy(&petsc_local_to_global0),
196 "ISLocalToGlobalMappingDestroy");
197 }
198 else
199 {
200 ISLocalToGlobalMapping petsc_local_to_global1;
201 common::petsc::check(ISLocalToGlobalMappingCreate(
202 MPI_COMM_SELF, 1, _maps[1].size(), _maps[1].data(),
203 PETSC_COPY_VALUES, &petsc_local_to_global1),
204 "ISLocalToGlobalMappingCreate");
205 common::petsc::check(MatSetLocalToGlobalMapping(A, petsc_local_to_global0,
206 petsc_local_to_global1),
207 "MatSetLocalToGlobalMapping");
208 common::petsc::check(ISLocalToGlobalMappingDestroy(&petsc_local_to_global0),
209 "ISLocalToGlobalMappingDestroy");
210 common::petsc::check(ISLocalToGlobalMappingDestroy(&petsc_local_to_global1),
211 "ISLocalToGlobalMappingDestroy");
212 }
213
214 return A;
215}
216
220template <std::floating_point T>
222 const std::vector<std::vector<const Form<PetscScalar, T>*>>& a,
223 std::optional<std::vector<std::vector<std::optional<std::string>>>> types)
224{
225 if (a.empty())
226 throw std::invalid_argument(
227 "Rectangular array of forms must be non-empty.");
228
229 // Extract and check row/column ranges
231
232 // Loop over each form and create matrix
233 int rows = a.size();
234 int cols = a.front().size();
235 std::vector<Mat> mats(rows * cols, nullptr);
236 std::shared_ptr<const mesh::Mesh<T>> mesh;
237 for (int i = 0; i < rows; ++i)
238 {
239 for (int j = 0; j < cols; ++j)
240 {
241 if (const Form<PetscScalar, T>* form = a[i][j]; form)
242 {
243 if (types)
244 mats[i * cols + j] = create_matrix(*form, types->at(i).at(j));
245 else
246 mats[i * cols + j] = create_matrix(*form, std::nullopt);
247 mesh = form->mesh();
248 }
249 }
250 }
251
252 if (!mesh)
253 throw std::invalid_argument("Could not find a Mesh.");
254
255 // Initialise block (MatNest) matrix. On error, destroy the
256 // already-created sub-matrices in `mats` before propagating, since
257 // the nest (which would otherwise take joint ownership of them) was
258 // never successfully assembled.
259 Mat A;
260 try
261 {
262 common::petsc::check(MatCreate(mesh->comm(), &A), "MatCreate");
263 common::petsc::check(MatSetType(A, MATNEST), "MatSetType");
265 MatNestSetSubMats(A, rows, nullptr, cols, nullptr, mats.data()),
266 "MatNestSetSubMats");
267 common::petsc::check(MatSetUp(A), "MatSetUp");
268 }
269 catch (...)
270 {
271 for (Mat& m : mats)
272 if (m)
273 common::petsc::check(MatDestroy(&m), "MatDestroy");
274 throw;
275 }
276
277 // De-reference Mat objects
278 for (Mat& m : mats)
279 if (m)
280 common::petsc::check(MatDestroy(&m), "MatDestroy");
281
282 return A;
283}
284
289 const std::vector<
290 std::pair<std::reference_wrapper<const common::IndexMap>, int>>& maps);
291
294 const std::vector<
295 std::pair<std::reference_wrapper<const common::IndexMap>, int>>& maps);
296
297// -- Vectors ----------------------------------------------------------------
298
311template <std::floating_point T>
313 Vec b, const Form<PetscScalar, T>& L,
314 std::span<const PetscScalar> constants,
315 const std::map<std::pair<IntegralType, int>,
316 std::pair<std::span<const PetscScalar>, int>>& coeffs)
317{
318 Vec b_local;
319 common::petsc::check(VecGhostGetLocalForm(b, &b_local),
320 "VecGhostGetLocalForm");
321 PetscInt n = 0;
322 common::petsc::check(VecGetSize(b_local, &n), "VecGetSize");
323 PetscScalar* array = nullptr;
324 common::petsc::check(VecGetArray(b_local, &array), "VecGetArray");
325 std::span<PetscScalar> _b(array, n);
326 fem::assemble_vector(_b, L, constants, coeffs);
327 common::petsc::check(VecRestoreArray(b_local, &array), "VecRestoreArray");
328 common::petsc::check(VecGhostRestoreLocalForm(b, &b_local),
329 "VecGhostRestoreLocalForm");
330}
331
342template <std::floating_point T>
344{
345 Vec b_local;
346 common::petsc::check(VecGhostGetLocalForm(b, &b_local),
347 "VecGhostGetLocalForm");
348 PetscInt n = 0;
349 common::petsc::check(VecGetSize(b_local, &n), "VecGetSize");
350 PetscScalar* array = nullptr;
351 common::petsc::check(VecGetArray(b_local, &array), "VecGetArray");
352 std::span<PetscScalar> _b(array, n);
354 common::petsc::check(VecRestoreArray(b_local, &array), "VecRestoreArray");
355 common::petsc::check(VecGhostRestoreLocalForm(b, &b_local),
356 "VecGhostRestoreLocalForm");
357}
358
359// FIXME: clarify zeroing of vector
360
390template <std::floating_point T>
392 Vec b,
393 std::vector<
394 std::optional<std::reference_wrapper<const Form<PetscScalar, T>>>>
395 a,
396 const std::vector<std::span<const PetscScalar>>& constants,
397 const std::vector<std::map<std::pair<IntegralType, int>,
398 std::pair<std::span<const PetscScalar>, int>>>&
399 coeffs,
400 const std::vector<
401 std::vector<std::reference_wrapper<const DirichletBC<PetscScalar, T>>>>&
402 bcs1,
403 const std::vector<Vec>& x0, PetscScalar alpha)
404{
405 if (!x0.empty() and x0.size() != a.size())
406 throw std::invalid_argument("Mismatch between x0 and a in apply_lifting.");
407
408 Vec b_local;
409 common::petsc::check(VecGhostGetLocalForm(b, &b_local),
410 "VecGhostGetLocalForm");
411 PetscInt n = 0;
412 common::petsc::check(VecGetSize(b_local, &n), "VecGetSize");
413 PetscScalar* array = nullptr;
414 common::petsc::check(VecGetArray(b_local, &array), "VecGetArray");
415 std::span<PetscScalar> _b(array, n);
416
417 if (x0.empty())
418 fem::apply_lifting(_b, a, constants, coeffs, bcs1, {}, alpha);
419 else
420 {
421 std::vector<std::span<const PetscScalar>> x0_ref;
422 std::vector<Vec> x0_local(a.size());
423 std::vector<const PetscScalar*> x0_array(a.size());
424 for (std::size_t i = 0; i < a.size(); ++i)
425 {
426 assert(x0[i]);
427 common::petsc::check(VecGhostGetLocalForm(x0[i], &x0_local[i]),
428 "VecGhostGetLocalForm");
429 PetscInt n0 = 0;
430 common::petsc::check(VecGetSize(x0_local[i], &n0), "VecGetSize");
431 common::petsc::check(VecGetArrayRead(x0_local[i], &x0_array[i]),
432 "VecGetArrayRead");
433 x0_ref.emplace_back(x0_array[i], n0);
434 }
435
436 fem::apply_lifting(_b, a, constants, coeffs, bcs1, x0_ref, alpha);
437
438 for (std::size_t i = 0; i < x0_local.size(); ++i)
439 {
440 common::petsc::check(VecRestoreArrayRead(x0_local[i], &x0_array[i]),
441 "VecRestoreArrayRead");
442 common::petsc::check(VecGhostRestoreLocalForm(x0[i], &x0_local[i]),
443 "VecGhostRestoreLocalForm");
444 }
445 }
446
447 common::petsc::check(VecRestoreArray(b_local, &array), "VecRestoreArray");
448 common::petsc::check(VecGhostRestoreLocalForm(b, &b_local),
449 "VecGhostRestoreLocalForm");
450}
451
452// FIXME: clarify zeroing of vector
453
479template <std::floating_point T>
481 Vec b,
482 const std::vector<
483 std::optional<std::reference_wrapper<const Form<PetscScalar, T>>>>& a,
484 const std::vector<
485 std::vector<std::reference_wrapper<const DirichletBC<PetscScalar, T>>>>&
486 bcs1,
487 const std::vector<Vec>& x0, PetscScalar alpha)
488{
489 if (!x0.empty() and x0.size() != a.size())
490 throw std::invalid_argument("Mismatch between x0 and a in apply_lifting.");
491
492 Vec b_local;
493 common::petsc::check(VecGhostGetLocalForm(b, &b_local),
494 "VecGhostGetLocalForm");
495 PetscInt n = 0;
496 common::petsc::check(VecGetSize(b_local, &n), "VecGetSize");
497 PetscScalar* array = nullptr;
498 common::petsc::check(VecGetArray(b_local, &array), "VecGetArray");
499 std::span<PetscScalar> _b(array, n);
500
501 if (x0.empty())
502 fem::apply_lifting(_b, a, bcs1, {}, alpha);
503 else
504 {
505 std::vector<std::span<const PetscScalar>> x0_ref;
506 std::vector<Vec> x0_local(a.size());
507 std::vector<const PetscScalar*> x0_array(a.size());
508 for (std::size_t i = 0; i < a.size(); ++i)
509 {
510 assert(x0[i]);
511 common::petsc::check(VecGhostGetLocalForm(x0[i], &x0_local[i]),
512 "VecGhostGetLocalForm");
513 PetscInt n0 = 0;
514 common::petsc::check(VecGetSize(x0_local[i], &n0), "VecGetSize");
515 common::petsc::check(VecGetArrayRead(x0_local[i], &x0_array[i]),
516 "VecGetArrayRead");
517 x0_ref.emplace_back(x0_array[i], n0);
518 }
519
520 fem::apply_lifting(_b, a, bcs1, x0_ref, alpha);
521
522 for (std::size_t i = 0; i < x0_local.size(); ++i)
523 {
524 common::petsc::check(VecRestoreArrayRead(x0_local[i], &x0_array[i]),
525 "VecRestoreArrayRead");
526 common::petsc::check(VecGhostRestoreLocalForm(x0[i], &x0_local[i]),
527 "VecGhostRestoreLocalForm");
528 }
529 }
530
531 common::petsc::check(VecRestoreArray(b_local, &array), "VecRestoreArray");
532 common::petsc::check(VecGhostRestoreLocalForm(b, &b_local),
533 "VecGhostRestoreLocalForm");
534}
535
536// -- Setting bcs ------------------------------------------------------------
537
538// FIXME: Move these function elsewhere?
539
552template <std::floating_point T>
553void set_bc(Vec b,
554 const std::vector<
555 std::reference_wrapper<const DirichletBC<PetscScalar, T>>>& bcs,
556 std::optional<const Vec> x0, PetscScalar alpha = 1)
557{
558 PetscInt n = 0;
559 common::petsc::check(VecGetLocalSize(b, &n), "VecGetLocalSize");
560 PetscScalar* array = nullptr;
561 common::petsc::check(VecGetArray(b, &array), "VecGetArray");
562 std::span<PetscScalar> _b(array, n);
563 if (x0.has_value())
564 {
565 Vec x0_local;
566 common::petsc::check(VecGhostGetLocalForm(x0.value(), &x0_local),
567 "VecGhostGetLocalForm");
568 PetscInt n0 = 0;
569 common::petsc::check(VecGetSize(x0_local, &n0), "VecGetSize");
570 const PetscScalar* x0_array = nullptr;
571 common::petsc::check(VecGetArrayRead(x0_local, &x0_array),
572 "VecGetArrayRead");
573 std::span<const PetscScalar> _x0(x0_array, n0);
574 for (auto& bc : bcs)
575 bc.get().set(_b, _x0, alpha);
576 common::petsc::check(VecRestoreArrayRead(x0_local, &x0_array),
577 "VecRestoreArrayRead");
578 common::petsc::check(VecGhostRestoreLocalForm(x0.value(), &x0_local),
579 "VecGhostRestoreLocalForm");
580 }
581 else
582 {
583 for (auto& bc : bcs)
584 bc.get().set(_b, std::nullopt, alpha);
585 }
586 common::petsc::check(VecRestoreArray(b, &array), "VecRestoreArray");
587}
588
589// -- Nonlinear problem assembly ---------------------------------------------
590
591namespace impl
592{
597template <std::floating_point T>
598void assign(const Vec x, Function<PetscScalar, T>& u)
599{
600 Vec x_local = nullptr;
601 common::petsc::check(VecGhostGetLocalForm(x, &x_local),
602 "VecGhostGetLocalForm");
603 PetscInt n = 0;
604 common::petsc::check(VecGetSize(x_local, &n), "VecGetSize");
605
606 std::span<PetscScalar> _u = u.x()->array();
607 if (static_cast<std::size_t>(n) != _u.size())
608 {
609 throw std::runtime_error(std::format(
610 "Vector has {} local entries, function has {}.", n, _u.size()));
611 }
612
613 const PetscScalar* array = nullptr;
614 common::petsc::check(VecGetArrayRead(x_local, &array), "VecGetArrayRead");
615 std::ranges::copy(std::span<const PetscScalar>(array, n), _u.begin());
616 common::petsc::check(VecRestoreArrayRead(x_local, &array),
617 "VecRestoreArrayRead");
618 common::petsc::check(VecGhostRestoreLocalForm(x, &x_local),
619 "VecGhostRestoreLocalForm");
620}
621
627template <std::floating_point T>
628void assemble_operator(
629 Mat A, const Form<PetscScalar, T>& a,
630 const std::vector<
631 std::reference_wrapper<const DirichletBC<PetscScalar, T>>>& bcs)
632{
633 common::petsc::check(MatZeroEntries(A), "MatZeroEntries");
635
636 // The unit diagonal is only meaningful when the rows and columns are
637 // indexed by the same space
638 if (a.function_spaces()[0] == a.function_spaces()[1])
639 {
640 // Flush to switch from adding to inserting
641 common::petsc::check(MatAssemblyBegin(A, MAT_FLUSH_ASSEMBLY),
642 "MatAssemblyBegin");
643 common::petsc::check(MatAssemblyEnd(A, MAT_FLUSH_ASSEMBLY),
644 "MatAssemblyEnd");
646 *a.function_spaces()[0], bcs);
647 }
648
649 common::petsc::check(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY),
650 "MatAssemblyBegin");
651 common::petsc::check(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY), "MatAssemblyEnd");
652}
653} // namespace impl
654
680template <std::floating_point T>
682 const Vec x, Vec b, const Form<PetscScalar, T>& F,
683 const Form<PetscScalar, T>& J,
684 const std::vector<
685 std::reference_wrapper<const DirichletBC<PetscScalar, T>>>& bcs,
687{
688 common::petsc::check(VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD),
689 "VecGhostUpdateBegin");
690 common::petsc::check(VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD),
691 "VecGhostUpdateEnd");
692 impl::assign(x, u);
693
694 // Zero the local form, as assembly accumulates into ghost entries
695 Vec b_local = nullptr;
696 common::petsc::check(VecGhostGetLocalForm(b, &b_local),
697 "VecGhostGetLocalForm");
698 common::petsc::check(VecZeroEntries(b_local), "VecZeroEntries");
699 common::petsc::check(VecGhostRestoreLocalForm(b, &b_local),
700 "VecGhostRestoreLocalForm");
701
702 assemble_vector(b, F);
703
704 std::vector<std::optional<std::reference_wrapper<const Form<PetscScalar, T>>>>
705 a{J};
706 std::vector<
707 std::vector<std::reference_wrapper<const DirichletBC<PetscScalar, T>>>>
708 bcs1{bcs};
709 apply_lifting(b, a, bcs1, std::vector<Vec>{x}, -1);
710
711 common::petsc::check(VecGhostUpdateBegin(b, ADD_VALUES, SCATTER_REVERSE),
712 "VecGhostUpdateBegin");
713 common::petsc::check(VecGhostUpdateEnd(b, ADD_VALUES, SCATTER_REVERSE),
714 "VecGhostUpdateEnd");
715
716 set_bc(b, bcs, x, -1);
717
718 common::petsc::check(VecGhostUpdateBegin(b, INSERT_VALUES, SCATTER_FORWARD),
719 "VecGhostUpdateBegin");
720 common::petsc::check(VecGhostUpdateEnd(b, INSERT_VALUES, SCATTER_FORWARD),
721 "VecGhostUpdateEnd");
722}
723
755template <std::floating_point T>
757 const Vec x, Mat Jmat, Mat Pmat, const Form<PetscScalar, T>& J,
758 const std::vector<
759 std::reference_wrapper<const DirichletBC<PetscScalar, T>>>& bcs,
760 Function<PetscScalar, T>& u, const Form<PetscScalar, T>* P = nullptr)
761{
762 common::petsc::check(VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD),
763 "VecGhostUpdateBegin");
764 common::petsc::check(VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD),
765 "VecGhostUpdateEnd");
766 impl::assign(x, u);
767
768 impl::assemble_operator(Jmat, J, bcs);
769 if (P)
770 impl::assemble_operator(Pmat, *P, bcs);
771}
772
773} // namespace petsc
774} // namespace dolfinx::fem
775
776#endif
Functions supporting assembly of finite element fem::Form and fem::Expression.
Definition IndexMap.h:95
std::int32_t size_local() const noexcept
Number of indices owned by this process.
Definition IndexMap.cpp:945
Definition DirichletBC.h:259
A representation of finite element variational forms.
Definition Form.h:118
std::shared_ptr< const mesh::Mesh< geometry_type > > mesh() const
Common mesh for the form (the 'integration domain').
Definition Form.h:367
Definition Function.h:48
std::shared_ptr< const la::Vector< value_type > > x() const
Underlying vector (const version).
Definition Function.h:155
Definition SparsityPattern.h:26
void finalize()
Finalize sparsity pattern and communicate off-process entries.
Definition SparsityPattern.cpp:264
static auto set_block_fn(Mat A, InsertMode mode)
Return a function with an interface for adding or inserting values into the matrix A using blocked in...
Definition petsc.h:260
static auto set_fn(Mat A, InsertMode mode)
Return a function with an interface for adding or inserting values into the matrix A (calls MatSetVal...
Definition petsc.h:227
Functions supporting finite element method operations.
void check(PetscErrorCode ierr, std::string_view petsc_function, std::source_location loc=std::source_location::current())
Throw a std::runtime_error via error() if ierr indicates a PETSc call failed.
Definition petsc.h:41
Miscellaneous classes, functions and types.
Definition dolfinx_common.h:8
std::tuple< std::int64_t, std::vector< std::int32_t >, std::vector< std::vector< std::int64_t > >, std::vector< std::vector< int > > > stack_index_maps(const std::vector< std::pair< std::reference_wrapper< const IndexMap >, int > > &maps)
Compute layout data and ghost indices for a stacked (concatenated) index map, i.e....
Definition IndexMap.cpp:659
Helper functions for assembly into PETSc data structures.
Definition petsc.h:45
Mat create_matrix(const Form< PetscScalar, T > &a, std::optional< std::string > type=std::nullopt)
Create a matrix.
Definition petsc.h:53
void assemble_jacobian(const Vec x, Mat Jmat, Mat Pmat, const Form< PetscScalar, T > &J, const std::vector< std::reference_wrapper< const DirichletBC< PetscScalar, T > > > &bcs, Function< PetscScalar, T > &u, const Form< PetscScalar, T > *P=nullptr)
Assemble the Jacobian of a nonlinear problem into Jmat, and a preconditioner into Pmat.
Definition petsc.h:756
Mat create_matrix_block(const std::vector< std::vector< const Form< PetscScalar, T > * > > &a, std::optional< std::string > type=std::nullopt)
Initialise a monolithic matrix for an array of bilinear forms.
Definition petsc.h:72
Mat create_matrix_nest(const std::vector< std::vector< const Form< PetscScalar, T > * > > &a, std::optional< std::vector< std::vector< std::optional< std::string > > > > types)
Create nested (MatNest) matrix.
Definition petsc.h:221
void assemble_vector(Vec b, const Form< PetscScalar, T > &L, std::span< const PetscScalar > constants, const std::map< std::pair< IntegralType, int >, std::pair< std::span< const PetscScalar >, int > > &coeffs)
Assemble linear form into an already allocated PETSc vector.
Definition petsc.h:312
void set_bc(Vec b, const std::vector< std::reference_wrapper< const DirichletBC< PetscScalar, T > > > &bcs, std::optional< const Vec > x0, PetscScalar alpha=1)
Entries in b that are constrained by a Dirichlet boundary conditions are set to alpha * (x_bc - x0),...
Definition petsc.h:553
Vec create_vector_block(const std::vector< std::pair< std::reference_wrapper< const common::IndexMap >, int > > &maps)
Initialise monolithic vector. Vector is not zeroed.
Definition petsc.cpp:21
void assemble_residual(const Vec x, Vec b, const Form< PetscScalar, T > &F, const Form< PetscScalar, T > &J, const std::vector< std::reference_wrapper< const DirichletBC< PetscScalar, T > > > &bcs, Function< PetscScalar, T > &u)
Assemble the residual of a nonlinear problem into b, with Dirichlet conditions applied.
Definition petsc.h:681
void apply_lifting(Vec b, std::vector< std::optional< std::reference_wrapper< const Form< PetscScalar, T > > > > a, const std::vector< std::span< const PetscScalar > > &constants, const std::vector< std::map< std::pair< IntegralType, int >, std::pair< std::span< const PetscScalar >, int > > > &coeffs, const std::vector< std::vector< std::reference_wrapper< const DirichletBC< PetscScalar, T > > > > &bcs1, const std::vector< Vec > &x0, PetscScalar alpha)
Modify RHS vector to account for Dirichlet boundary conditions.
Definition petsc.h:391
Vec create_vector_nest(const std::vector< std::pair< std::reference_wrapper< const common::IndexMap >, int > > &maps)
Create nested (VecNest) vector. Vector is not zeroed.
Definition petsc.cpp:65
Finite element method functionality.
Definition assemble_expression_impl.h:24
void assemble_matrix(la::MatSet< T > auto mat_add, const Form< T, U > &a, std::span< const T > constants, const std::map< std::pair< IntegralType, int >, std::pair< std::span< const T >, int > > &coefficients, std::span< const std::int8_t > dof_marker0, std::span< const std::int8_t > dof_marker1)
Assemble bilinear form into a matrix. Matrix must already be initialised. Does not zero or finalise t...
Definition assembler.h:515
void set_diagonal(auto set_fn, std::span< const std::int32_t > rows, T diagonal=1.0)
Sets a value to the diagonal of a matrix for specified rows.
Definition assembler.h:646
std::vector< std::vector< std::array< std::shared_ptr< const FunctionSpace< U > >, 2 > > > extract_function_spaces(const std::vector< std::vector< const Form< T, U > * > > &a)
Extract test (0) and trial (1) function spaces pairs for each bilinear form for a rectangular array o...
Definition utils.h:173
void apply_lifting(V &&b, const std::vector< std::optional< std::reference_wrapper< const Form< T, U > > > > &a, const std::vector< std::span< const T > > &constants, const std::vector< std::map< std::pair< IntegralType, int >, std::pair< std::span< const T >, int > > > &coeffs, const std::vector< std::vector< std::reference_wrapper< const DirichletBC< T, U > > > > &bcs1, const std::vector< std::span< const T > > &x0, T alpha)
Modify the right-hand side vector to account for constraints (Dirichlet boundary condition constraint...
Definition assembler.h:342
void assemble_vector(V &&b, const Form< T, U > &L, std::span< const T > constants, const std::map< std::pair< IntegralType, int >, std::pair< std::span< const T >, int > > &coefficients)
Assemble linear form into a vector.
Definition assembler.h:234
la::SparsityPattern create_sparsity_pattern(const Form< T, U > &a)
Create a sparsity pattern for a given form.
Definition utils.h:198
std::array< std::vector< std::shared_ptr< const FunctionSpace< T > > >, 2 > common_function_spaces(const std::vector< std::vector< std::array< std::shared_ptr< const FunctionSpace< T > >, 2 > > > &V)
Extract FunctionSpaces for (0) rows blocks and (1) columns blocks from a rectangular array of (test,...
Definition FunctionSpace.h:443
Mat create_matrix(MPI_Comm comm, const SparsityPattern &sp, std::optional< std::string_view > type=std::nullopt)
Create a PETSc Mat. Caller is responsible for destroying the returned object.
Definition petsc.cpp:222
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32