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.7.3
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 "Constant.h"
10#include "Function.h"
11#include <algorithm>
12#include <array>
13#include <concepts>
14#include <dolfinx/common/types.h>
15#include <dolfinx/mesh/Mesh.h>
16#include <functional>
17#include <span>
18#include <utility>
19#include <vector>
20
21namespace dolfinx::fem
22{
23template <dolfinx::scalar T>
24class Constant;
25
38template <dolfinx::scalar T,
39 std::floating_point U = dolfinx::scalar_value_type_t<T>>
41{
42public:
47 using scalar_type = T;
48
50 using geometry_type = U;
51
65 const std::vector<std::shared_ptr<
67 const std::vector<std::shared_ptr<const Constant<scalar_type>>>&
69 std::span<const geometry_type> X, std::array<std::size_t, 2> Xshape,
70 std::function<void(scalar_type*, const scalar_type*, const scalar_type*,
71 const geometry_type*, const int*, const uint8_t*)>
72 fn,
73 const std::vector<int>& value_shape,
74 std::shared_ptr<const FunctionSpace<geometry_type>>
76 = nullptr)
77 : _coefficients(coefficients), _constants(constants),
78 _x_ref(std::vector<geometry_type>(X.begin(), X.end()), Xshape), _fn(fn),
79 _value_shape(value_shape),
80 _argument_function_space(argument_function_space)
81 {
82 for (auto& c : _coefficients)
83 {
84 assert(c);
85 if (c->function_space()->mesh()
86 != _coefficients.front()->function_space()->mesh())
87 {
88 throw std::runtime_error("Coefficients not all defined on same mesh.");
89 }
90 }
91 }
92
94 Expression(Expression&& e) = default;
95
97 virtual ~Expression() = default;
98
102 std::shared_ptr<const FunctionSpace<geometry_type>>
104 {
105 return _argument_function_space;
106 };
107
110 const std::vector<
111 std::shared_ptr<const Function<scalar_type, geometry_type>>>&
113 {
114 return _coefficients;
115 }
116
121 const std::vector<std::shared_ptr<const Constant<scalar_type>>>&
122 constants() const
123 {
124 return _constants;
125 }
126
132 std::vector<int> coefficient_offsets() const
133 {
134 std::vector<int> n{0};
135 for (auto& c : _coefficients)
136 {
137 if (!c)
138 throw std::runtime_error("Not all form coefficients have been set.");
139 n.push_back(n.back() + c->function_space()->element()->space_dimension());
140 }
141 return n;
142 }
143
152 std::span<const std::int32_t> cells, std::span<scalar_type> values,
153 std::array<std::size_t, 2> vshape) const
154 {
155 // Prepare coefficients and constants
156 const auto [coeffs, cstride] = pack_coefficients(*this, cells);
157 const std::vector<scalar_type> constant_data = pack_constants(*this);
158 auto fn = this->get_tabulate_expression();
159
160 // Prepare cell geometry
161 auto x_dofmap = mesh.geometry().dofmap();
162
163 // Get geometry data
164 auto cmaps = mesh.geometry().cmaps();
165 assert(cmaps.size() == 1);
166
167 const std::size_t num_dofs_g = cmaps.back().dim();
168 auto x_g = mesh.geometry().x();
169
170 // Create data structures used in evaluation
171 std::vector<geometry_type> coord_dofs(3 * num_dofs_g);
172
173 int num_argument_dofs = 1;
174 std::span<const std::uint32_t> cell_info;
175 std::function<void(const std::span<scalar_type>&,
176 const std::span<const std::uint32_t>&, std::int32_t,
177 int)>
178 dof_transform_to_transpose
179 = [](const std::span<scalar_type>&,
180 const std::span<const std::uint32_t>&, std::int32_t, int)
181 {
182 // Do nothing
183 };
184
185 if (_argument_function_space)
186 {
187 num_argument_dofs
188 = _argument_function_space->dofmap()->element_dof_layout().num_dofs();
189 auto element = _argument_function_space->element();
190
191 assert(element);
192 if (element->needs_dof_transformations())
193 {
194 mesh.topology_mutable()->create_entity_permutations();
195 cell_info = std::span(mesh.topology()->get_cell_permutation_info());
196 dof_transform_to_transpose
197 = element->template get_dof_transformation_to_transpose_function<
198 scalar_type>();
199 }
200 }
201
202 // Iterate over cells and 'assemble' into values
203 const int size0 = _x_ref.second[0] * value_size();
204 std::vector<scalar_type> values_local(size0 * num_argument_dofs, 0);
205 for (std::size_t c = 0; c < cells.size(); ++c)
206 {
207 const std::int32_t cell = cells[c];
208 auto x_dofs = MDSPAN_IMPL_STANDARD_NAMESPACE::
209 MDSPAN_IMPL_PROPOSED_NAMESPACE::submdspan(
210 x_dofmap, cell, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
211 for (std::size_t i = 0; i < x_dofs.size(); ++i)
212 {
213 std::copy_n(std::next(x_g.begin(), 3 * x_dofs[i]), 3,
214 std::next(coord_dofs.begin(), 3 * i));
215 }
216
217 const scalar_type* coeff_cell = coeffs.data() + c * cstride;
218 std::fill(values_local.begin(), values_local.end(), 0);
219 _fn(values_local.data(), coeff_cell, constant_data.data(),
220 coord_dofs.data(), nullptr, nullptr);
221
222 dof_transform_to_transpose(values_local, cell_info, c, size0);
223 for (std::size_t j = 0; j < values_local.size(); ++j)
224 values[c * vshape[1] + j] = values_local[j];
225 }
226 }
227
230 const std::function<void(scalar_type*, const scalar_type*, const scalar_type*,
231 const geometry_type*, const int*, const uint8_t*)>&
233 {
234 return _fn;
235 }
236
239 int value_size() const
240 {
241 return std::reduce(_value_shape.begin(), _value_shape.end(), 1,
242 std::multiplies{});
243 }
244
247 const std::vector<int>& value_shape() const { return _value_shape; }
248
251 std::pair<std::vector<geometry_type>, std::array<std::size_t, 2>> X() const
252 {
253 return _x_ref;
254 }
255
256private:
257 // Function space for Argument
258 std::shared_ptr<const FunctionSpace<geometry_type>> _argument_function_space;
259
260 // Coefficients associated with the Expression
261 std::vector<std::shared_ptr<const Function<scalar_type, geometry_type>>>
262 _coefficients;
263
264 // Constants associated with the Expression
265 std::vector<std::shared_ptr<const Constant<scalar_type>>> _constants;
266
267 // Function to evaluate the Expression
268 std::function<void(scalar_type*, const scalar_type*, const scalar_type*,
269 const geometry_type*, const int*, const uint8_t*)>
270 _fn;
271
272 // Shape of the evaluated expression
273 std::vector<int> _value_shape;
274
275 // Evaluation points on reference cell. Synonymous with X in public
276 // interface.
277 std::pair<std::vector<geometry_type>, std::array<std::size_t, 2>> _x_ref;
278};
279} // namespace dolfinx::fem
Constant value which can be attached to a Form.
Definition Constant.h:23
Represents a mathematical expression evaluated at a pre-defined set of points on the reference cell.
Definition Expression.h:41
U geometry_type
Geometry type of the points.
Definition Expression.h:50
void eval(const mesh::Mesh< geometry_type > &mesh, std::span< const std::int32_t > cells, std::span< scalar_type > values, std::array< std::size_t, 2 > vshape) const
Evaluate Expression on cells.
Definition Expression.h:151
std::pair< std::vector< geometry_type >, std::array< std::size_t, 2 > > X() const
Evaluation points on the reference cell.
Definition Expression.h:251
const std::vector< std::shared_ptr< const Function< scalar_type, geometry_type > > > & coefficients() const
Get coefficients.
Definition Expression.h:112
Expression(const std::vector< std::shared_ptr< const Function< scalar_type, geometry_type > > > &coefficients, const std::vector< std::shared_ptr< const Constant< scalar_type > > > &constants, std::span< const geometry_type > X, std::array< std::size_t, 2 > Xshape, std::function< void(scalar_type *, const scalar_type *, const scalar_type *, const geometry_type *, const int *, const uint8_t *)> fn, const std::vector< int > &value_shape, std::shared_ptr< const FunctionSpace< geometry_type > > argument_function_space=nullptr)
Create an Expression.
Definition Expression.h:64
const std::vector< std::shared_ptr< const Constant< scalar_type > > > & constants() const
Get constants.
Definition Expression.h:122
std::vector< int > coefficient_offsets() const
Offset for each coefficient expansion array on a cell.
Definition Expression.h:132
int value_size() const
Get value size.
Definition Expression.h:239
Expression(Expression &&e)=default
Move constructor.
const std::vector< int > & value_shape() const
Get value shape.
Definition Expression.h:247
virtual ~Expression()=default
Destructor.
T scalar_type
Scalar type.
Definition Expression.h:47
const std::function< void(scalar_type *, const scalar_type *, const scalar_type *, const geometry_type *, const int *, const uint8_t *)> & get_tabulate_expression() const
Get function for tabulate_expression.
Definition Expression.h:232
std::shared_ptr< const FunctionSpace< geometry_type > > argument_function_space() const
Get argument function space.
Definition Expression.h:103
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
std::shared_ptr< Topology > topology_mutable() const
Get mesh topology if one really needs the mutable version.
Definition Mesh.h:72
std::shared_ptr< Topology > topology()
Get mesh topology.
Definition Mesh.h:64
Geometry< T > & geometry()
Get mesh geometry.
Definition Mesh.h:76
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
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:1196
void pack_coefficients(const Form< T, U > &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:974