41 #include <boost/tokenizer.hpp>
42 #include "boost/lexical_cast.hpp"
43 #include <boost/make_shared.hpp>
66 namespace IT = Input::Type;
70 =
IT::Record(
"Mesh",
"Record with mesh related data." )
72 "Input file with mesh description.")
74 "List of additional region definitions not contained in the mesh.")
76 "List of region set definitions. There are three region sets implicitly defined:\n"
77 "ALL (all regions of the mesh), BOUNDARY (all boundary regions), and BULK (all bulk regions)")
98 : in_record_(in_record),
131 for(
int i=0; i < 3; i++) {
133 for(
int j=0; j < i+2; j++)
137 for (
unsigned int sid=0; sid<RefElement<1>::n_sides; sid++)
138 for (
unsigned int nid=0; nid<RefElement<1>::n_nodes_per_side; nid++)
141 for (
unsigned int sid=0; sid<RefElement<2>::n_sides; sid++)
142 for (
unsigned int nid=0; nid<RefElement<2>::n_nodes_per_side; nid++)
145 for (
unsigned int sid=0; sid<RefElement<3>::n_sides; sid++)
146 for (
unsigned int nid=0; nid<RefElement<3>::n_nodes_per_side; nid++)
173 switch (elm->dim()) {
230 if (ele->quality_measure_smooth() < 0.001)
xprintf(
Warn,
"Bad quality (<0.001) of the element %u.\n", ele.id());
261 for (
unsigned int n=0; n<e->n_nodes(); n++)
265 stable_sort(n->begin(), n->end());
271 if (nodes_list.size() == 0) {
272 intersection_element_list.clear();
273 }
else if (nodes_list.size() == 1) {
278 intersection_element_list.resize(
node_elements[*it1].size() );
280 it1=set_intersection(
283 intersection_element_list.begin());
284 intersection_element_list.resize(it1-intersection_element_list.begin());
286 for(;it2<nodes_list.end();++it2) {
287 it1=set_intersection(
288 intersection_element_list.begin(), intersection_element_list.end(),
290 intersection_element_list.begin());
291 intersection_element_list.resize(it1-intersection_element_list.begin());
298 unsigned int dim,
unsigned int &element_idx) {
299 bool is_neighbour =
false;
303 if (elements[*ele].dim() == dim) {
306 }
else if (elements[*ele].dim() == dim-1) {
307 if (is_neighbour)
xprintf(
UsrErr,
"Too matching elements id: %d and id: %d in the same mesh.\n",
308 elements(*ele).id(), elements(element_idx).id() );
313 element_list.resize( e_dest - element_list.begin());
321 && find(side_nodes.begin(), side_nodes.end(),
node_vector.
index( si->
node(ni) ) ) != side_nodes.end() ) ni++;
322 return ( ni == si->
n_nodes() );
338 unsigned int ngh_element_idx, last_edge_idx;
351 side_nodes.resize(bc_ele->n_nodes());
352 for (
unsigned n=0; n<bc_ele->n_nodes(); n++) side_nodes[n] =
node_vector.
index(bc_ele->node[n]);
356 xprintf(
UsrErr,
"Boundary element (id: %d) match a regular element (id: %d) of lower dimension.\n",
357 bc_ele.id(),
element(ngh_element_idx).id());
359 if (intersection_list.size() == 0) {
361 xprintf(
Warn,
"Lonely boundary element, id: %d, region: %d, dimension %d.\n", bc_ele.id(), bc_ele->region().id(), bc_ele->dim());
364 last_edge_idx=
edges.size();
365 edges.resize(last_edge_idx+1);
366 edg = &(
edges.back() );
368 edg->
side_ =
new struct SideIter[ intersection_list.size() ];
382 for (
unsigned int ecs=0; ecs<elem->
n_sides(); ecs++) {
404 for (
unsigned int s=0; s<e->n_sides(); s++)
407 if (e->edge_idx_[s] != Mesh::undef_idx)
continue;
411 side_nodes.resize(e->side(s)->n_nodes());
412 for (
unsigned n=0; n<e->side(s)->n_nodes(); n++) side_nodes[n] =
node_vector.
index(e->side(s)->node(n));
421 last_edge_idx=
edges.size();
422 edges.resize(last_edge_idx+1);
423 edg = &(
edges.back() );
425 edg->
side_ =
new struct SideIter[ intersection_list.size() ];
429 if (intersection_list.size() == 1) {
431 edg->
side_[0] = e->side(s);
432 e->edge_idx_[s] = last_edge_idx;
434 if (e->boundary_idx_ == NULL) {
435 e->boundary_idx_ =
new unsigned int [ e->n_sides() ];
436 std::fill( e->boundary_idx_, e->boundary_idx_ + e->n_sides(),
Mesh::undef_idx);
442 e->boundary_idx_[s] = bdr_idx;
447 for(
unsigned int ni = 0; ni< side_nodes.size(); ni++) bc_ele->node[ni] = &(
node_vector[side_nodes[ni]] );
461 for (
unsigned int ecs=0; ecs<elem->
n_sides(); ecs++) {
462 if (elem->
edge_idx_[ecs] != Mesh::undef_idx)
continue;
467 last_edge_idx=
edges.size();
468 edges.resize(last_edge_idx+1);
469 edg = &(
edges.back() );
487 ASSERT( is_neighbour || ( (
unsigned int) edg->
n_sides ) == intersection_list.size(),
"Some connected sides were not found.\n");
501 edg->side(0)->element()->permutation_idx_[edg->side(0)->el_idx()] = 0;
503 if (edg->n_sides > 1)
506 unsigned int permutation[edg->side(0)->n_nodes()];
508 for (
unsigned int i=0; i<edg->side(0)->n_nodes(); i++)
509 node_numbers[edg->side(0)->node(i)] = i;
511 for (
int sid=1; sid<edg->n_sides; sid++)
513 for (
unsigned int i=0; i<edg->side(0)->n_nodes(); i++)
514 permutation[node_numbers[edg->side(sid)->node(i)]] = i;
516 switch (edg->side(0)->dim())
535 unsigned int permutation[nb->element()->n_nodes()];
539 for (
unsigned int i=0; i<nb->element()->n_nodes(); i++)
540 node_numbers[nb->element()->node[i]] = i;
542 for (
unsigned int i=0; i<nb->side()->n_nodes(); i++)
543 permutation[node_numbers[nb->side()->node(i)]] = i;
545 switch (nb->side()->dim())
579 if( ele->n_neighs_vb > 0 ) {
580 ele->neigh_vb =
new struct Neighbour* [ele->n_neighs_vb];
587 ele = ngh->element();
613 for(
unsigned int i_ele=0; i_ele<
n_elements(); i_ele++) {
616 if (ele.
dim() == 1) {
618 for(
unsigned int i_elm=0; i_elm<
n_elements(); i_elm++) {
620 if (elm->dim() == 2) {
653 for(
unsigned int idx=0; idx <
element.
size(); idx++, ++map_it) {
655 if (last_id >=
id)
xprintf(
UsrErr,
"Element IDs in non-increasing order, ID: %d\n",
id);
656 last_id=*map_it = id;
667 if (
id < 0) last_id=*map_it=-1;
669 if (last_id >=
id)
xprintf(
UsrErr,
"Element IDs in non-increasing order, ID: %d\n",
id);
670 last_id=*map_it = id;
Class for the mesh partitioning. This should provide:
Mesh(const std::string &input_str="{mesh_file=\"\"}", MPI_Comm com=MPI_COMM_WORLD)
void read_regions_from_input(Input::Array region_list, MapElementIDToRegionID &map)
vector< vector< unsigned int > > node_elements
unsigned int * boundary_idx_
int get_id(const T *it) const
void read_sets_from_input(Input::Array arr)
void make_intersec_elements()
#define FOR_ELEMENTS(_mesh_, __i)
static const unsigned int undef_idx
void create_node_element_lists()
static unsigned int permutation_index(unsigned int p[n_nodes_per_side])
unsigned int max_edge_sides_[3]
Maximal number of sides per one edge in the actual mesh (set in make_neighbours_and_edges()).
boost::shared_ptr< Partitioning > part_
FullIter add_item(int id)
vector< vector< vector< unsigned int > > > side_nodes
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
vector< Boundary > boundary_
I/O functions with filename storing, able to track current line in opened file. All standard stdio fu...
Partitioning * get_part()
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
unsigned int n_elements() const
bool same_sides(const SideIter &si, vector< unsigned int > &side_nodes)
static Input::Type::Record input_type
std::vector< T >::iterator iterator
vector< int > const & elements_id_maps(bool boundary_domain) const
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()
vector< int > boundary_elements_id_
void count_element_types()
Dedicated class for storing path to input and output files.
void read_gmsh_from_stream(istream &in)
vector< vector< unsigned int > > master_elements
vector< Neighbour > vb_neighbours_
void read_mesh(Mesh *mesh, const RegionDB::MapElementIDToRegionID *el_to_reg_map=NULL)
static Input::Type::Record region_input_type
static Input::Type::Record input_type
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 make_edge_permutations()
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc...
unsigned int n_nodes() const
void element_to_neigh_vb()
static Input::Type::Record region_set_input_type
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)
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)
vector< int > bulk_elements_id_
IntersectionType get_type() const
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