63 "Use BIH for finding initial candidates, then continue by prolongation.")
65 "Use BIH for finding all candidates.")
67 "Use bounding boxes for finding initial candidates, then continue by prolongation.")
72 return IT::Record(
"Mesh",
"Record with mesh related data." )
75 "Input file with mesh description.")
77 "List of additional region and region set definitions not contained in the mesh. " 78 "There are three region sets implicitly defined:\n\n" 79 "- ALL (all regions of the mesh)\n" 80 "- .BOUNDARY (all boundary regions)\n" 81 "- BULK (all bulk regions)")
85 IT::Default(
"\"BIHsearch\""),
"Search algorithm for element intersections.")
87 "Maximal distance of observe point from Mesh relative to its size (bounding box). " 88 "Value is global and it can be rewrite at arbitrary ObservePoint by setting the key search_radius.")
111 istringstream is(
"{mesh_file=\"\"}");
153 for(
int i=0; i < 3; i++) {
155 for(
int j=0; j < i+2; j++)
159 for (
unsigned int sid=0; sid<RefElement<1>::n_sides; sid++)
160 for (
unsigned int nid=0; nid<RefElement<1>::n_nodes_per_side; nid++)
163 for (
unsigned int sid=0; sid<RefElement<2>::n_sides; sid++)
164 for (
unsigned int nid=0; nid<RefElement<2>::n_nodes_per_side; nid++)
167 for (
unsigned int sid=0; sid<RefElement<3>::n_sides; sid++)
168 for (
unsigned int nid=0; nid<RefElement<3>::n_nodes_per_side; nid++)
175 if (edg.side_)
delete[] edg.side_;
178 if (ele->node)
delete[] ele->node;
179 if (ele->edge_idx_)
delete[] ele->edge_idx_;
180 if (ele->permutation_idx_)
delete[] ele->permutation_idx_;
181 if (ele->boundary_idx_)
delete[] ele->boundary_idx_;
182 if (ele->neigh_vb)
delete[] ele->neigh_vb;
209 unsigned int li, count = 0;
229 switch (elm->dim()) {
245 for (
auto elem_to_region : map) {
261 if (ele->quality_measure_smooth() < 0.001)
WarningOut().fmt(
"Bad quality (<0.001) of the element {}.\n", ele.id());
274 id_4_old[i++] = ele.index();
300 for (
unsigned int n=0; n<e->n_nodes(); n++)
304 stable_sort(n->begin(), n->end());
310 if (nodes_list.size() == 0) {
311 intersection_element_list.clear();
312 }
else if (nodes_list.size() == 1) {
319 it1=set_intersection(
322 intersection_element_list.begin());
323 intersection_element_list.resize(it1-intersection_element_list.begin());
325 for(;it2<nodes_list.end();++it2) {
326 it1=set_intersection(
327 intersection_element_list.begin(), intersection_element_list.end(),
329 intersection_element_list.begin());
330 intersection_element_list.resize(it1-intersection_element_list.begin());
337 unsigned int dim,
unsigned int &element_idx) {
338 bool is_neighbour =
false;
342 if (elements[*ele].dim() == dim) {
345 }
else if (elements[*ele].dim() == dim-1) {
346 if (is_neighbour)
xprintf(
UsrErr,
"Too matching elements id: %d and id: %d in the same mesh.\n",
347 elements(*ele).id(), elements(element_idx).id() );
352 element_list.resize( e_dest - element_list.begin());
360 && find(side_nodes.begin(), side_nodes.end(),
node_vector.
index( si->
node(ni) ) ) != side_nodes.end() ) ni++;
361 return ( ni == si->
n_nodes() );
377 unsigned int ngh_element_idx, last_edge_idx;
390 side_nodes.resize(bc_ele->n_nodes());
391 for (
unsigned n=0; n<bc_ele->n_nodes(); n++) side_nodes[n] =
node_vector.
index(bc_ele->node[n]);
395 xprintf(
UsrErr,
"Boundary element (id: %d) match a regular element (id: %d) of lower dimension.\n",
396 bc_ele.id(),
element(ngh_element_idx).id());
398 if (intersection_list.size() == 0) {
400 WarningOut().fmt(
"Lonely boundary element, id: {}, region: {}, dimension {}.\n",
401 bc_ele.id(), bc_ele->region().id(), bc_ele->dim());
404 last_edge_idx=
edges.size();
405 edges.resize(last_edge_idx+1);
406 edg = &(
edges.back() );
408 edg->
side_ =
new struct SideIter[ intersection_list.size() ];
422 for (
unsigned int ecs=0; ecs<elem->
n_sides(); ecs++) {
428 int new_bc_ele_idx=bc_ele.index();
429 THROW( ExcDuplicateBoundary()
431 << EI_RegLast(this->
bc_elements[last_bc_ele_idx].region().label())
433 << EI_RegNew(this->
bc_elements[new_bc_ele_idx].region().label())
455 for (
unsigned int s=0; s<e->n_sides(); s++)
462 side_nodes.resize(e->side(s)->n_nodes());
463 for (
unsigned n=0; n<e->side(s)->n_nodes(); n++) side_nodes[n] =
node_vector.
index(e->side(s)->node(n));
472 last_edge_idx=
edges.size();
473 edges.resize(last_edge_idx+1);
474 edg = &(
edges.back() );
476 edg->
side_ =
new struct SideIter[ intersection_list.size() ];
480 if (intersection_list.size() == 1) {
482 edg->
side_[0] = e->side(s);
483 e->edge_idx_[s] = last_edge_idx;
485 if (e->boundary_idx_ == NULL) {
486 e->boundary_idx_ =
new unsigned int [ e->n_sides() ];
487 std::fill( e->boundary_idx_, e->boundary_idx_ + e->n_sides(),
Mesh::undef_idx);
493 e->boundary_idx_[s] = bdr_idx;
499 for(
unsigned int ni = 0; ni< side_nodes.size(); ni++) bc_ele->node[ni] = &(
node_vector[side_nodes[ni]] );
513 for (
unsigned int ecs=0; ecs<elem->
n_sides(); ecs++) {
519 last_edge_idx=
edges.size();
520 edges.resize(last_edge_idx+1);
521 edg = &(
edges.back() );
539 OLD_ASSERT( is_neighbour || ( (
unsigned int) edg->
n_sides ) == intersection_list.size(),
"Some connected sides were not found.\n");
553 edg->side(0)->element()->permutation_idx_[edg->side(0)->el_idx()] = 0;
555 if (edg->n_sides > 1)
558 unsigned int permutation[edg->side(0)->n_nodes()];
560 for (
unsigned int i=0; i<edg->side(0)->n_nodes(); i++)
561 node_numbers[edg->side(0)->node(i)] = i;
563 for (
int sid=1; sid<edg->n_sides; sid++)
565 for (
unsigned int i=0; i<edg->side(0)->n_nodes(); i++)
566 permutation[node_numbers[edg->side(sid)->node(i)]] = i;
568 switch (edg->side(0)->dim())
587 unsigned int permutation[nb->element()->n_nodes()];
591 for (
unsigned int i=0; i<nb->element()->n_nodes(); i++)
592 node_numbers[nb->element()->node[i]] = i;
594 for (
unsigned int i=0; i<nb->side()->n_nodes(); i++)
595 permutation[node_numbers[nb->side()->node(i)]] = i;
597 switch (nb->side()->dim())
631 if( ele->n_neighs_vb > 0 ) {
632 ele->neigh_vb =
new struct Neighbour* [ele->n_neighs_vb];
639 ele =
ngh->element();
660 intersections = std::make_shared<MixedMeshIntersections>(
this);
676 if (bulk_elements_id.size() ==0) {
681 map_it = bulk_elements_id.begin();
683 for(
unsigned int idx=0; idx <
element.
size(); idx++, ++map_it) {
685 if (last_id >=
id)
xprintf(
UsrErr,
"Element IDs in non-increasing order, ID: %d\n",
id);
686 last_id=*map_it = id;
690 map_it = boundary_elements_id.begin();
697 if (
id < 0) last_id=*map_it=-1;
699 if (last_id >=
id)
xprintf(
UsrErr,
"Element IDs in non-increasing order, ID: %d\n",
id);
700 last_id=*map_it = id;
709 it != region_list.
end();
754 bih_tree_ = std::make_shared<BIHTree>(
this);
759 return in_record_.
val<
double>(
"global_observe_search_radius");
769 node->point() = coords;
773 void Mesh::add_element(
unsigned int elm_id,
unsigned int dim,
unsigned int region_id,
unsigned int partition_id,
786 WarningOut().fmt(
"Bulk elements of zero size(dim=0) are not supported. Element ID: {}.\n", elm_id);
792 ele->
init(dim,
this, region_idx);
793 ele->
pid = partition_id;
797 unsigned int node_id = node_ids[ni];
800 "Unknown node id %d in specification of element with id=%d.\n", node_id, elm_id);
801 ele->
node[ni] = node;
809 WarningOut().fmt(
"Tetrahedron element with id {} has wrong numbering or is degenerated (Jacobian = {}).",ele->
index(),jac);
Distribution * el_ds
Parallel distribution of elements.
Class for the mesh partitioning. This should provide:
int IdxInt
Define integers that are indices into large arrays (elements, nodes, dofs etc.)
Bounding box in 3d ambient space.
vector< vector< unsigned int > > const & node_elements()
#define FOR_ELEMENT_NODES(i, j)
unsigned int * boundary_idx_
int get_id(const T *it) const
bool is_boundary() const
Returns true if it is a Boundary region and false if it is a Bulk region.
MapElementIDToRegionID el_to_reg_map_
MixedMeshIntersections & mixed_intersections()
#define FOR_ELEMENTS(_mesh_, __i)
void add_node(unsigned int node_id, arma::vec3 coords)
Add new node of given id and coordinates to mesh.
#define MessageOut()
Macro defining 'message' record of log.
unsigned int * permutation_idx_
static const Input::Type::Record & get_input_type()
static const unsigned int undef_idx
void create_node_element_lists()
static unsigned int permutation_index(unsigned int p[n_nodes_per_side])
static const Input::Type::Record & get_input_type()
std::shared_ptr< MixedMeshIntersections > intersections
unsigned int max_edge_sides_[3]
Maximal number of sides per one edge in the actual mesh (set in make_neighbours_and_edges()).
BoundingBox mesh_box_
Bounding box of whole mesh.
unsigned int index() const
void expand(const Point &point)
double tetrahedron_jacobian() const
string create_label_from_id(unsigned int id) const
FullIter add_item(int id)
vector< vector< vector< unsigned int > > > side_nodes
FullIter find_id(const int id)
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
void add_physical_name(unsigned int dim, unsigned int id, std::string name)
Add new node of given id and coordinates to mesh.
vector< Boundary > boundary_
Partitioning * get_part()
void compute_element_boxes()
Precompute element bounding boxes if it is not done yet.
Region get_region(unsigned int id, unsigned int dim)
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
void elements_id_maps(vector< IdxInt > &bulk_elements_id, vector< IdxInt > &boundary_elements_id) const
void read_regions_from_input(Input::Array region_list)
unsigned int n_elements() const
bool same_sides(const SideIter &si, vector< unsigned int > &side_nodes)
std::vector< T >::iterator iterator
IntersectionSearch get_intersection_search()
Getter for input type selection for intersection search algorithm.
friend class RegionSetBase
static const Input::Type::Selection & get_input_intersection_variant()
The definition of input record for selection of variant of file format.
unsigned int n_sides() const
#define START_TIMER(tag)
Starts a timer with specified tag.
Class for O(log N) lookup for intersections with a set of bounding boxes.
unsigned int index(const T *pointer) const
#define FOR_NEIGHBOURS(_mesh_, it)
ElementVector bc_elements
SideIter side(const unsigned int loc_index)
Region implicit_boundary_region()
std::shared_ptr< BIHTree > bih_tree_
#define FOR_NODES(_mesh_, i)
vector< vector< unsigned int > > node_elements_
#define INPUT_CHECK(i,...)
Debugging macros.
void init(unsigned int dim, Mesh *mesh_in, RegionIdx reg)
void count_element_types()
const BIHTree & get_bih_tree()
Getter for BIH. Creates and compute BIH at first call.
void mark_used_region(unsigned int idx)
void print_region_table(ostream &stream) const
Support classes for parallel programing.
Region add_region(unsigned int id, const std::string &label, unsigned int dim, const std::string &address="implicit")
vector< Neighbour > vb_neighbours_
IdxInt * row_4_el
Index set assigning to global element index the local index used in parallel vectors.
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
void intersect_element_lists(vector< unsigned int > const &nodes_list, vector< unsigned int > &intersection_element_list)
void modify_element_ids(const RegionDB::MapElementIDToRegionID &map)
#define WarningOut()
Macro defining 'warning' record of log.
void make_edge_permutations()
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc...
static Input::Type::Abstract & get_input_type()
unsigned int n_nodes() const
void add_element(unsigned int elm_id, unsigned int dim, unsigned int region_id, unsigned int partition_id, std::vector< unsigned int > node_ids)
Add new element of given id to mesh.
bool is_valid() const
Returns false if the region has undefined/invalid value.
IntersectionSearch
Types of search algorithm for finding intersection candidates.
void element_to_neigh_vb()
const Node * node(unsigned int i) const
void reinit(Input::Record in_record)
FullIter end()
Returns FullFullIterer of the fictions past the end element.
#define FOR_SIDES(_mesh_, it)
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
bool find_lower_dim_element(ElementVector &elements, vector< unsigned int > &element_list, unsigned int dim, unsigned int &element_idx)
std::shared_ptr< Partitioning > part_
void make_neighbours_and_edges()
NodeVector node_vector
Vector of nodes of the mesh.
double global_observe_radius() const
Maximal distance of observe point from Mesh relative to its size.
Main class for computation of intersection of meshes of combined dimensions.
ElementVector element
Vector of elements of the mesh.
unsigned int n_nodes() const
unsigned int idx() const
Returns a global index of the region.
std::vector< BoundingBox > element_box_
Auxiliary vector of mesh elements bounding boxes.
IdxInt * el_4_loc
Index set assigning to local element index its global index.