Loading...
Searching...
No Matches
Function.h
// Copyright (C) 2003-2024 Anders Logg, Garth N. Wells and Massimiliano Leoni
//
// This file is part of DOLFINx (https://www.fenicsproject.org)
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "DofMap.h"
#include "FiniteElement.h"
#include "FunctionSpace.h"
#include "assembler.h"
#include "interpolate.h"
#include <algorithm>
#include <basix/mdspan.hpp>
#include <concepts>
#include <dolfinx/common/IndexMap.h>
#include <dolfinx/common/types.h>
#include <dolfinx/la/Vector.h>
#include <dolfinx/mesh/Geometry.h>
#include <dolfinx/mesh/Mesh.h>
#include <dolfinx/mesh/Topology.h>
#include <functional>
#include <memory>
#include <numeric>
#include <span>
#include <string>
#include <utility>
#include <vector>
namespace dolfinx::fem
{
template <dolfinx::scalar T, std::floating_point U>
class Expression;
template <dolfinx::scalar T, std::floating_point U = dolfinx::scalar_value_t<T>>
class Function
{
public:
using value_type = T;
using geometry_type = U;
explicit Function(std::shared_ptr<const FunctionSpace<geometry_type>> V)
: _function_space(V),
_x(std::make_shared<la::Vector<value_type>>(
V->dofmaps(0)->index_map, V->dofmaps(0)->index_map_bs()))
{
if (!V->component().empty())
{
throw std::runtime_error("Cannot create Function from subspace. Consider "
"collapsing the function space");
}
}
Function(std::shared_ptr<const FunctionSpace<geometry_type>> V,
std::shared_ptr<la::Vector<value_type>> x)
: _function_space(V), _x(x)
{
// NOTE: We do not check for a subspace since this constructor is
// used for creating subfunctions
// Assertion uses '<=' to deal with sub-functions
assert(V->dofmap());
assert(V->dofmap()->index_map->size_global() * V->dofmap()->index_map_bs()
<= _x->bs() * _x->index_map()->size_global());
}
// Copy constructor
Function(const Function& v) = delete;
Function(Function&& v) = default;
~Function() = default;
Function& operator=(Function&& v) = default;
// Assignment
Function& operator=(const Function& v) = delete;
Function sub(int i) const
{
auto sub_space = std::make_shared<FunctionSpace<geometry_type>>(
_function_space->sub({i}));
assert(sub_space);
return Function(sub_space, _x);
}
Function collapse() const
{
// Create new collapsed FunctionSpace
auto [V, map] = _function_space->collapse();
// Create new vector
auto x = std::make_shared<la::Vector<value_type>>(
V.dofmap()->index_map, V.dofmap()->index_map_bs());
// Copy values into new vector
std::span<const value_type> x_old = _x->array();
std::span<value_type> x_new = x->array();
for (std::size_t i = 0; i < map.size(); ++i)
{
assert((int)i < x_new.size());
assert(map[i] < x_old.size());
x_new[i] = x_old[map[i]];
}
return Function(
std::make_shared<FunctionSpace<geometry_type>>(std::move(V)), x);
}
std::shared_ptr<const FunctionSpace<geometry_type>> function_space() const
{
return _function_space;
}
std::shared_ptr<const la::Vector<value_type>> x() const { return _x; }
std::shared_ptr<la::Vector<value_type>> x() { return _x; }
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)
{
assert(_function_space);
assert(_function_space->mesh());
int tdim = _function_space->mesh()->topology()->dim();
auto cmap = _function_space->mesh()->topology()->index_map(tdim);
assert(cmap);
std::vector<std::int32_t> cells(cmap->size_local() + cmap->num_ghosts(), 0);
std::iota(cells.begin(), cells.end(), 0);
interpolate(f, cells);
}
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,
std::span<const std::int32_t> cells)
{
assert(_function_space);
assert(_function_space->element());
assert(_function_space->mesh());
const std::vector<geometry_type> x
= fem::interpolation_coords<geometry_type>(
*_function_space->element(), _function_space->mesh()->geometry(),
cells);
md::mdspan<const geometry_type,
md::extents<std::size_t, 3, md::dynamic_extent>>
_x(x.data(), 3, x.size() / 3);
const auto [fx, fshape] = f(_x);
assert(fshape.size() <= 2);
if (int vs = _function_space->element()->value_size();
vs == 1 and fshape.size() == 1)
{
// Check for scalar-valued functions
if (fshape.front() != x.size() / 3)
throw std::runtime_error("Data returned by callable has wrong length");
}
else
{
// Check for vector/tensor value
if (fshape.size() != 2)
throw std::runtime_error("Expected 2D array of data");
if (fshape[0] != vs)
{
throw std::runtime_error(
"Data returned by callable has wrong shape(0) size");
}
if (fshape[1] != x.size() / 3)
{
throw std::runtime_error(
"Data returned by callable has wrong shape(1) size");
}
}
std::array<std::size_t, 2> _fshape;
if (fshape.size() == 1)
_fshape = {1, fshape[0]};
else
_fshape = {fshape[0], fshape[1]};
fem::interpolate(*this, std::span<const value_type>(fx.data(), fx.size()),
_fshape, cells);
}
void interpolate(const Function<value_type, geometry_type>& u)
{
assert(_function_space);
assert(_function_space->mesh());
int tdim = _function_space->mesh()->topology()->dim();
auto cmap = _function_space->mesh()->topology()->index_map(tdim);
assert(cmap);
std::vector<std::int32_t> cells(cmap->size_local() + cmap->num_ghosts(), 0);
std::iota(cells.begin(), cells.end(), 0);
interpolate(u, cells, cells);
}
void interpolate(const Function<value_type, geometry_type>& u0,
std::span<const std::int32_t> cells0,
std::span<const std::int32_t> cells1 = {})
{
if (cells1.empty())
cells1 = cells0;
fem::interpolate(*this, cells1, u0, cells0);
}
void interpolate(const Expression<value_type, geometry_type>& e)
{
assert(_function_space);
assert(_function_space->mesh());
int tdim = _function_space->mesh()->topology()->dim();
auto cmap = _function_space->mesh()->topology()->index_map(tdim);
assert(cmap);
std::vector<std::int32_t> cells(cmap->size_local() + cmap->num_ghosts(), 0);
std::iota(cells.begin(), cells.end(), 0);
interpolate(e, cells);
}
void interpolate(const Expression<value_type, geometry_type>& e0,
std::span<const std::int32_t> cells0,
std::span<const std::int32_t> cells1 = {})
{
// Extract mesh
const mesh::Mesh<geometry_type>* mesh0 = nullptr;
for (auto& c : e0.coefficients())
{
assert(c);
assert(c->function_space());
assert(c->function_space()->mesh());
if (const mesh::Mesh<geometry_type>* mesh
= c->function_space()->mesh().get();
!mesh0)
{
mesh0 = mesh;
}
else if (mesh != mesh0)
{
throw std::runtime_error(
"Expression coefficient Functions have different meshes.");
}
}
// If Expression has no Function coefficients take mesh from `this`.
assert(_function_space);
assert(_function_space->mesh());
if (!mesh0)
mesh0 = _function_space->mesh().get();
// If cells1 is empty and Function and Expression meshes are the
// same, make cells1 the same as cells0. Otherwise check that
// lengths of cells0 and cells1 are the same.
if (cells1.empty() and mesh0 == _function_space->mesh().get())
cells1 = cells0;
else if (cells0.size() != cells1.size())
throw std::runtime_error("Cells lists have different lengths.");
// Check that Function and Expression spaces are compatible
assert(_function_space->element());
std::size_t value_size = e0.value_size();
if (e0.argument_space())
throw std::runtime_error("Cannot interpolate Expression with Argument.");
if (value_size != (std::size_t)_function_space->element()->value_size())
{
throw std::runtime_error(
"Function value size not equal to Expression value size.");
}
// Compatibility check
{
auto [X0, shape0] = e0.X();
auto [X1, shape1] = _function_space->element()->interpolation_points();
if (shape0 != shape1)
{
throw std::runtime_error(
"Function element interpolation points has different shape to "
"Expression interpolation points");
}
for (std::size_t i = 0; i < X0.size(); ++i)
{
if (std::abs(X0[i] - X1[i]) > 1.0e-10)
{
throw std::runtime_error("Function element interpolation points not "
"equal to Expression interpolation points");
}
}
}
// Array to hold evaluated Expression
std::size_t num_cells = cells0.size();
std::size_t num_points = e0.X().second[0];
std::vector<value_type> fdata(num_cells * num_points * value_size);
md::mdspan<const value_type, md::dextents<std::size_t, 3>> f(
fdata.data(), num_cells, num_points, value_size);
// Evaluate Expression at points
tabulate_expression(std::span(fdata), e0, *mesh0,
md::mdspan(cells0.data(), cells0.size()));
// Reshape evaluated data to fit interpolate.
// Expression returns matrix of shape (num_cells, num_points *
// value_size), i.e. xyzxyz ordering of dof values per cell per
// point. The interpolation uses xxyyzz input, ordered for all
// points of each cell, i.e. (value_size, num_cells*num_points).
std::vector<value_type> fdata1(num_cells * num_points * value_size);
md::mdspan<value_type, md::dextents<std::size_t, 3>> f1(
fdata1.data(), value_size, num_cells, num_points);
for (std::size_t i = 0; i < f.extent(0); ++i)
for (std::size_t j = 0; j < f.extent(1); ++j)
for (std::size_t k = 0; k < f.extent(2); ++k)
f1(k, i, j) = f(i, j, k);
// Interpolate values into appropriate space
fem::interpolate(*this,
std::span<const value_type>(fdata1.data(), fdata1.size()),
{value_size, num_cells * num_points}, cells1);
}
void interpolate(const Function<value_type, geometry_type>& v,
std::span<const std::int32_t> cells,
const geometry::PointOwnershipData<U>& interpolation_data)
{
fem::interpolate(*this, v, cells, interpolation_data);
}
void eval(std::span<const geometry_type> x, std::array<std::size_t, 2> xshape,
std::span<const std::int32_t> cells, std::span<value_type> u,
std::array<std::size_t, 2> ushape) const
{
if (cells.empty())
return;
assert(x.size() == xshape[0] * xshape[1]);
assert(u.size() == ushape[0] * ushape[1]);
// TODO: This could be easily made more efficient by exploiting
// points being ordered by the cell to which they belong.
if (xshape[0] != cells.size())
{
throw std::runtime_error(
"Number of points and number of cells must be equal.");
}
if (xshape[0] != ushape[0])
{
throw std::runtime_error(
"Length of array for Function values must be the "
"same as the number of points.");
}
// Get mesh
assert(_function_space);
auto mesh = _function_space->mesh();
assert(mesh);
const std::size_t gdim = mesh->geometry().dim();
const std::size_t tdim = mesh->topology()->dim();
auto map = mesh->topology()->index_map(tdim);
// Get coordinate map
const CoordinateElement<geometry_type>& cmap = mesh->geometry().cmap();
// Get geometry data
auto x_dofmap = mesh->geometry().dofmap();
const std::size_t num_dofs_g = cmap.dim();
auto x_g = mesh->geometry().x();
// Get element
auto element = _function_space->element();
assert(element);
const int bs_element = element->block_size();
const std::size_t reference_value_size = element->reference_value_size();
const std::size_t value_size
= _function_space->element()->reference_value_size();
const std::size_t space_dimension = element->space_dimension() / bs_element;
// If the space has sub elements, concatenate the evaluations on the
// sub elements
const int num_sub_elements = element->num_sub_elements();
if (num_sub_elements > 1 and num_sub_elements != bs_element)
{
throw std::runtime_error("Function::eval is not supported for mixed "
"elements. Extract subspaces.");
}
// Create work vector for expansion coefficients
std::vector<value_type> coefficients(space_dimension * bs_element);
// Get dofmap
std::shared_ptr<const DofMap> dofmap = _function_space->dofmap();
assert(dofmap);
const int bs_dof = dofmap->bs();
std::span<const std::uint32_t> cell_info;
if (element->needs_dof_transformations())
{
mesh->topology_mutable()->create_entity_permutations();
cell_info = std::span(mesh->topology()->get_cell_permutation_info());
}
std::vector<geometry_type> coord_dofs_b(num_dofs_g * gdim);
impl::mdspan_t<geometry_type, 2> coord_dofs(coord_dofs_b.data(), num_dofs_g,
gdim);
std::vector<geometry_type> xp_b(1 * gdim);
impl::mdspan_t<geometry_type, 2> xp(xp_b.data(), 1, gdim);
// Loop over points
std::ranges::fill(u, 0.0);
std::span<const value_type> _v = _x->array();
// Evaluate geometry basis at point (0, 0, 0) on the reference cell.
// Used in affine case.
std::array<std::size_t, 4> phi0_shape = cmap.tabulate_shape(1, 1);
std::vector<geometry_type> phi0_b(std::reduce(
phi0_shape.begin(), phi0_shape.end(), 1, std::multiplies{}));
impl::mdspan_t<const geometry_type, 4> phi0(phi0_b.data(), phi0_shape);
cmap.tabulate(1, std::vector<geometry_type>(tdim), {1, tdim}, phi0_b);
auto dphi0
= md::submdspan(phi0, std::pair(1, tdim + 1), 0, md::full_extent, 0);
// Data structure for evaluating geometry basis at specific points.
// Used in non-affine case.
std::array<std::size_t, 4> phi_shape = cmap.tabulate_shape(1, 1);
std::vector<geometry_type> phi_b(
std::reduce(phi_shape.begin(), phi_shape.end(), 1, std::multiplies{}));
impl::mdspan_t<const geometry_type, 4> phi(phi_b.data(), phi_shape);
auto dphi
= md::submdspan(phi, std::pair(1, tdim + 1), 0, md::full_extent, 0);
// Reference coordinates for each point
std::vector<geometry_type> Xb(xshape[0] * tdim);
impl::mdspan_t<geometry_type, 2> X(Xb.data(), xshape[0], tdim);
// Geometry data at each point
std::vector<geometry_type> J_b(xshape[0] * gdim * tdim);
impl::mdspan_t<geometry_type, 3> J(J_b.data(), xshape[0], gdim, tdim);
std::vector<geometry_type> K_b(xshape[0] * tdim * gdim);
impl::mdspan_t<geometry_type, 3> K(K_b.data(), xshape[0], tdim, gdim);
std::vector<geometry_type> detJ(xshape[0]);
std::vector<geometry_type> det_scratch(2 * gdim * tdim);
// Prepare geometry data in each cell
for (std::size_t p = 0; p < cells.size(); ++p)
{
const int cell_index = cells[p];
// Skip negative cell indices
if (cell_index < 0)
continue;
// Get cell geometry (coordinate dofs)
auto x_dofs = md::submdspan(x_dofmap, cell_index, md::full_extent);
assert(x_dofs.size() == num_dofs_g);
for (std::size_t i = 0; i < num_dofs_g; ++i)
{
const int pos = 3 * x_dofs[i];
for (std::size_t j = 0; j < gdim; ++j)
coord_dofs(i, j) = x_g[pos + j];
}
for (std::size_t j = 0; j < gdim; ++j)
xp(0, j) = x[p * xshape[1] + j];
auto _J = md::submdspan(J, p, md::full_extent, md::full_extent);
auto _K = md::submdspan(K, p, md::full_extent, md::full_extent);
std::array<geometry_type, 3> Xpb{0, 0, 0};
md::mdspan<geometry_type, md::extents<std::size_t, 1, md::dynamic_extent>>
Xp(Xpb.data(), 1, tdim);
// Compute reference coordinates X, and J, detJ and K
if (cmap.is_affine())
{
CoordinateElement<geometry_type>::compute_jacobian(dphi0, coord_dofs,
_J);
CoordinateElement<geometry_type>::compute_jacobian_inverse(_J, _K);
std::array<geometry_type, 3> x0{0, 0, 0};
for (std::size_t i = 0; i < coord_dofs.extent(1); ++i)
x0[i] += coord_dofs(0, i);
CoordinateElement<geometry_type>::pull_back_affine(Xp, _K, x0, xp);
detJ[p]
= CoordinateElement<geometry_type>::compute_jacobian_determinant(
_J, det_scratch);
}
else
{
// Pull-back physical point xp to reference coordinate Xp
cmap.pull_back_nonaffine(Xp, xp, coord_dofs);
cmap.tabulate(1, std::span(Xpb.data(), tdim), {1, tdim}, phi_b);
CoordinateElement<geometry_type>::compute_jacobian(dphi, coord_dofs,
_J);
CoordinateElement<geometry_type>::compute_jacobian_inverse(_J, _K);
detJ[p]
= CoordinateElement<geometry_type>::compute_jacobian_determinant(
_J, det_scratch);
}
for (std::size_t j = 0; j < X.extent(1); ++j)
X(p, j) = Xpb[j];
}
// Prepare basis function data structures
std::vector<geometry_type> basis_derivatives_reference_values_b(
1 * xshape[0] * space_dimension * reference_value_size);
impl::mdspan_t<const geometry_type, 4> basis_derivatives_reference_values(
basis_derivatives_reference_values_b.data(), 1, xshape[0],
space_dimension, reference_value_size);
std::vector<geometry_type> basis_values_b(space_dimension * value_size);
impl::mdspan_t<geometry_type, 2> basis_values(basis_values_b.data(),
space_dimension, value_size);
// Compute basis on reference element
element->tabulate(basis_derivatives_reference_values_b, Xb,
{X.extent(0), X.extent(1)}, 0);
using xu_t = impl::mdspan_t<geometry_type, 2>;
using xU_t = impl::mdspan_t<const geometry_type, 2>;
using xJ_t = impl::mdspan_t<const geometry_type, 2>;
using xK_t = impl::mdspan_t<const geometry_type, 2>;
auto push_forward_fn
= element->basix_element().template map_fn<xu_t, xU_t, xJ_t, xK_t>();
// Transformation function for basis function values
auto apply_dof_transformation
= element->template dof_transformation_fn<geometry_type>(
doftransform::standard);
// Size of tensor for symmetric elements, unused in non-symmetric case, but
// placed outside the loop for pre-computation.
int matrix_size;
if (element->symmetric())
{
matrix_size = 0;
while (matrix_size * matrix_size < (int)ushape[1])
++matrix_size;
}
const std::size_t num_basis_values = space_dimension * reference_value_size;
for (std::size_t p = 0; p < cells.size(); ++p)
{
const int cell_index = cells[p];
if (cell_index < 0) // Skip negative cell indices
continue;
// Permute the reference basis function values to account for the
// cell's orientation
apply_dof_transformation(
std::span(basis_derivatives_reference_values_b.data()
+ p * num_basis_values,
num_basis_values),
cell_info, cell_index, reference_value_size);
{
auto _U = md::submdspan(basis_derivatives_reference_values, 0, p,
md::full_extent, md::full_extent);
auto _J = md::submdspan(J, p, md::full_extent, md::full_extent);
auto _K = md::submdspan(K, p, md::full_extent, md::full_extent);
push_forward_fn(basis_values, _U, _J, detJ[p], _K);
}
// Get degrees of freedom for current cell
std::span<const std::int32_t> dofs = dofmap->cell_dofs(cell_index);
for (std::size_t i = 0; i < dofs.size(); ++i)
for (int k = 0; k < bs_dof; ++k)
coefficients[bs_dof * i + k] = _v[bs_dof * dofs[i] + k];
if (element->symmetric())
{
int row = 0;
int rowstart = 0;
// Compute expansion
for (int k = 0; k < bs_element; ++k)
{
if (k - rowstart > row)
{
row++;
rowstart = k;
}
for (std::size_t i = 0; i < space_dimension; ++i)
{
for (std::size_t j = 0; j < value_size; ++j)
{
u[p * ushape[1]
+ (j * bs_element + row * matrix_size + k - rowstart)]
+= coefficients[bs_element * i + k] * basis_values(i, j);
if (k - rowstart != row)
{
u[p * ushape[1]
+ (j * bs_element + row + matrix_size * (k - rowstart))]
+= coefficients[bs_element * i + k] * basis_values(i, j);
}
}
}
}
}
else
{
// Compute expansion
for (int k = 0; k < bs_element; ++k)
{
for (std::size_t i = 0; i < space_dimension; ++i)
{
for (std::size_t j = 0; j < value_size; ++j)
{
u[p * ushape[1] + (j * bs_element + k)]
+= coefficients[bs_element * i + k] * basis_values(i, j);
}
}
}
}
}
}
std::string name = "u";
private:
// Function space
std::shared_ptr<const FunctionSpace<geometry_type>> _function_space;
// Vector of expansion coefficients (local)
std::shared_ptr<la::Vector<value_type>> _x;
};
} // namespace dolfinx::fem
DofMap.h
Degree-of-freedom map representations and tools.
assembler.h
Functions supporting assembly of finite element fem::Form and fem::Expression.
dolfinx::fem::CoordinateElement
Definition CoordinateElement.h:38
dolfinx::fem::CoordinateElement::compute_jacobian
static void compute_jacobian(const U &dphi, const V &cell_geometry, W &&J)
Definition CoordinateElement.h:133
dolfinx::fem::CoordinateElement::tabulate
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:55
dolfinx::fem::CoordinateElement::compute_jacobian_inverse
static void compute_jacobian_inverse(const U &J, V &&K)
Compute the inverse of the Jacobian.
Definition CoordinateElement.h:142
dolfinx::fem::CoordinateElement::tabulate_shape
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:48
dolfinx::fem::CoordinateElement::dim
int dim() const
The dimension of the coordinate element space.
Definition CoordinateElement.cpp:205
dolfinx::fem::CoordinateElement::pull_back_nonaffine
void pull_back_nonaffine(mdspan2_t< T > X, mdspan2_t< const T > x, mdspan2_t< const T > cell_geometry, double tol=1.0e-6, int maxit=15) const
Compute reference coordinates X for physical coordinates x for a non-affine map.
Definition CoordinateElement.cpp:83
dolfinx::fem::CoordinateElement::is_affine
bool is_affine() const noexcept
Definition CoordinateElement.h:266
dolfinx::fem::CoordinateElement::compute_jacobian_determinant
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
dolfinx::fem::CoordinateElement::pull_back_affine
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
dolfinx::fem::Expression
An Expression represents a mathematical expression evaluated at a pre-defined points on a reference c...
Definition Expression.h:41
dolfinx::fem::Expression::X
std::pair< std::vector< geometry_type >, std::array< std::size_t, 2 > > X() const
Evaluation point coordinates on the reference cell.
Definition Expression.h:166
dolfinx::fem::Expression::coefficients
const std::vector< std::shared_ptr< const Function< scalar_type, geometry_type > > > & coefficients() const
Expression coefficients.
Definition Expression.h:115
dolfinx::fem::Expression::argument_space
std::shared_ptr< const FunctionSpace< geometry_type > > argument_space() const
Argument function space.
Definition Expression.h:106
dolfinx::fem::Expression::value_size
int value_size() const
Value size of the Expression result.
Definition Expression.h:156
dolfinx::fem::FunctionSpace
This class represents a finite element function space defined by a mesh, a finite element,...
Definition FunctionSpace.h:34
dolfinx::fem::Function
Definition Function.h:47
dolfinx::fem::Function::geometry_type
U geometry_type
Geometry type of the Mesh that the Function is defined on.
Definition Function.h:53
dolfinx::fem::Function::interpolate
void interpolate(const Function< value_type, geometry_type > &u)
Interpolate a Function over all cells.
Definition Function.h:237
dolfinx::fem::Function::function_space
std::shared_ptr< const FunctionSpace< geometry_type > > function_space() const
Access the function space.
Definition Function.h:144
dolfinx::fem::Function::interpolate
void interpolate(const Function< value_type, geometry_type > &v, std::span< const std::int32_t > cells, const geometry::PointOwnershipData< U > &interpolation_data)
Interpolate a Function defined on a different mesh.
Definition Function.h:415
dolfinx::fem::Function::interpolate
void interpolate(const Expression< value_type, geometry_type > &e0, std::span< const std::int32_t > cells0, std::span< const std::int32_t > cells1={})
Interpolate an Expression over a subset of cells.
Definition Function.h:307
dolfinx::fem::Function::Function
Function(std::shared_ptr< const FunctionSpace< geometry_type > > V)
Create function on given function space.
Definition Function.h:57
dolfinx::fem::Function::interpolate
void interpolate(const Function< value_type, geometry_type > &u0, std::span< const std::int32_t > cells0, std::span< const std::int32_t > cells1={})
Interpolate a Function over a subset of cells.
Definition Function.h:265
dolfinx::fem::Function::collapse
Function collapse() const
Collapse a subfunction (view into a Function) to a stand-alone Function.
Definition Function.h:119
dolfinx::fem::Function::interpolate
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:157
dolfinx::fem::Function::sub
Function sub(int i) const
Extract a sub-function (a view into the Function).
Definition Function.h:108
dolfinx::fem::Function::interpolate
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, std::span< const std::int32_t > cells)
Interpolate an expression f(x) over a set of cells.
Definition Function.h:176
dolfinx::fem::Function::name
std::string name
Name.
Definition Function.h:723
dolfinx::fem::Function::x
std::shared_ptr< la::Vector< value_type > > x()
Underlying vector.
Definition Function.h:153
dolfinx::fem::Function::interpolate
void interpolate(const Expression< value_type, geometry_type > &e)
Interpolate an Expression on all cells.
Definition Function.h:279
dolfinx::fem::Function::~Function
~Function()=default
Destructor.
dolfinx::fem::Function::eval
void eval(std::span< const geometry_type > x, std::array< std::size_t, 2 > xshape, std::span< const std::int32_t > cells, std::span< value_type > u, std::array< std::size_t, 2 > ushape) const
Evaluate the Function at points.
Definition Function.h:434
dolfinx::fem::Function::Function
Function(Function &&v)=default
Move constructor.
dolfinx::fem::Function::x
std::shared_ptr< const la::Vector< value_type > > x() const
Underlying vector (const version).
Definition Function.h:150
dolfinx::fem::Function::operator=
Function & operator=(Function &&v)=default
Move assignment.
dolfinx::fem::Function::Function
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:77
dolfinx::fem::Function::value_type
T value_type
Definition Function.h:51
dolfinx::la::Vector
A vector that can be distributed across processes.
Definition Vector.h:50
dolfinx::mesh::Mesh
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition Mesh.h:23
dolfinx::fem
Finite element method functionality.
Definition assemble_expression_impl.h:23
dolfinx::fem::tabulate_expression
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:64
dolfinx::fem::interpolate
void interpolate(Function< T, U > &u, std::span< const T > f, std::array< std::size_t, 2 > fshape, std::span< const std::int32_t > cells)
Interpolate an evaluated expression f(x) in a finite element space.
Definition interpolate.h:1056
dolfinx::fem::doftransform::standard
@ standard
Standard.
Definition FiniteElement.h:27
dolfinx::fem::interpolation_coords
std::vector< T > interpolation_coords(const fem::FiniteElement< T > &element, const mesh::Geometry< T > &geometry, std::span< const std::int32_t > cells)
Compute the evaluation points in the physical space at which an expression should be computed to inte...
Definition interpolate.h:51
dolfinx::la
Linear algebra interface.
Definition sparsitybuild.h:15
dolfinx::mesh
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32
dolfinx::geometry::PointOwnershipData
Information on the ownership of points distributed across processes.
Definition utils.h:30