174 if (!_component.empty())
176 throw std::runtime_error(
"Cannot tabulate coordinates for a "
177 "FunctionSpace that is a subspace.");
181 if (_element->is_mixed())
183 throw std::runtime_error(
184 "Cannot tabulate coordinates for a mixed FunctionSpace.");
190 const std::size_t gdim = _mesh->geometry().dim();
191 const int tdim = _mesh->topology()->dim();
195 std::shared_ptr<const common::IndexMap> index_map = _dofmap->index_map;
197 const int index_map_bs = _dofmap->index_map_bs();
198 const int dofmap_bs = _dofmap->bs();
200 const int element_block_size = _element->block_size();
201 const std::size_t scalar_dofs
202 = _element->space_dimension() / element_block_size;
203 const std::int32_t num_dofs
204 = index_map_bs * (index_map->size_local() + index_map->num_ghosts())
208 if (!_element->interpolation_ident())
210 throw std::runtime_error(
"Cannot evaluate dof coordinates - this element "
211 "does not have pointwise evaluation.");
213 const auto [X, Xshape] = _element->interpolation_points();
216 if (_mesh->geometry().cmaps().size() > 1)
217 throw std::runtime_error(
"Mixed topology not supported");
221 auto x_dofmap = _mesh->geometry().dofmap();
222 const std::size_t num_dofs_g = cmap.
dim();
223 std::span<const T> x_g = _mesh->geometry().x();
226 const std::size_t shape_c0 = transpose ? 3 : num_dofs;
227 const std::size_t shape_c1 = transpose ? num_dofs : 3;
228 std::vector<T> coords(shape_c0 * shape_c1, 0);
230 using mdspan2_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
231 T, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>;
232 using cmdspan4_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
233 const T, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 4>>;
236 std::vector<T> x_b(scalar_dofs * gdim);
237 mdspan2_t x(x_b.data(), scalar_dofs, gdim);
239 std::vector<T> coordinate_dofs_b(num_dofs_g * gdim);
240 mdspan2_t coordinate_dofs(coordinate_dofs_b.data(), num_dofs_g, gdim);
242 auto map = _mesh->topology()->index_map(tdim);
244 const int num_cells = map->size_local() + map->num_ghosts();
246 std::span<const std::uint32_t> cell_info;
247 if (_element->needs_dof_transformations())
249 _mesh->topology_mutable()->create_entity_permutations();
250 cell_info = std::span(_mesh->topology()->get_cell_permutation_info());
253 auto apply_dof_transformation
254 = _element->template get_dof_transformation_function<T>();
256 const std::array<std::size_t, 4> phi_shape
258 std::vector<T> phi_b(
259 std::reduce(phi_shape.begin(), phi_shape.end(), 1, std::multiplies{}));
260 cmdspan4_t phi_full(phi_b.data(), phi_shape);
262 auto phi = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
263 submdspan(phi_full, 0, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent,
264 MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent, 0);
266 for (
int c = 0; c < num_cells; ++c)
269 auto x_dofs = MDSPAN_IMPL_STANDARD_NAMESPACE::
270 MDSPAN_IMPL_PROPOSED_NAMESPACE::submdspan(
271 x_dofmap, c, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
272 for (std::size_t i = 0; i < x_dofs.size(); ++i)
273 for (std::size_t j = 0; j < gdim; ++j)
274 coordinate_dofs(i, j) = x_g[3 * x_dofs[i] + j];
278 apply_dof_transformation(
279 x_b, std::span(cell_info.data(), cell_info.size()), c, x.extent(1));
282 auto dofs = _dofmap->cell_dofs(c);
287 for (std::size_t i = 0; i < dofs.size(); ++i)
288 for (std::size_t j = 0; j < gdim; ++j)
289 coords[dofs[i] * 3 + j] = x(i, j);
293 for (std::size_t i = 0; i < dofs.size(); ++i)
294 for (std::size_t j = 0; j < gdim; ++j)
295 coords[j * num_dofs + dofs[i]] = x(i, j);