DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
Function.h
1// Copyright (C) 2003-2026 Anders Logg, Garth N. Wells and Massimiliano Leoni
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 "DofMap.h"
10#include "FiniteElement.h"
11#include "FunctionSpace.h"
12#include "assembler.h"
13#include "interpolate.h"
14#include <algorithm>
15#include <basix/mdspan.hpp>
16#include <concepts>
17#include <dolfinx/common/IndexMap.h>
18#include <dolfinx/common/types.h>
19#include <dolfinx/la/Vector.h>
20#include <dolfinx/mesh/Geometry.h>
21#include <dolfinx/mesh/Mesh.h>
22#include <dolfinx/mesh/Topology.h>
23#include <functional>
24#include <memory>
25#include <numeric>
26#include <span>
27#include <stdexcept>
28#include <string>
29#include <utility>
30#include <vector>
31
32namespace dolfinx::fem
33{
34template <dolfinx::scalar T, std::floating_point U>
35class Expression;
36
46template <dolfinx::scalar T, std::floating_point U = dolfinx::scalar_value_t<T>>
48{
49public:
52 using value_type = T;
54 using geometry_type = U;
55
58 explicit Function(std::shared_ptr<const FunctionSpace<geometry_type>> V)
59 : _function_space(V), _x(std::make_shared<la::Vector<value_type>>(
60 V->dofmaps().front()->index_map,
61 V->dofmaps().front()->index_map_bs()))
62 {
63 if (!V->component().empty())
64 {
65 throw std::invalid_argument(
66 "Cannot create Function from subspace. Consider "
67 "collapsing the function space");
68 }
69 }
70
79 Function(std::shared_ptr<const FunctionSpace<geometry_type>> V,
80 std::shared_ptr<la::Vector<value_type>> x)
81 : _function_space(V), _x(x)
82 {
83 // NOTE: We do not check for a subspace since this constructor is
84 // used for creating subfunctions
85
86 // Assertion uses '<=' to deal with sub-functions
87 assert(V->dofmap());
88 assert(V->dofmap()->index_map->size_global() * V->dofmap()->index_map_bs()
89 <= _x->bs() * _x->index_map()->size_global());
90 }
91
92 // Copy constructor
93 Function(const Function& v) = delete;
94
96 Function(Function&& v) = default;
97
99 ~Function() = default;
100
102 Function& operator=(Function&& v) = default;
103
104 // Assignment
105 Function& operator=(const Function& v) = delete;
106
110 Function sub(int i) const
111 {
112 auto sub_space = std::make_shared<FunctionSpace<geometry_type>>(
113 _function_space->sub({i}));
114 assert(sub_space);
115 return Function(sub_space, _x);
116 }
117
122 {
123 // Create new collapsed FunctionSpace
124 auto [V, map] = _function_space->collapse();
125
126 // Create new vector
127 auto x = std::make_shared<la::Vector<value_type>>(
128 V.dofmap()->index_map, V.dofmap()->index_map_bs());
129
130 // Copy values into new vector
131 std::span<const value_type> x_old = _x->array();
132 std::span<value_type> x_new = x->array();
133 for (auto mapj : map)
134 {
135 for (std::size_t i = 0; i < mapj.size(); ++i)
136 {
137 assert(i < x_new.size());
138 assert(static_cast<std::size_t>(mapj[i]) < x_old.size());
139 x_new[i] = x_old[mapj[i]];
140 }
141 }
142
143 return Function(
144 std::make_shared<FunctionSpace<geometry_type>>(std::move(V)), x);
145 }
146
149 std::shared_ptr<const FunctionSpace<geometry_type>> function_space() const
150 {
151 return _function_space;
152 }
153
155 std::shared_ptr<const la::Vector<value_type>> x() const { return _x; }
156
158 std::shared_ptr<la::Vector<value_type>> x() { return _x; }
159
165 const std::function<
166 std::pair<std::vector<value_type>, std::vector<std::size_t>>(
167 md::mdspan<const geometry_type,
168 md::extents<std::size_t, 3, md::dynamic_extent>>)>& f,
169 mesh::CellRange auto&& cells)
170 {
171 assert(_function_space);
172 assert(_function_space->element());
173 assert(_function_space->mesh());
174 const std::vector<geometry_type> x
176 *_function_space->element(), _function_space->mesh()->geometry(),
177 cells);
178 md::mdspan<const geometry_type,
179 md::extents<std::size_t, 3, md::dynamic_extent>>
180 _x(x.data(), 3, x.size() / 3);
181
182 const auto [fx, fshape] = f(_x);
183 assert(fshape.size() <= 2);
184 if (std::size_t vs = _function_space->element()->value_size();
185 vs == 1 and fshape.size() == 1)
186 {
187 // Check for scalar-valued functions
188 if (fshape.front() != x.size() / 3)
189 throw std::invalid_argument(
190 "Data returned by callable has wrong length");
191 }
192 else
193 {
194 // Check for vector/tensor value
195 if (fshape.size() != 2)
196 throw std::invalid_argument("Expected 2D array of data");
197
198 if (fshape[0] != vs)
199 {
200 throw std::invalid_argument(
201 "Data returned by callable has wrong shape(0) size");
202 }
203
204 if (fshape[1] != x.size() / 3)
205 {
206 throw std::invalid_argument(
207 "Data returned by callable has wrong shape(1) size");
208 }
209 }
210
211 std::array<std::size_t, 2> _fshape;
212 if (fshape.size() == 1)
213 _fshape = {1, fshape[0]};
214 else
215 _fshape = {fshape[0], fshape[1]};
216
217 fem::interpolate(*this, std::span<const value_type>(fx.data(), fx.size()),
218 _fshape, cells);
219 }
220
225 const std::function<
226 std::pair<std::vector<value_type>, std::vector<std::size_t>>(
227 md::mdspan<const geometry_type,
228 md::extents<std::size_t, 3, md::dynamic_extent>>)>& f)
229 {
230 assert(_function_space);
231 assert(_function_space->mesh());
232 int tdim = _function_space->mesh()->topology()->dim();
233 auto cmap = _function_space->mesh()->topology()->index_map(tdim);
234 assert(cmap);
235 std::int32_t num_cells = cmap->size_local() + cmap->num_ghosts();
236 interpolate(f, std::ranges::iota_view(0, num_cells));
237 }
238
255 mesh::CellRange auto&& cells0, mesh::CellRange auto&& cells1)
256 {
257 fem::interpolate(*this, cells1, u0, cells0);
258 }
259
267 mesh::CellRange auto&& cells)
268 {
269 fem::interpolate(*this, u, cells);
270 }
271
278 {
279 assert(_function_space);
280 assert(_function_space->mesh());
281 int tdim = _function_space->mesh()->topology()->dim();
282 auto cmap = _function_space->mesh()->topology()->index_map(tdim);
283 assert(cmap);
284 fem::interpolate(*this, u);
285 }
286
303 mesh::CellRange auto&& cells0, mesh::CellRange auto&& cells1)
304 {
305 // Extract mesh
306 const mesh::Mesh<geometry_type>* mesh0 = nullptr;
307 for (auto& c : e0.coefficients())
308 {
309 assert(c);
310 assert(c->function_space());
311 assert(c->function_space()->mesh());
312 if (auto mesh = c->function_space()->mesh().get(); !mesh0)
313 mesh0 = mesh;
314 else if (mesh != mesh0)
315 {
316 throw std::invalid_argument(
317 "Expression coefficient Functions have different meshes.");
318 }
319 }
320
321 // If Expression has no Function coefficients take mesh from `this`.
322 assert(_function_space);
323 assert(_function_space->mesh());
324 if (!mesh0)
325 mesh0 = _function_space->mesh().get();
326
327 if (cells0.size() != cells1.size())
328 throw std::invalid_argument("Cell lists have different lengths.");
329
330 // Check that Function and Expression spaces are compatible
331 assert(_function_space->element());
332 std::size_t value_size = e0.value_size();
333 if (e0.argument_space())
334 throw std::invalid_argument(
335 "Cannot interpolate Expression with Argument.");
336
337 if (value_size != (std::size_t)_function_space->element()->value_size())
338 {
339 throw std::invalid_argument(
340 "Function value size not equal to Expression value size.");
341 }
342
343 // Compatibility check
344 {
345 auto [X0, shape0] = e0.X();
346 auto [X1, shape1] = _function_space->element()->interpolation_points();
347 if (shape0 != shape1)
348 {
349 throw std::invalid_argument(
350 "Function element interpolation points has different shape to "
351 "Expression interpolation points");
352 }
353
354 for (std::size_t i = 0; i < X0.size(); ++i)
355 {
356 if (std::abs(X0[i] - X1[i]) > 1.0e-10)
357 {
358 throw std::invalid_argument(
359 "Function element interpolation points not "
360 "equal to Expression interpolation points");
361 }
362 }
363 }
364
365 // Array to hold evaluated Expression
366 std::size_t num_cells = cells0.size();
367 std::size_t num_points = e0.X().second[0];
368 std::vector<value_type> fdata(num_cells * num_points * value_size);
369 md::mdspan<const value_type, md::dextents<std::size_t, 3>> f(
370 fdata.data(), num_cells, num_points, value_size);
371
372 // Evaluate Expression at points
373 std::vector<std::int32_t> _cells0(cells0.begin(), cells0.end());
374 tabulate_expression(std::span(fdata), e0, *mesh0,
375 md::mdspan(_cells0.data(), _cells0.size()));
376
377 // Reshape evaluated data to fit interpolate.
378 // Expression returns matrix of shape (num_cells, num_points *
379 // value_size), i.e. xyzxyz ordering of dof values per cell per
380 // point. The interpolation uses xxyyzz input, ordered for all
381 // points of each cell, i.e. (value_size, num_cells*num_points).
382 std::vector<value_type> fdata1(num_cells * num_points * value_size);
383 md::mdspan<value_type, md::dextents<std::size_t, 3>> f1(
384 fdata1.data(), value_size, num_cells, num_points);
385 for (std::size_t i = 0; i < f.extent(0); ++i)
386 for (std::size_t j = 0; j < f.extent(1); ++j)
387 for (std::size_t k = 0; k < f.extent(2); ++k)
388 f1(k, i, j) = f(i, j, k);
389
390 // Interpolate values into appropriate space
391 fem::interpolate(*this,
392 std::span<const value_type>(fdata1.data(), fdata1.size()),
393 {value_size, num_cells * num_points}, cells1);
394 }
395
406 mesh::CellRange auto&& cells)
407 {
408 interpolate(e0, cells, cells);
409 }
410
417 {
418 assert(_function_space);
419 assert(_function_space->mesh());
420 int tdim = _function_space->mesh()->topology()->dim();
421 auto map = _function_space->mesh()->topology()->index_map(tdim);
422 assert(map);
424 e, std::ranges::iota_view(0, map->size_local() + map->num_ghosts()));
425 }
426
440 mesh::CellRange auto&& cells, double tol, int maxit,
441 const geometry::PointOwnershipData<U>& interpolation_data)
442 {
443 fem::interpolate(*this, u, cells, tol, maxit, interpolation_data);
444 }
445
462 void eval(std::span<const geometry_type> x, std::array<std::size_t, 2> xshape,
463 mesh::CellRange auto&& cells, std::span<value_type> u,
464 std::array<std::size_t, 2> ushape, double tol, int maxit) const
465 {
466 if (cells.empty())
467 return;
468
469 assert(x.size() == xshape[0] * xshape[1]);
470 assert(u.size() == ushape[0] * ushape[1]);
471
472 // TODO: This could be easily made more efficient by exploiting
473 // points being ordered by the cell to which they belong.
474
475 if (xshape[0] != cells.size())
476 {
477 throw std::invalid_argument(
478 "Number of points and number of cells must be equal.");
479 }
480
481 if (xshape[0] != ushape[0])
482 {
483 throw std::invalid_argument(
484 "Length of array for Function values must be the "
485 "same as the number of points.");
486 }
487
488 // Get mesh
489 assert(_function_space);
490 auto mesh = _function_space->mesh();
491 assert(mesh);
492 const std::size_t gdim = mesh->geometry().dim();
493 const std::size_t tdim = mesh->topology()->dim();
494 auto map = mesh->topology()->index_map(tdim);
495
496 // Get coordinate map
498 = mesh->geometry().cmaps().front();
499
500 // Get geometry data
501 auto x_dofmap = mesh->geometry().dofmaps().front();
502 const std::size_t num_dofs_g = cmap.dim();
503 auto x_g = mesh->geometry().x();
504
505 // Get element
506 auto element = _function_space->element();
507 assert(element);
508 const int bs_element = element->block_size();
509 const std::size_t reference_value_size = element->reference_value_size();
510 const std::size_t value_size
511 = _function_space->element()->reference_value_size();
512 const std::size_t space_dimension = element->space_dimension() / bs_element;
513
514 // If the space has sub elements, concatenate the evaluations on the
515 // sub elements
516 const int num_sub_elements = element->num_sub_elements();
517 if (num_sub_elements > 1 and num_sub_elements != bs_element)
518 {
519 throw std::invalid_argument("Function::eval is not supported for mixed "
520 "elements. Extract subspaces.");
521 }
522
523 // Create work vector for expansion coefficients
524 std::vector<value_type> coefficients(space_dimension * bs_element);
525
526 // Get dofmap
527 std::shared_ptr<const DofMap> dofmap = _function_space->dofmap();
528 assert(dofmap);
529 const int bs_dof = dofmap->bs();
530
531 std::span<const std::uint32_t> cell_info;
532 if (element->needs_dof_transformations())
533 {
534 mesh->topology_mutable()->create_entity_permutations();
535 cell_info = std::span(mesh->topology()->get_cell_permutation_info());
536 }
537
538 std::vector<geometry_type> coord_dofs_b(num_dofs_g * gdim);
539 impl::mdspan_t<geometry_type, 2> coord_dofs(coord_dofs_b.data(), num_dofs_g,
540 gdim);
541 std::vector<geometry_type> xp_b(1 * gdim);
542 impl::mdspan_t<geometry_type, 2> xp(xp_b.data(), 1, gdim);
543
544 // Loop over points
545 std::ranges::fill(u, 0);
546 std::span<const value_type> _v = _x->array();
547
548 // Evaluate geometry basis at point (0, 0, 0) on the reference cell.
549 // Used in affine case.
550 std::array<std::size_t, 4> phi0_shape = cmap.tabulate_shape(1, 1);
551 std::vector<geometry_type> phi0_b(std::reduce(
552 phi0_shape.begin(), phi0_shape.end(), 1, std::multiplies{}));
553 impl::mdspan_t<const geometry_type, 4> phi0(phi0_b.data(), phi0_shape);
554 cmap.tabulate(1, std::vector<geometry_type>(tdim), {1, tdim}, phi0_b);
555 auto dphi0
556 = md::submdspan(phi0, std::pair(1, tdim + 1), 0, md::full_extent, 0);
557
558 // Data structure for evaluating geometry basis at specific points.
559 // Used in non-affine case.
560 std::array<std::size_t, 4> phi_shape = cmap.tabulate_shape(1, 1);
561 std::vector<geometry_type> phi_b(
562 std::reduce(phi_shape.begin(), phi_shape.end(), 1, std::multiplies{}));
563 impl::mdspan_t<const geometry_type, 4> phi(phi_b.data(), phi_shape);
564 auto dphi
565 = md::submdspan(phi, std::pair(1, tdim + 1), 0, md::full_extent, 0);
566
567 // Reference coordinates for each point
568 std::vector<geometry_type> Xb(xshape[0] * tdim);
569 impl::mdspan_t<geometry_type, 2> X(Xb.data(), xshape[0], tdim);
570
571 // Geometry data at each point
572 std::vector<geometry_type> J_b(xshape[0] * gdim * tdim);
573 impl::mdspan_t<geometry_type, 3> J(J_b.data(), xshape[0], gdim, tdim);
574 std::vector<geometry_type> K_b(xshape[0] * tdim * gdim);
575 impl::mdspan_t<geometry_type, 3> K(K_b.data(), xshape[0], tdim, gdim);
576 std::vector<geometry_type> detJ(xshape[0]);
577 std::vector<geometry_type> det_scratch(2 * gdim * tdim);
578
579 // Scratch space for pull-back of point coordinates for non-affine cells
580 std::vector<geometry_type> pull_back_scratch(
581 cmap.is_affine() ? 0 : cmap.pull_back_working_size(gdim));
582
583 // Prepare geometry data in each cell
584 for (auto cell_it = cells.begin(); cell_it != cells.end(); ++cell_it)
585 {
586 // Skip negative cell indices
587 if (*cell_it < 0)
588 continue;
589
590 // Get cell geometry (coordinate dofs)
591 auto x_dofs = md::submdspan(x_dofmap, *cell_it, md::full_extent);
592 assert(x_dofs.size() == num_dofs_g);
593 for (std::size_t i = 0; i < num_dofs_g; ++i)
594 {
595 const int pos = 3 * x_dofs[i];
596 for (std::size_t j = 0; j < gdim; ++j)
597 coord_dofs(i, j) = x_g[pos + j];
598 }
599
600 std::size_t p = std::ranges::distance(cells.begin(), cell_it);
601 for (std::size_t j = 0; j < gdim; ++j)
602 xp(0, j) = x[p * xshape[1] + j];
603
604 auto _J = md::submdspan(J, p, md::full_extent, md::full_extent);
605 auto _K = md::submdspan(K, p, md::full_extent, md::full_extent);
606
607 std::array<geometry_type, 3> Xpb{0, 0, 0};
608 md::mdspan<geometry_type, md::extents<std::size_t, 1, md::dynamic_extent>>
609 Xp(Xpb.data(), 1, tdim);
610
611 // Compute reference coordinates X, and J, detJ and K
612 if (cmap.is_affine())
613 {
615 _J);
617 std::array<geometry_type, 3> x0{0, 0, 0};
618 for (std::size_t i = 0; i < coord_dofs.extent(1); ++i)
619 x0[i] += coord_dofs(0, i);
621 detJ[p]
623 _J, det_scratch);
624 }
625 else
626 {
627 // Pull-back physical point xp to reference coordinate Xp
628 cmap.pull_back_nonaffine(Xp, xp, coord_dofs, pull_back_scratch, tol,
629 maxit);
630 cmap.tabulate(1, std::span(Xpb.data(), tdim), {1, tdim}, phi_b);
632 _J);
634 detJ[p]
636 _J, det_scratch);
637 }
638
639 for (std::size_t j = 0; j < X.extent(1); ++j)
640 X(p, j) = Xpb[j];
641 }
642
643 // Prepare basis function data structures
644 std::vector<geometry_type> basis_derivatives_reference_values_b(
645 1 * xshape[0] * space_dimension * reference_value_size);
646 impl::mdspan_t<const geometry_type, 4> basis_derivatives_reference_values(
647 basis_derivatives_reference_values_b.data(), 1, xshape[0],
648 space_dimension, reference_value_size);
649 std::vector<geometry_type> basis_values_b(space_dimension * value_size);
650 impl::mdspan_t<geometry_type, 2> basis_values(basis_values_b.data(),
651 space_dimension, value_size);
652
653 // Compute basis on reference element
654 element->tabulate(basis_derivatives_reference_values_b, Xb,
655 {X.extent(0), X.extent(1)}, 0);
656
657 using xu_t = impl::mdspan_t<geometry_type, 2>;
658 using xU_t = impl::mdspan_t<const geometry_type, 2>;
659 using xJ_t = impl::mdspan_t<const geometry_type, 2>;
660 using xK_t = impl::mdspan_t<const geometry_type, 2>;
661 auto push_forward_fn
662 = element->basix_element().template map_fn<xu_t, xU_t, xJ_t, xK_t>();
663
664 // Transformation function for basis function values
665 auto apply_dof_transformation
666 = element->template dof_transformation_fn<geometry_type>(
668
669 // Size of tensor for symmetric elements, unused in non-symmetric
670 // case, but placed outside the loop for pre-computation.
671 int matrix_size = 0;
672 if (element->symmetric())
673 {
674 while (matrix_size * matrix_size < (int)ushape[1])
675 ++matrix_size;
676 }
677
678 const std::size_t num_basis_values = space_dimension * reference_value_size;
679 for (auto cell_it = cells.begin(); cell_it != cells.end(); ++cell_it)
680 {
681 if (*cell_it < 0) // Skip negative cell indices
682 continue;
683
684 // Permute the reference basis function values to account for the
685 // cell's orientation
686 std::size_t p = std::ranges::distance(cells.begin(), cell_it);
687 if (apply_dof_transformation)
688 {
689 apply_dof_transformation(
690 std::span(basis_derivatives_reference_values_b.data()
691 + p * num_basis_values,
692 num_basis_values),
693 cell_info, *cell_it, reference_value_size);
694 }
695
696 {
697 auto _U = md::submdspan(basis_derivatives_reference_values, 0, p,
698 md::full_extent, md::full_extent);
699 auto _J = md::submdspan(J, p, md::full_extent, md::full_extent);
700 auto _K = md::submdspan(K, p, md::full_extent, md::full_extent);
701 push_forward_fn(basis_values, _U, _J, detJ[p], _K);
702 }
703
704 // Get degrees of freedom for current cell
705 std::span<const std::int32_t> dofs = dofmap->cell_dofs(*cell_it);
706 for (std::size_t i = 0; i < dofs.size(); ++i)
707 for (int k = 0; k < bs_dof; ++k)
708 coefficients[bs_dof * i + k] = _v[bs_dof * dofs[i] + k];
709
710 if (element->symmetric())
711 {
712 // Compute expansion
713 int row = 0;
714 int rowstart = 0;
715 for (int k = 0; k < bs_element; ++k)
716 {
717 if (k - rowstart > row)
718 {
719 row++;
720 rowstart = k;
721 }
722 for (std::size_t i = 0; i < space_dimension; ++i)
723 {
724 for (std::size_t j = 0; j < value_size; ++j)
725 {
726 u[p * ushape[1]
727 + (j * bs_element + row * matrix_size + k - rowstart)]
728 += coefficients[bs_element * i + k] * basis_values(i, j);
729 if (k - rowstart != row)
730 {
731 u[p * ushape[1]
732 + (j * bs_element + row + matrix_size * (k - rowstart))]
733 += coefficients[bs_element * i + k] * basis_values(i, j);
734 }
735 }
736 }
737 }
738 }
739 else
740 {
741 // Compute expansion
742 for (int k = 0; k < bs_element; ++k)
743 {
744 for (std::size_t i = 0; i < space_dimension; ++i)
745 {
746 for (std::size_t j = 0; j < value_size; ++j)
747 {
748 u[p * ushape[1] + (j * bs_element + k)]
749 += coefficients[bs_element * i + k] * basis_values(i, j);
750 }
751 }
752 }
753 }
754 }
755 }
756
758 std::string name = "u";
759
760private:
761 // Function space
762 std::shared_ptr<const FunctionSpace<geometry_type>> _function_space;
763
764 // Vector of expansion coefficients (local)
765 std::shared_ptr<la::Vector<value_type>> _x;
766};
767
768} // namespace dolfinx::fem
Degree-of-freedom map representations and tools.
Functions supporting assembly of finite element fem::Form and fem::Expression.
Definition CoordinateElement.h:38
static void compute_jacobian(const U &dphi, const V &cell_geometry, W &&J)
Definition CoordinateElement.h:133
void tabulate(int nd, std::span< const T > X, std::array< std::size_t, 2 > shape, std::span< T > basis) const
Evaluate basis values and derivatives at set of points.
Definition CoordinateElement.cpp:59
std::size_t pull_back_working_size(std::size_t gdim) const
Compute the working array size required for pull back.
Definition CoordinateElement.cpp:243
static void compute_jacobian_inverse(const U &J, V &&K)
Compute the inverse of the Jacobian.
Definition CoordinateElement.h:142
void pull_back_nonaffine(mdspan2_t< T > X, mdspan2_t< const T > x, mdspan2_t< const T > cell_geometry, std::span< T > working_array, double tol, int maxit) const
Compute reference coordinates X for physical coordinates x for a non-affine map.
Definition CoordinateElement.cpp:87
std::array< std::size_t, 4 > tabulate_shape(std::size_t nd, std::size_t num_points) const
Shape of array to fill when calling tabulate.
Definition CoordinateElement.cpp:52
int dim() const
The dimension of the coordinate element space.
Definition CoordinateElement.cpp:222
bool is_affine() const noexcept
Check if geometry map is affine.
Definition CoordinateElement.h:289
static double compute_jacobian_determinant(const U &J, std::span< typename U::value_type > w)
Compute the determinant of the Jacobian.
Definition CoordinateElement.h:159
static void pull_back_affine(U &&X, const V &K, std::array< T, 3 > x0, const W &x)
Compute reference coordinates X for physical coordinates x for an affine map. For the affine case,...
Definition CoordinateElement.h:215
An Expression represents a mathematical expression evaluated at a pre-defined points on a reference c...
Definition Expression.h:43
std::pair< std::vector< geometry_type >, std::array< std::size_t, 2 > > X() const
Evaluation point coordinates on the reference cell.
Definition Expression.h:165
const std::vector< std::shared_ptr< const Function< scalar_type, geometry_type > > > & coefficients() const
Expression coefficients.
Definition Expression.h:114
std::shared_ptr< const FunctionSpace< geometry_type > > argument_space() const
Argument function space.
Definition Expression.h:105
int value_size() const
Value size of the Expression result.
Definition Expression.h:155
This class represents a finite element function space defined by a mesh, a finite element,...
Definition FunctionSpace.h:35
Definition Function.h:48
U geometry_type
Geometry type of the Mesh that the Function is defined on.
Definition Function.h:54
void interpolate(const Function< value_type, geometry_type > &u, mesh::CellRange auto &&cells)
Interpolate a Function over a subset of cells.
Definition Function.h:266
void interpolate(const Function< value_type, geometry_type > &u)
Interpolate a Function over all cells.
Definition Function.h:277
void interpolate(const Expression< value_type, geometry_type > &e0, mesh::CellRange auto &&cells0, mesh::CellRange auto &&cells1)
Interpolate an Expression over a subset of cells.
Definition Function.h:302
std::shared_ptr< const FunctionSpace< geometry_type > > function_space() const
Access the function space.
Definition Function.h:149
void interpolate(const Expression< value_type, geometry_type > &e0, mesh::CellRange auto &&cells)
Interpolate an Expression over a subset of cells.
Definition Function.h:405
Function(std::shared_ptr< const FunctionSpace< geometry_type > > V)
Create function on given function space.
Definition Function.h:58
void interpolate(const std::function< std::pair< std::vector< value_type >, std::vector< std::size_t > >(md::mdspan< const geometry_type, md::extents< std::size_t, 3, md::dynamic_extent > >)> &f, mesh::CellRange auto &&cells)
Interpolate an expression f(x) over a set of cells.
Definition Function.h:164
void interpolate(const Function< value_type, geometry_type > &u0, mesh::CellRange auto &&cells0, mesh::CellRange auto &&cells1)
Interpolate a Function over a subset of cells.
Definition Function.h:254
void eval(std::span< const geometry_type > x, std::array< std::size_t, 2 > xshape, mesh::CellRange auto &&cells, std::span< value_type > u, std::array< std::size_t, 2 > ushape, double tol, int maxit) const
Evaluate the Function at points.
Definition Function.h:462
Function collapse() const
Collapse a subfunction (view into a Function) to a stand-alone Function.
Definition Function.h:121
void interpolate(const std::function< std::pair< std::vector< value_type >, std::vector< std::size_t > >(md::mdspan< const geometry_type, md::extents< std::size_t, 3, md::dynamic_extent > >)> &f)
Interpolate an expression f(x) on the whole domain.
Definition Function.h:224
Function sub(int i) const
Extract a sub-function (a view into the Function).
Definition Function.h:110
std::string name
Name.
Definition Function.h:758
std::shared_ptr< la::Vector< value_type > > x()
Underlying vector.
Definition Function.h:158
void interpolate(const Function< value_type, geometry_type > &u, mesh::CellRange auto &&cells, double tol, int maxit, const geometry::PointOwnershipData< U > &interpolation_data)
Interpolate a Function defined on a different mesh.
Definition Function.h:439
void interpolate(const Expression< value_type, geometry_type > &e)
Interpolate an Expression on all cells.
Definition Function.h:416
~Function()=default
Destructor.
Function(Function &&v)=default
Move constructor.
std::shared_ptr< const la::Vector< value_type > > x() const
Underlying vector (const version).
Definition Function.h:155
Function & operator=(Function &&v)=default
Move assignment.
Function(std::shared_ptr< const FunctionSpace< geometry_type > > V, std::shared_ptr< la::Vector< value_type > > x)
Create function on given function space with a given vector.
Definition Function.h:79
T value_type
Definition Function.h:52
A vector that can be distributed across processes.
Definition Vector.h:50
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition Mesh.h:23
Requirement on range of cell indices.
Definition Topology.h:32
Finite element method functionality.
Definition assemble_expression_impl.h:24
void interpolate(Function< T, U > &u, std::span< const T > f, std::array< std::size_t, 2 > fshape, mesh::CellRange auto &&cells)
Interpolate an evaluated expression f(x) in a finite element space.
Definition interpolate.h:1160
void tabulate_expression(std::span< T > values, const fem::Expression< T, U > &e, md::mdspan< const T, md::dextents< std::size_t, 2 > > coeffs, std::span< const T > constants, const mesh::Mesh< U > &mesh, fem::MDSpan2 auto entities, std::optional< std::pair< std::reference_wrapper< const FiniteElement< U > >, std::size_t > > element)
Evaluate an Expression on cells or facets.
Definition assembler.h:66
@ standard
Standard.
Definition FiniteElement.h:29
std::vector< T > interpolation_coords(const fem::FiniteElement< T > &element, const mesh::Geometry< T > &geometry, mesh::CellRange auto &&cells)
Compute the evaluation points in the physical space at which an expression should be computed to inte...
Definition interpolate.h:44
Linear algebra interface.
Definition dolfinx_la.h:7
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32
Information on the ownership of points distributed across processes.
Definition utils.h:34