geompack_scaffold_mesh.cc
Go to the documentation of this file.
1// LIC// ====================================================================
2// LIC// This file forms part of oomph-lib, the object-oriented,
3// LIC// multi-physics finite-element library, available
4// LIC// at http://www.oomph-lib.org.
5// LIC//
6// LIC// Copyright (C) 2006-2025 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
27
28namespace oomph
29{
30 //=====================================================================
31 /// Constructor: Pass the filename of the mesh files
32 //=====================================================================
34 const std::string& mesh_file_name, const std::string& curve_file_name)
35 {
36 // Read the output mesh file to find informations about the nodes
37 // and elements of the mesh
38
39 // Process mesh file
40 //---------------------
41 std::ifstream mesh_file(mesh_file_name.c_str(), std::ios_base::in);
42
43 // Number of nodes
44 unsigned n_node;
46
47 // Coordinates of nodes and extra information index
51 for (unsigned i = 0; i < n_node; i++)
52 {
53 mesh_file >> x_node[i];
54 mesh_file >> y_node[i];
56 }
57
58 // Extra information (nodes lying on a curve)
59 unsigned n_vx;
60 mesh_file >> n_vx;
61
62 // Dummy storage for the node code
64
65 // Storage for the curve indice
66 Vector<int> icurv(n_vx); // it's negative if not used
67
68 // Dummy storage for the location of the point on the curve
69 double dummy_ucurv;
70
71 for (unsigned i = 0; i < n_vx; i++)
72 {
74 mesh_file >> icurv[i];
76 }
77
78 // Number of local nodes per element
79 unsigned n_local_node;
81
82 // Number of elements
83 unsigned n_element;
85
86 // Storage for global node numbers for all elements
88
89 // Storage for edge information
90 // (needed for a possible construction of midside node
91 // in the following build from scaffold function)
93
94 // Initialize counter
95 unsigned k = 0;
96
97 // Read global node numbers for all elements
98 for (unsigned i = 0; i < n_element; i++)
99 {
100 for (unsigned j = 0; j < n_local_node; j++)
101 {
103 k++;
104 }
105 }
106
107 // Initialize counter
108 unsigned l = 0;
109
110 // Read the edge information
111 for (unsigned i = 0; i < n_element; i++)
112 {
113 for (unsigned j = 0; j < n_local_node; j++)
114 {
115 mesh_file >> edgeinfo[l];
116 l++;
117 }
118 }
119
120 mesh_file.close();
121
122 // Create a vector of boolean so as not to create the same node twice
123 std::vector<bool> done(n_node);
124 for (unsigned i = 0; i < n_node; i++)
125 {
126 done[i] = false;
127 }
128
129 // Resize the Node vector
130 Node_pt.resize(n_node, 0);
131
132 // Resize the Element vector
133 Element_pt.resize(n_element);
134
135
136 // Process curve file to extract information about boundaries
137 // ----------------------------------------------------------
138
139 // Important: the input file must NOT have NURBS curve
140 std::ifstream curve_file(curve_file_name.c_str(), std::ios_base::in);
141
142 // Number of curves
143 unsigned n_curv;
145
146 // Storage of several information for each curve
148
149 // Resize to n_curv rows
150 curv.resize(n_curv);
151
152 // Curve type
153 unsigned type;
154
155 // Loop over the curves to extract information
156 for (unsigned i = 0; i < n_curv; i++)
157 {
158 curve_file >> type;
159 if (type == 1)
160 {
161 curv[i].resize(4);
162 curv[i][0] = type;
163 for (unsigned j = 1; j < 4; j++)
164 {
165 curve_file >> curv[i][j];
166 }
167 }
168 else if (type == 2)
169 {
170 curv[i].resize(5);
171 curv[i][0] = type;
172 for (unsigned j = 1; j < 5; j++)
173 {
174 curve_file >> curv[i][j];
175 }
176 }
177 else
178 {
179 std::ostringstream error_stream;
180 error_stream << "Current we can only process curves of\n"
181 << "type 1 (straight lines) and 2 (circular arcs\n"
182 << "You've specified: type " << type << std::endl;
183
184 throw OomphLibError(
186 }
187 }
188
189 curve_file.close();
190
191 // Searching the number of boundaries
192 int d = 0;
193 for (unsigned i = 0; i < n_curv; i++)
194 {
195 if (d < curv[i][1])
196 {
197 d = curv[i][1]; // the boundary code is the 2nd value of each curve
198 }
199 }
200 oomph_info << "The number of boundaries is " << d << std::endl;
201
202 // Set number of boundaries
203 if (d > 0)
204 {
205 set_nboundary(d);
206 }
207
208 // Search the boundary number of node located on a boundary
209 // If after this, boundary_of_node[j][0] is -1 then node j
210 // is not located on any boundary.
211 // If boundary_of_node[j][0] is positive, the node is located
212 // on the boundary indicated by that number.
213 // If boundary_of_node[j][1] is also positive, the node is also
214 // located on that boundary. Note: We're ignoring the (remote)
215 // possibility that node is located on 3 or more boundaries
216 // as one of them would have to be an internal boundary which
217 // would be odd...
219 boundary_of_node.resize(n_node);
220 unsigned n;
221 for (unsigned i = 0; i < n_node; i++)
222 {
223 n = 0;
224 boundary_of_node[i].resize(2);
225 boundary_of_node[i][0] = -1;
226 boundary_of_node[i][1] = -1;
227 if (vertinfo[i] == 2) // it's an endpoint
228 {
229 for (unsigned j = 0; j < n_curv; j++)
230 {
231 for (unsigned m = 2; m < curv[j].size(); m++)
232 {
233 if (curv[j][m] ==
234 static_cast<int>(i + 1)) // node number begins at 1
235 { // in the mesh file !!!
236 boundary_of_node[i][n] = curv[j][1];
237 n++;
238 }
239 }
240 }
241 }
242 if (vertinfo[i] > 20)
243 {
244 int a = 0;
245 a = (vertinfo[i]) / 20;
246 int b;
247 b = icurv[a - 1]; // 1st value of vector at [0] !!
248 boundary_of_node[i][0] =
249 curv[b - 1][1]; // 1st value of vector at [0] !!
250 }
251 }
252
253
254 // Create the elements
255 //--------------------
256
257 unsigned count = 0;
258 unsigned c;
259 for (unsigned e = 0; e < n_element; e++)
260 {
261 // Build simplex four node quad in the scaffold mesh
263
264 // Construction of the two first nodes of the element
265 for (unsigned j = 0; j < 2; j++)
266 {
267 c = global_node[count];
268 if (done[c - 1] == false) // c-1 because node number begins
269 // at 1 in the mesh file
270 {
271 // If the node is located on a boundary construct a boundary node
272 if ((d > 0) && ((boundary_of_node[c - 1][0] > 0) ||
273 (boundary_of_node[c - 1][1] > 0)))
274 {
275 // Construct a boundary node
277 // Add to the look=up schemes
278 if (boundary_of_node[c - 1][0] > 0)
279 {
280 add_boundary_node(boundary_of_node[c - 1][0] - 1, Node_pt[c - 1]);
281 }
282 if (boundary_of_node[c - 1][1] > 0)
283 {
284 add_boundary_node(boundary_of_node[c - 1][1] - 1, Node_pt[c - 1]);
285 }
286 }
287 // Otherwise construct a normal node
288 else
289 {
291 }
292 done[c - 1] = true;
293 Node_pt[c - 1]->x(0) = x_node[c - 1];
294 Node_pt[c - 1]->x(1) = y_node[c - 1];
295 }
296 else
297 {
298 finite_element_pt(e)->node_pt(j) = Node_pt[c - 1];
299 }
300 count++;
301 }
302
303 // Construction of the third node not in anticlockwise order
304 c = global_node[count + 1];
305 if (done[c - 1] ==
306 false) // c-1 because node number begins at 1 in the mesh file
307 {
308 // If the node is on a boundary, construct a boundary node
309 if ((d > 0) && ((boundary_of_node[c - 1][0] > 0) ||
310 (boundary_of_node[c - 1][1] > 0)))
311 {
312 // Construct the node
314 // Add to the look-up schemes
315 if (boundary_of_node[c - 1][0] > 0)
316 {
317 add_boundary_node(boundary_of_node[c - 1][0] - 1, Node_pt[c - 1]);
318 }
319 if (boundary_of_node[c - 1][1] > 0)
320 {
321 add_boundary_node(boundary_of_node[c - 1][1] - 1, Node_pt[c - 1]);
322 }
323 }
324 // otherwise construct a normal node
325 else
326 {
328 }
329 done[c - 1] = true;
330 Node_pt[c - 1]->x(0) = x_node[c - 1];
331 Node_pt[c - 1]->x(1) = y_node[c - 1];
332 }
333 else
334 {
335 finite_element_pt(e)->node_pt(2) = Node_pt[c - 1];
336 }
337
338 count++;
339
340 // Construction of the fourth node
341 c = global_node[count - 1];
342 if (done[c - 1] ==
343 false) // c-1 because node number begins at 1 in the mesh file
344 {
345 // If the node is on a boundary, constuct a boundary node
346 if ((d > 0) && ((boundary_of_node[c - 1][0] > 0) ||
347 (boundary_of_node[c - 1][1] > 0)))
348 {
349 // Construct the boundary node
351 // Add to the look-up schemes
352 if (boundary_of_node[c - 1][0] > 0)
353 {
354 add_boundary_node(boundary_of_node[c - 1][0] - 1, Node_pt[c - 1]);
355 }
356 if (boundary_of_node[c - 1][1] > 0)
357 {
358 add_boundary_node(boundary_of_node[c - 1][1] - 1, Node_pt[c - 1]);
359 }
360 }
361 // Otherwise construct a normal node
362 else
363 {
365 }
366 done[c - 1] = true;
367 Node_pt[c - 1]->x(0) = x_node[c - 1];
368 Node_pt[c - 1]->x(1) = y_node[c - 1];
369 }
370 else
371 {
372 finite_element_pt(e)->node_pt(3) = Node_pt[c - 1];
373 }
374
375 count++;
376 }
377 }
378
379} // namespace oomph
e
Definition cfortran.h:571
cstr elem_len * i
Definition cfortran.h:603
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition elements.cc:4320
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object.
Definition elements.h:2513
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...
Definition elements.h:2542
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition elements.h:2179
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Definition mesh.cc:243
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition mesh.h:183
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Definition mesh.h:477
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Definition mesh.h:509
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition mesh.h:186
An OomphLibError object which should be thrown when an run-time error is encountered....
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...