10 #include "CoordinateElement.h"
12 #include "ElementDofLayout.h"
13 #include "Expression.h"
16 #include "sparsitybuild.h"
18 #include <dolfinx/la/SparsityPattern.h>
19 #include <dolfinx/mesh/cell_types.h>
26 #include <type_traits>
58 template <
typename T,
typename =
void>
59 struct scalar_value_type
66 struct scalar_value_type<T, std::void_t<typename T::value_type>>
68 typedef typename T::value_type value_type;
72 using scalar_value_type_t =
typename scalar_value_type<T>::value_type;
84 std::vector<std::vector<std::array<std::shared_ptr<const FunctionSpace>, 2>>>
87 std::vector<std::vector<std::array<std::shared_ptr<const FunctionSpace>, 2>>>
89 std::vector<std::array<std::shared_ptr<const FunctionSpace>, 2>>(
91 for (std::size_t i = 0; i < a.size(); ++i)
93 for (std::size_t j = 0; j < a[i].size(); ++j)
95 if (
const Form<T>* form = a[i][j]; form)
96 spaces[i][j] = {form->function_spaces()[0], form->function_spaces()[1]};
107 const std::array<std::reference_wrapper<const DofMap>, 2>& dofmaps,
108 const std::set<IntegralType>& integrals);
115 template <
typename T>
120 throw std::runtime_error(
121 "Cannot create sparsity pattern. Form is not a bilinear form");
125 std::array<std::reference_wrapper<const DofMap>, 2> dofmaps{
128 std::shared_ptr mesh = a.
mesh();
136 const int tdim = mesh->topology().dim();
137 mesh->topology_mutable().create_entities(tdim - 1);
138 mesh->topology_mutable().create_connectivity(tdim - 1, tdim);
144 const std::array index_maps{dofmaps[0].get().index_map,
145 dofmaps[1].get().index_map};
147 = {dofmaps[0].get().index_map_bs(), dofmaps[1].get().index_map_bs()};
151 for (
auto type : types)
159 const std::vector<std::int32_t>& cells = a.
cell_domains(
id);
168 {{dofmaps[0], dofmaps[1]}});
176 {{dofmaps[0], dofmaps[1]}});
180 throw std::runtime_error(
"Unsupported integral type");
192 const std::vector<int>& parent_map
205 mesh::Topology& topology,
206 const std::function<std::vector<int>(
207 const graph::AdjacencyList<std::int32_t>&)>& reorder_fn,
208 const FiniteElement& element);
227 template <
typename T>
229 const ufcx_form& ufcx_form,
230 const std::vector<std::shared_ptr<const FunctionSpace>>& spaces,
231 const std::vector<std::shared_ptr<
const Function<T>>>& coefficients,
232 const std::vector<std::shared_ptr<
const Constant<T>>>& constants,
234 const std::shared_ptr<const mesh::Mesh>& mesh =
nullptr)
236 if (ufcx_form.rank != (
int)spaces.size())
237 throw std::runtime_error(
"Wrong number of argument spaces for Form.");
238 if (ufcx_form.num_coefficients != (
int)coefficients.size())
240 throw std::runtime_error(
241 "Mismatch between number of expected and provided Form coefficients.");
243 if (ufcx_form.num_constants != (
int)constants.size())
245 throw std::runtime_error(
246 "Mismatch between number of expected and provided Form constants.");
251 for (std::size_t i = 0; i < spaces.size(); ++i)
253 assert(spaces[i]->element());
254 ufcx_finite_element* ufcx_element = ufcx_form.finite_elements[i];
255 assert(ufcx_element);
256 if (std::string(ufcx_element->signature)
257 != spaces[i]->element()->signature())
259 throw std::runtime_error(
260 "Cannot create form. Wrong type of function space for argument.");
267 using kern = std::function<void(
268 T*,
const T*,
const T*,
269 const typename impl::scalar_value_type<T>::value_type*,
const int*,
270 const std::uint8_t*)>;
271 std::map<IntegralType, std::pair<std::vector<std::pair<int, kern>>,
275 bool needs_facet_permutations =
false;
278 std::vector<int> cell_integral_ids(ufcx_form.integral_ids(
cell),
279 ufcx_form.integral_ids(
cell)
280 + ufcx_form.num_integrals(
cell));
281 for (
int i = 0; i < ufcx_form.num_integrals(
cell); ++i)
283 ufcx_integral* integral = ufcx_form.integrals(
cell)[i];
287 if constexpr (std::is_same_v<T, float>)
288 k = integral->tabulate_tensor_float32;
289 else if constexpr (std::is_same_v<T, std::complex<float>>)
291 k =
reinterpret_cast<void (*)(
292 T*,
const T*,
const T*,
293 const typename impl::scalar_value_type<T>::value_type*,
const int*,
294 const unsigned char*)
>(integral->tabulate_tensor_complex64);
296 else if constexpr (std::is_same_v<T, double>)
297 k = integral->tabulate_tensor_float64;
298 else if constexpr (std::is_same_v<T, std::complex<double>>)
300 k =
reinterpret_cast<void (*)(
301 T*,
const T*,
const T*,
302 const typename impl::scalar_value_type<T>::value_type*,
const int*,
303 const unsigned char*)
>(integral->tabulate_tensor_complex128);
309 if (integral->needs_facet_permutations)
310 needs_facet_permutations =
true;
315 it != subdomains.end() and !cell_integral_ids.empty())
328 auto mesh = spaces[0]->mesh();
329 const int tdim = mesh->topology().dim();
330 spaces[0]->mesh()->topology_mutable().create_entities(tdim - 1);
335 std::vector<int> exterior_facet_integral_ids(
345 if constexpr (std::is_same_v<T, float>)
346 k = integral->tabulate_tensor_float32;
347 else if constexpr (std::is_same_v<T, std::complex<float>>)
349 k =
reinterpret_cast<void (*)(
350 T*,
const T*,
const T*,
351 const typename impl::scalar_value_type<T>::value_type*,
const int*,
352 const unsigned char*)
>(integral->tabulate_tensor_complex64);
354 else if constexpr (std::is_same_v<T, double>)
355 k = integral->tabulate_tensor_float64;
356 else if constexpr (std::is_same_v<T, std::complex<double>>)
358 k =
reinterpret_cast<void (*)(
359 T*,
const T*,
const T*,
360 const typename impl::scalar_value_type<T>::value_type*,
const int*,
361 const unsigned char*)
>(integral->tabulate_tensor_complex128);
366 exterior_facet_integral_ids[i], k);
367 if (integral->needs_facet_permutations)
368 needs_facet_permutations =
true;
373 it != subdomains.end() and !exterior_facet_integral_ids.empty())
379 std::vector<int> interior_facet_integral_ids(
389 if constexpr (std::is_same_v<T, float>)
390 k = integral->tabulate_tensor_float32;
391 else if constexpr (std::is_same_v<T, std::complex<float>>)
393 k =
reinterpret_cast<void (*)(
394 T*,
const T*,
const T*,
395 const typename impl::scalar_value_type<T>::value_type*,
const int*,
396 const unsigned char*)
>(integral->tabulate_tensor_complex64);
398 else if constexpr (std::is_same_v<T, double>)
399 k = integral->tabulate_tensor_float64;
400 else if constexpr (std::is_same_v<T, std::complex<double>>)
402 k =
reinterpret_cast<void (*)(
403 T*,
const T*,
const T*,
404 const typename impl::scalar_value_type<T>::value_type*,
const int*,
405 const unsigned char*)
>(integral->tabulate_tensor_complex128);
410 interior_facet_integral_ids[i], k);
411 if (integral->needs_facet_permutations)
412 needs_facet_permutations =
true;
417 it != subdomains.end() and !interior_facet_integral_ids.empty())
422 return Form<T>(spaces, integral_data, coefficients, constants,
423 needs_facet_permutations, mesh);
435 template <
typename T>
437 const ufcx_form& ufcx_form,
438 const std::vector<std::shared_ptr<const FunctionSpace>>& spaces,
439 const std::map<std::string, std::shared_ptr<
const Function<T>>>&
441 const std::map<std::string, std::shared_ptr<
const Constant<T>>>& constants,
443 const std::shared_ptr<const mesh::Mesh>& mesh =
nullptr)
446 std::vector<std::shared_ptr<const Function<T>>> coeff_map;
449 if (
auto it = coefficients.find(name); it != coefficients.end())
450 coeff_map.push_back(it->second);
453 throw std::runtime_error(
"Form coefficient \"" + name
454 +
"\" not provided.");
459 std::vector<std::shared_ptr<const Constant<T>>> const_map;
462 if (
auto it = constants.find(name); it != constants.end())
463 const_map.push_back(it->second);
465 throw std::runtime_error(
"Form constant \"" + name +
"\" not provided.");
468 return create_form(ufcx_form, spaces, coeff_map, const_map, subdomains, mesh);
482 template <
typename T>
484 ufcx_form* (*fptr)(),
485 const std::vector<std::shared_ptr<const FunctionSpace>>& spaces,
486 const std::map<std::string, std::shared_ptr<
const Function<T>>>&
488 const std::map<std::string, std::shared_ptr<
const Constant<T>>>& constants,
490 const std::shared_ptr<const mesh::Mesh>& mesh =
nullptr)
492 ufcx_form* form = fptr();
493 Form<T> L = create_form<T>(*form, spaces, coefficients, constants, subdomains,
509 const basix::FiniteElement& e,
int bs,
510 const std::function<std::vector<int>(
527 ufcx_function_space* (*fptr)(
const char*),
const std::string& function_name,
528 const std::shared_ptr<mesh::Mesh>& mesh,
537 template <
typename T>
538 std::span<const std::uint32_t> get_cell_orientation_info(
539 const std::vector<std::shared_ptr<
const Function<T>>>& coefficients)
541 bool needs_dof_transformations =
false;
542 for (
auto coeff : coefficients)
544 std::shared_ptr<const FiniteElement> element
545 = coeff->function_space()->element();
546 if (element->needs_dof_transformations())
548 needs_dof_transformations =
true;
553 std::span<const std::uint32_t> cell_info;
554 if (needs_dof_transformations)
556 auto mesh = coefficients.front()->function_space()->mesh();
557 mesh->topology_mutable().create_entity_permutations();
558 cell_info = std::span(mesh->topology().get_cell_permutation_info());
565 template <
typename T,
int _bs,
typename Functor>
566 static inline void pack(
const std::span<T>& coeffs, std::int32_t cell,
int bs,
567 const std::span<const T>& v,
568 const std::span<const std::uint32_t>& cell_info,
569 const DofMap& dofmap, Functor transform)
571 auto dofs = dofmap.cell_dofs(cell);
572 for (std::size_t i = 0; i < dofs.size(); ++i)
574 if constexpr (_bs < 0)
576 const int pos_c = bs * i;
577 const int pos_v = bs * dofs[i];
578 for (
int k = 0; k < bs; ++k)
579 coeffs[pos_c + k] = v[pos_v + k];
583 const int pos_c = _bs * i;
584 const int pos_v = _bs * dofs[i];
585 for (
int k = 0; k < _bs; ++k)
586 coeffs[pos_c + k] = v[pos_v + k];
590 transform(coeffs, cell_info, cell, 1);
607 template <
typename T,
typename Functor>
610 const std::span<const std::uint32_t>& cell_info,
611 const std::span<const std::int32_t>& entities,
612 std::size_t estride, Functor fetch_cells,
616 const std::span<const T>& v = u.
x()->array();
618 std::shared_ptr<const FiniteElement> element = u.
function_space()->element();
619 int space_dim = element->space_dimension();
620 const auto transformation
621 = element->get_dof_transformation_function<T>(
false,
true);
623 const int bs = dofmap.
bs();
627 for (std::size_t e = 0; e < entities.size(); e += estride)
629 auto entity = entities.subspan(e, estride);
630 std::int32_t
cell = fetch_cells(entity);
631 auto cell_coeff = c.subspan(e / estride * cstride + offset, space_dim);
632 pack<T, 1>(cell_coeff,
cell, bs, v, cell_info, dofmap, transformation);
636 for (std::size_t e = 0; e < entities.size(); e += estride)
638 auto entity = entities.subspan(e, estride);
639 std::int32_t
cell = fetch_cells(entity);
640 auto cell_coeff = c.subspan(e / estride * cstride + offset, space_dim);
641 pack<T, 2>(cell_coeff,
cell, bs, v, cell_info, dofmap, transformation);
645 for (std::size_t e = 0; e < entities.size(); e += estride)
647 auto entity = entities.subspan(e, estride);
648 std::int32_t
cell = fetch_cells(entity);
649 auto cell_coeff = c.subspan(e / estride * cstride + offset, space_dim);
650 pack<T, 3>(cell_coeff,
cell, bs, v, cell_info, dofmap, transformation);
654 for (std::size_t e = 0; e < entities.size(); e += estride)
656 auto entity = entities.subspan(e, estride);
657 std::int32_t
cell = fetch_cells(entity);
658 auto cell_coeff = c.subspan(e / estride * cstride + offset, space_dim);
659 pack<T, -1>(cell_coeff,
cell, bs, v, cell_info, dofmap, transformation);
673 template <
typename T>
674 std::pair<std::vector<T>,
int>
679 const std::vector<std::shared_ptr<const Function<T>>>& coefficients
683 std::size_t num_entities = 0;
685 if (!coefficients.empty())
687 cstride = offsets.back();
688 switch (integral_type)
700 throw std::runtime_error(
701 "Could not allocate coefficient data. Integral type not supported.");
705 return {std::vector<T>(num_entities * cstride), cstride};
712 template <
typename T>
713 std::map<std::pair<IntegralType, int>, std::pair<std::vector<T>,
int>>
716 std::map<std::pair<IntegralType, int>, std::pair<std::vector<T>,
int>> coeffs;
722 coeffs.end(), std::pair(integral_type,
id),
737 template <
typename T>
739 const std::span<T>& c,
int cstride)
742 const std::vector<std::shared_ptr<const Function<T>>>& coefficients
746 if (!coefficients.empty())
748 std::span<const std::uint32_t> cell_info
749 = impl::get_cell_orientation_info(coefficients);
751 switch (integral_type)
755 auto fetch_cell = [](
auto entity) {
return entity.front(); };
756 const std::vector<std::int32_t>& cells = form.
cell_domains(
id);
758 for (std::size_t coeff = 0; coeff < coefficients.size(); ++coeff)
760 impl::pack_coefficient_entity(c, cstride, *coefficients[coeff],
761 cell_info, cells, 1, fetch_cell,
771 auto fetch_cell = [](
auto& entity) {
return entity.front(); };
774 for (std::size_t coeff = 0; coeff < coefficients.size(); ++coeff)
776 impl::pack_coefficient_entity(c, cstride, *coefficients[coeff],
777 cell_info, facets, 2, fetch_cell,
787 auto fetch_cell0 = [](
auto& entity) {
return entity[0]; };
788 auto fetch_cell1 = [](
auto& entity) {
return entity[2]; };
791 for (std::size_t coeff = 0; coeff < coefficients.size(); ++coeff)
794 impl::pack_coefficient_entity(c, 2 * cstride, *coefficients[coeff],
795 cell_info, facets, 4, fetch_cell0,
798 impl::pack_coefficient_entity(c, 2 * cstride, *coefficients[coeff],
799 cell_info, facets, 4, fetch_cell1,
800 offsets[coeff] + offsets[coeff + 1]);
805 throw std::runtime_error(
806 "Could not pack coefficient. Integral type not supported.");
812 template <
typename T>
814 const ufcx_expression& expression,
815 const std::vector<std::shared_ptr<
const Function<T>>>& coefficients,
816 const std::vector<std::shared_ptr<
const Constant<T>>>& constants,
817 const std::shared_ptr<const mesh::Mesh>& mesh =
nullptr,
818 const std::shared_ptr<const FunctionSpace>& argument_function_space
821 if (expression.rank > 0 and !argument_function_space)
823 throw std::runtime_error(
824 "Expression has Argument but no Argument function space was provided.");
827 const std::size_t size
828 = expression.num_points * expression.topological_dimension;
829 std::span<const double> X(expression.points, size);
830 std::array<std::size_t, 2> Xshape
831 = {
static_cast<std::size_t
>(expression.num_points),
832 static_cast<std::size_t
>(expression.topological_dimension)};
834 std::vector<int> value_shape;
835 for (
int i = 0; i < expression.num_components; ++i)
836 value_shape.push_back(expression.value_shape[i]);
838 std::function<void(T*,
const T*,
const T*,
839 const typename impl::scalar_value_type<T>::value_type*,
840 const int*,
const std::uint8_t*)>
841 tabulate_tensor =
nullptr;
842 if constexpr (std::is_same_v<T, float>)
843 tabulate_tensor = expression.tabulate_tensor_float32;
844 else if constexpr (std::is_same_v<T, std::complex<float>>)
846 tabulate_tensor =
reinterpret_cast<void (*)(
847 T*,
const T*,
const T*,
848 const typename impl::scalar_value_type<T>::value_type*,
const int*,
849 const unsigned char*)
>(expression.tabulate_tensor_complex64);
851 else if constexpr (std::is_same_v<T, double>)
852 tabulate_tensor = expression.tabulate_tensor_float64;
853 else if constexpr (std::is_same_v<T, std::complex<double>>)
855 tabulate_tensor =
reinterpret_cast<void (*)(
856 T*,
const T*,
const T*,
857 const typename impl::scalar_value_type<T>::value_type*,
const int*,
858 const unsigned char*)
>(expression.tabulate_tensor_complex128);
862 throw std::runtime_error(
"Type not supported.");
864 assert(tabulate_tensor);
866 return Expression(coefficients, constants, X, Xshape, tabulate_tensor,
867 value_shape, mesh, argument_function_space);
872 template <
typename T>
874 const ufcx_expression& expression,
875 const std::map<std::string, std::shared_ptr<
const Function<T>>>&
877 const std::map<std::string, std::shared_ptr<
const Constant<T>>>& constants,
878 const std::shared_ptr<const mesh::Mesh>& mesh =
nullptr,
879 const std::shared_ptr<const FunctionSpace>& argument_function_space
883 std::vector<std::shared_ptr<const Function<T>>> coeff_map;
884 std::vector<std::string> coefficient_names;
885 for (
int i = 0; i < expression.num_coefficients; ++i)
886 coefficient_names.push_back(expression.coefficient_names[i]);
888 for (
const std::string& name : coefficient_names)
890 if (
auto it = coefficients.find(name); it != coefficients.end())
891 coeff_map.push_back(it->second);
894 throw std::runtime_error(
"Expression coefficient \"" + name
895 +
"\" not provided.");
900 std::vector<std::shared_ptr<const Constant<T>>> const_map;
901 std::vector<std::string> constant_names;
902 for (
int i = 0; i < expression.num_constants; ++i)
903 constant_names.push_back(expression.constant_names[i]);
905 for (
const std::string& name : constant_names)
907 if (
auto it = constants.find(name); it != constants.end())
908 const_map.push_back(it->second);
911 throw std::runtime_error(
"Expression constant \"" + name
912 +
"\" not provided.");
917 argument_function_space);
925 template <
typename T>
927 std::map<std::pair<IntegralType, int>,
928 std::pair<std::vector<T>,
int>>& coeffs)
930 for (
auto& [key, val] : coeffs)
931 pack_coefficients<T>(form, key.first, key.second, val.first, val.second);
940 template <
typename T>
941 std::pair<std::vector<T>,
int>
943 const std::span<const std::int32_t>& cells)
946 const std::vector<std::shared_ptr<const Function<T>>>& coefficients
951 const int cstride = offsets.back();
952 std::vector<T> c(cells.size() * offsets.back());
953 if (!coefficients.empty())
955 std::span<const std::uint32_t> cell_info
956 = impl::get_cell_orientation_info(coefficients);
959 for (std::size_t coeff = 0; coeff < coefficients.size(); ++coeff)
960 impl::pack_coefficient_entity(
961 std::span(c), cstride, *coefficients[coeff], cell_info, cells, 1,
962 [](
auto entity) {
return entity[0]; }, offsets[coeff]);
964 return {std::move(c), cstride};
969 template <
typename U>
972 using T =
typename U::scalar_type;
973 const std::vector<std::shared_ptr<const Constant<T>>>& constants
977 std::int32_t size = std::accumulate(constants.cbegin(), constants.cend(), 0,
978 [](std::int32_t sum,
auto& constant)
979 { return sum + constant->value.size(); });
982 std::vector<T> constant_values(size);
983 std::int32_t offset = 0;
984 for (
auto& constant : constants)
986 const std::vector<T>& value = constant->value;
987 std::copy(value.cbegin(), value.cend(),
988 std::next(constant_values.begin(), offset));
989 offset += value.size();
992 return constant_values;
Degree-of-freedeom map representations ans tools.
A timer can be used for timing tasks. The basic usage is.
Definition: Timer.h:31
double stop()
Stop timer, return wall time elapsed and store timing data into logger.
Definition: Timer.cpp:45
Constant value which can be attached to a Form. Constants may be scalar (rank 0), vector (rank 1),...
Definition: Constant.h:20
Degree-of-freedom map.
Definition: DofMap.h:71
int bs() const noexcept
Return the block size for the dofmap.
Definition: DofMap.cpp:183
Represents a mathematical expression evaluated at a pre-defined set of points on the reference cell....
Definition: Expression.h:34
const std::vector< std::shared_ptr< const Function< T > > > & coefficients() const
Get coefficients.
Definition: Expression.h:105
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:122
This class represents a function in a finite element function space , given by.
Definition: Function.h:45
std::shared_ptr< const la::Vector< T > > x() const
Underlying vector.
Definition: Function.h:142
std::shared_ptr< const FunctionSpace > function_space() const
Access the function space.
Definition: Function.h:136
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition: AdjacencyList.h:26
This class provides a sparsity pattern data structure that can be used to initialize sparse matrices....
Definition: SparsityPattern.h:34
Topology stores the topology of a mesh, consisting of mesh entities and connectivity (incidence relat...
Definition: Topology.h:44
void pack_coefficient_entity(const std::span< T > &c, int cstride, const Function< T > &u, const std::span< const std::uint32_t > &cell_info, const std::span< const std::int32_t > &entities, std::size_t estride, Functor fetch_cells, std::int32_t offset)
Pack a single coefficient for a set of active entities.
Definition: utils.h:608
Miscellaneous classes, functions and types.
void interior_facets(la::SparsityPattern &pattern, const mesh::Topology &topology, const std::array< const std::reference_wrapper< const DofMap >, 2 > &dofmaps)
Iterate over interior facets and insert entries into sparsity pattern.
Definition: sparsitybuild.cpp:43
void cells(la::SparsityPattern &pattern, const mesh::Topology &topology, const std::array< const std::reference_wrapper< const DofMap >, 2 > &dofmaps)
Iterate over cells and insert entries into sparsity pattern.
Definition: sparsitybuild.cpp:18
void exterior_facets(la::SparsityPattern &pattern, const mesh::Topology &topology, const std::array< const std::reference_wrapper< const DofMap >, 2 > &dofmaps)
Iterate over exterior facets and insert entries into sparsity pattern.
Definition: sparsitybuild.cpp:112
Finite element method functionality.
Definition: assemble_matrix_impl.h:25
std::vector< std::string > get_constant_names(const ufcx_form &ufcx_form)
Get the name of each constant in a UFC form.
Definition: utils.cpp:196
Form< T > create_form(const ufcx_form &ufcx_form, const std::vector< std::shared_ptr< const FunctionSpace >> &spaces, const std::vector< std::shared_ptr< const Function< T >>> &coefficients, const std::vector< std::shared_ptr< const Constant< T >>> &constants, const std::map< IntegralType, const mesh::MeshTags< int > * > &subdomains, const std::shared_ptr< const mesh::Mesh > &mesh=nullptr)
Create a Form from UFC input.
Definition: utils.h:228
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:970
std::pair< std::vector< T >, int > allocate_coefficient_storage(const Form< T > &form, IntegralType integral_type, int id)
Allocate storage for coefficients of a pair (integral_type, id) from a fem::Form form.
Definition: utils.h:675
std::vector< std::string > get_coefficient_names(const ufcx_form &ufcx_form)
Get the name of each coefficient in a UFC form.
Definition: utils.cpp:187
void pack_coefficients(const Form< T > &form, IntegralType integral_type, int id, const std::span< T > &c, int cstride)
Pack coefficients of a Form for a given integral type and domain id.
Definition: utils.h:738
std::vector< std::vector< std::array< std::shared_ptr< const FunctionSpace >, 2 > > > extract_function_spaces(const std::vector< std::vector< const Form< T > * >> &a)
Extract test (0) and trial (1) function spaces pairs for each bilinear form for a rectangular array o...
Definition: utils.h:85
IntegralType
Type of integral.
Definition: Form.h:31
@ interior_facet
Interior facet.
@ exterior_facet
Exterior facet.
la::SparsityPattern create_sparsity_pattern(const mesh::Topology &topology, const std::array< std::reference_wrapper< const DofMap >, 2 > &dofmaps, const std::set< IntegralType > &integrals)
Create a sparsity pattern for a given form.
Definition: utils.cpp:30
ElementDofLayout create_element_dof_layout(const ufcx_dofmap &dofmap, const mesh::CellType cell_type, const std::vector< int > &parent_map={})
Create an ElementDofLayout from a ufcx_dofmap.
Definition: utils.cpp:73
FunctionSpace create_functionspace(const std::shared_ptr< mesh::Mesh > &mesh, const basix::FiniteElement &e, int bs, const std::function< std::vector< int >(const graph::AdjacencyList< std::int32_t > &)> &reorder_fn=nullptr)
Create a FunctionSpace from a Basix element.
Definition: utils.cpp:205
DofMap create_dofmap(MPI_Comm comm, const ElementDofLayout &layout, mesh::Topology &topology, const std::function< std::vector< int >(const graph::AdjacencyList< std::int32_t > &)> &reorder_fn, const FiniteElement &element)
Create a dof map on mesh.
Definition: utils.cpp:140
Expression< T > create_expression(const ufcx_expression &expression, const std::vector< std::shared_ptr< const Function< T >>> &coefficients, const std::vector< std::shared_ptr< const Constant< T >>> &constants, const std::shared_ptr< const mesh::Mesh > &mesh=nullptr, const std::shared_ptr< const FunctionSpace > &argument_function_space=nullptr)
Create Expression from UFC.
Definition: utils.h:813
Mesh data structures and algorithms on meshes.
Definition: DofMap.h:30
CellType
Cell type identifier.
Definition: cell_types.h:22