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
DirichletBC.h
1 // Copyright (C) 2007-2020 Michal Habera, Anders Logg and 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 <array>
10 #include <dolfinx/fem/Function.h>
11 #include <dolfinx/fem/FunctionSpace.h>
12 #include <dolfinx/la/utils.h>
13 #include <functional>
14 #include <memory>
15 #include <vector>
16 #include <xtensor/xtensor.hpp>
17 #include <xtl/xspan.hpp>
18 
19 namespace dolfinx
20 {
21 
22 namespace mesh
23 {
24 class Mesh;
25 } // namespace mesh
26 
27 namespace fem
28 {
29 
53 std::array<std::vector<std::int32_t>, 2> locate_dofs_topological(
54  const std::array<std::reference_wrapper<const fem::FunctionSpace>, 2>& V,
55  const int dim, const xtl::span<const std::int32_t>& entities,
56  bool remote = true);
57 
79 std::vector<std::int32_t>
80 locate_dofs_topological(const fem::FunctionSpace& V, const int dim,
81  const xtl::span<const std::int32_t>& entities,
82  bool remote = true);
83 
97 std::array<std::vector<std::int32_t>, 2> locate_dofs_geometrical(
98  const std::array<std::reference_wrapper<const fem::FunctionSpace>, 2>& V,
99  const std::function<xt::xtensor<bool, 1>(const xt::xtensor<double, 2>&)>&
100  marker_fn);
101 
113 std::vector<std::int32_t> locate_dofs_geometrical(
114  const fem::FunctionSpace& V,
115  const std::function<xt::xtensor<bool, 1>(const xt::xtensor<double, 2>&)>&
116  marker_fn);
117 
128 
129 template <typename T>
130 class DirichletBC
131 {
132 
133 public:
148  template <typename U>
149  DirichletBC(const std::shared_ptr<const fem::Function<T>>& g, U&& dofs)
150  : _function_space(g->function_space()), _g(g),
151  _dofs0(std::forward<U>(dofs))
152  {
153  const int owned_size0 = _function_space->dofmap()->index_map->size_local();
154  auto it = std::lower_bound(_dofs0.begin(), _dofs0.end(), owned_size0);
155  const int map0_bs = _function_space->dofmap()->index_map_bs();
156  _owned_indices0 = map0_bs * std::distance(_dofs0.begin(), it);
157 
158  const int bs = _function_space->dofmap()->bs();
159  if (bs > 1)
160  {
161  // Unroll for the block size
162  const std::vector<std::int32_t> dof_tmp = _dofs0;
163  _dofs0.resize(bs * dof_tmp.size());
164  for (std::size_t i = 0; i < dof_tmp.size(); ++i)
165  {
166  for (int k = 0; k < bs; ++k)
167  _dofs0[bs * i + k] = bs * dof_tmp[i] + k;
168  }
169  }
170 
171  // TODO: allows single dofs array (let one point to the other)
172  _dofs1_g = _dofs0;
173  }
174 
192  DirichletBC(const std::shared_ptr<const fem::Function<T>>& g,
193  const std::array<std::vector<std::int32_t>, 2>& V_g_dofs,
194  std::shared_ptr<const fem::FunctionSpace> V)
195  : _function_space(V), _g(g), _dofs0(V_g_dofs[0]), _dofs1_g(V_g_dofs[1])
196  {
197  assert(_dofs0.size() == _dofs1_g.size());
198  assert(_function_space);
199  assert(_g);
200 
201  const int map0_bs = _function_space->dofmap()->index_map_bs();
202  const int map0_size = _function_space->dofmap()->index_map->size_local();
203  const int owned_size0 = map0_bs * map0_size;
204  auto it0 = std::lower_bound(_dofs0.begin(), _dofs0.end(), owned_size0);
205  _owned_indices0 = std::distance(_dofs0.begin(), it0);
206  }
207 
210  DirichletBC(const DirichletBC& bc) = default;
211 
214  DirichletBC(DirichletBC&& bc) = default;
215 
217  ~DirichletBC() = default;
218 
221  DirichletBC& operator=(const DirichletBC& bc) = default;
222 
224  DirichletBC& operator=(DirichletBC&& bc) = default;
225 
228  std::shared_ptr<const fem::FunctionSpace> function_space() const
229  {
230  return _function_space;
231  }
232 
235  std::shared_ptr<const fem::Function<T>> value() const { return _g; }
236 
243  std::pair<xtl::span<const std::int32_t>, std::int32_t> dof_indices() const
244  {
245  return {tcb::make_span(_dofs0), _owned_indices0};
246  }
247 
259  void set(xtl::span<T> x, double scale = 1.0) const
260  {
261  assert(_g);
262  const std::vector<T>& g = _g->x()->array();
263  for (std::size_t i = 0; i < _dofs0.size(); ++i)
264  {
265  if (_dofs0[i] < (std::int32_t)x.size())
266  {
267  assert(_dofs1_g[i] < (std::int32_t)g.size());
268  x[_dofs0[i]] = scale * g[_dofs1_g[i]];
269  }
270  }
271  }
272 
277  void set(xtl::span<T> x, const xtl::span<const T>& x0,
278  double scale = 1.0) const
279  {
280  assert(_g);
281  const std::vector<T>& g = _g->x()->array();
282  assert(x.size() <= x0.size());
283  for (std::size_t i = 0; i < _dofs0.size(); ++i)
284  {
285  if (_dofs0[i] < (std::int32_t)x.size())
286  {
287  assert(_dofs1_g[i] < (std::int32_t)g.size());
288  x[_dofs0[i]] = scale * (g[_dofs1_g[i]] - x0[_dofs0[i]]);
289  }
290  }
291  }
292 
301  void dof_values(xtl::span<T> values) const
302  {
303  assert(_g);
304  const std::vector<T>& g = _g->x()->array();
305  for (std::size_t i = 0; i < _dofs1_g.size(); ++i)
306  values[_dofs0[i]] = g[_dofs1_g[i]];
307  }
308 
315  void mark_dofs(std::vector<bool>& markers) const
316  {
317  for (std::size_t i = 0; i < _dofs0.size(); ++i)
318  {
319  assert(_dofs0[i] < (std::int32_t)markers.size());
320  markers[_dofs0[i]] = true;
321  }
322  }
323 
324 private:
325  // The function space (possibly a sub function space)
326  std::shared_ptr<const fem::FunctionSpace> _function_space;
327 
328  // The function
329  std::shared_ptr<const fem::Function<T>> _g;
330 
331  // Dof indices (_dofs0) in _function_space and (_dofs1_g) in the
332  // space of _g
333  std::vector<std::int32_t> _dofs0, _dofs1_g;
334 
335  // The first _owned_indices in _dofs are owned by this process
336  int _owned_indices0 = -1;
337  int _owned_indices1 = -1;
338 };
339 } // namespace fem
340 } // namespace dolfinx
dolfinx::fem::DirichletBC::set
void set(xtl::span< T > x, const xtl::span< const T > &x0, double scale=1.0) const
Set bc entries in x to scale * (x0 - x_bc)
Definition: DirichletBC.h:277
dolfinx::fem::DirichletBC::dof_indices
std::pair< xtl::span< const std::int32_t >, std::int32_t > dof_indices() const
Access dof indices (local indices, unrolled), including ghosts, to which a Dirichlet condition is app...
Definition: DirichletBC.h:243
dolfinx::fem::Function
This class represents a function in a finite element function space , given by.
Definition: Form.h:23
dolfinx::fem::DirichletBC::function_space
std::shared_ptr< const fem::FunctionSpace > function_space() const
The function space to which boundary conditions are applied.
Definition: DirichletBC.h:228
dolfinx::fem::FunctionSpace
This class represents a finite element function space defined by a mesh, a finite element,...
Definition: FunctionSpace.h:33
dolfinx::fem::DirichletBC::~DirichletBC
~DirichletBC()=default
Destructor.
dolfinx::fem::DirichletBC::DirichletBC
DirichletBC(const std::shared_ptr< const fem::Function< T >> &g, const std::array< std::vector< std::int32_t >, 2 > &V_g_dofs, std::shared_ptr< const fem::FunctionSpace > V)
Create a representation of a Dirichlet boundary condition where the space being constrained and the f...
Definition: DirichletBC.h:192
dolfinx::fem::DirichletBC::DirichletBC
DirichletBC(const std::shared_ptr< const fem::Function< T >> &g, U &&dofs)
Create a representation of a Dirichlet boundary condition where the space being constrained is the sa...
Definition: DirichletBC.h:149
dolfinx::fem::DirichletBC::operator=
DirichletBC & operator=(const DirichletBC &bc)=default
Assignment operator.
dolfinx::mesh::Mesh
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition: Mesh.h:55
dolfinx::fem::DirichletBC::value
std::shared_ptr< const fem::Function< T > > value() const
Return boundary value function g.
Definition: DirichletBC.h:235
dolfinx::fem::DirichletBC::dof_values
void dof_values(xtl::span< T > values) const
Definition: DirichletBC.h:301
dolfinx::fem::DirichletBC
Interface for setting (strong) Dirichlet boundary conditions.
Definition: assembler.h:20
dolfinx::fem::locate_dofs_geometrical
std::array< std::vector< std::int32_t >, 2 > locate_dofs_geometrical(const std::array< std::reference_wrapper< const fem::FunctionSpace >, 2 > &V, const std::function< xt::xtensor< bool, 1 >(const xt::xtensor< double, 2 > &)> &marker_fn)
Finds degrees of freedom whose geometric coordinate is true for the provided marking function.
Definition: DirichletBC.cpp:450
dolfinx::fem::DirichletBC::mark_dofs
void mark_dofs(std::vector< bool > &markers) const
Set markers[i] = true if dof i has a boundary condition applied. Value of markers[i] is not changed o...
Definition: DirichletBC.h:315
dolfinx::fem::DirichletBC::set
void set(xtl::span< T > x, double scale=1.0) const
Set bc entries in x to scale * x_bc
Definition: DirichletBC.h:259
dolfinx::fem::locate_dofs_topological
std::array< std::vector< std::int32_t >, 2 > locate_dofs_topological(const std::array< std::reference_wrapper< const fem::FunctionSpace >, 2 > &V, const int dim, const xtl::span< const std::int32_t > &entities, bool remote=true)
Find degrees-of-freedom which belong to the provided mesh entities (topological). Note that degrees-o...
Definition: DirichletBC.cpp:244