Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/v0.1.0/v0.9.0/cpp
DOLFINx  0.1.0
DOLFINx C++ interface
assembler.h
1 // Copyright (C) 2018-2020 Garth N. Wells
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 #include "assemble_matrix_impl.h"
10 #include "assemble_scalar_impl.h"
11 #include "assemble_vector_impl.h"
12 #include <memory>
13 #include <vector>
14 #include <xtl/xspan.hpp>
15 
16 namespace dolfinx::fem
17 {
18 
19 template <typename T>
21 template <typename T>
22 class Form;
23 class FunctionSpace;
24 
25 // -- Scalar ----------------------------------------------------------------
26 
32 template <typename T>
34 {
35  return fem::impl::assemble_scalar(M);
36 }
37 
38 // -- Vectors ----------------------------------------------------------------
39 
44 template <typename T>
45 void assemble_vector(xtl::span<T> b, const Form<T>& L)
46 {
47  fem::impl::assemble_vector(b, L);
48 }
49 
50 // FIXME: clarify how x0 is used
51 // FIXME: if bcs entries are set
52 
53 // FIXME: need to pass an array of Vec for x0?
54 // FIXME: clarify zeroing of vector
55 
68 template <typename T>
70  xtl::span<T> b, const std::vector<std::shared_ptr<const Form<T>>>& a,
71  const std::vector<std::vector<std::shared_ptr<const DirichletBC<T>>>>& bcs1,
72  const std::vector<xtl::span<const T>>& x0, double scale)
73 {
74  fem::impl::apply_lifting(b, a, bcs1, x0, scale);
75 }
76 
77 // -- Matrices ---------------------------------------------------------------
78 
79 // Experimental
85 template <typename T>
87  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
88  const std::int32_t*, const T*)>& mat_add,
89  const Form<T>& a,
90  const std::vector<std::shared_ptr<const DirichletBC<T>>>& bcs)
91 {
92  // Index maps for dof ranges
93  auto map0 = a.function_spaces().at(0)->dofmap()->index_map;
94  auto map1 = a.function_spaces().at(1)->dofmap()->index_map;
95  auto bs0 = a.function_spaces().at(0)->dofmap()->index_map_bs();
96  auto bs1 = a.function_spaces().at(1)->dofmap()->index_map_bs();
97 
98  // Build dof markers
99  std::vector<bool> dof_marker0, dof_marker1;
100  assert(map0);
101  std::int32_t dim0 = bs0 * (map0->size_local() + map0->num_ghosts());
102  assert(map1);
103  std::int32_t dim1 = bs1 * (map1->size_local() + map1->num_ghosts());
104  for (std::size_t k = 0; k < bcs.size(); ++k)
105  {
106  assert(bcs[k]);
107  assert(bcs[k]->function_space());
108  if (a.function_spaces().at(0)->contains(*bcs[k]->function_space()))
109  {
110  dof_marker0.resize(dim0, false);
111  bcs[k]->mark_dofs(dof_marker0);
112  }
113 
114  if (a.function_spaces().at(1)->contains(*bcs[k]->function_space()))
115  {
116  dof_marker1.resize(dim1, false);
117  bcs[k]->mark_dofs(dof_marker1);
118  }
119  }
120 
121  // Assemble
122  impl::assemble_matrix(mat_add, a, dof_marker0, dof_marker1);
123 }
124 
135 template <typename T>
137  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
138  const std::int32_t*, const T*)>& mat_add,
139  const Form<T>& a, const std::vector<bool>& dof_marker0,
140  const std::vector<bool>& dof_marker1)
141 
142 {
143  impl::assemble_matrix(mat_add, a, dof_marker0, dof_marker1);
144 }
145 
156 template <typename T>
158  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
159  const std::int32_t*, const T*)>& set_fn,
160  const xtl::span<const std::int32_t>& rows, T diagonal = 1.0)
161 {
162  for (std::size_t i = 0; i < rows.size(); ++i)
163  {
164  const std::int32_t row = rows[i];
165  set_fn(1, &row, 1, &row, &diagonal);
166  }
167 }
168 
184 template <typename T>
186  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
187  const std::int32_t*, const T*)>& set_fn,
188  const fem::FunctionSpace& V,
189  const std::vector<std::shared_ptr<const DirichletBC<T>>>& bcs,
190  T diagonal = 1.0)
191 {
192  for (const auto& bc : bcs)
193  {
194  assert(bc);
195  if (V.contains(*bc->function_space()))
196  {
197  const auto [dofs, range] = bc->dof_indices();
198  set_diagonal<T>(set_fn, dofs.first(range), diagonal);
199  }
200  }
201 }
202 
203 // -- Setting bcs ------------------------------------------------------------
204 
205 // FIXME: Move these function elsewhere?
206 
207 // FIXME: clarify x0
208 // FIXME: clarify what happens with ghosts
209 
213 template <typename T>
214 void set_bc(xtl::span<T> b,
215  const std::vector<std::shared_ptr<const DirichletBC<T>>>& bcs,
216  const xtl::span<const T>& x0, double scale = 1.0)
217 {
218  if (b.size() > x0.size())
219  throw std::runtime_error("Size mismatch between b and x0 vectors.");
220  for (const auto& bc : bcs)
221  {
222  assert(bc);
223  bc->set(b, x0, scale);
224  }
225 }
226 
230 template <typename T>
231 void set_bc(xtl::span<T> b,
232  const std::vector<std::shared_ptr<const DirichletBC<T>>>& bcs,
233  double scale = 1.0)
234 {
235  for (const auto& bc : bcs)
236  {
237  assert(bc);
238  bc->set(b, scale);
239  }
240 }
241 
242 // FIXME: Handle null block
243 // FIXME: Pass function spaces rather than forms
244 
252 template <typename T>
253 std::vector<std::vector<std::shared_ptr<const fem::DirichletBC<T>>>>
254 bcs_rows(const std::vector<const Form<T>*>& L,
255  const std::vector<std::shared_ptr<const fem::DirichletBC<T>>>& bcs)
256 {
257  // Pack DirichletBC pointers for rows
258  std::vector<std::vector<std::shared_ptr<const fem::DirichletBC<T>>>> bcs0(
259  L.size());
260  for (std::size_t i = 0; i < L.size(); ++i)
261  for (const std::shared_ptr<const DirichletBC<T>>& bc : bcs)
262  if (L[i]->function_spaces()[0]->contains(*bc->function_space()))
263  bcs0[i].push_back(bc);
264  return bcs0;
265 }
266 
267 // FIXME: Handle null block
268 // FIXME: Pass function spaces rather than forms
269 
277 template <typename T>
278 std::vector<
279  std::vector<std::vector<std::shared_ptr<const fem::DirichletBC<T>>>>>
280 bcs_cols(const std::vector<std::vector<std::shared_ptr<const Form<T>>>>& a,
281  const std::vector<std::shared_ptr<const DirichletBC<T>>>& bcs)
282 {
283  // Pack DirichletBC pointers for columns
284  std::vector<
285  std::vector<std::vector<std::shared_ptr<const fem::DirichletBC<T>>>>>
286  bcs1(a.size());
287  for (std::size_t i = 0; i < a.size(); ++i)
288  {
289  for (std::size_t j = 0; j < a[i].size(); ++j)
290  {
291  bcs1[i].resize(a[j].size());
292  for (const std::shared_ptr<const DirichletBC<T>>& bc : bcs)
293  {
294  // FIXME: handle case where a[i][j] is null
295  if (a[i][j])
296  {
297  if (a[i][j]->function_spaces()[1]->contains(*bc->function_space()))
298  bcs1[i][j].push_back(bc);
299  }
300  }
301  }
302  }
303 
304  return bcs1;
305 }
306 
307 } // namespace dolfinx::fem
dolfinx::fem::FunctionSpace
This class represents a finite element function space defined by a mesh, a finite element,...
Definition: FunctionSpace.h:33
dolfinx::fem::Form
Class for variational forms.
Definition: assembler.h:22
dolfinx::fem::set_diagonal
void set_diagonal(const std::function< int(std::int32_t, const std::int32_t *, std::int32_t, const std::int32_t *, const T *)> &set_fn, const xtl::span< const std::int32_t > &rows, T diagonal=1.0)
Sets a value to the diagonal of a matrix for specified rows. It is typically called after assembly....
Definition: assembler.h:157
dolfinx::fem::assemble_vector
void assemble_vector(xtl::span< T > b, const Form< T > &L)
Assemble linear form into a vector.
Definition: assembler.h:45
dolfinx::fem::apply_lifting
void apply_lifting(xtl::span< T > b, const std::vector< std::shared_ptr< const Form< T >>> &a, const std::vector< std::vector< std::shared_ptr< const DirichletBC< T >>>> &bcs1, const std::vector< xtl::span< const T >> &x0, double scale)
Modify b such that:
Definition: assembler.h:69
dolfinx::fem::assemble_scalar
T assemble_scalar(const Form< T > &M)
Assemble functional into scalar. Caller is responsible for accumulation across processes.
Definition: assembler.h:33
dolfinx::fem::DirichletBC
Interface for setting (strong) Dirichlet boundary conditions.
Definition: assembler.h:20
dolfinx::fem::FunctionSpace::contains
bool contains(const FunctionSpace &V) const
Check whether V is subspace of this, or this itself.
Definition: FunctionSpace.cpp:223
dolfinx::fem::set_bc
void set_bc(xtl::span< T > b, const std::vector< std::shared_ptr< const DirichletBC< T >>> &bcs, const xtl::span< const T > &x0, double scale=1.0)
Set bc values in owned (local) part of the vector, multiplied by 'scale'. The vectors b and x0 must h...
Definition: assembler.h:214
dolfinx::fem
Finite element method functionality.
Definition: assemble_matrix_impl.h:22
dolfinx::fem::bcs_cols
std::vector< std::vector< std::vector< std::shared_ptr< const fem::DirichletBC< T > > > > > bcs_cols(const std::vector< std::vector< std::shared_ptr< const Form< T >>>> &a, const std::vector< std::shared_ptr< const DirichletBC< T >>> &bcs)
Arrange boundary conditions by block.
Definition: assembler.h:280
dolfinx::fem::bcs_rows
std::vector< std::vector< std::shared_ptr< const fem::DirichletBC< T > > > > bcs_rows(const std::vector< const Form< T > * > &L, const std::vector< std::shared_ptr< const fem::DirichletBC< T >>> &bcs)
Arrange boundary conditions by block.
Definition: assembler.h:254
dolfinx::fem::Form::function_spaces
const std::vector< std::shared_ptr< const fem::FunctionSpace > > & function_spaces() const
Return function spaces for all arguments.
Definition: Form.h:149
dolfinx::fem::assemble_matrix
void assemble_matrix(const std::function< int(std::int32_t, const std::int32_t *, std::int32_t, const std::int32_t *, const T *)> &mat_add, const Form< T > &a, const std::vector< std::shared_ptr< const DirichletBC< T >>> &bcs)
Assemble bilinear form into a matrix.
Definition: assembler.h:86