Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/dolfinx/v0.9.0/cpp/doxygen/d6/d6e/Expression_8h_source.html
DOLFINx 0.6.0
DOLFINx C++ interface
Loading...
Searching...
No Matches
Expression.h
1// Copyright (C) 2020 - 2021 Jack S. Hale and Michal Habera
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 "Function.h"
10#include <algorithm>
11#include <array>
12#include <dolfinx/mesh/Mesh.h>
13#include <functional>
14#include <span>
15#include <utility>
16#include <vector>
17
18namespace dolfinx::fem
19{
20template <typename T>
21class Constant;
22
31
32template <typename T>
34{
35 template <typename X, typename = void>
36 struct scalar_value_type
37 {
38 typedef X value_type;
39 };
40 template <typename X>
41 struct scalar_value_type<X, std::void_t<typename X::value_type>>
42 {
43 typedef typename X::value_type value_type;
44 };
45 using scalar_value_type_t = typename scalar_value_type<T>::value_type;
46
47public:
62 const std::vector<std::shared_ptr<const Function<T>>>& coefficients,
63 const std::vector<std::shared_ptr<const Constant<T>>>& constants,
64 std::span<const double> X, std::array<std::size_t, 2> Xshape,
65 const std::function<void(T*, const T*, const T*,
66 const scalar_value_type_t*, const int*,
67 const uint8_t*)>
68 fn,
69 const std::vector<int>& value_shape,
70 std::shared_ptr<const mesh::Mesh> mesh = nullptr,
71 std::shared_ptr<const FunctionSpace> argument_function_space = nullptr)
72 : _coefficients(coefficients), _constants(constants), _mesh(mesh),
73 _x_ref(std::vector<double>(X.begin(), X.end()), Xshape), _fn(fn),
74 _value_shape(value_shape),
75 _argument_function_space(argument_function_space)
76 {
77 // Extract mesh from argument's function space
78 if (!_mesh and argument_function_space)
79 _mesh = argument_function_space->mesh();
80 if (argument_function_space and _mesh != argument_function_space->mesh())
81 throw std::runtime_error("Incompatible mesh");
82 if (!_mesh)
83 {
84 throw std::runtime_error(
85 "No mesh could be associated with the Expression.");
86 }
87 }
88
90 Expression(Expression&& form) = default;
91
93 virtual ~Expression() = default;
94
97 std::shared_ptr<const FunctionSpace> argument_function_space() const
98 {
99 return _argument_function_space;
100 };
101
104 const std::vector<std::shared_ptr<const Function<T>>>& coefficients() const
105 {
106 return _coefficients;
107 }
108
113 const std::vector<std::shared_ptr<const Constant<T>>>& constants() const
114 {
115 return _constants;
116 }
117
121 std::vector<int> coefficient_offsets() const
122 {
123 std::vector<int> n{0};
124 for (auto& c : _coefficients)
125 {
126 if (!c)
127 throw std::runtime_error("Not all form coefficients have been set.");
128 n.push_back(n.back() + c->function_space()->element()->space_dimension());
129 }
130 return n;
131 }
132
139 void eval(std::span<const std::int32_t> cells, std::span<T> values,
140 std::array<std::size_t, 2> vshape) const
141 {
142 // Extract data from Expression
143 assert(_mesh);
144
145 // Prepare coefficients and constants
146 const auto [coeffs, cstride] = pack_coefficients(*this, cells);
147 const std::vector<T> constant_data = pack_constants(*this);
148 const auto& fn = this->get_tabulate_expression();
149
150 // Prepare cell geometry
152 = _mesh->geometry().dofmap();
153 const std::size_t num_dofs_g = _mesh->geometry().cmap().dim();
154 std::span<const double> x_g = _mesh->geometry().x();
155
156 // Create data structures used in evaluation
157 std::vector<scalar_value_type_t> coordinate_dofs(3 * num_dofs_g);
158
159 int num_argument_dofs = 1;
160 std::span<const std::uint32_t> cell_info;
161 std::function<void(const std::span<T>&,
162 const std::span<const std::uint32_t>&, std::int32_t,
163 int)>
164 dof_transform_to_transpose
165 = [](const std::span<T>&, const std::span<const std::uint32_t>&,
166 std::int32_t, int)
167 {
168 // Do nothing
169 };
170
171 if (_argument_function_space)
172 {
173 num_argument_dofs
174 = _argument_function_space->dofmap()->element_dof_layout().num_dofs();
175 auto element = _argument_function_space->element();
176
177 assert(element);
178 if (element->needs_dof_transformations())
179 {
180 _mesh->topology_mutable().create_entity_permutations();
181 cell_info = std::span(_mesh->topology().get_cell_permutation_info());
182 dof_transform_to_transpose
183 = element
184 ->template get_dof_transformation_to_transpose_function<T>();
185 }
186 }
187
188 const int size0 = _x_ref.second[0] * value_size();
189 std::vector<T> values_local(size0 * num_argument_dofs, 0);
190 const std::span<T> _values_local(values_local);
191
192 // Iterate over cells and 'assemble' into values
193 for (std::size_t c = 0; c < cells.size(); ++c)
194 {
195 const std::int32_t cell = cells[c];
196
197 auto x_dofs = x_dofmap.links(cell);
198 for (std::size_t i = 0; i < x_dofs.size(); ++i)
199 {
200 std::copy_n(std::next(x_g.begin(), 3 * x_dofs[i]), 3,
201 std::next(coordinate_dofs.begin(), 3 * i));
202 }
203
204 const T* coeff_cell = coeffs.data() + c * cstride;
205 std::fill(values_local.begin(), values_local.end(), 0);
206 _fn(values_local.data(), coeff_cell, constant_data.data(),
207 coordinate_dofs.data(), nullptr, nullptr);
208
209 dof_transform_to_transpose(_values_local, cell_info, c, size0);
210 for (std::size_t j = 0; j < values_local.size(); ++j)
211 values[c * vshape[1] + j] = values_local[j];
212 }
213 }
214
217 const std::function<void(T*, const T*, const T*, const scalar_value_type_t*,
218 const int*, const uint8_t*)>&
220 {
221 return _fn;
222 }
223
226 std::shared_ptr<const mesh::Mesh> mesh() const { return _mesh; }
227
230 int value_size() const
231 {
232 return std::reduce(_value_shape.begin(), _value_shape.end(), 1,
233 std::multiplies{});
234 }
235
238 const std::vector<int>& value_shape() const { return _value_shape; }
239
242 std::pair<std::vector<double>, std::array<std::size_t, 2>> X() const
243 {
244 return _x_ref;
245 }
246
248 using scalar_type = T;
249
250private:
251 // Function space for Argument
252 std::shared_ptr<const FunctionSpace> _argument_function_space;
253
254 // Coefficients associated with the Expression
255 std::vector<std::shared_ptr<const Function<T>>> _coefficients;
256
257 // Constants associated with the Expression
258 std::vector<std::shared_ptr<const Constant<T>>> _constants;
259
260 // Function to evaluate the Expression
261 std::function<void(T*, const T*, const T*, const scalar_value_type_t*,
262 const int*, const uint8_t*)>
263 _fn;
264
265 // The mesh
266 std::shared_ptr<const mesh::Mesh> _mesh;
267
268 // Shape of the evaluated expression
269 std::vector<int> _value_shape;
270
271 // Evaluation points on reference cell. Synonymous with X in public interface.
272 std::pair<std::vector<double>, std::array<std::size_t, 2>> _x_ref;
273};
274} // namespace dolfinx::fem
Constant value which can be attached to a Form. Constants may be scalar (rank 0), vector (rank 1),...
Definition: Constant.h:20
Represents a mathematical expression evaluated at a pre-defined set of points on the reference cell....
Definition: Expression.h:34
void eval(std::span< const std::int32_t > cells, std::span< T > values, std::array< std::size_t, 2 > vshape) const
Evaluate the expression on cells.
Definition: Expression.h:139
std::vector< int > coefficient_offsets() const
Offset for each coefficient expansion array on a cell. Used to pack data for multiple coefficients in...
Definition: Expression.h:121
Expression(const std::vector< std::shared_ptr< const Function< T > > > &coefficients, const std::vector< std::shared_ptr< const Constant< T > > > &constants, std::span< const double > X, std::array< std::size_t, 2 > Xshape, const std::function< void(T *, const T *, const T *, const scalar_value_type_t *, const int *, const uint8_t *)> fn, const std::vector< int > &value_shape, std::shared_ptr< const mesh::Mesh > mesh=nullptr, std::shared_ptr< const FunctionSpace > argument_function_space=nullptr)
Create an Expression.
Definition: Expression.h:61
int value_size() const
Get value size.
Definition: Expression.h:230
const std::vector< std::shared_ptr< const Function< T > > > & coefficients() const
Get coefficients.
Definition: Expression.h:104
const std::vector< std::shared_ptr< const Constant< T > > > & constants() const
Get constants.
Definition: Expression.h:113
Expression(Expression &&form)=default
Move constructor.
std::pair< std::vector< double >, std::array< std::size_t, 2 > > X() const
Evaluation points on the reference cell.
Definition: Expression.h:242
const std::vector< int > & value_shape() const
Get value shape.
Definition: Expression.h:238
virtual ~Expression()=default
Destructor.
std::shared_ptr< const FunctionSpace > argument_function_space() const
Get argument function space.
Definition: Expression.h:97
std::shared_ptr< const mesh::Mesh > mesh() const
Get mesh.
Definition: Expression.h:226
T scalar_type
Scalar type (T)
Definition: Expression.h:248
const std::function< void(T *, const T *, const T *, const scalar_value_type_t *, const int *, const uint8_t *)> & get_tabulate_expression() const
Get function for tabulate_expression.
Definition: Expression.h:219
This class represents a function in a finite element function space , given by.
Definition: Function.h:43
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition: AdjacencyList.h:27
std::span< T > links(int node)
Get the links (edges) for given node.
Definition: AdjacencyList.h:109
Finite element method functionality.
Definition: assemble_matrix_impl.h:25
void pack_coefficients(const Form< T > &form, IntegralType integral_type, int id, std::span< T > c, int cstride)
Pack coefficients of a Form for a given integral type and domain id.
Definition: utils.h:755
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:985