DOLFIN-X
DOLFIN-X 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 <Eigen/Dense>
10 #include <dolfinx/function/Function.h>
11 #include <dolfinx/la/utils.h>
12 #include <functional>
13 #include <memory>
14 #include <vector>
15 
16 namespace dolfinx
17 {
18 
19 namespace function
20 {
21 template <typename T>
22 class Function;
23 class FunctionSpace;
24 } // namespace function
25 
26 namespace mesh
27 {
28 class Mesh;
29 } // namespace mesh
30 
31 namespace fem
32 {
33 
60 Eigen::Array<std::int32_t, Eigen::Dynamic, Eigen::Dynamic>
62  const std::vector<std::reference_wrapper<function::FunctionSpace>>& V,
63  const int dim, const Eigen::Ref<const Eigen::ArrayXi>& entities,
64  bool remote = true);
65 
82 Eigen::Array<std::int32_t, Eigen::Dynamic, Eigen::Dynamic>
84  const std::vector<std::reference_wrapper<function::FunctionSpace>>& V,
85  const std::function<Eigen::Array<bool, Eigen::Dynamic, 1>(
86  const Eigen::Ref<const Eigen::Array<double, 3, Eigen::Dynamic,
87  Eigen::RowMajor>>&)>& marker);
88 
99 
100 template <typename T>
101 class DirichletBC
102 {
103 
104 public:
112  const std::shared_ptr<const function::Function<T>>& g,
113  const Eigen::Ref<const Eigen::Array<std::int32_t, Eigen::Dynamic, 1>>&
114  dofs)
115  : _function_space(g->function_space()), _g(g), _dofs(dofs.rows(), 2)
116  {
117  // Stack indices as columns, fits column-major _dofs layout
118  _dofs.col(0) = dofs;
119  _dofs.col(1) = dofs;
120  const int owned_size = _function_space->dofmap()->index_map->block_size()
121  * _function_space->dofmap()->index_map->size_local();
122  auto* it = std::lower_bound(_dofs.col(0).data(),
123  _dofs.col(0).data() + _dofs.rows(), owned_size);
124  _owned_indices = std::distance(_dofs.col(0).data(), it);
125  }
126 
137  const std::shared_ptr<const function::Function<T>>& g,
138  const Eigen::Ref<const Eigen::Array<std::int32_t, Eigen::Dynamic, 2>>&
139  V_g_dofs,
140  std::shared_ptr<const function::FunctionSpace> V)
141  : _function_space(V), _g(g), _dofs(V_g_dofs)
142  {
143  const int owned_size = _function_space->dofmap()->index_map->block_size()
144  * _function_space->dofmap()->index_map->size_local();
145  auto* it = std::lower_bound(_dofs.col(0).data(),
146  _dofs.col(0).data() + _dofs.rows(), owned_size);
147  _owned_indices = std::distance(_dofs.col(0).data(), it);
148  }
149 
152  DirichletBC(const DirichletBC& bc) = default;
153 
156  DirichletBC(DirichletBC&& bc) = default;
157 
159  ~DirichletBC() = default;
160 
163  DirichletBC& operator=(const DirichletBC& bc) = default;
164 
167 
170  std::shared_ptr<const function::FunctionSpace> function_space() const
171  {
172  return _function_space;
173  }
174 
177  std::shared_ptr<const function::Function<T>> value() const { return _g; }
178 
181  const Eigen::Array<std::int32_t, Eigen::Dynamic, 2>& dofs() const
182  {
183  return _dofs;
184  }
185 
189  const Eigen::Ref<const Eigen::Array<std::int32_t, Eigen::Dynamic, 2>>
190  dofs_owned() const
191  {
192  return _dofs.block<Eigen::Dynamic, 2>(0, 0, _owned_indices, 2);
193  }
194 
197  void set(Eigen::Ref<Eigen::Matrix<T, Eigen::Dynamic, 1>> x,
198  double scale = 1.0) const
199  {
200  // FIXME: This one excludes ghosts. Need to straighten out.
201  assert(_g);
202  auto& g = _g->x()->array();
203  for (Eigen::Index i = 0; i < _dofs.rows(); ++i)
204  {
205  if (_dofs(i, 0) < x.rows())
206  x[_dofs(i, 0)] = scale * g[_dofs(i, 1)];
207  }
208  }
209 
212  void set(Eigen::Ref<Eigen::Matrix<T, Eigen::Dynamic, 1>> x,
213  const Eigen::Ref<const Eigen::Matrix<T, Eigen::Dynamic, 1>>& x0,
214  double scale = 1.0) const
215  {
216  // FIXME: This one excludes ghosts. Need to straighten out.
217  assert(_g);
218  auto& g = _g->x()->array();
219  assert(x.rows() <= x0.rows());
220  for (Eigen::Index i = 0; i < _dofs.rows(); ++i)
221  {
222  if (_dofs(i, 0) < x.rows())
223  x[_dofs(i, 0)] = scale * (g[_dofs(i, 1)] - x0[_dofs(i, 0)]);
224  }
225  }
226 
230  void dof_values(Eigen::Ref<Eigen::Matrix<T, Eigen::Dynamic, 1>> values) const
231  {
232  assert(_g);
233  auto& g = _g->x()->array();
234  for (Eigen::Index i = 0; i < _dofs.rows(); ++i)
235  values[_dofs(i, 0)] = g[_dofs(i, 1)];
236  }
237 
241  void mark_dofs(std::vector<bool>& markers) const
242  {
243  for (Eigen::Index i = 0; i < _dofs.rows(); ++i)
244  {
245  assert(_dofs(i, 0) < (std::int32_t)markers.size());
246  markers[_dofs(i, 0)] = true;
247  }
248  }
249 
250 private:
251  // The function space (possibly a sub function space)
252  std::shared_ptr<const function::FunctionSpace> _function_space;
253 
254  // The function
255  std::shared_ptr<const function::Function<T>> _g;
256 
257  // Pairs of dof indices in _function_space (i, 0) and in the space of
258  // _g (i, 1)
259  Eigen::Array<std::int32_t, Eigen::Dynamic, 2> _dofs;
260 
261  // The first _owned_indices in _dofs are owned by this process
262  int _owned_indices = -1;
263 };
264 } // namespace fem
265 } // namespace dolfinx
dolfinx::fem::DirichletBC::DirichletBC
DirichletBC(const std::shared_ptr< const function::Function< T >> &g, const Eigen::Ref< const Eigen::Array< std::int32_t, Eigen::Dynamic, 2 >> &V_g_dofs, std::shared_ptr< const function::FunctionSpace > V)
Create boundary condition.
Definition: DirichletBC.h:136
dolfinx::fem::DirichletBC::set
void set(Eigen::Ref< Eigen::Matrix< T, Eigen::Dynamic, 1 >> x, double scale=1.0) const
Set bc entries in x to scale*x_bc.
Definition: DirichletBC.h:197
dolfinx::fem::DirichletBC::DirichletBC
DirichletBC(DirichletBC &&bc)=default
Move constructor.
dolfinx::fem::DirichletBC::~DirichletBC
~DirichletBC()=default
Destructor.
dolfinx::fem::DirichletBC::function_space
std::shared_ptr< const function::FunctionSpace > function_space() const
The function space to which boundary conditions are applied.
Definition: DirichletBC.h:170
dolfinx::fem::locate_dofs_topological
Eigen::Array< std::int32_t, Eigen::Dynamic, Eigen::Dynamic > locate_dofs_topological(const std::vector< std::reference_wrapper< function::FunctionSpace >> &V, const int dim, const Eigen::Ref< const Eigen::ArrayXi > &entities, bool remote=true)
Build an array of degree-of-freedom indices that are associated with give mesh entities (topological)
Definition: DirichletBC.cpp:496
dolfinx::fem::DirichletBC::dofs_owned
const Eigen::Ref< const Eigen::Array< std::int32_t, Eigen::Dynamic, 2 > > dofs_owned() const
Get array of dof indices owned by this process to which a Dirichlet BC is applied....
Definition: DirichletBC.h:190
dolfinx::fem::DirichletBC::DirichletBC
DirichletBC(const DirichletBC &bc)=default
Copy constructor.
dolfinx::fem::DirichletBC::operator=
DirichletBC & operator=(const DirichletBC &bc)=default
Assignment operator.
dolfinx::fem::locate_dofs_geometrical
Eigen::Array< std::int32_t, Eigen::Dynamic, Eigen::Dynamic > locate_dofs_geometrical(const std::vector< std::reference_wrapper< function::FunctionSpace >> &V, const std::function< Eigen::Array< bool, Eigen::Dynamic, 1 >(const Eigen::Ref< const Eigen::Array< double, 3, Eigen::Dynamic, Eigen::RowMajor >> &)> &marker)
Build an array of degree-of-freedom indices based on coordinates of the degree-of-freedom (geometric)...
Definition: DirichletBC.cpp:510
dolfinx::mesh::Mesh
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition: Mesh.h:47
dolfinx::fem::DirichletBC::dof_values
void dof_values(Eigen::Ref< Eigen::Matrix< T, Eigen::Dynamic, 1 >> values) const
Set boundary condition value for entres with an applied boundary condition. Other entries are not mod...
Definition: DirichletBC.h:230
dolfinx::fem::DirichletBC
Interface for setting (strong) Dirichlet boundary conditions.
Definition: assembler.h:26
dolfinx::fem::DirichletBC::DirichletBC
DirichletBC(const std::shared_ptr< const function::Function< T >> &g, const Eigen::Ref< const Eigen::Array< std::int32_t, Eigen::Dynamic, 1 >> &dofs)
Create boundary condition.
Definition: DirichletBC.h:111
dolfinx::function::Function
This class represents a function in a finite element function space , given by.
Definition: DirichletBC.h:22
dolfinx::fem::DirichletBC::set
void set(Eigen::Ref< Eigen::Matrix< T, Eigen::Dynamic, 1 >> x, const Eigen::Ref< const Eigen::Matrix< T, Eigen::Dynamic, 1 >> &x0, double scale=1.0) const
Set bc entries in x to scale*(x0 - x_bc).
Definition: DirichletBC.h:212
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:241
dolfinx::fem::DirichletBC::dofs
const Eigen::Array< std::int32_t, Eigen::Dynamic, 2 > & dofs() const
Get array of dof indices to which a Dirichlet boundary condition is applied. The array is sorted and ...
Definition: DirichletBC.h:181
dolfinx::fem::DirichletBC::operator=
DirichletBC & operator=(DirichletBC &&bc)=default
Move assignment operator.
dolfinx::function::FunctionSpace
This class represents a finite element function space defined by a mesh, a finite element,...
Definition: FunctionSpace.h:38
dolfinx::fem::DirichletBC::value
std::shared_ptr< const function::Function< T > > value() const
Return boundary value function g.
Definition: DirichletBC.h:177