10#include <basix/mdspan.hpp> 
   13#include <dolfinx/common/IndexMap.h> 
   14#include <dolfinx/common/MPI.h> 
   15#include <dolfinx/common/sort.h> 
   16#include <dolfinx/fem/CoordinateElement.h> 
   17#include <dolfinx/fem/ElementDofLayout.h> 
   18#include <dolfinx/fem/dofmapbuilder.h> 
   19#include <dolfinx/graph/AdjacencyList.h> 
   20#include <dolfinx/graph/partition.h> 
   31template <std::
floating_po
int T>
 
   50  template <
typename U, 
typename V, 
typename W>
 
   51    requires std::is_convertible_v<std::remove_cvref_t<U>,
 
   52                                   std::vector<std::int32_t>>
 
   53                 and std::is_convertible_v<std::remove_cvref_t<V>,
 
   55                 and std::is_convertible_v<std::remove_cvref_t<W>,
 
   56                                           std::vector<std::int64_t>>
 
   61               std::remove_reference_t<typename V::value_type>>>& elements,
 
   64        _cmaps(elements), _x(std::forward<V>(
x)),
 
   67    assert(_x.size() % 3 == 0);
 
   68    if (_x.size() / 3 != _input_global_indices.size())
 
   69      throw std::runtime_error(
"Geometry size mis-match");
 
 
   88  int dim()
 const { 
return _dim; }
 
   91  MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
 
   93      MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>
 
   96    int ndofs = _cmaps[0].dim();
 
   97    return MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
 
   99        MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>(
 
  100        _dofmap.data(), _dofmap.size() / ndofs, ndofs);
 
 
  104  std::shared_ptr<const common::IndexMap> 
index_map()
 const 
 
  113  std::span<const value_type> 
x()
 const { 
return _x; }
 
  120  std::span<value_type> 
x() { 
return _x; }
 
  125  const std::vector<fem::CoordinateElement<value_type>>& 
cmaps()
 const 
 
  133    return _input_global_indices;
 
 
  141  std::vector<std::int32_t> _dofmap;
 
  144  std::shared_ptr<const common::IndexMap> _index_map;
 
  147  std::vector<fem::CoordinateElement<value_type>> _cmaps;
 
  151  std::vector<value_type> _x;
 
  154  std::vector<std::int64_t> _input_global_indices;
 
 
  180    MPI_Comm comm, 
const Topology& topology,
 
  182        std::remove_reference_t<typename U::value_type>>>& elements,
 
  191  std::vector<fem::ElementDofLayout> dof_layouts;
 
  192  for (
auto e : elements)
 
  193    dof_layouts.push_back(e.create_dof_layout());
 
  196  auto [_dof_index_map, bs, dofmap]
 
  199      = std::make_shared<common::IndexMap>(std::move(_dof_index_map));
 
  202  if (elements[0].needs_dof_permutations())
 
  204    if (elements.size() > 1)
 
  205      throw std::runtime_error(
"Unsupported for Mixed Topology");
 
  206    const int D = topology.
dim();
 
  207    const int num_cells = topology.
connectivity(D, 0)->num_nodes();
 
  208    const std::vector<std::uint32_t>& cell_info
 
  211    int dim = elements[0].dim();
 
  212    for (std::int32_t cell = 0; cell < num_cells; ++cell)
 
  214      std::span<std::int32_t> dofs(dofmap.data() + cell * dim, dim);
 
  215      elements[0].unpermute_dofs(dofs, cell_info[cell]);
 
  220      = [](
auto comm, 
auto& cell_nodes, 
auto& x, 
int dim, 
auto& dofmap)
 
  224    std::vector<std::int64_t> indices = cell_nodes.array();
 
  226    indices.erase(std::unique(indices.begin(), indices.end()), indices.end());
 
  243    std::vector<std::int64_t> igi(indices.size());
 
  244    std::transform(l2l.cbegin(), l2l.cend(), igi.begin(),
 
  245                   [&indices](
auto index) { return indices[index]; });
 
  247    return std::tuple(std::move(coords), std::move(l2l), std::move(igi));
 
  250  auto [coords, l2l, igi] = remap_data(comm, cell_nodes, x, dim, dofmap);
 
  254  assert(coords.size() % dim == 0);
 
  255  const std::size_t shape0 = coords.size() / dim;
 
  256  const std::size_t shape1 = dim;
 
  257  std::vector<typename std::remove_reference_t<typename U::value_type>> xg(
 
  259  for (std::size_t i = 0; i < shape0; ++i)
 
  261    std::copy_n(std::next(coords.cbegin(), shape1 * l2l[i]), shape1,
 
  262                std::next(xg.begin(), 3 * i));
 
  266      dof_index_map, std::move(dofmap), elements, std::move(xg), dim,
 
 
  278template <std::
floating_po
int T>
 
  279std::pair<mesh::Geometry<T>, std::vector<int32_t>>
 
  281                   int dim, std::span<const std::int32_t> subentity_to_entity)
 
  283  if (geometry.
cmaps().size() > 1)
 
  284    throw std::runtime_error(
"Mixed topology not supported");
 
  292  std::vector<std::int32_t> x_indices;
 
  293  x_indices.reserve(num_entity_dofs * subentity_to_entity.size());
 
  295    auto xdofs = geometry.
dofmap();
 
  296    const int tdim = topology.
dim();
 
  299    const std::vector<std::vector<std::vector<int>>>& closure_dofs
 
  305    for (std::size_t i = 0; i < subentity_to_entity.size(); ++i)
 
  307      const std::int32_t idx = subentity_to_entity[i];
 
  308      assert(!e_to_c->links(idx).empty());
 
  310      const std::int32_t cell = e_to_c->links(idx).back();
 
  311      auto cell_entities = c_to_e->links(cell);
 
  312      auto it = std::find(cell_entities.begin(), cell_entities.end(), idx);
 
  313      assert(it != cell_entities.end());
 
  314      std::size_t local_entity = std::distance(cell_entities.begin(), it);
 
  316      auto xc = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
 
  317          submdspan(xdofs, cell, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
 
  318      for (std::int32_t entity_dof : closure_dofs[dim][local_entity])
 
  319        x_indices.push_back(xc[entity_dof]);
 
  323  std::vector<std::int32_t> sub_x_dofs = x_indices;
 
  324  std::sort(sub_x_dofs.begin(), sub_x_dofs.end());
 
  325  sub_x_dofs.erase(std::unique(sub_x_dofs.begin(), sub_x_dofs.end()),
 
  331  auto subx_to_x_dofmap
 
  333  std::shared_ptr<common::IndexMap> sub_x_dof_index_map;
 
  335    std::pair<common::IndexMap, std::vector<int32_t>> map_data
 
  336        = x_index_map->create_submap(subx_to_x_dofmap);
 
  338        = std::make_shared<common::IndexMap>(std::move(map_data.first));
 
  341    subx_to_x_dofmap.reserve(sub_x_dof_index_map->size_local()
 
  342                             + sub_x_dof_index_map->num_ghosts());
 
  343    std::transform(map_data.second.begin(), map_data.second.end(),
 
  344                   std::back_inserter(subx_to_x_dofmap),
 
  345                   [offset = x_index_map->size_local()](
auto x_dof_index)
 
  346                   { return offset + x_dof_index; });
 
  350  std::span<const T> x = geometry.
x();
 
  351  std::int32_t sub_num_x_dofs = subx_to_x_dofmap.size();
 
  352  std::vector<T> sub_x(3 * sub_num_x_dofs);
 
  353  for (
int i = 0; i < sub_num_x_dofs; ++i)
 
  355    std::copy_n(std::next(x.begin(), 3 * subx_to_x_dofmap[i]), 3,
 
  356                std::next(sub_x.begin(), 3 * i));
 
  360  std::vector<std::int32_t> x_to_subx_dof_map(
 
  361      x_index_map->size_local() + x_index_map->num_ghosts(), -1);
 
  362  for (std::size_t i = 0; i < subx_to_x_dofmap.size(); ++i)
 
  363    x_to_subx_dof_map[subx_to_x_dofmap[i]] = i;
 
  366  std::vector<std::int32_t> sub_x_dofmap;
 
  367  sub_x_dofmap.reserve(x_indices.size());
 
  368  std::transform(x_indices.cbegin(), x_indices.cend(),
 
  369                 std::back_inserter(sub_x_dofmap),
 
  370                 [&x_to_subx_dof_map](
auto x_dof)
 
  372                   assert(x_to_subx_dof_map[x_dof] != -1);
 
  373                   return x_to_subx_dof_map[x_dof];
 
  380                                          geometry.
cmaps()[0].degree(),
 
  381                                          geometry.
cmaps()[0].variant());
 
  386  std::vector<std::int64_t> sub_igi;
 
  387  sub_igi.reserve(subx_to_x_dofmap.size());
 
  388  std::transform(subx_to_x_dofmap.begin(), subx_to_x_dofmap.end(),
 
  389                 std::back_inserter(sub_igi),
 
  390                 [&igi](std::int32_t sub_x_dof) { return igi[sub_x_dof]; });
 
  393  return {
Geometry<T>(sub_x_dof_index_map, std::move(sub_x_dofmap),
 
  394                      {sub_coord_ele}, std::move(sub_x), geometry.
dim(),
 
  396          std::move(subx_to_x_dofmap)};
 
 
A CoordinateElement manages coordinate mappings for isoparametric cells.
Definition CoordinateElement.h:39
 
The class represents the degree-of-freedom (dofs) for an element. Dofs are associated with a mesh ent...
Definition ElementDofLayout.h:31
 
const std::vector< std::vector< std::vector< int > > > & entity_closure_dofs_all() const
Direct access to all entity closure dofs (dof = _entity_dofs[dim][entity][i])
Definition ElementDofLayout.cpp:92
 
int num_entity_closure_dofs(int dim) const
Return the number of closure dofs for a given entity dimension.
Definition ElementDofLayout.cpp:68
 
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition AdjacencyList.h:28
 
Geometry stores the geometry imposed on a mesh.
Definition Geometry.h:33
 
~Geometry()=default
Destructor.
 
and std::is_convertible_v< std::remove_cvref_t< V >, std::vector< T > > and std::is_convertible_v< std::remove_cvref_t< W >, std::vector< std::int64_t > > Geometry(std::shared_ptr< const common::IndexMap > index_map, U &&dofmap, const std::vector< fem::CoordinateElement< typename std::remove_reference_t< typename V::value_type > > > &elements, V &&x, int dim, W &&input_global_indices)
Constructor of object that holds mesh geometry data.
Definition Geometry.h:57
 
std::span< value_type > x()
Access geometry degrees-of-freedom data (non-const version).
Definition Geometry.h:120
 
std::shared_ptr< const common::IndexMap > index_map() const
Index map.
Definition Geometry.h:104
 
Geometry(Geometry &&)=default
Move constructor.
 
Geometry(const Geometry &)=default
Copy constructor.
 
int dim() const
Return Euclidean dimension of coordinate system.
Definition Geometry.h:88
 
Geometry & operator=(Geometry &&)=default
Move Assignment.
 
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const std::int32_t, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents< std::size_t, 2 > > dofmap() const
DOF map.
Definition Geometry.h:94
 
const std::vector< std::int64_t > & input_global_indices() const
Global user indices.
Definition Geometry.h:131
 
std::span< const value_type > x() const
Access geometry degrees-of-freedom data (const version).
Definition Geometry.h:113
 
Geometry & operator=(const Geometry &)=delete
Copy Assignment.
 
const std::vector< fem::CoordinateElement< value_type > > & cmaps() const
The elements that describes the geometry maps.
Definition Geometry.h:125
 
T value_type
Value type.
Definition Geometry.h:36
 
Topology stores the topology of a mesh, consisting of mesh entities and connectivity (incidence relat...
Definition Topology.h:44
 
std::shared_ptr< const graph::AdjacencyList< std::int32_t > > connectivity(int d0, int d1) const
Return connectivity from entities of dimension d0 to entities of dimension d1.
Definition Topology.cpp:836
 
const std::vector< std::uint32_t > & get_cell_permutation_info() const
Returns the permutation information.
Definition Topology.cpp:851
 
int dim() const noexcept
Return the topological dimension of the mesh.
Definition Topology.cpp:728
 
std::vector< typename std::remove_reference_t< typename U::value_type > > distribute_data(MPI_Comm comm, std::span< const std::int64_t > indices, const U &x, int shape1)
Distribute rows of a rectangular data array to ranks where they are required (scalable version).
Definition MPI.h:676
 
std::vector< int32_t > compute_owned_indices(std::span< const std::int32_t > indices, const IndexMap &map)
Given a vector of indices (local numbering, owned or ghost) and an index map, this function returns t...
Definition IndexMap.cpp:39
 
std::tuple< common::IndexMap, int, std::vector< std::int32_t > > build_dofmap_data(MPI_Comm comm, const mesh::Topology &topology, const std::vector< ElementDofLayout > &element_dof_layouts, const std::function< std::vector< int >(const graph::AdjacencyList< std::int32_t > &)> &reorder_fn)
Build dofmap data for an element on a mesh topology.
Definition dofmapbuilder.cpp:651
 
std::vector< std::int64_t > compute_local_to_global(std::span< const std::int64_t > global, std::span< const std::int32_t > local)
Given an adjacency list with global, possibly non-contiguous, link indices and a local adjacency list...
Definition partition.cpp:378
 
std::vector< std::int32_t > compute_local_to_local(std::span< const std::int64_t > local0_to_global, std::span< const std::int64_t > local1_to_global)
Compute a local0-to-local1 map from two local-to-global maps with common global indices.
Definition partition.cpp:401
 
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32
 
mesh::Geometry< typename std::remove_reference_t< typename U::value_type > > create_geometry(MPI_Comm comm, const Topology &topology, const std::vector< fem::CoordinateElement< std::remove_reference_t< typename U::value_type > > > &elements, const graph::AdjacencyList< std::int64_t > &cell_nodes, const U &x, int dim, std::function< std::vector< int >(const graph::AdjacencyList< std::int32_t > &)> reorder_fn=nullptr)
Build Geometry from input data.
Definition Geometry.h:179
 
std::pair< mesh::Geometry< T >, std::vector< int32_t > > create_subgeometry(const Topology &topology, const Geometry< T > &geometry, int dim, std::span< const std::int32_t > subentity_to_entity)
Create a sub-geometry for a subset of entities.
Definition Geometry.h:280
 
CellType cell_entity_type(CellType type, int d, int index)
Return type of cell for entity of dimension d at given entity index.
Definition cell_types.cpp:64
 
CellType
Cell type identifier.
Definition cell_types.h:22
 
void radix_sort(std::span< T > array)
Sort a vector of integers with radix sorting algorithm. The bucket size is determined by the number o...
Definition sort.h:27