23#include "libmesh/boundary_info.h"
24#include "libmesh/cell_c0polyhedron.h"
25#include "libmesh/distributed_mesh.h"
26#include "libmesh/elem.h"
27#include "libmesh/face_c0polygon.h"
28#include "libmesh/int_range.h"
29#include "libmesh/mesh_base.h"
30#include "libmesh/parallel_elem.h"
31#include "libmesh/parallel_mesh.h"
32#include "libmesh/remote_elem.h"
40#ifdef LIBMESH_ENABLE_UNIQUE_ID
41static const unsigned int header_size = 12;
43static const unsigned int header_size = 11;
65 libmesh_assert_equal_to (packed_header, elem_magic_header);
69 const unsigned int level =
70 cast_int<unsigned int>(*in);
73 const int typeint = cast_int<int>(*(in+4));
74 libmesh_assert_greater_equal (typeint, 0);
77 cast_int<ElemType>(typeint);
82 unsigned int variable_topology_size = 0;
87 if (has_runtime_topology)
89 auto topology_in = in + header_size;
90 n_nodes = cast_int<unsigned int>(*topology_in++);
91 n_sides = cast_int<unsigned int>(*topology_in++);
92 n_edges = cast_int<unsigned int>(*topology_in++);
93 variable_topology_size = 3;
98 for (
unsigned int s = 0; s != n_sides; ++s)
100 const unsigned int n_side_nodes =
101 cast_int<unsigned int>(*topology_in++);
102 topology_in += n_side_nodes;
103 variable_topology_size += n_side_nodes + 1;
108 const unsigned int pre_indexing_size =
109 header_size + variable_topology_size +
n_nodes + n_sides*2;
111 const unsigned int indexing_size =
115 unsigned int total_packed_bc_data = 1;
116 largest_id_type on_boundary = *(in + pre_indexing_size + indexing_size);
121 total_packed_bc_data++;
122 largest_id_type allow_children_on_boundary = *(in + pre_indexing_size + indexing_size + 1);
126 if (level == 0 || allow_children_on_boundary)
128 for (
unsigned int s = 0; s != n_sides; ++s)
130 const int n_bcs = cast_int<int>
131 (*(in + pre_indexing_size + indexing_size +
132 total_packed_bc_data++));
133 libmesh_assert_greater_equal (n_bcs, 0);
134 total_packed_bc_data += n_bcs;
140 for (
unsigned int e = 0; e != n_edges; ++e)
142 const int n_bcs = cast_int<int>
143 (*(in + pre_indexing_size + indexing_size +
144 total_packed_bc_data++));
145 libmesh_assert_greater_equal (n_bcs, 0);
146 total_packed_bc_data += n_bcs;
149 for (
unsigned short sf=0; sf != 2; ++sf)
151 const int n_bcs = cast_int<int>
152 (*(in + pre_indexing_size + indexing_size +
153 total_packed_bc_data++));
154 libmesh_assert_greater_equal (n_bcs, 0);
155 total_packed_bc_data += n_bcs;
163 pre_indexing_size + indexing_size + total_packed_bc_data;
172 return packed_size(std::vector<largest_id_type>::const_iterator(in));
182 unsigned int variable_topology_size = 0;
186 variable_topology_size = 3;
190 if (elem->
dim() == 3)
191 for (
auto s : elem->side_index_range())
192 variable_topology_size +=
193 1 +
cast_int<unsigned
int>(elem->nodes_on_side(s).size());
197 unsigned int total_packed_bcs = 1;
198 const unsigned int n_sides = elem->
n_sides();
201 for (
auto s : elem->side_index_range())
202 if (
mesh->get_boundary_info().n_raw_boundary_ids(elem,s))
216 total_packed_bcs += n_sides;
217 for (
unsigned int s = 0; s != n_sides; ++s)
223 if (elem->
level() == 0)
225 const unsigned int n_edges = elem->
n_edges();
226 total_packed_bcs += n_edges;
227 for (
unsigned int e = 0; e != n_edges; ++e)
231 total_packed_bcs += 2;
232 for (
unsigned short sf=0; sf != 2; ++sf)
241 header_size + variable_topology_size + elem->
n_nodes() + n_sides*2 +
252 return packable_size(elem,
static_cast<const MeshBase *
>(
mesh));
262 return packable_size(elem,
static_cast<const MeshBase *
>(
mesh));
270 std::back_insert_iterator<std::vector<largest_id_type>> data_out,
276 *data_out++ = elem_magic_header;
279#ifdef LIBMESH_ENABLE_AMR
292 *data_out++ = (refinement_info);
304 *data_out++ = (elem->
id());
306#ifdef LIBMESH_ENABLE_UNIQUE_ID
314#ifdef LIBMESH_ENABLE_AMR
316 if (elem->
level() == 0)
323 *data_out++ =(elem->
parent()->
id());
331 if ((elem->
dim() < LIBMESH_DIM) &&
338 if (has_variable_topology)
345 for (
const Node & node : elem->node_ref_range())
346 *data_out++ = node.id();
348 if (has_variable_topology && elem->
dim() == 3)
349 for (
auto s : elem->side_index_range())
351 const std::vector<unsigned int> side_nodes =
353 *data_out++ = side_nodes.size();
354 for (
const auto node : side_nodes)
359 for (
auto neigh : elem->neighbor_ptr_range())
363 *data_out++ = (neigh->id());
367 *data_out++ = neigh->which_neighbor_am_i(elem);
383 for (
auto s : elem->side_index_range())
384 if (
mesh->get_boundary_info().n_raw_boundary_ids(elem,s))
390 *data_out++ = on_boundary;
399 std::vector<boundary_id_type> bcs;
400 for (
auto s : elem->side_index_range())
404 *data_out++ =(bcs.size());
406 for (
const auto & bid : bcs)
414 if (elem->
level() == 0)
416 std::vector<boundary_id_type> bcs;
417 for (
auto e : elem->edge_index_range())
421 *data_out++ =(bcs.size());
423 for (
const auto & bid : bcs)
427 for (
unsigned short sf=0; sf != 2; ++sf)
431 *data_out++ =(bcs.size());
433 for (
const auto & bid : bcs)
444 std::back_insert_iterator<std::vector<largest_id_type>> data_out,
447 pack(elem, data_out,
static_cast<const MeshBase*
>(
mesh));
455 std::back_insert_iterator<std::vector<largest_id_type>> data_out,
458 pack(elem, data_out,
static_cast<const MeshBase*
>(
mesh));
470 const std::vector<largest_id_type>::const_iterator original_in = in;
473 libmesh_assert_equal_to (incoming_header, elem_magic_header);
477 const unsigned int level =
478 cast_int<unsigned int>(*in++);
480#ifdef LIBMESH_ENABLE_AMR
482 const unsigned int p_level =
483 cast_int<unsigned int>(*in++);
486 const int rflag = cast_int<int>(*in++);
487 const int invalid_rflag =
489 libmesh_assert_greater_equal (rflag, 0);
491 libmesh_assert_less (rflag, invalid_rflag*2+1);
493 const bool has_children = (rflag > invalid_rflag);
496 cast_int<Elem::RefinementState>(rflag - invalid_rflag - 1) :
497 cast_int<Elem::RefinementState>(rflag);
500 const int pflag = cast_int<int>(*in++);
501 libmesh_assert_greater_equal (pflag, 0);
504 cast_int<Elem::RefinementState>(pflag);
510 const int typeint = cast_int<int>(*in++);
511 libmesh_assert_greater_equal (typeint, 0);
514 cast_int<ElemType>(typeint);
525 cast_int<processor_id_type>(*in++);
531 cast_int<subdomain_id_type>(*in++);
535 cast_int<dof_id_type>(*in++);
538#ifdef LIBMESH_ENABLE_UNIQUE_ID
541 cast_int<unique_id_type>(*in++);
544#ifdef LIBMESH_ENABLE_AMR
553 : cast_int<dof_id_type>(*in++);
560 const unsigned int which_child_am_i =
562 ?
static_cast<unsigned int>(*in++)
563 : cast_int<unsigned int>(*in++);
573 libmesh_assert_equal_to (in - original_in, header_size + 1);
575 if (has_runtime_topology)
577 n_nodes = cast_int<unsigned int>(*in++);
578 n_sides = cast_int<unsigned int>(*in++);
579 n_edges = cast_int<unsigned int>(*in++);
583 libmesh_assert_less (2, n_sides);
584 libmesh_assert_equal_to (
n_nodes % n_sides, 0);
585 libmesh_assert_equal_to (n_edges, n_sides);
589 libmesh_assert_less (3,
n_nodes);
590 libmesh_assert_less (3, n_sides);
595 const auto node_ids_in = in;
598 std::vector<std::vector<unsigned int>> polyhedron_side_nodes;
601 polyhedron_side_nodes.resize(n_sides);
603 std::vector<bool> node_seen(
n_nodes,
false);
604 unsigned int next_new_node = 0;
606 for (
auto & side_nodes : polyhedron_side_nodes)
608 const unsigned int n_side_nodes =
609 cast_int<unsigned int>(*in++);
610 libmesh_assert_less (2, n_side_nodes);
611 side_nodes.resize(n_side_nodes);
612 for (
auto & node : side_nodes)
614 node = cast_int<unsigned int>(*in++);
615 libmesh_assert_less (node,
n_nodes);
620 libmesh_assert_equal_to (node, next_new_node);
621 node_seen[node] =
true;
642 libmesh_assert_equal_to (elem->
level(), level);
643 libmesh_assert_equal_to (elem->
id(),
id);
647 libmesh_assert_equal_to (elem->
processor_id(), processor_id);
648 libmesh_assert_equal_to (elem->
subdomain_id(), subdomain_id);
649 libmesh_assert_equal_to (elem->
type(), type);
651 libmesh_assert_equal_to (elem->
n_sides(), n_sides);
652 libmesh_assert_equal_to (elem->
n_edges(), n_edges);
658 polyhedron_side_nodes[s]);
663 for (
unsigned int i=0; i !=
n_nodes; ++i)
664 libmesh_assert_equal_to
666 cast_int<dof_id_type>(*(node_ids_in + i)));
669#ifdef LIBMESH_ENABLE_AMR
671 libmesh_assert_equal_to (elem->
has_children(), has_children);
676 libmesh_assert_equal_to (elem->
p_level(), p_level);
693 if (elem->
dim() < LIBMESH_DIM)
743 cast_int<dof_id_type>(*in++);
746 cast_int<dof_id_type>(*in++);
819#ifdef LIBMESH_ENABLE_AMR
838 Elem * parent =
nullptr;
839#ifdef LIBMESH_ENABLE_AMR
854 libmesh_assert_equal_to (level, 0);
858 elem = std::make_unique<C0Polygon>(
n_nodes, parent).release();
861 std::vector<std::shared_ptr<Polygon>> sides(n_sides);
864 const auto & side_nodes = polyhedron_side_nodes[s];
865 auto side = std::make_shared<C0Polygon>
866 (cast_int<unsigned int>(side_nodes.size()));
870 cast_int<dof_id_type>
871 (*(node_ids_in + side_nodes[n]));
874 sides[s] = std::move(side);
877 std::unique_ptr<Node> generated_mid_node;
878 auto polyhedron = std::make_unique<C0Polyhedron>
879 (sides, generated_mid_node, parent);
881 libmesh_assert_equal_to (polyhedron->n_nodes(),
n_nodes);
883 if (generated_mid_node)
886 cast_int<dof_id_type>(*(node_ids_in +
n_nodes - 1));
887 polyhedron->set_node(
n_nodes - 1,
891 elem = polyhedron.release();
897#ifdef LIBMESH_ENABLE_AMR
904 parent->
add_child(elem, which_child_am_i);
911 libmesh_assert_equal_to (elem->
level(), level);
919 for (
unsigned int c=0; c != nc; ++c)
929#ifdef LIBMESH_ENABLE_UNIQUE_ID
935 libmesh_assert_equal_to (elem->
n_sides(), n_sides);
936 libmesh_assert_equal_to (elem->
n_edges(), n_edges);
939 for (
unsigned int n=0; n !=
n_nodes; n++)
942 (cast_int<dof_id_type>(*(node_ids_in + n))));
945 for (
unsigned int n = 0; n !=
n_nodes; ++n)
946 libmesh_assert_equal_to
948 cast_int<dof_id_type>(*(node_ids_in + n)));
980 cast_int<dof_id_type>(*in++);
983 cast_int<dof_id_type>(*in++);
1025 auto on_boundary = *in++;
1031 auto children_on_boundary = *in++;
1032 if (elem->
level() == 0 || children_on_boundary)
1037 cast_int<boundary_id_type>(*in++);
1041 (elem, s, cast_int<boundary_id_type>(*in++));
1053 cast_int<boundary_id_type>(*in++);
1057 (elem, e, cast_int<boundary_id_type>(*in++));
1060 for (
unsigned short sf=0; sf != 2; ++sf)
1063 cast_int<boundary_id_type>(*in++);
1067 (elem, sf, cast_int<boundary_id_type>(*in++));
void ErrorVector unsigned int
void add_shellface(const dof_id_type elem, const unsigned short int shellface, const boundary_id_type id)
Add shell face shellface of element number elem with boundary id id to the boundary information data ...
void shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface, std::vector< boundary_id_type > &vec_to_fill) const
unsigned int n_raw_boundary_ids(const Elem *const elem, const unsigned short int side) const
void add_edge(const dof_id_type elem, const unsigned short int edge, const boundary_id_type id)
Add edge edge of element number elem with boundary id id to the boundary information data structure.
void edge_boundary_ids(const Elem *const elem, const unsigned short int edge, std::vector< boundary_id_type > &vec_to_fill) const
unsigned int n_shellface_boundary_ids(const Elem *const elem, const unsigned short int shellface) const
unsigned int n_edge_boundary_ids(const Elem *const elem, const unsigned short int edge) const
void raw_boundary_ids(const Elem *const elem, const unsigned short int side, std::vector< boundary_id_type > &vec_to_fill) const
bool is_children_on_boundary_side() const
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure.
The DistributedMesh class is derived from the MeshBase class, and is intended to provide identical fu...
static unsigned int unpackable_indexing_size(std::vector< largest_id_type >::const_iterator begin)
If we have indices packed into an buffer for communications, how much of that buffer applies to this ...
processor_id_type processor_id() const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
unique_id_type unique_id() const
void pack_indexing(std::back_insert_iterator< std::vector< largest_id_type > > target) const
A method for creating packed data from our index buffer - basically a copy with prepended size with o...
static constexpr unique_id_type invalid_unique_id
An invalid unique_id to distinguish an uninitialized DofObject.
bool valid_unique_id() const
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
void set_unique_id(unique_id_type new_id)
Sets the unique_id for this DofObject.
unsigned int packed_indexing_size() const
If we pack our indices into an buffer for communications, how many ints do we need?
void unpack_indexing(std::vector< largest_id_type >::const_iterator begin)
A method for creating our index buffer from packed data - basically with our current implementation w...
This is the base class from which all geometric element types are derived.
virtual Node *& set_node(const unsigned int i)
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
RefinementState refinement_flag() const
static const unsigned int type_to_n_nodes_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of nodes in the element...
void hack_p_level_and_refinement_flag(const unsigned int p, RefinementState pflag)
Sets the value of the p-refinement level for the element without altering the p-level of its ancestor...
static const unsigned int type_to_n_edges_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of edges on the element...
bool has_children() const
virtual unsigned int n_nodes() const =0
const Elem * parent() const
void make_links_to_me_local(unsigned int n, unsigned int neighbor_side)
Resets the neighbor_side pointers of our nth neighbor (and its descendants, if appropriate) to point ...
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
const Elem * child_ptr(unsigned int i) const
RefinementState
Enumeration of possible element refinement states.
@ INVALID_REFINEMENTSTATE
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
void set_interior_parent(Elem *p)
Sets the pointer to the element's interior_parent.
unsigned int which_child_am_i(const Elem *e) const
virtual unsigned short dim() const =0
subdomain_id_type subdomain_id() const
static const unsigned int type_to_dim_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the geometric dimension of the ele...
static const unsigned int type_to_n_sides_map[INVALID_ELEM]
This array maps the integer representation of the ElemType enum to the number of sides on the element...
unsigned int level() const
virtual bool runtime_topology() const
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
IntRange< unsigned short > edge_index_range() const
virtual unsigned int n_children() const =0
virtual ElemType type() const =0
const Elem * interior_parent() const
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
virtual unsigned int n_edges() const =0
virtual unsigned int n_sides() const =0
dof_id_type node_id(const unsigned int i) const
unsigned int p_level() const
RefinementState p_refinement_flag() const
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
const Elem * neighbor_ptr(unsigned int i) const
IntRange< unsigned short > side_index_range() const
This is the MeshBase class.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
virtual const Node * node_ptr(const dof_id_type i) const =0
virtual const Elem * elem_ptr(const dof_id_type i) const =0
const MeshBase & interior_mesh() const
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
A Node is like a Point, but with more information.
processor_id_type processor_id() const
std::pair< T1, T2 > unpack(BufferIter in, Context *ctx)
static unsigned int packed_size(BufferIter iter)
unsigned int packable_size(const std::pair< T1, T2 > &pr, const Context *ctx)
void pack(const std::pair< T1, T2 > &pr, OutputIter data_out, const Context *ctx)
In parallel meshes where a ghost element has neighbors which do not exist on the local processor,...
uint8_t processor_id_type
Tnew cast_int(Told oldvar)
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
ElemType
Defines an enum for geometric element types.
void libmesh_ignore(const Args &...)
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
const RemoteElem * remote_elem
const dof_id_type n_nodes