Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/dolfinx/v0.9.0/cpp/doxygen/d8/d18/Form_8h_source.html
DOLFINx 0.7.3
DOLFINx C++ interface
Loading...
Searching...
No Matches
Form.h
1// Copyright (C) 2019-2023 Garth N. Wells and Chris Richardson
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 "FunctionSpace.h"
10#include <algorithm>
11#include <array>
12#include <concepts>
13#include <dolfinx/common/IndexMap.h>
14#include <dolfinx/common/types.h>
15#include <dolfinx/mesh/Mesh.h>
16#include <functional>
17#include <memory>
18#include <span>
19#include <string>
20#include <tuple>
21#include <vector>
22
23namespace dolfinx::fem
24{
25
26template <dolfinx::scalar T>
27class Constant;
28template <dolfinx::scalar T, std::floating_point U>
29class Function;
30
32enum class IntegralType : std::int8_t
33{
34 cell = 0,
35 exterior_facet = 1,
36 interior_facet = 2,
37 vertex = 3
38};
39
63template <dolfinx::scalar T,
64 std::floating_point U = dolfinx::scalar_value_type_t<T>>
65class Form
66{
67public:
69 using scalar_type = T;
70
87 Form(const std::vector<std::shared_ptr<const FunctionSpace<U>>>& V,
88 const std::map<IntegralType,
89 std::vector<std::tuple<
90 int,
91 std::function<void(T*, const T*, const T*,
92 const scalar_value_type_t<T>*,
93 const int*, const std::uint8_t*)>,
94 std::vector<std::int32_t>>>>& integrals,
95 const std::vector<std::shared_ptr<const Function<T, U>>>& coefficients,
96 const std::vector<std::shared_ptr<const Constant<T>>>& constants,
98 std::shared_ptr<const mesh::Mesh<U>> mesh = nullptr)
99 : _function_spaces(V), _coefficients(coefficients), _constants(constants),
100 _mesh(mesh), _needs_facet_permutations(needs_facet_permutations)
101 {
102 // Extract _mesh from FunctionSpace, and check they are the same
103 if (!_mesh and !V.empty())
104 _mesh = V[0]->mesh();
105 for (auto& space : V)
106 {
107 if (_mesh != space->mesh())
108 throw std::runtime_error("Incompatible mesh");
109 }
110 if (!_mesh)
111 throw std::runtime_error("No mesh could be associated with the Form.");
112
113 // Store kernels, looping over integrals by domain type (dimension)
114 for (auto& [type, kernels] : integrals)
115 {
116 auto& integrals = _integrals[static_cast<std::size_t>(type)];
117 for (auto& [id, kern, e] : kernels)
118 integrals.insert({id, {kern, std::vector(e.begin(), e.end())}});
119 }
120 }
121
123 Form(const Form& form) = delete;
124
126 Form(Form&& form) = default;
127
129 virtual ~Form() = default;
130
134 int rank() const { return _function_spaces.size(); }
135
138 std::shared_ptr<const mesh::Mesh<U>> mesh() const { return _mesh; }
139
142 const std::vector<std::shared_ptr<const FunctionSpace<U>>>&
144 {
145 return _function_spaces;
146 }
147
153 std::function<void(T*, const T*, const T*, const scalar_value_type_t<T>*,
154 const int*, const std::uint8_t*)>
155 kernel(IntegralType type, int i) const
156 {
157 auto integrals = _integrals[static_cast<std::size_t>(type)];
158 if (auto it = integrals.find(i); it != integrals.end())
159 return it->second.first;
160 else
161 throw std::runtime_error("No kernel for requested domain index.");
162 }
163
166 std::set<IntegralType> integral_types() const
167 {
168 std::set<IntegralType> set;
169 for (std::size_t i = 0; i < _integrals.size(); ++i)
170 {
171 if (!_integrals[i].empty())
172 set.insert(static_cast<IntegralType>(i));
173 }
174
175 return set;
176 }
177
182 {
183 return _integrals[static_cast<std::size_t>(type)].size();
184 }
185
192 std::vector<int> integral_ids(IntegralType type) const
193 {
194 std::vector<int> ids;
195 auto& integrals = _integrals[static_cast<std::size_t>(type)];
196 std::transform(integrals.begin(), integrals.end(), std::back_inserter(ids),
197 [](auto& integral) { return integral.first; });
198 return ids;
199 }
200
218 std::span<const std::int32_t> domain(IntegralType type, int i) const
219 {
220 auto& integral = _integrals[static_cast<std::size_t>(type)];
221 if (auto it = integral.find(i); it != integral.end())
222 return it->second.second;
223 else
224 throw std::runtime_error("No mesh entities for requested domain index.");
225 }
226
228 const std::vector<std::shared_ptr<const Function<T, U>>>& coefficients() const
229 {
230 return _coefficients;
231 }
232
236 bool needs_facet_permutations() const { return _needs_facet_permutations; }
237
241 std::vector<int> coefficient_offsets() const
242 {
243 std::vector<int> n = {0};
244 for (auto& c : _coefficients)
245 {
246 if (!c)
247 throw std::runtime_error("Not all form coefficients have been set.");
248 n.push_back(n.back() + c->function_space()->element()->space_dimension());
249 }
250 return n;
251 }
252
254 const std::vector<std::shared_ptr<const Constant<T>>>& constants() const
255 {
256 return _constants;
257 }
258
259private:
260 using kern = std::function<void(T*, const T*, const T*,
261 const scalar_value_type_t<T>*, const int*,
262 const std::uint8_t*)>;
263
264 // Function spaces (one for each argument)
265 std::vector<std::shared_ptr<const FunctionSpace<U>>> _function_spaces;
266
267 // Form coefficients
268 std::vector<std::shared_ptr<const Function<T, U>>> _coefficients;
269
270 // Constants associated with the Form
271 std::vector<std::shared_ptr<const Constant<T>>> _constants;
272
273 // The mesh
274 std::shared_ptr<const mesh::Mesh<U>> _mesh;
275
276 // Integrals. Array index is
277 // static_cast<std::size_t(IntegralType::foo)
278 std::array<std::map<int, std::pair<kern, std::vector<std::int32_t>>>, 4>
279 _integrals;
280
281 // True if permutation data needs to be passed into these integrals
282 bool _needs_facet_permutations;
283};
284} // namespace dolfinx::fem
Constant value which can be attached to a Form.
Definition Constant.h:23
A representation of finite element variational forms.
Definition Form.h:66
const std::vector< std::shared_ptr< const FunctionSpace< U > > > & function_spaces() const
Return function spaces for all arguments.
Definition Form.h:143
bool needs_facet_permutations() const
Get bool indicating whether permutation data needs to be passed into these integrals.
Definition Form.h:236
Form(Form &&form)=default
Move constructor.
int rank() const
Rank of the form (bilinear form = 2, linear form = 1, functional = 0, etc)
Definition Form.h:134
std::shared_ptr< const mesh::Mesh< U > > mesh() const
Extract common mesh for the form.
Definition Form.h:138
Form(const Form &form)=delete
Copy constructor.
virtual ~Form()=default
Destructor.
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:241
Form(const std::vector< std::shared_ptr< const FunctionSpace< U > > > &V, const std::map< IntegralType, std::vector< std::tuple< int, std::function< void(T *, const T *, const T *, const scalar_value_type_t< T > *, const int *, const std::uint8_t *)>, std::vector< std::int32_t > > > > &integrals, const std::vector< std::shared_ptr< const Function< T, U > > > &coefficients, const std::vector< std::shared_ptr< const Constant< T > > > &constants, bool needs_facet_permutations, std::shared_ptr< const mesh::Mesh< U > > mesh=nullptr)
Create a finite element form.
Definition Form.h:87
std::span< const std::int32_t > domain(IntegralType type, int i) const
Get the list of cell indices for the ith integral (kernel) for the cell domain type.
Definition Form.h:218
const std::vector< std::shared_ptr< const Constant< T > > > & constants() const
Access constants.
Definition Form.h:254
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:192
std::set< IntegralType > integral_types() const
Get types of integrals in the form.
Definition Form.h:166
std::function< void(T *, const T *, const T *, const scalar_value_type_t< T > *, const int *, const std::uint8_t *)> kernel(IntegralType type, int i) const
Get the kernel function for integral i on given domain type.
Definition Form.h:155
int num_integrals(IntegralType type) const
Number of integrals on given domain type.
Definition Form.h:181
T scalar_type
Scalar type.
Definition Form.h:69
const std::vector< std::shared_ptr< const Function< T, U > > > & coefficients() const
Access coefficients.
Definition Form.h:228
This class represents a finite element function space defined by a mesh, a finite element,...
Definition FunctionSpace.h:35
This class represents a function in a finite element function space , given by.
Definition Function.h:45
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition Mesh.h:23
This concept is used to constrain the a template type to floating point real or complex types....
Definition types.h:20
Finite element method functionality.
Definition assemble_matrix_impl.h:25
IntegralType
Type of integral.
Definition Form.h:33
@ interior_facet
Interior facet.
@ exterior_facet
Exterior facet.