55 return IT::Record(
"Mesh",
"Record with mesh related data." )
58 "Input file with mesh description.")
60 "List of additional region and region set definitions not contained in the mesh. " 61 "There are three region sets implicitly defined:\n\n" 62 "- ALL (all regions of the mesh)\n" 63 "- .BOUNDARY (all boundary regions)\n" 64 "- BULK (all bulk regions)")
91 istringstream is(
"{mesh_file=\"\"}");
129 for(
int i=0; i < 3; i++) {
131 for(
int j=0; j < i+2; j++)
135 for (
unsigned int sid=0; sid<RefElement<1>::n_sides; sid++)
136 for (
unsigned int nid=0; nid<RefElement<1>::n_nodes_per_side; nid++)
139 for (
unsigned int sid=0; sid<RefElement<2>::n_sides; sid++)
140 for (
unsigned int nid=0; nid<RefElement<2>::n_nodes_per_side; nid++)
143 for (
unsigned int sid=0; sid<RefElement<3>::n_sides; sid++)
144 for (
unsigned int nid=0; nid<RefElement<3>::n_nodes_per_side; nid++)
151 if (edg.side_)
delete[] edg.side_;
154 if (ele->node)
delete[] ele->node;
155 if (ele->edge_idx_)
delete[] ele->edge_idx_;
156 if (ele->permutation_idx_)
delete[] ele->permutation_idx_;
157 if (ele->boundary_idx_)
delete[] ele->boundary_idx_;
158 if (ele->neigh_vb)
delete[] ele->neigh_vb;
185 unsigned int li, count = 0;
205 switch (elm->dim()) {
221 for (
auto elem_to_region : map) {
237 if (ele->quality_measure_smooth() < 0.001)
WarningOut().fmt(
"Bad quality (<0.001) of the element {}.\n", ele.id());
250 id_4_old[i++] = ele.index();
276 for (
unsigned int n=0; n<e->n_nodes(); n++)
280 stable_sort(n->begin(), n->end());
286 if (nodes_list.size() == 0) {
287 intersection_element_list.clear();
288 }
else if (nodes_list.size() == 1) {
295 it1=set_intersection(
298 intersection_element_list.begin());
299 intersection_element_list.resize(it1-intersection_element_list.begin());
301 for(;it2<nodes_list.end();++it2) {
302 it1=set_intersection(
303 intersection_element_list.begin(), intersection_element_list.end(),
305 intersection_element_list.begin());
306 intersection_element_list.resize(it1-intersection_element_list.begin());
313 unsigned int dim,
unsigned int &element_idx) {
314 bool is_neighbour =
false;
318 if (elements[*ele].dim() == dim) {
321 }
else if (elements[*ele].dim() == dim-1) {
322 if (is_neighbour)
xprintf(
UsrErr,
"Too matching elements id: %d and id: %d in the same mesh.\n",
323 elements(*ele).id(), elements(element_idx).id() );
328 element_list.resize( e_dest - element_list.begin());
336 && find(side_nodes.begin(), side_nodes.end(),
node_vector.
index( si->
node(ni) ) ) != side_nodes.end() ) ni++;
337 return ( ni == si->
n_nodes() );
353 unsigned int ngh_element_idx, last_edge_idx;
366 side_nodes.resize(bc_ele->n_nodes());
367 for (
unsigned n=0; n<bc_ele->n_nodes(); n++) side_nodes[n] =
node_vector.
index(bc_ele->node[n]);
371 xprintf(
UsrErr,
"Boundary element (id: %d) match a regular element (id: %d) of lower dimension.\n",
372 bc_ele.id(),
element(ngh_element_idx).id());
374 if (intersection_list.size() == 0) {
376 WarningOut().fmt(
"Lonely boundary element, id: {}, region: {}, dimension {}.\n",
377 bc_ele.id(), bc_ele->region().id(), bc_ele->dim());
380 last_edge_idx=
edges.size();
381 edges.resize(last_edge_idx+1);
382 edg = &(
edges.back() );
384 edg->
side_ =
new struct SideIter[ intersection_list.size() ];
398 for (
unsigned int ecs=0; ecs<elem->
n_sides(); ecs++) {
404 int new_bc_ele_idx=bc_ele.index();
405 THROW( ExcDuplicateBoundary()
407 << EI_RegLast(this->
bc_elements[last_bc_ele_idx].region().label())
409 << EI_RegNew(this->
bc_elements[new_bc_ele_idx].region().label())
431 for (
unsigned int s=0; s<e->n_sides(); s++)
438 side_nodes.resize(e->side(s)->n_nodes());
439 for (
unsigned n=0; n<e->side(s)->n_nodes(); n++) side_nodes[n] =
node_vector.
index(e->side(s)->node(n));
448 last_edge_idx=
edges.size();
449 edges.resize(last_edge_idx+1);
450 edg = &(
edges.back() );
452 edg->
side_ =
new struct SideIter[ intersection_list.size() ];
456 if (intersection_list.size() == 1) {
458 edg->
side_[0] = e->side(s);
459 e->edge_idx_[s] = last_edge_idx;
461 if (e->boundary_idx_ == NULL) {
462 e->boundary_idx_ =
new unsigned int [ e->n_sides() ];
463 std::fill( e->boundary_idx_, e->boundary_idx_ + e->n_sides(),
Mesh::undef_idx);
469 e->boundary_idx_[s] = bdr_idx;
475 for(
unsigned int ni = 0; ni< side_nodes.size(); ni++) bc_ele->node[ni] = &(
node_vector[side_nodes[ni]] );
489 for (
unsigned int ecs=0; ecs<elem->
n_sides(); ecs++) {
495 last_edge_idx=
edges.size();
496 edges.resize(last_edge_idx+1);
497 edg = &(
edges.back() );
515 OLD_ASSERT( is_neighbour || ( (
unsigned int) edg->
n_sides ) == intersection_list.size(),
"Some connected sides were not found.\n");
529 edg->side(0)->element()->permutation_idx_[edg->side(0)->el_idx()] = 0;
531 if (edg->n_sides > 1)
534 unsigned int permutation[edg->side(0)->n_nodes()];
536 for (
unsigned int i=0; i<edg->side(0)->n_nodes(); i++)
537 node_numbers[edg->side(0)->node(i)] = i;
539 for (
int sid=1; sid<edg->n_sides; sid++)
541 for (
unsigned int i=0; i<edg->side(0)->n_nodes(); i++)
542 permutation[node_numbers[edg->side(sid)->node(i)]] = i;
544 switch (edg->side(0)->dim())
563 unsigned int permutation[nb->element()->n_nodes()];
567 for (
unsigned int i=0; i<nb->element()->n_nodes(); i++)
568 node_numbers[nb->element()->node[i]] = i;
570 for (
unsigned int i=0; i<nb->side()->n_nodes(); i++)
571 permutation[node_numbers[nb->side()->node(i)]] = i;
573 switch (nb->side()->dim())
607 if( ele->n_neighs_vb > 0 ) {
608 ele->neigh_vb =
new struct Neighbour* [ele->n_neighs_vb];
615 ele =
ngh->element();
641 for(
unsigned int i_ele=0; i_ele<
n_elements(); i_ele++) {
644 if (ele.
dim() == 1) {
649 for(
unsigned int i_elm : candidate_list) {
651 if (elm->dim() == 2) {
677 if (bulk_elements_id.size() ==0) {
682 map_it = bulk_elements_id.begin();
684 for(
unsigned int idx=0; idx <
element.
size(); idx++, ++map_it) {
686 if (last_id >=
id)
xprintf(
UsrErr,
"Element IDs in non-increasing order, ID: %d\n",
id);
687 last_id=*map_it = id;
691 map_it = boundary_elements_id.begin();
698 if (
id < 0) last_id=*map_it=-1;
700 if (last_id >=
id)
xprintf(
UsrErr,
"Element IDs in non-increasing order, ID: %d\n",
id);
701 last_id=*map_it = id;
713 it != region_list.
end();
737 bih_tree_ = std::make_shared<BIHTree>(
this);
749 node->point() = coords;
753 void Mesh::add_element(
unsigned int elm_id,
unsigned int dim,
unsigned int region_id,
unsigned int partition_id,
766 WarningOut().fmt(
"Bulk elements of zero size(dim=0) are not supported. Element ID: {}.\n", elm_id);
772 ele->
init(dim,
this, region_idx);
773 ele->
pid = partition_id;
777 unsigned int node_id = node_ids[ni];
780 "Unknown node id %d in specification of element with id=%d.\n", node_id, elm_id);
781 ele->
node[ni] = node;
Distribution * el_ds
Parallel distribution of elements.
Class for the mesh partitioning. This should provide:
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.
void make_intersec_elements()
MapElementIDToRegionID el_to_reg_map_
#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()
unsigned int max_edge_sides_[3]
Maximal number of sides per one edge in the actual mesh (set in make_neighbours_and_edges()).
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()
int * el_4_loc
Index set assigning to local element index its global index.
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
void elements_id_maps(vector< int > &bulk_elements_id, vector< int > &boundary_elements_id) const
friend class RegionSetBase
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_
vector< vector< unsigned int > > node_elements_
#define INPUT_CHECK(i,...)
Debugging macros.
void init(unsigned int dim, Mesh *mesh_in, RegionIdx reg)
void find_bounding_box(const BoundingBox &boundingBox, std::vector< unsigned int > &result_list) const
void count_element_types()
const BIHTree & get_bih_tree()
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< vector< unsigned int > > master_elements
vector< Neighbour > vb_neighbours_
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
vector< Intersection > intersections
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.
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.
void GetIntersection(const TBisector &, const TBisector &, TPosition &, double &, double &)
bool find_lower_dim_element(ElementVector &elements, vector< unsigned int > &element_list, unsigned int dim, unsigned int &element_idx)
IntersectionType get_type() const
std::shared_ptr< Partitioning > part_
void make_neighbours_and_edges()
NodeVector node_vector
Vector of nodes of the mesh.
ElementVector element
Vector of elements of the mesh.
unsigned int n_nodes() const
unsigned int idx() const
Returns a global index of the region.
BoundingBox bounding_box()