38 std::map<Node*, bool> done;
45 for (
unsigned e = 0;
e < nelem;
e++)
48 for (
unsigned j = 0; j < nnod_el; j++)
58 std::ostringstream error_stream;
60 unsigned nnod =
nnode();
61 for (
unsigned j = 0; j < nnod; j++)
65 error_stream <<
"Scaffold node " << j
66 <<
" does not seem to be attached to any element";
73 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
90 std::ifstream element_file(ele_file_name.c_str(), std::ios_base::in);
93 if (!element_file.is_open())
95 std::string error_msg(
"Failed to open element file: ");
96 error_msg +=
"\"" + ele_file_name +
"\".";
98 error_msg, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
103 element_file >> n_element;
106 unsigned n_local_node;
107 element_file >> n_local_node;
108 if (n_local_node != 3)
110 std::ostringstream error_stream;
112 <<
"Triangle should only be used to generate 3-noded triangles!\n"
113 <<
"Your triangle input file, contains data for " << n_local_node
114 <<
"-noded triangles" << std::endl;
117 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
121 unsigned dummy_attribute;
127 unsigned dummy_element_number;
133 std::map<unsigned, bool> global_node_done;
140 unsigned attribute_flag;
141 element_file >> attribute_flag;
144 if (attribute_flag == 0)
146 for (
unsigned i = 0;
i < n_element;
i++)
148 element_file >> dummy_element_number;
149 for (
unsigned j = 0; j < n_local_node; j++)
161 for (
unsigned i = 0;
i < n_element;
i++)
163 element_file >> dummy_element_number;
164 for (
unsigned j = 0; j < n_local_node; j++)
175 element_file.close();
183 std::string err(
"Triangle is using 0-based indexing, ");
184 err +=
"however the oomph-lib interface can only handle 1-based indexing "
187 "This is likely to be due to the input file using 0-based indexing.";
188 err +=
"Alternatively you may have specified the -z flag when running "
191 err, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
200 std::ifstream node_file(node_file_name.c_str(), std::ios_base::in);
203 if (!node_file.is_open())
205 std::string error_msg(
"Failed to open node file: ");
206 error_msg +=
"\"" + node_file_name +
"\".";
208 error_msg, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
216 std::vector<bool> done(n_node,
false);
223 node_file >> dimension;
229 OOMPH_CURRENT_FUNCTION,
230 OOMPH_EXCEPTION_LOCATION);
235 node_file >> attribute_flag;
238 unsigned boundary_markers_flag;
239 node_file >> boundary_markers_flag;
242 unsigned dummy_node_number;
250 if (attribute_flag == 0)
252 if (boundary_markers_flag == 1)
254 for (
unsigned i = 0;
i < n_node;
i++)
256 node_file >> dummy_node_number;
257 node_file >> x_node[
i];
258 node_file >> y_node[
i];
259 node_file >> bound[
i];
265 for (
unsigned i = 0;
i < n_node;
i++)
267 node_file >> dummy_node_number;
268 node_file >> x_node[
i];
269 node_file >> y_node[
i];
277 if (boundary_markers_flag == 1)
279 for (
unsigned i = 0;
i < n_node;
i++)
281 node_file >> dummy_node_number;
282 node_file >> x_node[
i];
283 node_file >> y_node[
i];
284 node_file >> dummy_attribute;
285 node_file >> bound[
i];
291 for (
unsigned i = 0;
i < n_node;
i++)
293 node_file >> dummy_node_number;
294 node_file >> x_node[
i];
295 node_file >> y_node[
i];
296 node_file >> dummy_attribute;
306 unsigned n_bound = 0;
307 if (boundary_markers_flag == 1)
310 for (
unsigned i = 1;
i < n_node;
i++)
312 if (bound[
i] > n_bound)
323 std::ifstream poly_file(poly_file_name.c_str(), std::ios_base::in);
326 if (!poly_file.is_open())
328 std::string error_msg(
"Failed to open poly file: ");
329 error_msg +=
"\"" + poly_file_name +
"\".";
331 error_msg, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
335 unsigned n_node_poly;
336 poly_file >> n_node_poly;
339 poly_file >> dimension;
342 poly_file >> attribute_flag;
345 poly_file >> boundary_markers_flag;
353 if (attribute_flag == 0)
355 if (boundary_markers_flag == 1)
357 for (
unsigned i = 0;
i < n_node_poly;
i++)
367 for (
unsigned i = 0;
i < n_node_poly;
i++)
377 if (boundary_markers_flag == 1)
379 for (
unsigned i = 0;
i < n_node_poly;
i++)
390 for (
unsigned i = 0;
i < n_node_poly;
i++)
407 poly_file >> n_segment;
410 poly_file >> boundary_markers_flag;
421 unsigned dummy_segment_number;
428 for (
unsigned i = 0;
i < n_segment;
i++)
430 poly_file >> dummy_segment_number;
431 poly_file >> first_node[
i];
432 poly_file >> second_node[
i];
433 poly_file >> segment_boundary[
i];
435 if (segment_boundary[
i] > n_bound)
437 n_bound = segment_boundary[
i];
440 node_on_edges[first_node[
i]].insert(
i);
441 node_on_edges[second_node[
i]].insert(
i);
454 for (
unsigned ihole = 0; ihole < nhole; ihole++)
459 poly_file >> dummy_hole;
482 unsigned counter = 0;
483 for (
unsigned e = 0;
e < n_element;
e++)
486 for (
unsigned j = 0; j < n_local_node; j++)
493 if ((boundary_markers_flag == 1) &&
531 unsigned glob_num[3] = {0, 0, 0};
541 for (
unsigned e = 0;
e < n_element;
e++)
547 for (
unsigned i = 0;
i < 3;
i++)
553 const unsigned element_offset =
e * n_local_node;
554 for (
unsigned i = 0;
i < 3;
i++)
566 for (
unsigned i = 0;
i < 3;
i++)
568 std::vector<unsigned> local_edge_index;
572 std::set_intersection(node_on_edges[glob_num[
i]].begin(),
573 node_on_edges[glob_num[
i]].end(),
574 node_on_edges[glob_num[(
i + 1) % 3]].begin(),
575 node_on_edges[glob_num[(
i + 1) % 3]].end(),
576 std::insert_iterator<std::vector<unsigned>>(
577 local_edge_index, local_edge_index.begin()));
581 if (local_edge_index.size() > 1)
584 "Nodes in scaffold mesh share more than one global edge",
585 OOMPH_CURRENT_FUNCTION,
586 OOMPH_EXCEPTION_LOCATION);
591 if (local_edge_index.size() == 0)
602 else if (local_edge_index.size() == 1)
607 if (local_edge_index[0] < n_segment)
615 Node_pt[glob_num[(
i + 1) % 3] - 1]);
623 std::ostringstream error_stream;
625 unsigned nnod =
nnode();
626 error_stream <<
"Checking presence of " << nnod <<
" global nodes\n";
627 for (
unsigned j = 0; j < nnod; j++)
629 if (!global_node_done[j])
631 error_stream <<
"Global node " << j
632 <<
" was not listed in *.ele file\n";
639 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
647 #ifdef OOMPH_HAS_TRIANGLE_LIB
659 unsigned n_local_node =
661 if (n_local_node != 3)
663 std::ostringstream error_stream;
665 <<
"Triangle should only be used to generate 3-noded triangles!\n"
666 <<
"Your triangle input file, contains data for " << n_local_node
667 <<
"-noded triangles" << std::endl;
670 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
680 std::map<unsigned, bool> global_node_done;
687 unsigned attribute_flag =
691 if (attribute_flag == 0)
693 for (
unsigned i = 0;
i < n_element;
i++)
695 for (
unsigned j = 0; j < n_local_node; j++)
707 for (
unsigned i = 0;
i < n_element;
i++)
709 for (
unsigned j = 0; j < n_local_node; j++)
728 std::vector<bool> done(n_node,
false);
734 unsigned boundary_markers_flag = 0;
737 boundary_markers_flag = 1;
746 if (boundary_markers_flag == 1)
748 for (
unsigned i = 0;
i < n_node;
i++)
757 for (
unsigned i = 0;
i < n_node;
i++)
767 unsigned n_bound = 0;
768 if (boundary_markers_flag == 1)
771 for (
unsigned i = 1;
i < n_node;
i++)
773 if (bound[
i] > n_bound)
800 for (
unsigned i = 0;
i < n_segment;
i++)
802 first_node[
i] =
static_cast<unsigned>(triangle_data.
segmentlist[2 *
i]);
804 static_cast<unsigned>(triangle_data.
segmentlist[2 *
i + 1]);
805 segment_boundary[
i] =
808 if (segment_boundary[
i] > n_bound)
810 n_bound = segment_boundary[
i];
813 node_on_edges[first_node[
i]].insert(
i);
814 node_on_edges[second_node[
i]].insert(
i);
824 unsigned count_coords = 0;
827 for (
unsigned ihole = 0; ihole < nhole; ihole++)
856 unsigned counter = 0;
857 for (
unsigned e = 0;
e < n_element;
e++)
860 for (
unsigned j = 0; j < n_local_node; j++)
867 if ((boundary_markers_flag == 1) &&
906 unsigned glob_num[3] = {0, 0, 0};
916 for (
unsigned e = 0;
e < n_element;
e++)
922 for (
unsigned i = 0;
i < 3;
i++)
928 const unsigned element_offset =
e * n_local_node;
929 for (
unsigned i = 0;
i < 3;
i++)
941 for (
unsigned i = 0;
i < 3;
i++)
943 std::vector<unsigned> local_edge_index;
947 std::set_intersection(node_on_edges[glob_num[
i]].begin(),
948 node_on_edges[glob_num[
i]].end(),
949 node_on_edges[glob_num[(
i + 1) % 3]].begin(),
950 node_on_edges[glob_num[(
i + 1) % 3]].end(),
951 std::insert_iterator<std::vector<unsigned>>(
952 local_edge_index, local_edge_index.begin()));
956 if (local_edge_index.size() > 1)
959 "Nodes in scaffold mesh share more than one global edge",
960 OOMPH_CURRENT_FUNCTION,
961 OOMPH_EXCEPTION_LOCATION);
967 if (local_edge_index.size() == 0)
978 else if (local_edge_index.size() == 1)
983 if (local_edge_index[0] < n_segment)
991 Node_pt[glob_num[(
i + 1) % 3] - 1]);
999 std::ostringstream error_stream;
1000 bool broken =
false;
1001 unsigned nnod =
nnode();
1002 error_stream <<
"Checking presence of " << nnod <<
" global nodes\n";
1003 for (
unsigned j = 0; j < nnod; j++)
1005 if (!global_node_done[j])
1007 error_stream <<
"Global node " << j
1008 <<
" was not listed in *.ele file\n";
1015 <<
"This error means that some of the nodes are not connected \n"
1016 <<
" to (bulk) elements. This can happen if there is an isolated\n"
1017 <<
" boundary line in the mesh. One possible cause for this is\n"
1018 <<
" specifying a hole coordinate in the wrong place so that there\n"
1019 <<
" a gap between the mesh and the outer boundary.\n";
1021 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
unsigned nnode() const
Return the number of nodes.
virtual Node * construct_boundary_node(const unsigned &n)
Construct the local node n as a boundary node; that is a node that MAY be placed on a mesh boundary a...
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Vector< Node * > Node_pt
Vector of pointers to nodes.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
unsigned long nnode() const
Return number of nodes in the mesh.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
unsigned long nelement() const
Return number of elements in the mesh.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
An OomphLibError object which should be thrown when an run-time error is encountered....
unsigned global_node_number(const unsigned &i)
Return the global node of each local node listed element-by-element e*n_local_node + n_local Note tha...
Vector< unsigned > Global_node
Storage for global node numbers listed element-by-element.
void check_mesh_integrity()
Check mesh integrity – performs some internal consistency checks and throws error if violated.
unsigned Nglobal_edge
Number of internal edges.
Vector< double > Element_attribute
Vector of double attributes for each element.
TriangleScaffoldMesh()
Empty constructor.
Vector< Vector< unsigned > > Edge_boundary
Vector of vectors containing the boundary ids of the elements' edges.
Vector< Vector< double > > Hole_centre
Vectors of hole centre coordinates.
Vector< Vector< unsigned > > Edge_index
Vector of vectors containing the global edge index of.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
The Triangle data structure, modified from the triangle.h header supplied with triangle 1....
double * pointlist
Pointer to list of points x coordinate followed by y coordinate.
int numberoftriangleattributes
int * pointmarkerlist
Pointer to list of point markers.
double * triangleattributelist