Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/dolfinx/v0.9.0/cpp/doxygen/df/df5/Function_8h_source.html
DOLFINx 0.7.3
DOLFINx C++ interface
Loading...
Searching...
No Matches
Function.h
1// Copyright (C) 2003-2022 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 "interpolate.h"
13#include <concepts>
14#include <dolfinx/common/IndexMap.h>
15#include <dolfinx/common/types.h>
16#include <dolfinx/la/Vector.h>
17#include <dolfinx/mesh/Geometry.h>
18#include <dolfinx/mesh/Mesh.h>
19#include <dolfinx/mesh/Topology.h>
20#include <functional>
21#include <memory>
22#include <numeric>
23#include <span>
24#include <string>
25#include <utility>
26#include <vector>
27
28namespace dolfinx::fem
29{
30template <dolfinx::scalar T, std::floating_point U>
31class Expression;
32
42template <dolfinx::scalar T,
43 std::floating_point U = dolfinx::scalar_value_type_t<T>>
45{
46public:
49 using value_type = T;
51 using geometry_type = U;
52
55 explicit Function(std::shared_ptr<const FunctionSpace<U>> V)
56 : _function_space(V),
57 _x(std::make_shared<la::Vector<T>>(V->dofmap()->index_map,
58 V->dofmap()->index_map_bs()))
59 {
60 if (!V->component().empty())
61 {
62 throw std::runtime_error("Cannot create Function from subspace. Consider "
63 "collapsing the function space");
64 }
65 }
66
75 Function(std::shared_ptr<const FunctionSpace<U>> V,
76 std::shared_ptr<la::Vector<T>> x)
77 : _function_space(V), _x(x)
78 {
79 // We do not check for a subspace since this constructor is used for
80 // creating subfunctions
81
82 // Assertion uses '<=' to deal with sub-functions
83 assert(V->dofmap());
84 assert(V->dofmap()->index_map->size_global() * V->dofmap()->index_map_bs()
85 <= _x->bs() * _x->index_map()->size_global());
86 }
87
88 // Copy constructor
89 Function(const Function& v) = delete;
90
92 Function(Function&& v) = default;
93
95 ~Function() = default;
96
98 Function& operator=(Function&& v) = default;
99
100 // Assignment
101 Function& operator=(const Function& v) = delete;
102
106 Function sub(int i) const
107 {
108 auto sub_space = _function_space->sub({i});
109 assert(sub_space);
110 return Function(sub_space, _x);
111 }
112
117 {
118 // Create new collapsed FunctionSpace
119 auto [V, map] = _function_space->collapse();
120
121 // Create new vector
122 auto x = std::make_shared<la::Vector<T>>(V.dofmap()->index_map,
123 V.dofmap()->index_map_bs());
124
125 // Copy values into new vector
126 std::span<const T> x_old = _x->array();
127 std::span<T> x_new = x->mutable_array();
128 for (std::size_t i = 0; i < map.size(); ++i)
129 {
130 assert((int)i < x_new.size());
131 assert(map[i] < x_old.size());
132 x_new[i] = x_old[map[i]];
133 }
134
135 return Function(std::make_shared<FunctionSpace<U>>(std::move(V)), x);
136 }
137
140 std::shared_ptr<const FunctionSpace<U>> function_space() const
141 {
142 return _function_space;
143 }
144
146 std::shared_ptr<const la::Vector<T>> x() const { return _x; }
147
149 std::shared_ptr<la::Vector<T>> x() { return _x; }
150
158 const Function<T, U>& v, std::span<const std::int32_t> cells,
159 const std::tuple<std::vector<std::int32_t>, std::vector<std::int32_t>,
160 std::vector<U>, std::vector<std::int32_t>>&
161 nmm_interpolation_data
162 = {})
163 {
164 fem::interpolate(*this, v, cells, nmm_interpolation_data);
165 }
166
173 const Function<T, U>& v,
174 const std::tuple<std::vector<std::int32_t>, std::vector<std::int32_t>,
175 std::vector<U>, std::vector<std::int32_t>>&
176 nmm_interpolation_data
177 = {})
178 {
179 assert(_function_space);
180 assert(_function_space->mesh());
181 int tdim = _function_space->mesh()->topology()->dim();
182 auto cell_map = _function_space->mesh()->topology()->index_map(tdim);
183 assert(cell_map);
184 std::int32_t num_cells = cell_map->size_local() + cell_map->num_ghosts();
185 std::vector<std::int32_t> cells(num_cells, 0);
186 std::iota(cells.begin(), cells.end(), 0);
187 interpolate(v, cells, nmm_interpolation_data);
188 }
189
194 const std::function<std::pair<std::vector<T>, std::vector<std::size_t>>(
195 MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
196 const U, MDSPAN_IMPL_STANDARD_NAMESPACE::extents<
197 std::size_t, 3,
198 MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent>>)>&
199 f,
200 std::span<const std::int32_t> cells)
201 {
202 assert(_function_space);
203 assert(_function_space->element());
204 assert(_function_space->mesh());
205 const std::vector<U> x = fem::interpolation_coords<U>(
206 *_function_space->element(), _function_space->mesh()->geometry(),
207 cells);
208 MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
209 const U,
210 MDSPAN_IMPL_STANDARD_NAMESPACE::extents<
211 std::size_t, 3, MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent>>
212 _x(x.data(), 3, x.size() / 3);
213
214 const auto [fx, fshape] = f(_x);
215 assert(fshape.size() <= 2);
216 if (int vs = _function_space->element()->value_size();
217 vs == 1 and fshape.size() == 1)
218 {
219 // Check for scalar-valued functions
220 if (fshape.front() != x.size() / 3)
221 throw std::runtime_error("Data returned by callable has wrong length");
222 }
223 else
224 {
225 // Check for vector/tensor value
226 if (fshape.size() != 2)
227 throw std::runtime_error("Expected 2D array of data");
228
229 if (fshape[0] != vs)
230 {
231 throw std::runtime_error(
232 "Data returned by callable has wrong shape(0) size");
233 }
234
235 if (fshape[1] != x.size() / 3)
236 {
237 throw std::runtime_error(
238 "Data returned by callable has wrong shape(1) size");
239 }
240 }
241
242 std::array<std::size_t, 2> _fshape;
243 if (fshape.size() == 1)
244 _fshape = {1, fshape[0]};
245 else
246 _fshape = {fshape[0], fshape[1]};
247
248 fem::interpolate(*this, std::span<const T>(fx.data(), fx.size()), _fshape,
249 cells);
250 }
251
255 const std::function<std::pair<std::vector<T>, std::vector<std::size_t>>(
256 MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
257 const U, MDSPAN_IMPL_STANDARD_NAMESPACE::extents<
258 std::size_t, 3,
259 MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent>>)>&
260 f)
261 {
262 assert(_function_space);
263 assert(_function_space->mesh());
264 const int tdim = _function_space->mesh()->topology()->dim();
265 auto cell_map = _function_space->mesh()->topology()->index_map(tdim);
266 assert(cell_map);
267 std::int32_t num_cells = cell_map->size_local() + cell_map->num_ghosts();
268 std::vector<std::int32_t> cells(num_cells, 0);
269 std::iota(cells.begin(), cells.end(), 0);
270 interpolate(f, cells);
271 }
272
280 std::span<const std::int32_t> cells)
281 {
282 // Check that spaces are compatible
283 assert(_function_space);
284 assert(_function_space->element());
285 std::size_t value_size = e.value_size();
287 throw std::runtime_error("Cannot interpolate Expression with Argument");
288
289 if (value_size != _function_space->element()->value_size())
290 {
291 throw std::runtime_error(
292 "Function value size not equal to Expression value size");
293 }
294
295 {
296 // Compatibility check
297 auto [X0, shape0] = e.X();
298 auto [X1, shape1] = _function_space->element()->interpolation_points();
299 if (shape0 != shape1)
300 {
301 throw std::runtime_error(
302 "Function element interpolation points has different shape to "
303 "Expression interpolation points");
304 }
305
306 for (std::size_t i = 0; i < X0.size(); ++i)
307 {
308 if (std::abs(X0[i] - X1[i]) > 1.0e-10)
309 {
310 throw std::runtime_error("Function element interpolation points not "
311 "equal to Expression interpolation points");
312 }
313 }
314 }
315
316 // Array to hold evaluated Expression
317 std::size_t num_cells = cells.size();
318 std::size_t num_points = e.X().second[0];
319 std::vector<T> fdata(num_cells * num_points * value_size);
320 MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
321 const T, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 3>>
322 f(fdata.data(), num_cells, num_points, value_size);
323
324 // Evaluate Expression at points
325 assert(_function_space->mesh());
326 e.eval(*_function_space->mesh(), cells, fdata,
327 {num_cells, num_points * value_size});
328
329 // Reshape evaluated data to fit interpolate
330 // Expression returns matrix of shape (num_cells, num_points *
331 // value_size), i.e. xyzxyz ordering of dof values per cell per
332 // point. The interpolation uses xxyyzz input, ordered for all
333 // points of each cell, i.e. (value_size, num_cells*num_points)
334 std::vector<T> fdata1(num_cells * num_points * value_size);
335 MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
336 T, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 3>>
337 f1(fdata1.data(), value_size, num_cells, num_points);
338 for (std::size_t i = 0; i < f.extent(0); ++i)
339 for (std::size_t j = 0; j < f.extent(1); ++j)
340 for (std::size_t k = 0; k < f.extent(2); ++k)
341 f1(k, i, j) = f(i, j, k);
342
343 // Interpolate values into appropriate space
344 fem::interpolate(*this, std::span<const T>(fdata1.data(), fdata1.size()),
345 {value_size, num_cells * num_points}, cells);
346 }
347
351 {
352 assert(_function_space);
353 assert(_function_space->mesh());
354 const int tdim = _function_space->mesh()->topology()->dim();
355 auto cell_map = _function_space->mesh()->topology()->index_map(tdim);
356 assert(cell_map);
357 std::int32_t num_cells = cell_map->size_local() + cell_map->num_ghosts();
358 std::vector<std::int32_t> cells(num_cells, 0);
359 std::iota(cells.begin(), cells.end(), 0);
360 interpolate(e, cells);
361 }
362
375 void eval(std::span<const U> x, std::array<std::size_t, 2> xshape,
376 std::span<const std::int32_t> cells, std::span<T> u,
377 std::array<std::size_t, 2> ushape) const
378 {
379 if (cells.empty())
380 return;
381
382 assert(x.size() == xshape[0] * xshape[1]);
383 assert(u.size() == ushape[0] * ushape[1]);
384
385 // TODO: This could be easily made more efficient by exploiting points
386 // being ordered by the cell to which they belong.
387
388 if (xshape[0] != cells.size())
389 {
390 throw std::runtime_error(
391 "Number of points and number of cells must be equal.");
392 }
393
394 if (xshape[0] != ushape[0])
395 {
396 throw std::runtime_error(
397 "Length of array for Function values must be the "
398 "same as the number of points.");
399 }
400
401 // Get mesh
402 assert(_function_space);
403 auto mesh = _function_space->mesh();
404 assert(mesh);
405 const std::size_t gdim = mesh->geometry().dim();
406 const std::size_t tdim = mesh->topology()->dim();
407 auto map = mesh->topology()->index_map(tdim);
408
409 // Get coordinate map
410 if (mesh->geometry().cmaps().size() > 1)
411 {
412 throw std::runtime_error(
413 "Function with multiple geometry maps not implemented.");
414 }
415 const CoordinateElement<U>& cmap = mesh->geometry().cmaps()[0];
416
417 // Get geometry data
418 auto x_dofmap = mesh->geometry().dofmap();
419 const std::size_t num_dofs_g = cmap.dim();
420 std::span<const U> x_g = mesh->geometry().x();
421
422 // Get element
423 auto element = _function_space->element();
424 assert(element);
425 const int bs_element = element->block_size();
426 const std::size_t reference_value_size
427 = element->reference_value_size() / bs_element;
428 const std::size_t value_size = element->value_size() / bs_element;
429 const std::size_t space_dimension = element->space_dimension() / bs_element;
430
431 // If the space has sub elements, concatenate the evaluations on the
432 // sub elements
433 const int num_sub_elements = element->num_sub_elements();
434 if (num_sub_elements > 1 and num_sub_elements != bs_element)
435 {
436 throw std::runtime_error("Function::eval is not supported for mixed "
437 "elements. Extract subspaces.");
438 }
439
440 // Create work vector for expansion coefficients
441 std::vector<T> coefficients(space_dimension * bs_element);
442
443 // Get dofmap
444 std::shared_ptr<const DofMap> dofmap = _function_space->dofmap();
445 assert(dofmap);
446 const int bs_dof = dofmap->bs();
447
448 std::span<const std::uint32_t> cell_info;
449 if (element->needs_dof_transformations())
450 {
451 mesh->topology_mutable()->create_entity_permutations();
452 cell_info = std::span(mesh->topology()->get_cell_permutation_info());
453 }
454
455 using cmdspan4_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
456 const U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 4>>;
457 using mdspan2_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
458 U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>;
459 using mdspan3_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
460 U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 3>>;
461
462 std::vector<U> coord_dofs_b(num_dofs_g * gdim);
463 mdspan2_t coord_dofs(coord_dofs_b.data(), num_dofs_g, gdim);
464 std::vector<U> xp_b(1 * gdim);
465 mdspan2_t xp(xp_b.data(), 1, gdim);
466
467 // Loop over points
468 std::fill(u.data(), u.data() + u.size(), 0.0);
469 std::span<const T> _v = _x->array();
470
471 // Evaluate geometry basis at point (0, 0, 0) on the reference cell.
472 // Used in affine case.
473 std::array<std::size_t, 4> phi0_shape = cmap.tabulate_shape(1, 1);
474 std::vector<U> phi0_b(std::reduce(phi0_shape.begin(), phi0_shape.end(), 1,
475 std::multiplies{}));
476 cmdspan4_t phi0(phi0_b.data(), phi0_shape);
477 cmap.tabulate(1, std::vector<U>(tdim), {1, tdim}, phi0_b);
478 auto dphi0
479 = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
480 submdspan(phi0, std::pair(1, tdim + 1), 0,
481 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent, 0);
482
483 // Data structure for evaluating geometry basis at specific points.
484 // Used in non-affine case.
485 std::array<std::size_t, 4> phi_shape = cmap.tabulate_shape(1, 1);
486 std::vector<U> phi_b(
487 std::reduce(phi_shape.begin(), phi_shape.end(), 1, std::multiplies{}));
488 cmdspan4_t phi(phi_b.data(), phi_shape);
489 auto dphi = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
490 submdspan(phi, std::pair(1, tdim + 1), 0,
491 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent, 0);
492
493 // Reference coordinates for each point
494 std::vector<U> Xb(xshape[0] * tdim);
495 mdspan2_t X(Xb.data(), xshape[0], tdim);
496
497 // Geometry data at each point
498 std::vector<U> J_b(xshape[0] * gdim * tdim);
499 mdspan3_t J(J_b.data(), xshape[0], gdim, tdim);
500 std::vector<U> K_b(xshape[0] * tdim * gdim);
501 mdspan3_t K(K_b.data(), xshape[0], tdim, gdim);
502 std::vector<U> detJ(xshape[0]);
503 std::vector<U> det_scratch(2 * gdim * tdim);
504
505 // Prepare geometry data in each cell
506 for (std::size_t p = 0; p < cells.size(); ++p)
507 {
508 const int cell_index = cells[p];
509
510 // Skip negative cell indices
511 if (cell_index < 0)
512 continue;
513
514 // Get cell geometry (coordinate dofs)
515 auto x_dofs
516 = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
517 submdspan(x_dofmap, cell_index,
518 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
519 assert(x_dofs.size() == num_dofs_g);
520 for (std::size_t i = 0; i < num_dofs_g; ++i)
521 {
522 const int pos = 3 * x_dofs[i];
523 for (std::size_t j = 0; j < gdim; ++j)
524 coord_dofs(i, j) = x_g[pos + j];
525 }
526
527 for (std::size_t j = 0; j < gdim; ++j)
528 xp(0, j) = x[p * xshape[1] + j];
529
530 auto _J = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
531 submdspan(J, p, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent,
532 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
533 auto _K = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
534 submdspan(K, p, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent,
535 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
536
537 std::array<U, 3> Xpb = {0, 0, 0};
538 MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
539 U,
540 MDSPAN_IMPL_STANDARD_NAMESPACE::extents<
541 std::size_t, 1, MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent>>
542 Xp(Xpb.data(), 1, tdim);
543
544 // Compute reference coordinates X, and J, detJ and K
545 if (cmap.is_affine())
546 {
547 CoordinateElement<U>::compute_jacobian(dphi0, coord_dofs, _J);
549 std::array<U, 3> x0 = {0, 0, 0};
550 for (std::size_t i = 0; i < coord_dofs.extent(1); ++i)
551 x0[i] += coord_dofs(0, i);
554 _J, det_scratch);
555 }
556 else
557 {
558 // Pull-back physical point xp to reference coordinate Xp
559 cmap.pull_back_nonaffine(Xp, xp, coord_dofs);
560
561 cmap.tabulate(1, std::span(Xpb.data(), tdim), {1, tdim}, phi_b);
562 CoordinateElement<U>::compute_jacobian(dphi, coord_dofs, _J);
565 _J, det_scratch);
566 }
567
568 for (std::size_t j = 0; j < X.extent(1); ++j)
569 X(p, j) = Xpb[j];
570 }
571
572 // Prepare basis function data structures
573 std::vector<U> basis_derivatives_reference_values_b(
574 1 * xshape[0] * space_dimension * reference_value_size);
575 cmdspan4_t basis_derivatives_reference_values(
576 basis_derivatives_reference_values_b.data(), 1, xshape[0],
577 space_dimension, reference_value_size);
578 std::vector<U> basis_values_b(space_dimension * value_size);
579 mdspan2_t basis_values(basis_values_b.data(), space_dimension, value_size);
580
581 // Compute basis on reference element
582 element->tabulate(basis_derivatives_reference_values_b, Xb,
583 {X.extent(0), X.extent(1)}, 0);
584
585 using xu_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
586 U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>;
587 using xU_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
588 const U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>;
589 using xJ_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
590 const U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>;
591 using xK_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
592 const U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>;
593 auto push_forward_fn
594 = element->basix_element().template map_fn<xu_t, xU_t, xJ_t, xK_t>();
595
596 auto apply_dof_transformation
597 = element->template get_dof_transformation_function<U>();
598 const std::size_t num_basis_values = space_dimension * reference_value_size;
599
600 for (std::size_t p = 0; p < cells.size(); ++p)
601 {
602 const int cell_index = cells[p];
603
604 // Skip negative cell indices
605 if (cell_index < 0)
606 continue;
607
608 // Permute the reference values to account for the cell's
609 // orientation
610 apply_dof_transformation(
611 std::span(basis_derivatives_reference_values_b.data()
612 + p * num_basis_values,
613 num_basis_values),
614 cell_info, cell_index, reference_value_size);
615
616 {
617 auto _U
618 = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
619 submdspan(basis_derivatives_reference_values, 0, p,
620 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent,
621 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
622 auto _J
623 = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
624 submdspan(J, p, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent,
625 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
626 auto _K
627 = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
628 submdspan(K, p, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent,
629 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
630 push_forward_fn(basis_values, _U, _J, detJ[p], _K);
631 }
632
633 // Get degrees of freedom for current cell
634 std::span<const std::int32_t> dofs = dofmap->cell_dofs(cell_index);
635 for (std::size_t i = 0; i < dofs.size(); ++i)
636 for (int k = 0; k < bs_dof; ++k)
637 coefficients[bs_dof * i + k] = _v[bs_dof * dofs[i] + k];
638
639 // Compute expansion
640 using X = typename dolfinx::scalar_value_type_t<T>;
641 for (int k = 0; k < bs_element; ++k)
642 {
643 for (std::size_t i = 0; i < space_dimension; ++i)
644 {
645 for (std::size_t j = 0; j < value_size; ++j)
646 {
647 u[p * ushape[1] + (j * bs_element + k)]
648 += coefficients[bs_element * i + k]
649 * static_cast<X>(basis_values(i, j));
650 }
651 }
652 }
653 }
654 }
655
657 std::string name = "u";
658
659private:
660 // The function space
661 std::shared_ptr<const FunctionSpace<U>> _function_space;
662
663 // The vector of expansion coefficients (local)
664 std::shared_ptr<la::Vector<T>> _x;
665};
666
667} // namespace dolfinx::fem
Degree-of-freedom map representations and tools.
A CoordinateElement manages coordinate mappings for isoparametric cells.
Definition CoordinateElement.h:39
static void compute_jacobian(const U &dphi, const V &cell_geometry, W &&J)
Compute Jacobian for a cell with given geometry using the basis functions and first order derivatives...
Definition CoordinateElement.h:106
static void pull_back_affine(U &&X, const V &K, const 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:189
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:53
static void compute_jacobian_inverse(const U &J, V &&K)
Compute the inverse of the Jacobian.
Definition CoordinateElement.h:115
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:46
int dim() const
The dimension of the coordinate element space.
Definition CoordinateElement.cpp:193
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:70
bool is_affine() const noexcept
Check is geometry map is affine.
Definition CoordinateElement.h:243
static double compute_jacobian_determinant(const U &J, std::span< typename U::value_type > w)
Compute the determinant of the Jacobian.
Definition CoordinateElement.h:132
Represents a mathematical expression evaluated at a pre-defined set of points on the reference cell.
Definition Expression.h:41
void eval(const mesh::Mesh< geometry_type > &mesh, std::span< const std::int32_t > cells, std::span< scalar_type > values, std::array< std::size_t, 2 > vshape) const
Evaluate Expression on cells.
Definition Expression.h:151
std::pair< std::vector< geometry_type >, std::array< std::size_t, 2 > > X() const
Evaluation points on the reference cell.
Definition Expression.h:251
int value_size() const
Get value size.
Definition Expression.h:239
std::shared_ptr< const FunctionSpace< geometry_type > > argument_function_space() const
Get argument function space.
Definition Expression.h:103
This class represents a finite element function space defined by a mesh, a finite element,...
Definition FunctionSpace.h:35
This class represents a function in a finite element function space , given by.
Definition Function.h:45
U geometry_type
Geometry type of the Mesh that the Function is defined on.
Definition Function.h:51
void interpolate(const Expression< T, U > &e, std::span< const std::int32_t > cells)
Interpolate an Expression (based on UFL)
Definition Function.h:279
void interpolate(const std::function< std::pair< std::vector< T >, std::vector< std::size_t > >(MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const U, MDSPAN_IMPL_STANDARD_NAMESPACE::extents< std::size_t, 3, MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent > >)> &f)
Interpolate an expression function on the whole domain.
Definition Function.h:254
void interpolate(const std::function< std::pair< std::vector< T >, std::vector< std::size_t > >(MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const U, MDSPAN_IMPL_STANDARD_NAMESPACE::extents< std::size_t, 3, MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent > >)> &f, std::span< const std::int32_t > cells)
Interpolate an expression function on a list of cells.
Definition Function.h:193
void eval(std::span< const U > x, std::array< std::size_t, 2 > xshape, std::span< const std::int32_t > cells, std::span< T > u, std::array< std::size_t, 2 > ushape) const
Evaluate the Function at points.
Definition Function.h:375
Function collapse() const
Collapse a subfunction (view into a Function) to a stand-alone Function.
Definition Function.h:116
Function sub(int i) const
Extract sub-function (a view into the Function).
Definition Function.h:106
Function(std::shared_ptr< const FunctionSpace< U > > V, std::shared_ptr< la::Vector< T > > x)
Create function on given function space with a given vector.
Definition Function.h:75
Function(std::shared_ptr< const FunctionSpace< U > > V)
Create function on given function space.
Definition Function.h:55
std::string name
Name.
Definition Function.h:657
void interpolate(const Function< T, U > &v, std::span< const std::int32_t > cells, const std::tuple< std::vector< std::int32_t >, std::vector< std::int32_t >, std::vector< U >, std::vector< std::int32_t > > &nmm_interpolation_data={})
Interpolate a provided Function.
Definition Function.h:157
std::shared_ptr< const FunctionSpace< U > > function_space() const
Access the function space.
Definition Function.h:140
void interpolate(const Expression< T, U > &e)
Interpolate an Expression (based on UFL) on all cells.
Definition Function.h:350
std::shared_ptr< la::Vector< T > > x()
Underlying vector.
Definition Function.h:149
std::shared_ptr< const la::Vector< T > > x() const
Underlying vector.
Definition Function.h:146
~Function()=default
Destructor.
void interpolate(const Function< T, U > &v, const std::tuple< std::vector< std::int32_t >, std::vector< std::int32_t >, std::vector< U >, std::vector< std::int32_t > > &nmm_interpolation_data={})
Interpolate a provided Function.
Definition Function.h:172
Function(Function &&v)=default
Move constructor.
Function & operator=(Function &&v)=default
Move assignment.
T value_type
Field type for the Function, e.g. double, std::complex<float>, etc.
Definition Function.h:49
Distributed vector.
Definition Vector.h:31
This concept is used to constrain the a template type to floating point real or complex types....
Definition types.h:20
Finite element method functionality.
Definition assemble_matrix_impl.h:25
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 expression f(x) in a finite element space.
Definition interpolate.h:748