File: Expression.h

package info (click to toggle)
fenics-dolfinx 1%3A0.10.0.post4-1exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 6,028 kB
  • sloc: cpp: 36,535; python: 25,391; makefile: 226; sh: 171; xml: 55
file content (193 lines) | stat: -rw-r--r-- 6,353 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright (C) 2020-2025 Jack S. Hale, Michal Habera and Garth N. Wells
//
// This file is part of DOLFINx (https://www.fenicsproject.org)
//
// SPDX-License-Identifier:    LGPL-3.0-or-later

#pragma once

#include "Constant.h"
#include "Function.h"
#include <algorithm>
#include <array>
#include <concepts>
#include <dolfinx/common/types.h>
#include <dolfinx/mesh/Mesh.h>
#include <functional>
#include <memory>
#include <span>
#include <utility>
#include <vector>

namespace dolfinx::fem
{
template <dolfinx::scalar T, std::floating_point U>
class Function;

/// @brief An Expression represents a mathematical expression evaluated
/// at a pre-defined points on a reference cell.
///
/// An Expression can be evaluated using ::tabulate_expression.
///
/// An example of Expression use is to evaluate the gradient of a
/// Function at quadrature points in cells. The evaluated gradient can
/// then be used as input in to a non-FEniCS function that evaluates a
/// material constitutive model.
///
/// @tparam T The scalar type.
/// @tparam U The mesh geometry scalar type.
template <dolfinx::scalar T, std::floating_point U = dolfinx::scalar_value_t<T>>
class Expression
{
public:
  /// @brief Scalar type.
  ///
  /// Field type for the Expression, e.g. `double`,
  /// `std::complex<float>`, etc.
  using scalar_type = T;

  /// Geometry type of the points.
  using geometry_type = U;

  /// @brief Create an Expression.
  ///
  /// @note Users should prefer the fem::create_expression factory
  /// functions for creating an Expression.
  ///
  /// @param[in] coefficients Coefficients in the Expression.
  /// @param[in] constants Constants in the Expression.
  /// @param[in] X Points on the reference cell, `shape=(number of
  /// points, tdim)` and storage is row-major.
  /// @param[in] Xshape Shape of `X`.
  /// @param[in] fn Function for tabulating the Expression.
  /// @param[in] value_shape Shape of Expression evaluated at single
  /// point.
  /// @param[in] argument_space Function space for Argument. Used to
  /// computed a 1-form expression, e.g. can be used to create a matrix
  /// that when applied to a degree-of-freedom vector gives the
  /// expression values at the evaluation points.
  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*, void*)>
                 fn,
             const std::vector<std::size_t>& value_shape,
             std::shared_ptr<const FunctionSpace<geometry_type>> argument_space
             = nullptr)
      : _argument_space(argument_space), _coefficients(coefficients),
        _constants(constants), _fn(fn), _value_shape(value_shape),
        _x_ref(std::vector<geometry_type>(X.begin(), X.end()), Xshape)

  {
    for (auto& c : _coefficients)
    {
      assert(c);
      if (c->function_space()->mesh()
          != _coefficients.front()->function_space()->mesh())
      {
        throw std::runtime_error("Coefficients not all defined on same mesh.");
      }
    }
  }

  /// Move constructor
  Expression(Expression&& e) = default;

  /// Destructor
  virtual ~Expression() = default;

  /// @brief Argument function space.
  /// @return Argument function space, nullptr if there is no argument.
  std::shared_ptr<const FunctionSpace<geometry_type>> argument_space() const
  {
    return _argument_space;
  };

  /// @brief Expression coefficients.
  /// @return List of attached coefficients.
  const std::vector<
      std::shared_ptr<const Function<scalar_type, geometry_type>>>&
  coefficients() const
  {
    return _coefficients;
  }

  /// @brief Expression constants.
  ///
  /// @return List of attached constants.
  const std::vector<std::shared_ptr<const Constant<scalar_type>>>&
  constants() const
  {
    return _constants;
  }

  /// @brief Offset for each coefficient expansion array on a cell.
  ///
  /// Used to pack data for multiple coefficients into a flat array. The
  /// last entry is the size required to store all coefficients.
  /// @return The offsets.
  std::vector<int> coefficient_offsets() const
  {
    std::vector<int> n{0};
    for (auto& c : _coefficients)
    {
      if (!c)
        throw std::runtime_error("Not all form coefficients have been set.");
      n.push_back(n.back() + c->function_space()->element()->space_dimension());
    }
    return n;
  }

  /// @brief Function for tabulating the Expression.
  const std::function<void(scalar_type*, const scalar_type*, const scalar_type*,
                           const geometry_type*, const int*, const uint8_t*,
                           void*)>&
  kernel() const
  {
    return _fn;
  }

  /// @brief Value size of the Expression result.
  int value_size() const
  {
    return std::reduce(_value_shape.begin(), _value_shape.end(), 1,
                       std::multiplies{});
  }

  /// @brief Value shape of of Expression result (at a point),
  const std::vector<std::size_t>& value_shape() const { return _value_shape; }

  /// @brief Evaluation point coordinates on the reference cell.
  std::pair<std::vector<geometry_type>, std::array<std::size_t, 2>> X() const
  {
    return _x_ref;
  }

private:
  // Function space for Argument
  std::shared_ptr<const FunctionSpace<geometry_type>> _argument_space;

  // Coefficients associated with the Expression
  std::vector<std::shared_ptr<const Function<scalar_type, geometry_type>>>
      _coefficients;

  // Constants associated with the Expression
  std::vector<std::shared_ptr<const Constant<scalar_type>>> _constants;

  // Function to evaluate the Expression
  std::function<void(scalar_type*, const scalar_type*, const scalar_type*,
                     const geometry_type*, const int*, const uint8_t*, void*)>
      _fn;

  // Shape of the evaluated Expression
  std::vector<std::size_t> _value_shape;

  // Evaluation points on reference cell
  std::pair<std::vector<geometry_type>, std::array<std::size_t, 2>> _x_ref;
};
} // namespace dolfinx::fem