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>
 
   49  template <
typename U, 
typename V, 
typename W>
 
   50    requires std::is_convertible_v<std::remove_cvref_t<U>,
 
   51                                   std::vector<std::int32_t>>
 
   52                 and std::is_convertible_v<std::remove_cvref_t<V>,
 
   54                 and std::is_convertible_v<std::remove_cvref_t<W>,
 
   55                                           std::vector<std::int64_t>>
 
   59          typename std::remove_reference_t<typename V::value_type>>& element,
 
   62        _x(std::forward<V>(
x)),
 
   65    assert(_x.size() % 3 == 0);
 
   66    if (_x.size() / 3 != _input_global_indices.size())
 
   67      throw std::runtime_error(
"Geometry size mis-match");
 
 
   81  template <
typename V, 
typename W>
 
   82    requires std::is_convertible_v<std::remove_cvref_t<V>, std::vector<T>>
 
   83                 and std::is_convertible_v<std::remove_cvref_t<W>,
 
   84                                           std::vector<std::int64_t>>
 
   86      std::shared_ptr<const common::IndexMap> 
index_map,
 
   87      const std::vector<std::vector<std::int32_t>>& dofmaps,
 
   89          typename std::remove_reference_t<typename V::value_type>>>& elements,
 
   91      : _dim(
dim), _dofmaps(dofmaps), _index_map(
index_map), _cmaps(elements),
 
   92        _x(std::forward<V>(
x)),
 
   95    assert(_x.size() % 3 == 0);
 
   96    if (_x.size() / 3 != _input_global_indices.size())
 
   97      throw std::runtime_error(
"Geometry size mis-match");
 
 
  116  int dim()
 const { 
return _dim; }
 
  120  MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
 
  122      MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>
 
  125    if (_dofmaps.size() != 1)
 
  126      throw std::runtime_error(
"Multiple dofmaps");
 
  128    int ndofs = _cmaps.front().dim();
 
  129    return MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
 
  131        MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>(
 
  132        _dofmaps.front().data(), _dofmaps.front().size() / ndofs, ndofs);
 
 
  139  MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
 
  141      MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>
 
  144    if (i < 0 or i >= (
int)_dofmaps.size())
 
  146      throw std::out_of_range(
"Cannot get dofmap:" + std::to_string(i)
 
  149    int ndofs = _cmaps[i].dim();
 
  151    return MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
 
  153        MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>(
 
  154        _dofmaps[i].data(), _dofmaps[i].size() / ndofs, ndofs);
 
 
  159  std::shared_ptr<const common::IndexMap> 
index_map()
 const 
 
  168  std::span<const value_type> 
x()
 const { 
return _x; }
 
  175  std::span<value_type> 
x() { 
return _x; }
 
  182    if (_cmaps.size() != 1)
 
  183      throw std::runtime_error(
"Multiple cmaps.");
 
  184    return _cmaps.front();
 
 
  192    if (i < 0 or i >= (
int)_cmaps.size())
 
  194      throw std::out_of_range(
"Cannot get cmap:" + std::to_string(i)
 
 
  203    return _input_global_indices;
 
 
  211  std::vector<std::vector<std::int32_t>> _dofmaps;
 
  214  std::shared_ptr<const common::IndexMap> _index_map;
 
  217  std::vector<fem::CoordinateElement<value_type>> _cmaps;
 
  221  std::vector<value_type> _x;
 
  224  std::vector<std::int64_t> _input_global_indices;
 
 
  229template <
typename U, 
typename V, 
typename W>
 
  230Geometry(std::shared_ptr<const common::IndexMap>, U,
 
  232             typename std::remove_reference_t<typename V::value_type>>>&,
 
  234         W) -> Geometry<typename std::remove_cvref_t<typename V::value_type>>;
 
  262Geometry<typename std::remove_reference_t<typename U::value_type>>
 
  266        std::remove_reference_t<typename U::value_type>>>& elements,
 
  267    std::span<const std::int64_t> nodes, std::span<const std::int64_t> xdofs,
 
  273  LOG(INFO) << 
"Create Geometry (multiple)";
 
  275  assert(std::is_sorted(nodes.begin(), nodes.end()));
 
  276  using T = 
typename std::remove_reference_t<typename U::value_type>;
 
  279  const int tdim = topology.
dim();
 
  280  const std::size_t num_cell_types = topology.
entity_types(tdim).size();
 
  281  if (elements.size() != num_cell_types)
 
  282    throw std::runtime_error(
"Mismatch between topology and geometry.");
 
  284  std::vector<fem::ElementDofLayout> dof_layouts;
 
  285  for (
const auto& el : elements)
 
  286    dof_layouts.push_back(el.create_dof_layout());
 
  288  LOG(INFO) << 
"Got " << dof_layouts.size() << 
" dof layouts";
 
  291  auto [_dof_index_map, bs, dofmaps]
 
  293                               topology, dof_layouts, reorder_fn);
 
  295      = std::make_shared<common::IndexMap>(std::move(_dof_index_map));
 
  298  if (elements.front().needs_dof_permutations())
 
  300    const std::int32_t num_cells
 
  302    const std::vector<std::uint32_t>& cell_info
 
  304    int d = elements.front().dim();
 
  305    for (std::int32_t cell = 0; cell < num_cells; ++cell)
 
  307      std::span dofs(dofmaps.front().data() + cell * d, d);
 
  308      elements.front().permute_inv(dofs, cell_info[cell]);
 
  312  LOG(INFO) << 
"Calling compute_local_to_global";
 
  319  LOG(INFO) << 
"xdofs.size = " << xdofs.size();
 
  320  std::vector<std::int32_t> all_dofmaps;
 
  322  for (
auto q : dofmaps)
 
  324    s << q.size() << 
" ";
 
  325    all_dofmaps.insert(all_dofmaps.end(), q.begin(), q.end());
 
  327  LOG(INFO) << 
"dofmap sizes = " << s.str();
 
  328  LOG(INFO) << 
"all_dofmaps.size = " << all_dofmaps.size();
 
  329  LOG(INFO) << 
"nodes.size = " << nodes.size();
 
  335  std::vector<std::int64_t> igi(nodes.size());
 
  336  std::transform(l2l.cbegin(), l2l.cend(), igi.begin(),
 
  337                 [&nodes](
auto index) { return nodes[index]; });
 
  340  assert(x.size() % dim == 0);
 
  341  const std::size_t shape0 = x.size() / dim;
 
  342  const std::size_t shape1 = dim;
 
  343  std::vector<T> xg(3 * shape0, 0);
 
  344  for (std::size_t i = 0; i < shape0; ++i)
 
  346    std::copy_n(std::next(x.begin(), shape1 * l2l[i]), shape1,
 
  347                std::next(xg.begin(), 3 * i));
 
  350  LOG(INFO) << 
"Creating geometry with " << dofmaps.size() << 
" dofmaps";
 
  352  return Geometry(dof_index_map, std::move(dofmaps), elements, std::move(xg),
 
  353                  dim, std::move(igi));
 
 
  380Geometry<typename std::remove_reference_t<typename U::value_type>>
 
  384        std::remove_reference_t<typename U::value_type>>& element,
 
  385    std::span<const std::int64_t> nodes, std::span<const std::int64_t> xdofs,
 
  391  assert(std::is_sorted(nodes.begin(), nodes.end()));
 
  392  using T = 
typename std::remove_reference_t<typename U::value_type>;
 
  397  auto [_dof_index_map, bs, dofmaps]
 
  399                               topology, {dof_layout}, reorder_fn);
 
  401      = std::make_shared<common::IndexMap>(std::move(_dof_index_map));
 
  404  if (element.needs_dof_permutations())
 
  406    const std::int32_t num_cells
 
  408    const std::vector<std::uint32_t>& cell_info
 
  410    int d = element.dim();
 
  411    for (std::int32_t cell = 0; cell < num_cells; ++cell)
 
  413      std::span dofs(dofmaps.front().data() + cell * d, d);
 
  414      element.permute_inv(dofs, cell_info[cell]);
 
  427  std::vector<std::int64_t> igi(nodes.size());
 
  428  std::transform(l2l.cbegin(), l2l.cend(), igi.begin(),
 
  429                 [&nodes](
auto index) { return nodes[index]; });
 
  432  assert(x.size() % dim == 0);
 
  433  const std::size_t shape0 = x.size() / dim;
 
  434  const std::size_t shape1 = dim;
 
  435  std::vector<T> xg(3 * shape0, 0);
 
  436  for (std::size_t i = 0; i < shape0; ++i)
 
  438    std::copy_n(std::next(x.cbegin(), shape1 * l2l[i]), shape1,
 
  439                std::next(xg.begin(), 3 * i));
 
  442  return Geometry(dof_index_map, std::move(dofmaps.front()), {element},
 
  443                  std::move(xg), dim, std::move(igi));
 
 
  454template <std::
floating_po
int T>
 
  455std::pair<Geometry<T>, std::vector<int32_t>>
 
  457                   int dim, std::span<const std::int32_t> subentity_to_entity)
 
  465  std::vector<std::int32_t> x_indices;
 
  466  x_indices.reserve(num_entity_dofs * subentity_to_entity.size());
 
  468    auto xdofs = geometry.
dofmap();
 
  469    const int tdim = topology.
dim();
 
  472    const std::vector<std::vector<std::vector<int>>>& closure_dofs
 
  478    for (std::size_t i = 0; i < subentity_to_entity.size(); ++i)
 
  480      const std::int32_t idx = subentity_to_entity[i];
 
  481      assert(!e_to_c->links(idx).empty());
 
  483      const std::int32_t cell = e_to_c->links(idx).back();
 
  484      auto cell_entities = c_to_e->links(cell);
 
  485      auto it = std::find(cell_entities.begin(), cell_entities.end(), idx);
 
  486      assert(it != cell_entities.end());
 
  487      std::size_t local_entity = std::distance(cell_entities.begin(), it);
 
  489      auto xc = MDSPAN_IMPL_STANDARD_NAMESPACE::submdspan(
 
  490          xdofs, cell, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
 
  491      for (std::int32_t entity_dof : closure_dofs[dim][local_entity])
 
  492        x_indices.push_back(xc[entity_dof]);
 
  496  std::vector<std::int32_t> sub_x_dofs = x_indices;
 
  497  std::sort(sub_x_dofs.begin(), sub_x_dofs.end());
 
  498  sub_x_dofs.erase(std::unique(sub_x_dofs.begin(), sub_x_dofs.end()),
 
  505  std::shared_ptr<common::IndexMap> sub_x_dof_index_map;
 
  506  std::vector<std::int32_t> subx_to_x_dofmap;
 
  510    sub_x_dof_index_map = std::make_shared<common::IndexMap>(std::move(map));
 
  511    subx_to_x_dofmap = std::move(new_to_old);
 
  515  std::span<const T> x = geometry.
x();
 
  516  std::int32_t sub_num_x_dofs = subx_to_x_dofmap.size();
 
  517  std::vector<T> sub_x(3 * sub_num_x_dofs);
 
  518  for (
int i = 0; i < sub_num_x_dofs; ++i)
 
  520    std::copy_n(std::next(x.begin(), 3 * subx_to_x_dofmap[i]), 3,
 
  521                std::next(sub_x.begin(), 3 * i));
 
  525  std::vector<std::int32_t> x_to_subx_dof_map(
 
  526      x_index_map->size_local() + x_index_map->num_ghosts(), -1);
 
  527  for (std::size_t i = 0; i < subx_to_x_dofmap.size(); ++i)
 
  528    x_to_subx_dof_map[subx_to_x_dofmap[i]] = i;
 
  531  std::vector<std::int32_t> sub_x_dofmap;
 
  532  sub_x_dofmap.reserve(x_indices.size());
 
  533  std::transform(x_indices.cbegin(), x_indices.cend(),
 
  534                 std::back_inserter(sub_x_dofmap),
 
  535                 [&x_to_subx_dof_map](
auto x_dof)
 
  537                   assert(x_to_subx_dof_map[x_dof] != -1);
 
  538                   return x_to_subx_dof_map[x_dof];
 
  545                                     geometry.
cmap().variant());
 
  550  std::vector<std::int64_t> sub_igi;
 
  551  sub_igi.reserve(subx_to_x_dofmap.size());
 
  552  std::transform(subx_to_x_dofmap.begin(), subx_to_x_dofmap.end(),
 
  553                 std::back_inserter(sub_igi),
 
  554                 [&igi](std::int32_t sub_x_dof) { return igi[sub_x_dof]; });
 
  557  return {
Geometry(sub_x_dof_index_map, std::move(sub_x_dofmap), {sub_cmap},
 
  558                   std::move(sub_x), geometry.
dim(), std::move(sub_igi)),
 
  559          std::move(subx_to_x_dofmap)};
 
 
Definition CoordinateElement.h:38
 
Definition ElementDofLayout.h:30
 
const std::vector< std::vector< std::vector< int > > > & entity_closure_dofs_all() const
Definition ElementDofLayout.cpp:92
 
int num_entity_closure_dofs(int dim) const
Definition ElementDofLayout.cpp:68
 
Definition AdjacencyList.h:28
 
Geometry stores the geometry imposed on a mesh.
Definition Geometry.h:33
 
~Geometry()=default
Destructor.
 
std::span< value_type > x()
Access geometry degrees-of-freedom data (non-const version).
Definition Geometry.h:175
 
Geometry(std::shared_ptr< const common::IndexMap > index_map, const std::vector< std::vector< std::int32_t > > &dofmaps, 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:85
 
Geometry(std::shared_ptr< const common::IndexMap > index_map, U &&dofmap, const fem::CoordinateElement< typename std::remove_reference_t< typename V::value_type > > &element, V &&x, int dim, W &&input_global_indices)
Constructor of object that holds mesh geometry data.
Definition Geometry.h:56
 
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const std::int32_t, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents< std::size_t, 2 > > dofmap(std::int32_t i) const
The dofmap associated with the ith coordinate map in the geometry.
Definition Geometry.h:142
 
std::shared_ptr< const common::IndexMap > index_map() const
Index map.
Definition Geometry.h:159
 
Geometry(Geometry &&)=default
Move constructor.
 
Geometry(const Geometry &)=default
Copy constructor.
 
const fem::CoordinateElement< value_type > & cmap() const
The element that describes the geometry map.
Definition Geometry.h:180
 
int dim() const
Return Euclidean dimension of coordinate system.
Definition Geometry.h:116
 
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
DofMap for the geometry.
Definition Geometry.h:123
 
const fem::CoordinateElement< value_type > & cmap(std::int32_t i) const
The element that describe the ith geometry map.
Definition Geometry.h:190
 
const std::vector< std::int64_t > & input_global_indices() const
Global user indices.
Definition Geometry.h:201
 
std::span< const value_type > x() const
Access geometry degrees-of-freedom data (const version).
Definition Geometry.h:168
 
Geometry & operator=(const Geometry &)=delete
Copy Assignment.
 
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 common::IndexMap > index_map(int dim) const
Get the IndexMap that described the parallel distribution of the mesh entities.
Definition Topology.cpp:813
 
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. Assumes only one entit...
Definition Topology.cpp:929
 
const std::vector< std::uint32_t > & get_cell_permutation_info() const
Returns the permutation information.
Definition Topology.cpp:979
 
std::vector< CellType > entity_types(std::int8_t dim) const
Get the entity types in the topology for a given dimension.
Definition Topology.cpp:1021
 
int dim() const noexcept
Return the topological dimension of the mesh.
Definition Topology.cpp:792
 
std::pair< IndexMap, std::vector< std::int32_t > > create_sub_index_map(const IndexMap &imap, std::span< const std::int32_t > indices, IndexMapOrder order=IndexMapOrder::any, bool allow_owner_change=false)
Create a new index map from a subset of indices in an existing index map.
Definition IndexMap.cpp:751
 
@ any
Allow arbitrary ordering of ghost indices in sub-maps.
 
std::tuple< common::IndexMap, int, std::vector< 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)
Definition dofmapbuilder.cpp:621
 
std::vector< std::int64_t > compute_local_to_global(std::span< const std::int64_t > global, std::span< const std::int32_t > local)
Definition partition.cpp:377
 
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:399
 
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32
 
Geometry< typename std::remove_reference_t< typename U::value_type > > create_geometry(const Topology &topology, const std::vector< fem::CoordinateElement< std::remove_reference_t< typename U::value_type > > > &elements, std::span< const std::int64_t > nodes, std::span< const std::int64_t > xdofs, 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:263
 
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
 
std::pair< 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:456
 
CellType
Cell type identifier.
Definition cell_types.h:22