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
assemble_matrix_impl.h
1 // Copyright (C) 2018-2019 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 "DofMap.h"
10 #include "Form.h"
11 #include "utils.h"
12 #include <dolfinx/fem/FunctionSpace.h>
13 #include <dolfinx/graph/AdjacencyList.h>
14 #include <dolfinx/la/utils.h>
15 #include <dolfinx/mesh/Geometry.h>
16 #include <dolfinx/mesh/Mesh.h>
17 #include <dolfinx/mesh/Topology.h>
18 #include <functional>
19 #include <iterator>
20 #include <vector>
21 
22 namespace dolfinx::fem::impl
23 {
24 
30 
31 template <typename T>
32 void assemble_matrix(
33  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
34  const std::int32_t*, const T*)>& mat_set_values,
35  const Form<T>& a, const std::vector<bool>& bc0,
36  const std::vector<bool>& bc1);
37 
39 template <typename T>
40 void assemble_cells(
41  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
42  const std::int32_t*, const T*)>& mat_set_values,
43  const mesh::Geometry& geometry,
44  const std::vector<std::int32_t>& active_cells,
45  const graph::AdjacencyList<std::int32_t>& dofmap0, const int bs0,
46  const graph::AdjacencyList<std::int32_t>& dofmap1, const int bs1,
47  const std::vector<bool>& bc0, const std::vector<bool>& bc1,
48  const std::function<void(T*, const T*, const T*, const double*, const int*,
49  const std::uint8_t*, const std::uint32_t)>& kernel,
50  const array2d<T>& coeffs, const std::vector<T>& constants,
51  const std::vector<std::uint32_t>& cell_info);
52 
54 template <typename T>
55 void assemble_exterior_facets(
56  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
57  const std::int32_t*, const T*)>& mat_set_values,
58  const mesh::Mesh& mesh, const std::vector<std::int32_t>& active_facets,
59  const graph::AdjacencyList<std::int32_t>& dofmap0, int bs0,
60  const graph::AdjacencyList<std::int32_t>& dofmap1, int bs1,
61  const std::vector<bool>& bc0, const std::vector<bool>& bc1,
62  const std::function<void(T*, const T*, const T*, const double*, const int*,
63  const std::uint8_t*, const std::uint32_t)>& fn,
64  const array2d<T>& coeffs, const std::vector<T>& constants,
65  const std::vector<std::uint32_t>& cell_info,
66  const std::vector<std::uint8_t>& perms);
67 
69 template <typename T>
70 void assemble_interior_facets(
71  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
72  const std::int32_t*, const T*)>& mat_set_values,
73  const mesh::Mesh& mesh, const std::vector<std::int32_t>& active_facets,
74  const DofMap& dofmap0, int bs0, const DofMap& dofmap1, int bs1,
75  const std::vector<bool>& bc0, const std::vector<bool>& bc1,
76  const std::function<void(T*, const T*, const T*, const double*, const int*,
77  const std::uint8_t*, const std::uint32_t)>& kernel,
78  const array2d<T>& coeffs, const std::vector<int>& offsets,
79  const std::vector<T>& constants,
80  const std::vector<std::uint32_t>& cell_info,
81  const std::vector<std::uint8_t>& perms);
82 
83 //-----------------------------------------------------------------------------
84 template <typename T>
85 void assemble_matrix(
86  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
87  const std::int32_t*, const T*)>& mat_set_values,
88  const Form<T>& a, const std::vector<bool>& bc0,
89  const std::vector<bool>& bc1)
90 {
91  std::shared_ptr<const mesh::Mesh> mesh = a.mesh();
92  assert(mesh);
93  const int tdim = mesh->topology().dim();
94  const std::int32_t num_cells
95  = mesh->topology().connectivity(tdim, 0)->num_nodes();
96 
97  // Get dofmap data
98  std::shared_ptr<const fem::DofMap> dofmap0
99  = a.function_spaces().at(0)->dofmap();
100  std::shared_ptr<const fem::DofMap> dofmap1
101  = a.function_spaces().at(1)->dofmap();
102  assert(dofmap0);
103  assert(dofmap1);
104  const graph::AdjacencyList<std::int32_t>& dofs0 = dofmap0->list();
105  const int bs0 = dofmap0->bs();
106  const graph::AdjacencyList<std::int32_t>& dofs1 = dofmap1->list();
107  const int bs1 = dofmap1->bs();
108 
109  // Prepare constants
110  const std::vector<T> constants = pack_constants(a);
111 
112  // Prepare coefficients
113  const array2d<T> coeffs = pack_coefficients(a);
114 
115  const bool needs_permutation_data = a.needs_permutation_data();
116  if (needs_permutation_data)
117  mesh->topology_mutable().create_entity_permutations();
118  const std::vector<std::uint32_t>& cell_info
119  = needs_permutation_data ? mesh->topology().get_cell_permutation_info()
120  : std::vector<std::uint32_t>(num_cells);
121 
122  for (int i : a.integral_ids(IntegralType::cell))
123  {
124  const auto& fn = a.kernel(IntegralType::cell, i);
125  const std::vector<std::int32_t>& active_cells
126  = a.domains(IntegralType::cell, i);
127  impl::assemble_cells<T>(mat_set_values, mesh->geometry(), active_cells,
128  dofs0, bs0, dofs1, bs1, bc0, bc1, fn, coeffs,
129  constants, cell_info);
130  }
131 
132  if (a.num_integrals(IntegralType::exterior_facet) > 0
133  or a.num_integrals(IntegralType::interior_facet) > 0)
134  {
135  mesh->topology_mutable().create_connectivity(tdim - 1, tdim);
136  mesh->topology_mutable().create_entity_permutations();
137 
138  const std::vector<std::uint8_t>& perms
139  = mesh->topology().get_facet_permutations();
140 
141  for (int i : a.integral_ids(IntegralType::exterior_facet))
142  {
143  const auto& fn = a.kernel(IntegralType::exterior_facet, i);
144  const std::vector<std::int32_t>& active_facets
145  = a.domains(IntegralType::exterior_facet, i);
146  impl::assemble_exterior_facets<T>(mat_set_values, *mesh, active_facets,
147  dofs0, bs0, dofs1, bs1, bc0, bc1, fn,
148  coeffs, constants, cell_info, perms);
149  }
150 
151  const std::vector<int> c_offsets = a.coefficient_offsets();
152  for (int i : a.integral_ids(IntegralType::interior_facet))
153  {
154  const auto& fn = a.kernel(IntegralType::interior_facet, i);
155  const std::vector<std::int32_t>& active_facets
156  = a.domains(IntegralType::interior_facet, i);
157  impl::assemble_interior_facets<T>(
158  mat_set_values, *mesh, active_facets, *dofmap0, bs0, *dofmap1, bs1,
159  bc0, bc1, fn, coeffs, c_offsets, constants, cell_info, perms);
160  }
161  }
162 }
163 //-----------------------------------------------------------------------------
164 template <typename T>
165 void assemble_cells(
166  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
167  const std::int32_t*, const T*)>& mat_set,
168  const mesh::Geometry& geometry,
169  const std::vector<std::int32_t>& active_cells,
170  const graph::AdjacencyList<std::int32_t>& dofmap0, const int bs0,
171  const graph::AdjacencyList<std::int32_t>& dofmap1, const int bs1,
172  const std::vector<bool>& bc0, const std::vector<bool>& bc1,
173  const std::function<void(T*, const T*, const T*, const double*, const int*,
174  const std::uint8_t*, const std::uint32_t)>& kernel,
175  const array2d<T>& coeffs, const std::vector<T>& constants,
176  const std::vector<std::uint32_t>& cell_info)
177 {
178  const std::size_t gdim = geometry.dim();
179 
180  // Prepare cell geometry
181  const graph::AdjacencyList<std::int32_t>& x_dofmap = geometry.dofmap();
182 
183  // FIXME: Add proper interface for num coordinate dofs
184  const std::size_t num_dofs_g = x_dofmap.num_links(0);
185  const xt::xtensor<double, 2>& x_g = geometry.x();
186 
187  // Iterate over active cells
188  const int num_dofs0 = dofmap0.links(0).size();
189  const int num_dofs1 = dofmap1.links(0).size();
190  const int ndim0 = bs0 * num_dofs0;
191  const int ndim1 = bs1 * num_dofs1;
192  std::vector<T> Ae(ndim0 * ndim1);
193  std::vector<double> coordinate_dofs(num_dofs_g * gdim);
194  for (std::int32_t c : active_cells)
195  {
196  // Get cell coordinates/geometry
197  auto x_dofs = x_dofmap.links(c);
198  for (std::size_t i = 0; i < x_dofs.size(); ++i)
199  {
200  std::copy_n(xt::row(x_g, x_dofs[i]).begin(), gdim,
201  std::next(coordinate_dofs.begin(), i * gdim));
202  }
203 
204  // Tabulate tensor
205  std::fill(Ae.begin(), Ae.end(), 0);
206  kernel(Ae.data(), coeffs.row(c).data(), constants.data(),
207  coordinate_dofs.data(), nullptr, nullptr, cell_info[c]);
208 
209  // Zero rows/columns for essential bcs
210  auto dofs0 = dofmap0.links(c);
211  auto dofs1 = dofmap1.links(c);
212  if (!bc0.empty())
213  {
214  for (int i = 0; i < num_dofs0; ++i)
215  {
216  for (int k = 0; k < bs0; ++k)
217  {
218  if (bc0[bs0 * dofs0[i] + k])
219  {
220  // Zero row bs0 * i + k
221  const int row = bs0 * i + k;
222  std::fill_n(std::next(Ae.begin(), ndim1 * row), ndim1, 0.0);
223  }
224  }
225  }
226  }
227 
228  if (!bc1.empty())
229  {
230  for (int j = 0; j < num_dofs1; ++j)
231  {
232  for (int k = 0; k < bs1; ++k)
233  {
234  if (bc1[bs1 * dofs1[j] + k])
235  {
236  // Zero column bs1 * j + k
237  const int col = bs1 * j + k;
238  for (int row = 0; row < ndim0; ++row)
239  Ae[row * ndim1 + col] = 0.0;
240  }
241  }
242  }
243  }
244 
245  mat_set(dofs0.size(), dofs0.data(), dofs1.size(), dofs1.data(), Ae.data());
246  }
247 } // namespace dolfinx::fem::impl
248 //-----------------------------------------------------------------------------
249 template <typename T>
250 void assemble_exterior_facets(
251  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
252  const std::int32_t*, const T*)>& mat_set_values,
253  const mesh::Mesh& mesh, const std::vector<std::int32_t>& active_facets,
254  const graph::AdjacencyList<std::int32_t>& dofmap0, int bs0,
255  const graph::AdjacencyList<std::int32_t>& dofmap1, int bs1,
256  const std::vector<bool>& bc0, const std::vector<bool>& bc1,
257  const std::function<void(T*, const T*, const T*, const double*, const int*,
258  const std::uint8_t*, const std::uint32_t)>& kernel,
259  const array2d<T>& coeffs, const std::vector<T>& constants,
260  const std::vector<std::uint32_t>& cell_info,
261  const std::vector<std::uint8_t>& perms)
262 {
263  const std::size_t gdim = mesh.geometry().dim();
264  const int tdim = mesh.topology().dim();
265 
266  // Prepare cell geometry
267  const graph::AdjacencyList<std::int32_t>& x_dofmap = mesh.geometry().dofmap();
268 
269  // FIXME: Add proper interface for num coordinate dofs
270  const std::size_t num_dofs_g = x_dofmap.num_links(0);
271  const xt::xtensor<double, 2>& x_g = mesh.geometry().x();
272 
273  // Data structures used in assembly
274  std::vector<double> coordinate_dofs(num_dofs_g * gdim);
275  const int num_dofs0 = dofmap0.links(0).size();
276  const int num_dofs1 = dofmap1.links(0).size();
277  const int ndim0 = bs0 * num_dofs0;
278  const int ndim1 = bs1 * num_dofs1;
279  std::vector<T> Ae(ndim0 * ndim1);
280 
281  // Iterate over all facets
282  auto f_to_c = mesh.topology().connectivity(tdim - 1, tdim);
283  assert(f_to_c);
284  auto c_to_f = mesh.topology().connectivity(tdim, tdim - 1);
285  assert(c_to_f);
286  for (std::int32_t f : active_facets)
287  {
288  auto cells = f_to_c->links(f);
289  assert(cells.size() == 1);
290 
291  // Get local index of facet with respect to the cell
292  auto facets = c_to_f->links(cells[0]);
293  auto it = std::find(facets.begin(), facets.end(), f);
294  assert(it != facets.end());
295  const int local_facet = std::distance(facets.begin(), it);
296 
297  // Get cell coordinates/geometry
298  auto x_dofs = x_dofmap.links(cells[0]);
299  for (std::size_t i = 0; i < x_dofs.size(); ++i)
300  {
301  std::copy_n(xt::row(x_g, x_dofs[i]).begin(), gdim,
302  std::next(coordinate_dofs.begin(), i * gdim));
303  }
304 
305  // Tabulate tensor
306  std::fill(Ae.begin(), Ae.end(), 0);
307  kernel(Ae.data(), coeffs.row(cells[0]).data(), constants.data(),
308  coordinate_dofs.data(), &local_facet,
309  &perms[cells[0] * facets.size() + local_facet], cell_info[cells[0]]);
310 
311  // Zero rows/columns for essential bcs
312  auto dofs0 = dofmap0.links(cells[0]);
313  auto dofs1 = dofmap1.links(cells[0]);
314  if (!bc0.empty())
315  {
316  for (int i = 0; i < num_dofs0; ++i)
317  {
318  for (int k = 0; k < bs0; ++k)
319  {
320  if (bc0[bs0 * dofs0[i] + k])
321  {
322  // Zero row bs0 * i + k
323  const int row = bs0 * i + k;
324  std::fill_n(std::next(Ae.begin(), ndim1 * row), ndim1, 0.0);
325  }
326  }
327  }
328  }
329  if (!bc1.empty())
330  {
331  for (int j = 0; j < num_dofs1; ++j)
332  {
333  for (int k = 0; k < bs1; ++k)
334  {
335  if (bc1[bs1 * dofs1[j] + k])
336  {
337  // Zero column bs1 * j + k
338  const int col = bs1 * j + k;
339  for (int row = 0; row < ndim0; ++row)
340  Ae[row * ndim1 + col] = 0.0;
341  }
342  }
343  }
344  }
345 
346  mat_set_values(dofs0.size(), dofs0.data(), dofs1.size(), dofs1.data(),
347  Ae.data());
348  }
349 }
350 //-----------------------------------------------------------------------------
351 template <typename T>
352 void assemble_interior_facets(
353  const std::function<int(std::int32_t, const std::int32_t*, std::int32_t,
354  const std::int32_t*, const T*)>& mat_set_values,
355  const mesh::Mesh& mesh, const std::vector<std::int32_t>& active_facets,
356  const DofMap& dofmap0, int bs0, const DofMap& dofmap1, int bs1,
357  const std::vector<bool>& bc0, const std::vector<bool>& bc1,
358  const std::function<void(T*, const T*, const T*, const double*, const int*,
359  const std::uint8_t*, const std::uint32_t)>& fn,
360  const array2d<T>& coeffs, const std::vector<int>& offsets,
361  const std::vector<T>& constants,
362  const std::vector<std::uint32_t>& cell_info,
363  const std::vector<std::uint8_t>& perms)
364 {
365  const std::size_t gdim = mesh.geometry().dim();
366  const int tdim = mesh.topology().dim();
367 
368  // Prepare cell geometry
369  const graph::AdjacencyList<std::int32_t>& x_dofmap = mesh.geometry().dofmap();
370 
371  // FIXME: Add proper interface for num coordinate dofs
372  const std::size_t num_dofs_g = x_dofmap.num_links(0);
373  const xt::xtensor<double, 2>& x_g = mesh.geometry().x();
374 
375  // Data structures used in assembly
376  xt::xtensor<double, 3> coordinate_dofs({2, num_dofs_g, gdim});
377  std::vector<T> Ae, be;
378  std::vector<T> coeff_array(2 * offsets.back());
379  assert(offsets.back() == coeffs.shape[1]);
380 
381  // Temporaries for joint dofmaps
382  std::vector<std::int32_t> dmapjoint0, dmapjoint1;
383 
384  // Iterate over all facets
385  auto c = mesh.topology().connectivity(tdim - 1, tdim);
386  assert(c);
387  auto c_to_f = mesh.topology().connectivity(tdim, tdim - 1);
388  assert(c_to_f);
389  for (std::int32_t facet_index : active_facets)
390  {
391  // Create attached cells
392  auto cells = c->links(facet_index);
393  assert(cells.size() == 2);
394 
395  // Get local index of facet with respect to the cell
396  auto facets0 = c_to_f->links(cells[0]);
397  const auto* it0 = std::find(facets0.begin(), facets0.end(), facet_index);
398  assert(it0 != facets0.end());
399  const int local_facet0 = std::distance(facets0.begin(), it0);
400  auto facets1 = c_to_f->links(cells[1]);
401  const auto* it1 = std::find(facets1.begin(), facets1.end(), facet_index);
402  assert(it1 != facets1.end());
403  const int local_facet1 = std::distance(facets1.begin(), it1);
404 
405  const std::array local_facet{local_facet0, local_facet1};
406 
407  // Get cell geometry
408  auto x_dofs0 = x_dofmap.links(cells[0]);
409  for (std::size_t i = 0; i < x_dofs0.size(); ++i)
410  {
411  std::copy_n(xt::view(x_g, x_dofs0[i]).begin(), gdim,
412  xt::view(coordinate_dofs, 0, i, xt::all()).begin());
413  }
414  auto x_dofs1 = x_dofmap.links(cells[1]);
415  for (std::size_t i = 0; i < x_dofs1.size(); ++i)
416  {
417  std::copy_n(xt::view(x_g, x_dofs1[i]).begin(), gdim,
418  xt::view(coordinate_dofs, 1, i, xt::all()).begin());
419  }
420 
421  // Get dof maps for cells and pack
422  xtl::span<const std::int32_t> dmap0_cell0 = dofmap0.cell_dofs(cells[0]);
423  xtl::span<const std::int32_t> dmap0_cell1 = dofmap0.cell_dofs(cells[1]);
424  dmapjoint0.resize(dmap0_cell0.size() + dmap0_cell1.size());
425  std::copy(dmap0_cell0.begin(), dmap0_cell0.end(), dmapjoint0.begin());
426  std::copy(dmap0_cell1.begin(), dmap0_cell1.end(),
427  std::next(dmapjoint0.begin(), dmap0_cell0.size()));
428 
429  xtl::span<const std::int32_t> dmap1_cell0 = dofmap1.cell_dofs(cells[0]);
430  xtl::span<const std::int32_t> dmap1_cell1 = dofmap1.cell_dofs(cells[1]);
431  dmapjoint1.resize(dmap1_cell0.size() + dmap1_cell1.size());
432  std::copy(dmap1_cell0.begin(), dmap1_cell0.end(), dmapjoint1.begin());
433  std::copy(dmap1_cell1.begin(), dmap1_cell1.end(),
434  std::next(dmapjoint1.begin(), dmap1_cell0.size()));
435 
436  // Layout for the restricted coefficients is flattened
437  // w[coefficient][restriction][dof]
438  auto coeff_cell0 = coeffs.row(cells[0]);
439  auto coeff_cell1 = coeffs.row(cells[1]);
440 
441  // Loop over coefficients
442  for (std::size_t i = 0; i < offsets.size() - 1; ++i)
443  {
444  // Loop over entries for coefficient i
445  const int num_entries = offsets[i + 1] - offsets[i];
446  std::copy_n(coeff_cell0.data() + offsets[i], num_entries,
447  std::next(coeff_array.begin(), 2 * offsets[i]));
448  std::copy_n(coeff_cell1.data() + offsets[i], num_entries,
449  std::next(coeff_array.begin(), offsets[i + 1] + offsets[i]));
450  }
451 
452  const int num_rows = bs0 * dmapjoint0.size();
453  const int num_cols = bs1 * dmapjoint1.size();
454 
455  // Tabulate tensor
456  Ae.resize(num_rows * num_cols);
457  std::fill(Ae.begin(), Ae.end(), 0);
458 
459  const int facets_per_cell = facets0.size();
460  const std::array perm{perms[cells[0] * facets_per_cell + local_facet[0]],
461  perms[cells[1] * facets_per_cell + local_facet[1]]};
462  fn(Ae.data(), coeff_array.data(), constants.data(), coordinate_dofs.data(),
463  local_facet.data(), perm.data(), cell_info[cells[0]]);
464 
465  // Zero rows/columns for essential bcs
466  if (!bc0.empty())
467  {
468  for (std::size_t i = 0; i < dmapjoint0.size(); ++i)
469  {
470  for (int k = 0; k < bs0; ++k)
471  {
472  if (bc0[bs0 * dmapjoint0[i] + k])
473  {
474  // Zero row bs0 * i + k
475  std::fill_n(std::next(Ae.begin(), num_cols * (bs0 * i + k)),
476  num_cols, 0.0);
477  }
478  }
479  }
480  }
481  if (!bc1.empty())
482  {
483  for (std::size_t j = 0; j < dmapjoint1.size(); ++j)
484  {
485  for (int k = 0; k < bs1; ++k)
486  {
487  if (bc1[bs1 * dmapjoint1[j] + k])
488  {
489  // Zero column bs1 * j + k
490  for (int m = 0; m < num_rows; ++m)
491  Ae[m * num_cols + bs1 * j + k] = 0.0;
492  }
493  }
494  }
495  }
496 
497  mat_set_values(dmapjoint0.size(), dmapjoint0.data(), dmapjoint1.size(),
498  dmapjoint1.data(), Ae.data());
499  }
500 }
501 //-----------------------------------------------------------------------------
502 
503 } // namespace dolfinx::fem::impl
dolfinx::graph::AdjacencyList::num_links
int num_links(int node) const
Number of connections for given node.
Definition: AdjacencyList.h:120
dolfinx::fem::Form::coefficient_offsets
std::vector< int > coefficient_offsets() const
Offset for each coefficient expansion array on a cell. Used to pack data for multiple coefficients in...
Definition: Form.h:243
dolfinx::fem::Form::num_integrals
int num_integrals(IntegralType type) const
Number of integrals of given type.
Definition: Form.h:186
dolfinx::mesh::Topology::dim
int dim() const
Return topological dimension.
Definition: Topology.cpp:162
dolfinx::mesh::Geometry::dofmap
const graph::AdjacencyList< std::int32_t > & dofmap() const
DOF map.
Definition: Geometry.cpp:21
dolfinx::mesh::Geometry::x
xt::xtensor< double, 2 > & x()
Geometry degrees-of-freedom.
Definition: Geometry.cpp:31
dolfinx::fem::pack_constants
std::vector< typename U::scalar_type > pack_constants(const U &u)
Pack constants of u of generic type U ready for assembly.
Definition: utils.h:431
dolfinx::fem::Form
Class for variational forms.
Definition: assembler.h:22
dolfinx::graph::AdjacencyList
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition: AdjacencyList.h:46
dolfinx::fem::DofMap
Degree-of-freedom map.
Definition: DofMap.h:65
dolfinx::mesh::Geometry::dim
int dim() const
Return Euclidean dimension of coordinate system.
Definition: Geometry.cpp:19
dolfinx::mesh::Mesh::topology
Topology & topology()
Get mesh topology.
Definition: Mesh.cpp:118
dolfinx::fem::pack_coefficients
array2d< typename U::scalar_type > pack_coefficients(const U &u)
Pack coefficients of u of generic type U ready for assembly.
Definition: utils.h:376
dolfinx::mesh::Mesh
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition: Mesh.h:55
dolfinx::mesh::Topology::connectivity
std::shared_ptr< const graph::AdjacencyList< std::int32_t > > connectivity(int d0, int d1) const
Return connectivity from entities of dimension d0 to entities of dimension d1.
Definition: Topology.cpp:263
dolfinx::fem::Form::kernel
const std::function< void(T *, const T *, const T *, const double *, const int *, const std::uint8_t *, const std::uint32_t)> & kernel(IntegralType type, int i) const
Get the function for 'kernel' for integral i of given type.
Definition: Form.h:161
dolfinx::fem::Form::integral_ids
std::vector< int > integral_ids(IntegralType type) const
Get the IDs for integrals (kernels) for given integral type. The IDs correspond to the domain IDs whi...
Definition: Form.h:200
dolfinx::fem::Form::mesh
std::shared_ptr< const mesh::Mesh > mesh() const
Extract common mesh for the form.
Definition: Form.h:144
dolfinx::fem::Form::needs_permutation_data
bool needs_permutation_data() const
Get bool indicating whether permutation data needs to be passed into these integrals.
Definition: Form.h:238
dolfinx::fem::Form::domains
const std::vector< std::int32_t > & domains(IntegralType type, int i) const
Get the list of mesh entity indices for the ith integral (kernel) for the given domain type,...
Definition: Form.h:217
dolfinx::array2d
This class provides a dynamic 2-dimensional row-wise array data structure.
Definition: array2d.h:20
dolfinx::mesh::Mesh::geometry
Geometry & geometry()
Get mesh geometry.
Definition: Mesh.cpp:124
dolfinx::array2d::shape
std::array< size_type, 2 > shape
The shape of the array.
Definition: array2d.h:157
dolfinx::array2d::row
constexpr xtl::span< value_type > row(size_type i)
Access a row in the array.
Definition: array2d.h:116
dolfinx::mesh::Geometry
Geometry stores the geometry imposed on a mesh.
Definition: Geometry.h:36
dolfinx::graph::AdjacencyList::links
xtl::span< T > links(int node)
Get the links (edges) for given node.
Definition: AdjacencyList.h:130
dolfinx::fem::DofMap::cell_dofs
xtl::span< const std::int32_t > cell_dofs(int cell) const
Local-to-global mapping of dofs on a cell.
Definition: DofMap.h:111
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