18#include <dolfinx/la/petsc.h>
40template <dolfinx::scalar T, std::
floating_po
int U>
52template <std::
floating_po
int T>
54 std::optional<std::string> type = std::nullopt)
71template <std::
floating_po
int T>
74 std::optional<std::string> type = std::nullopt)
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)
83 bs_dofs[i].push_back(_V->dofmap()->bs());
87 std::shared_ptr<const mesh::Mesh<T>>
mesh;
88 std::vector<std::vector<std::unique_ptr<la::SparsityPattern>>> patterns(
90 for (std::size_t row = 0; row < V[0].size(); ++row)
92 for (std::size_t col = 0; col < V[1].size(); ++col)
96 patterns[row].push_back(std::make_unique<la::SparsityPattern>(
102 patterns[row].push_back(
nullptr);
107 throw std::invalid_argument(
"Could not find a Mesh.");
110 std::array<std::vector<std::pair<
111 std::reference_wrapper<const common::IndexMap>,
int>>,
114 for (std::size_t d = 0; d < 2; ++d)
116 for (
auto& space : V[d])
118 maps[d].emplace_back(*space->dofmap()->index_map,
119 space->dofmap()->index_map_bs());
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());
145 std::array<std::vector<PetscInt>, 2> _maps;
146 for (
int d = 0; d < 2; ++d)
148 if (d == 1 and V[0] == V[1])
159 std::pair<std::reference_wrapper<const common::IndexMap>,
int>>& map
161 std::vector<PetscInt>& _map = _maps[d];
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)
172 auto offset = local_offset[f];
174 int bs = map[f].second;
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());
185 ISLocalToGlobalMapping petsc_local_to_global0;
187 MPI_COMM_SELF, 1, _maps[0].size(), _maps[0].data(),
188 PETSC_COPY_VALUES, &petsc_local_to_global0),
189 "ISLocalToGlobalMappingCreate");
193 petsc_local_to_global0),
194 "MatSetLocalToGlobalMapping");
196 "ISLocalToGlobalMappingDestroy");
200 ISLocalToGlobalMapping petsc_local_to_global1;
202 MPI_COMM_SELF, 1, _maps[1].size(), _maps[1].data(),
203 PETSC_COPY_VALUES, &petsc_local_to_global1),
204 "ISLocalToGlobalMappingCreate");
206 petsc_local_to_global1),
207 "MatSetLocalToGlobalMapping");
209 "ISLocalToGlobalMappingDestroy");
211 "ISLocalToGlobalMappingDestroy");
220template <std::
floating_po
int T>
223 std::optional<std::vector<std::vector<std::optional<std::string>>>> types)
226 throw std::invalid_argument(
227 "Rectangular array of forms must be non-empty.");
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)
239 for (
int j = 0; j < cols; ++j)
244 mats[i * cols + j] =
create_matrix(*form, types->at(i).at(j));
253 throw std::invalid_argument(
"Could not find a Mesh.");
265 MatNestSetSubMats(A, rows,
nullptr, cols,
nullptr, mats.data()),
266 "MatNestSetSubMats");
290 std::pair<std::reference_wrapper<const common::IndexMap>,
int>>& maps);
295 std::pair<std::reference_wrapper<const common::IndexMap>,
int>>& maps);
311template <std::
floating_po
int T>
314 std::span<const PetscScalar> constants,
315 const std::map<std::pair<IntegralType, int>,
316 std::pair<std::span<const PetscScalar>,
int>>& coeffs)
320 "VecGhostGetLocalForm");
323 PetscScalar* array =
nullptr;
325 std::span<PetscScalar> _b(array, n);
329 "VecGhostRestoreLocalForm");
342template <std::
floating_po
int T>
347 "VecGhostGetLocalForm");
350 PetscScalar* array =
nullptr;
352 std::span<PetscScalar> _b(array, n);
356 "VecGhostRestoreLocalForm");
390template <std::
floating_po
int T>
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>>>&
403 const std::vector<Vec>& x0, PetscScalar alpha)
405 if (!x0.empty() and x0.size() != a.size())
406 throw std::invalid_argument(
"Mismatch between x0 and a in apply_lifting.");
410 "VecGhostGetLocalForm");
413 PetscScalar* array =
nullptr;
415 std::span<PetscScalar> _b(array, n);
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)
428 "VecGhostGetLocalForm");
433 x0_ref.emplace_back(x0_array[i], n0);
438 for (std::size_t i = 0; i < x0_local.size(); ++i)
441 "VecRestoreArrayRead");
443 "VecGhostRestoreLocalForm");
449 "VecGhostRestoreLocalForm");
479template <std::
floating_po
int T>
487 const std::vector<Vec>& x0, PetscScalar alpha)
489 if (!x0.empty() and x0.size() != a.size())
490 throw std::invalid_argument(
"Mismatch between x0 and a in apply_lifting.");
494 "VecGhostGetLocalForm");
497 PetscScalar* array =
nullptr;
499 std::span<PetscScalar> _b(array, n);
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)
512 "VecGhostGetLocalForm");
517 x0_ref.emplace_back(x0_array[i], n0);
522 for (std::size_t i = 0; i < x0_local.size(); ++i)
525 "VecRestoreArrayRead");
527 "VecGhostRestoreLocalForm");
533 "VecGhostRestoreLocalForm");
552template <std::
floating_po
int T>
556 std::optional<const Vec> x0, PetscScalar alpha = 1)
560 PetscScalar* array =
nullptr;
562 std::span<PetscScalar> _b(array, n);
567 "VecGhostGetLocalForm");
570 const PetscScalar* x0_array =
nullptr;
573 std::span<const PetscScalar> _x0(x0_array, n0);
575 bc.get().set(_b, _x0, alpha);
577 "VecRestoreArrayRead");
579 "VecGhostRestoreLocalForm");
584 bc.get().set(_b, std::nullopt, alpha);
597template <std::
floating_po
int T>
600 Vec x_local =
nullptr;
602 "VecGhostGetLocalForm");
606 std::span<PetscScalar> _u = u.
x()->array();
607 if (
static_cast<std::size_t
>(n) != _u.size())
609 throw std::runtime_error(std::format(
610 "Vector has {} local entries, function has {}.", n, _u.size()));
613 const PetscScalar* array =
nullptr;
615 std::ranges::copy(std::span<const PetscScalar>(array, n), _u.begin());
617 "VecRestoreArrayRead");
619 "VecGhostRestoreLocalForm");
627template <std::
floating_po
int T>
628void assemble_operator(
629 Mat A,
const Form<PetscScalar, T>& a,
631 std::reference_wrapper<
const DirichletBC<PetscScalar, T>>>& bcs)
638 if (a.function_spaces()[0] == a.function_spaces()[1])
646 *a.function_spaces()[0], bcs);
680template <std::
floating_po
int T>
689 "VecGhostUpdateBegin");
691 "VecGhostUpdateEnd");
695 Vec b_local =
nullptr;
697 "VecGhostGetLocalForm");
700 "VecGhostRestoreLocalForm");
704 std::vector<std::optional<std::reference_wrapper<const Form<PetscScalar, T>>>>
707 std::vector<std::reference_wrapper<const DirichletBC<PetscScalar, T>>>>
712 "VecGhostUpdateBegin");
714 "VecGhostUpdateEnd");
719 "VecGhostUpdateBegin");
721 "VecGhostUpdateEnd");
755template <std::
floating_po
int T>
763 "VecGhostUpdateBegin");
765 "VecGhostUpdateEnd");
768 impl::assemble_operator(Jmat, J, bcs);
770 impl::assemble_operator(Pmat, *P, bcs);
Functions supporting assembly of finite element fem::Form and fem::Expression.
std::int32_t size_local() const noexcept
Number of indices owned by this process.
Definition IndexMap.cpp:945
Definition DirichletBC.h:259
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