31 #include <boost/tokenizer.hpp> 32 #include "boost/lexical_cast.hpp" 70 "Use BIH for finding initial candidates, then continue by prolongation.")
72 "Use BIH for finding all candidates.")
74 "Use bounding boxes for finding initial candidates, then continue by prolongation.")
79 return IT::Record(
"Mesh",
"Record with mesh related data." )
82 "Input file with mesh description.")
84 "List of additional region and region set definitions not contained in the mesh. " 85 "There are three region sets implicitly defined:\n\n" 86 "- ALL (all regions of the mesh)\n" 87 "- .BOUNDARY (all boundary regions)\n" 88 "- BULK (all bulk regions)")
92 IT::Default(
"\"BIHsearch\""),
"Search algorithm for element intersections.")
94 "Maximal distance of observe point from Mesh relative to its size (bounding box). " 95 "Value is global and it can be rewrite at arbitrary ObservePoint by setting the key search_radius.")
110 istringstream is(
"{mesh_file=\"\"}");
152 for(
int i=0; i < 3; i++) {
154 for(
int j=0; j < i+2; j++)
158 for (
unsigned int sid=0; sid<RefElement<1>::n_sides; sid++)
159 for (
unsigned int nid=0; nid<RefElement<1>::n_nodes_per_side; nid++)
162 for (
unsigned int sid=0; sid<RefElement<2>::n_sides; sid++)
163 for (
unsigned int nid=0; nid<RefElement<2>::n_nodes_per_side; nid++)
166 for (
unsigned int sid=0; sid<RefElement<3>::n_sides; sid++)
167 for (
unsigned int nid=0; nid<RefElement<3>::n_nodes_per_side; nid++)
174 if (edg.side_)
delete[] edg.side_;
177 if (ele->node)
delete[] ele->node;
178 if (ele->edge_idx_)
delete[] ele->edge_idx_;
179 if (ele->permutation_idx_)
delete[] ele->permutation_idx_;
180 if (ele->boundary_idx_)
delete[] ele->boundary_idx_;
181 if (ele->neigh_vb)
delete[] ele->neigh_vb;
208 unsigned int li, count = 0;
228 switch (elm->dim()) {
283 for (
auto elem_to_region : map) {
299 if (ele->quality_measure_smooth() < 0.001)
WarningOut().fmt(
"Bad quality (<0.001) of the element {}.\n", ele.id());
312 id_4_old[i++] = ele.index();
338 for (
unsigned int n=0; n<e->n_nodes(); n++)
342 stable_sort(n->begin(), n->end());
348 if (nodes_list.size() == 0) {
349 intersection_element_list.clear();
350 }
else if (nodes_list.size() == 1) {
355 intersection_element_list.resize(
node_elements[*it1].size() );
357 it1=set_intersection(
360 intersection_element_list.begin());
361 intersection_element_list.resize(it1-intersection_element_list.begin());
363 for(;it2<nodes_list.end();++it2) {
364 it1=set_intersection(
365 intersection_element_list.begin(), intersection_element_list.end(),
367 intersection_element_list.begin());
368 intersection_element_list.resize(it1-intersection_element_list.begin());
375 unsigned int dim,
unsigned int &element_idx) {
376 bool is_neighbour =
false;
380 if (elements[*ele].dim() == dim) {
383 }
else if (elements[*ele].dim() == dim-1) {
384 if (is_neighbour)
xprintf(
UsrErr,
"Too matching elements id: %d and id: %d in the same mesh.\n",
385 elements(*ele).id(), elements(element_idx).id() );
390 element_list.resize( e_dest - element_list.begin());
398 && find(side_nodes.begin(), side_nodes.end(),
node_vector.
index( si->
node(ni) ) ) != side_nodes.end() ) ni++;
399 return ( ni == si->
n_nodes() );
415 unsigned int ngh_element_idx, last_edge_idx;
428 side_nodes.resize(bc_ele->n_nodes());
429 for (
unsigned n=0; n<bc_ele->n_nodes(); n++) side_nodes[n] =
node_vector.
index(bc_ele->node[n]);
433 xprintf(
UsrErr,
"Boundary element (id: %d) match a regular element (id: %d) of lower dimension.\n",
434 bc_ele.id(),
element(ngh_element_idx).id());
436 if (intersection_list.size() == 0) {
438 WarningOut().fmt(
"Lonely boundary element, id: {}, region: {}, dimension {}.\n",
439 bc_ele.id(), bc_ele->region().id(), bc_ele->dim());
442 last_edge_idx=
edges.size();
443 edges.resize(last_edge_idx+1);
444 edg = &(
edges.back() );
446 edg->
side_ =
new struct SideIter[ intersection_list.size() ];
460 for (
unsigned int ecs=0; ecs<elem->
n_sides(); ecs++) {
466 int new_bc_ele_idx=bc_ele.index();
467 THROW( ExcDuplicateBoundary()
469 << EI_RegLast(this->
bc_elements[last_bc_ele_idx].region().label())
471 << EI_RegNew(this->
bc_elements[new_bc_ele_idx].region().label())
493 for (
unsigned int s=0; s<e->n_sides(); s++)
500 side_nodes.resize(e->side(s)->n_nodes());
501 for (
unsigned n=0; n<e->side(s)->n_nodes(); n++) side_nodes[n] =
node_vector.
index(e->side(s)->node(n));
510 last_edge_idx=
edges.size();
511 edges.resize(last_edge_idx+1);
512 edg = &(
edges.back() );
514 edg->
side_ =
new struct SideIter[ intersection_list.size() ];
518 if (intersection_list.size() == 1) {
520 edg->
side_[0] = e->side(s);
521 e->edge_idx_[s] = last_edge_idx;
523 if (e->boundary_idx_ == NULL) {
524 e->boundary_idx_ =
new unsigned int [ e->n_sides() ];
525 std::fill( e->boundary_idx_, e->boundary_idx_ + e->n_sides(),
Mesh::undef_idx);
531 e->boundary_idx_[s] = bdr_idx;
537 for(
unsigned int ni = 0; ni< side_nodes.size(); ni++) bc_ele->node[ni] = &(
node_vector[side_nodes[ni]] );
551 for (
unsigned int ecs=0; ecs<elem->
n_sides(); ecs++) {
557 last_edge_idx=
edges.size();
558 edges.resize(last_edge_idx+1);
559 edg = &(
edges.back() );
577 OLD_ASSERT( is_neighbour || ( (
unsigned int) edg->
n_sides ) == intersection_list.size(),
"Some connected sides were not found.\n");
591 edg->side(0)->element()->permutation_idx_[edg->side(0)->el_idx()] = 0;
593 if (edg->n_sides > 1)
596 unsigned int permutation[edg->side(0)->n_nodes()];
598 for (
unsigned int i=0; i<edg->side(0)->n_nodes(); i++)
599 node_numbers[edg->side(0)->node(i)] = i;
601 for (
int sid=1; sid<edg->n_sides; sid++)
603 for (
unsigned int i=0; i<edg->side(0)->n_nodes(); i++)
604 permutation[node_numbers[edg->side(sid)->node(i)]] = i;
606 switch (edg->side(0)->dim())
625 unsigned int permutation[nb->element()->n_nodes()];
629 for (
unsigned int i=0; i<nb->element()->n_nodes(); i++)
630 node_numbers[nb->element()->node[i]] = i;
632 for (
unsigned int i=0; i<nb->side()->n_nodes(); i++)
633 permutation[node_numbers[nb->side()->node(i)]] = i;
635 switch (nb->side()->dim())
669 if( ele->n_neighs_vb > 0 ) {
670 ele->neigh_vb =
new struct Neighbour* [ele->n_neighs_vb];
677 ele =
ngh->element();
698 intersections = std::make_shared<MixedMeshIntersections>(
this);
721 for(
unsigned int idx=0; idx <
element.
size(); idx++, ++map_it) {
723 if (last_id >=
id)
xprintf(
UsrErr,
"Element IDs in non-increasing order, ID: %d\n",
id);
724 last_id=*map_it = id;
735 if (
id < 0) last_id=*map_it=-1;
737 if (last_id >=
id)
xprintf(
UsrErr,
"Element IDs in non-increasing order, ID: %d\n",
id);
738 last_id=*map_it = id;
750 it != region_list.
end();
795 bih_tree_ = std::make_shared<BIHTree>(
this);
800 return in_record_.
val<
double>(
"global_observe_search_radius");
Distribution * el_ds
Parallel distribution of elements.
Class for the mesh partitioning. This should provide:
Mesh(Input::Record in_record, MPI_Comm com=MPI_COMM_WORLD)
Bounding box in 3d ambient space.
#define FOR_ELEMENT_NODES(i, j)
vector< vector< unsigned int > > node_elements
unsigned int * boundary_idx_
int get_id(const T *it) const
MapElementIDToRegionID el_to_reg_map_
MixedMeshIntersections & mixed_intersections()
#define FOR_ELEMENTS(_mesh_, __i)
#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.
void expand(const Point &point)
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)
vector< Boundary > boundary_
Partitioning * get_part()
int * el_4_loc
Index set assigning to local element index its global index.
void compute_element_boxes()
Precompute element bounding boxes if it is not done yet.
int * row_4_el
Index set assigning to global element index the local index used in parallel vectors.
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 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
vector< int > const & elements_id_maps(bool boundary_domain) const
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)
void read_mesh(Mesh *mesh)
vector< int > boundary_elements_id_
void count_element_types()
const BIHTree & get_bih_tree()
Getter for BIH. Creates and compute BIH at first call.
Dedicated class for storing path to input and output files.
void read_gmsh_from_stream(istream &in)
void mark_used_region(unsigned int idx)
void print_region_table(ostream &stream) const
Support classes for parallel programing.
vector< Neighbour > vb_neighbours_
void read_physical_names(Mesh *mesh)
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
Base of exceptions used in Flow123d.
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)
vector< int > bulk_elements_id_
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.