Toggle navigation
Documentation
Big picture
The finite element method
The data structure
Not-so-quick guide
Optimisation
Order of action functions
Example codes and tutorials
List of example codes and tutorials
Meshing
Solvers
MPI parallel processing
Post-processing/visualisation
Other
Change log
Creating documentation
Coding conventions
Index
FAQ
About
People
Contact/Get involved
Publications
Acknowledgements
Copyright
Picture show
Go
src
generic
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//====================================================================
26
#include "
geompack_scaffold_mesh.h
"
27
28
namespace
oomph
29
{
30
//=====================================================================
31
/// Constructor: Pass the filename of the mesh files
32
//=====================================================================
33
GeompackQuadScaffoldMesh::GeompackQuadScaffoldMesh
(
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
;
45
mesh_file
>>
n_node
;
46
47
// Coordinates of nodes and extra information index
48
Vector<double>
x_node
(
n_node
);
49
Vector<double>
y_node
(
n_node
);
50
Vector<int>
vertinfo
(
n_node
);
51
for
(
unsigned
i
= 0;
i
<
n_node
;
i
++)
52
{
53
mesh_file
>>
x_node
[
i
];
54
mesh_file
>>
y_node
[
i
];
55
mesh_file
>>
vertinfo
[
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
63
int
dummy_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
{
73
mesh_file
>>
dummy_node_code
;
74
mesh_file
>>
icurv
[
i
];
75
mesh_file
>>
dummy_ucurv
;
76
}
77
78
// Number of local nodes per element
79
unsigned
n_local_node
;
80
mesh_file
>>
n_local_node
;
81
82
// Number of elements
83
unsigned
n_element
;
84
mesh_file
>>
n_element
;
85
86
// Storage for global node numbers for all elements
87
Vector<unsigned>
global_node
(
n_local_node
*
n_element
);
88
89
// Storage for edge information
90
// (needed for a possible construction of midside node
91
// in the following build from scaffold function)
92
Vector<int>
edgeinfo
(
n_local_node
*
n_element
);
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
{
102
mesh_file
>>
global_node
[
k
];
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
;
144
curve_file
>>
n_curv
;
145
146
// Storage of several information for each curve
147
Vector<Vector<int>
>
curv
;
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
(
185
error_stream
.str(),
OOMPH_CURRENT_FUNCTION
,
OOMPH_EXCEPTION_LOCATION
);
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...
218
Vector<Vector<int>
>
boundary_of_node
;
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
262
Element_pt
[
e
] =
new
QElement<2, 2>
;
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
276
Node_pt
[c - 1] =
finite_element_pt
(
e
)->
construct_boundary_node
(
j
);
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
{
290
Node_pt
[c - 1] =
finite_element_pt
(
e
)->
construct_node
(
j
);
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
313
Node_pt
[c - 1] =
finite_element_pt
(
e
)->
construct_boundary_node
(2);
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
{
327
Node_pt
[c - 1] =
finite_element_pt
(
e
)->
construct_node
(2);
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
350
Node_pt
[c - 1] =
finite_element_pt
(
e
)->
construct_boundary_node
(3);
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
{
364
Node_pt
[c - 1] =
finite_element_pt
(
e
)->
construct_node
(3);
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
e
Definition
cfortran.h:571
i
cstr elem_len * i
Definition
cfortran.h:603
oomph::FiniteElement::size
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition
elements.cc:4320
oomph::FiniteElement::construct_node
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
oomph::FiniteElement::construct_boundary_node
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
oomph::FiniteElement::node_pt
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition
elements.h:2179
oomph::GeompackQuadScaffoldMesh::GeompackQuadScaffoldMesh
GeompackQuadScaffoldMesh()
Empty constructor.
Definition
geompack_scaffold_mesh.h:42
oomph::Mesh::add_boundary_node
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
oomph::Mesh::Node_pt
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition
mesh.h:183
oomph::Mesh::finite_element_pt
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Definition
mesh.h:477
oomph::Mesh::set_nboundary
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Definition
mesh.h:509
oomph::Mesh::Element_pt
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition
mesh.h:186
oomph::OomphLibError
An OomphLibError object which should be thrown when an run-time error is encountered....
Definition
oomph_definitions.h:229
oomph::TAdvectionDiffusionReactionElement
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
Definition
Tadvection_diffusion_reaction_elements.h:66
geompack_scaffold_mesh.h
oomph
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition
advection_diffusion_elements.cc:30
oomph::oomph_info
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...
Definition
oomph_definitions.cc:326