DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
expression_factory.h
Go to the documentation of this file.
1// Copyright (C) 2013-2026 Johan Hake, Jan Blechta, Garth N. Wells and Paul T.
2// Kühner
3//
4// This file is part of DOLFINx (https://www.fenicsproject.org)
5//
6// SPDX-License-Identifier: LGPL-3.0-or-later
7
8#pragma once
9
10#include "Constant.h"
11#include "Expression.h"
12#include "Function.h"
13#include "FunctionSpace.h"
14#include <array>
15#include <cassert>
16#include <complex>
17#include <concepts>
18#include <cstddef>
19#include <cstdint>
20#include <dolfinx/common/types.h>
21#include <dolfinx/mesh/EntityMap.h>
22#include <format>
23#include <functional>
24#include <map>
25#include <memory>
26#include <span>
27#include <stdexcept>
28#include <string>
29#include <type_traits>
30#include <ufcx.h>
31#include <utility>
32#include <vector>
33
36
37namespace dolfinx::fem
38{
40template <dolfinx::scalar T, std::floating_point U = scalar_value_t<T>>
42 const ufcx_expression& e,
43 const std::vector<std::shared_ptr<const Function<T, U>>>& coefficients,
44 const std::vector<std::shared_ptr<const Constant<T>>>& constants,
45 const std::vector<std::reference_wrapper<const mesh::EntityMap>>&
46 entity_maps,
47 std::shared_ptr<const FunctionSpace<U>> argument_space = nullptr)
48{
49 if (e.rank > 0 and !argument_space)
50 {
51 throw std::invalid_argument("Expression has Argument but no Argument "
52 "function space was provided.");
53 }
54
55 std::vector<U> X(e.points, e.points + e.num_points * e.entity_dimension);
56 std::array<std::size_t, 2> Xshape
57 = {static_cast<std::size_t>(e.num_points),
58 static_cast<std::size_t>(e.entity_dimension)};
59 std::vector<std::size_t> value_shape(e.value_shape,
60 e.value_shape + e.num_components);
61
62 static_assert(std::is_same_v<U, scalar_value_t<T>>,
63 "UFCx kernels require geometry type U == scalar_value_t<T>.");
64
65 using kptr_t = void (*)(T*, const T*, const T*, const U*, const int*,
66 const std::uint8_t*, void*);
67 std::function<void(T*, const T*, const T*, const U*, const int*,
68 const std::uint8_t*, void*)>
69 tabulate_tensor = nullptr;
70 if constexpr (std::is_same_v<T, float>)
71 tabulate_tensor = reinterpret_cast<kptr_t>(e.tabulate_tensor_float32);
72 else if constexpr (std::is_same_v<T, double>)
73 tabulate_tensor = reinterpret_cast<kptr_t>(e.tabulate_tensor_float64);
74#ifndef DOLFINX_NO_STDC_COMPLEX_KERNELS
75 else if constexpr (std::is_same_v<T, std::complex<float>>)
76 tabulate_tensor = reinterpret_cast<kptr_t>(e.tabulate_tensor_complex64);
77 else if constexpr (std::is_same_v<T, std::complex<double>>)
78 tabulate_tensor = reinterpret_cast<kptr_t>(e.tabulate_tensor_complex128);
79#endif // DOLFINX_NO_STDC_COMPLEX_KERNELS
80 else
81 throw std::invalid_argument("Type not supported.");
82
83 assert(tabulate_tensor);
84 std::uint64_t e_hash = e.coordinate_element_hash;
85 return Expression(coefficients, constants, std::span<const U>(X), Xshape,
86 tabulate_tensor, value_shape, entity_maps, e_hash,
87 argument_space);
88}
89
92template <dolfinx::scalar T, std::floating_point U = scalar_value_t<T>>
94 const ufcx_expression& e,
95 const std::map<std::string, std::shared_ptr<const Function<T, U>>>&
96 coefficients,
97 const std::map<std::string, std::shared_ptr<const Constant<T>>>& constants,
98 const std::vector<std::reference_wrapper<const mesh::EntityMap>>&
99 entity_maps,
100 std::shared_ptr<const FunctionSpace<U>> argument_space = nullptr)
101{
102 // Place coefficients in appropriate order
103 std::vector<std::shared_ptr<const Function<T, U>>> coeff_map;
104 std::vector<std::string> coefficient_names;
105 coefficient_names.reserve(e.num_coefficients);
106 for (int i = 0; i < e.num_coefficients; ++i)
107 coefficient_names.push_back(e.coefficient_names[i]);
108
109 for (const std::string& name : coefficient_names)
110 {
111 if (auto it = coefficients.find(name); it != coefficients.end())
112 coeff_map.push_back(it->second);
113 else
114 {
115 throw std::runtime_error(
116 std::format("Expression coefficient \"{}\" not provided.", name));
117 }
118 }
119
120 // Place constants in appropriate order
121 std::vector<std::shared_ptr<const Constant<T>>> const_map;
122 std::vector<std::string> constant_names;
123 constant_names.reserve(e.num_constants);
124 for (int i = 0; i < e.num_constants; ++i)
125 constant_names.push_back(e.constant_names[i]);
126
127 for (const std::string& name : constant_names)
128 {
129 if (auto it = constants.find(name); it != constants.end())
130 const_map.push_back(it->second);
131 else
132 {
133 throw std::runtime_error(
134 std::format("Expression constant \"{}\" not provided.", name));
135 }
136 }
137
138 return create_expression(e, coeff_map, const_map, entity_maps,
139 argument_space);
140}
141} // namespace dolfinx::fem
Constant (in space) value which can be attached to a Form.
Definition Constant.h:22
An Expression represents a mathematical expression evaluated at a pre-defined points on a reference c...
Definition Expression.h:43
This class represents a finite element function space defined by a mesh, a finite element,...
Definition FunctionSpace.h:35
Definition Function.h:44
Finite element method functionality.
Definition assemble_expression_impl.h:22
Expression< T, U > create_expression(const ufcx_expression &e, const std::vector< std::shared_ptr< const Function< T, U > > > &coefficients, const std::vector< std::shared_ptr< const Constant< T > > > &constants, const std::vector< std::reference_wrapper< const mesh::EntityMap > > &entity_maps, std::shared_ptr< const FunctionSpace< U > > argument_space=nullptr)
Create Expression from UFC.
Definition expression_factory.h:41