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
meshes
simple_rectangular_tri_mesh.template.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
#ifndef OOMPH_SIMPLE_RECTANGULAR_TRI_MESH_TEMPLATE_HEADER
27
#define OOMPH_SIMPLE_RECTANGULAR_TRI_MESH_TEMPLATE_HEADER
28
29
#ifndef OOMPH_SIMPLE_RECTANGULAR_TRI_MESH_HEADER
30
#error __FILE__ should only be included from simple_rectangular_tri_mesh.h.
31
#endif
// OOMPH_SIMPLE_RECTANGULAR_TRI_MESH_HEADER
32
33
#include <algorithm>
34
35
#include "
generic/Telements.h
"
36
37
// Simple 2D triangle mesh class
38
39
namespace
oomph
40
{
41
//====================================================================
42
/// Constructor for simple 2D triangular mesh class:
43
///
44
/// n_x : number of elements in the x direction
45
///
46
/// n_y : number of elements in the y direction
47
///
48
/// l_x : length in the x direction
49
///
50
/// l_y : length in the y direction
51
///
52
/// Ordering of elements: 'lower left' to 'lower right' then 'upwards'
53
//====================================================================
54
template
<
class
ELEMENT>
55
SimpleRectangularTriMesh<ELEMENT>::SimpleRectangularTriMesh
(
56
const
unsigned
&
n_x
,
57
const
unsigned
&
n_y
,
58
const
double
&
l_x
,
59
const
double
& l_y,
60
TimeStepper
* time_stepper_pt)
61
: Nx(
n_x
), Ny(
n_y
), Lx(
l_x
), Ly(l_y)
62
{
63
using namespace
MathematicalConstants;
64
65
// Mesh can only be built with 2D Telements.
66
MeshChecker::assert_geometric_element<TElementGeometricBase, ELEMENT>(2);
67
68
// Set number of boundaries
69
this->
set_nboundary
(4);
70
71
// Allocate the store for the elements
72
unsigned
n_element
= (
Nx
) * (
Ny
) * 2;
73
Element_pt
.resize(
n_element
, 0);
74
75
// Create first element
76
Element_pt
[0] =
new
ELEMENT;
77
78
// Currently this mesh only works for 3 and 6 noded triangles
79
if
((
finite_element_pt
(0)->nnode_1d() != 2) &&
80
(
finite_element_pt
(0)->
nnode_1d
() != 3) &&
81
(
finite_element_pt
(0)->
nnode_1d
() != 4))
82
{
83
throw
OomphLibError
(
84
"Currently this mesh only works for 3, 6 & 10-noded triangles"
,
85
OOMPH_CURRENT_FUNCTION
,
86
OOMPH_EXCEPTION_LOCATION
);
87
}
88
89
unsigned
n_node
= 0;
90
// Unless nnode_1d returned as !=2 default no extra nodes
91
unsigned
additional_nnode
= 0;
92
93
// Allocate storage if no extra nodes
94
if
(
finite_element_pt
(0)->nnode_1d() == 2)
95
{
96
n_node
= (
Nx
+ 1) * (
Ny
+ 1);
97
}
98
99
if
(
finite_element_pt
(0)->
nnode_1d
() == 3)
100
{
101
additional_nnode
= 3;
102
// Allocate storage for nodes (including extra)
103
n_node
= (2 *
Nx
+ 1) * (2 *
Ny
+ 1);
104
}
105
106
if
(
finite_element_pt
(0)->
nnode_1d
() == 4)
107
{
108
additional_nnode
= 7;
109
// Allocate storage for notes (including extra)
110
n_node
= (3 *
Nx
+ 1) * (3 *
Ny
+ 1);
111
}
112
113
Node_pt
.resize(
n_node
);
114
115
// Set up geometrical data
116
//------------------------
117
unsigned
long
node_count
= 0;
118
unsigned
long
element_count
= 0;
119
double
xinit
= 0.0,
yinit
= 0.0;
120
// Set the values of the increments
121
double
xstep
=
Lx
/ (
Nx
);
122
double
ystep
=
Ly
/ (
Ny
);
123
124
// FIRST NODE (lower left corner)
125
//-------------------------------
126
127
// Set the corner node
128
129
// Allocate memory for the corner node of the first element
130
//(which is not created loop as all subsequent bottom corners already exist)
131
Node_pt
[
node_count
] =
132
finite_element_pt
(0)->
construct_node
(1, time_stepper_pt);
133
134
// Set the pointer from the element
135
finite_element_pt
(0)->
node_pt
(1) =
Node_pt
[
node_count
];
136
137
// Don't increment node_count yet as we still need its containing box
138
//(position and boundaries for first node are allocated in the main loop)
139
140
// CREATE THE ELEMENTS (each has 3 local nodes)
141
//--------------------------------------------------
142
// Elements are created two at a time, the first being lower triangular
143
// and the second upper triangular, so that they form a containing box.
144
// Local nodes are numbered anti-clockwise with node_pt(1) being the
145
// right-angle corner of the triangle.
146
// The global node number, node_count, is considered to define
147
// a containing box, with node_count defined as the node number
148
// of the bottom left corner of the box.
149
for
(
unsigned
j
= 0;
j
<
Ny
+ 1; ++
j
)
150
{
151
for
(
unsigned
i
= 0;
i
<
Nx
+ 1; ++
i
)
152
{
153
// CURRENT BOX
154
//(nodes on RHS or top edge of domain do not define a box)
155
if
(
j
<
Ny
&&
i
<
Nx
)
156
{
157
// Create two elements
158
//------------------------------
159
if
(
element_count
!= 0)
// 0th element already exists
160
{
161
Element_pt
[
element_count
] =
new
ELEMENT;
162
}
163
164
Element_pt
[
element_count
+ 1] =
new
ELEMENT;
165
166
// Allocate memory for nodes in the current box
167
//--------------------------------------------
168
// If node on LHS of domain, allocate the top left corner node
169
if
(
i
== 0)
170
{
171
Node_pt
[
node_count
+
Nx
+ 1] =
172
finite_element_pt
(
element_count
)
173
->
construct_node
(0, time_stepper_pt);
174
}
175
176
// If on bottom row, allocate the bottom right corner node
177
if
(
j
== 0)
178
{
179
Node_pt
[
node_count
+ 1] =
finite_element_pt
(
element_count
)
180
->
construct_node
(2, time_stepper_pt);
181
}
182
183
// Always need to allocate top right corner node
184
Node_pt
[
node_count
+
Nx
+ 2] =
finite_element_pt
(
element_count
+ 1)
185
->
construct_node
(1, time_stepper_pt);
186
187
// Bottom left corner node is already allocated
188
189
// Set the pointers from the elements
190
//----------------------------------
191
finite_element_pt
(
element_count
)->
node_pt
(0) =
192
Node_pt
[
node_count
+
Nx
+ 1];
193
finite_element_pt
(
element_count
)->
node_pt
(1) =
Node_pt
[
node_count
];
194
finite_element_pt
(
element_count
)->
node_pt
(2) =
195
Node_pt
[
node_count
+ 1];
196
finite_element_pt
(
element_count
+ 1)->
node_pt
(0) =
197
Node_pt
[
node_count
+ 1];
198
finite_element_pt
(
element_count
+ 1)->
node_pt
(1) =
199
Node_pt
[
node_count
+
Nx
+ 2];
200
finite_element_pt
(
element_count
+ 1)->
node_pt
(2) =
201
Node_pt
[
node_count
+
Nx
+ 1];
202
203
element_count
+= 2;
204
}
205
206
// CURRENT (GLOBAL) NODE
207
// Set the position
208
Node_pt
[
node_count
]->x(0) =
xinit
+
i
*
xstep
;
209
Node_pt
[
node_count
]->x(1) =
yinit
+
j
*
ystep
;
210
211
// Add node to any relevant boundaries
212
if
(
j
== 0)
213
{
214
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
215
add_boundary_node
(0,
Node_pt
[
node_count
]);
216
}
217
if
(
j
==
Ny
)
218
{
219
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
220
add_boundary_node
(2,
Node_pt
[
node_count
]);
221
}
222
if
(
i
== 0)
223
{
224
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
225
add_boundary_node
(3,
Node_pt
[
node_count
]);
226
}
227
if
(
i
==
Nx
)
228
{
229
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
230
add_boundary_node
(1,
Node_pt
[
node_count
]);
231
}
232
233
// Increment counter
234
node_count
++;
235
}
236
}
237
238
if
(
additional_nnode
== 3)
239
{
240
// Reset element counter to allow looping over existing elements
241
// to add extra nodes.
242
// Note that the node_count is not reset so no entries are overwritten
243
element_count
= 0;
244
for
(
unsigned
j
= 0;
j
<
Ny
+ 1; ++
j
)
245
{
246
// Note: i counter reduced by 1 since i axis runs through middle of
247
// elements on x-axis
248
for
(
unsigned
i
= 0;
i
<
Nx
; ++
i
)
249
{
250
// The additional nodes will be added in stages for ease of
251
// application. Note: local numbering follows the anti-clockwise
252
// pattern, node 3 halfway between nodes 0-1, 4 between 1-2 and the
253
// 5th local node between 2-0.
254
255
// Restricted to stop creation of additional nodes outside the mesh
256
if
(
j
<
Ny
)
257
{
258
// If on the bottom row middle-node at bottom needs allocating
259
if
(
j
== 0)
260
{
261
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
262
->
construct_node
(4, time_stepper_pt);
263
}
264
265
// Due to directions of iteration node at middle of top box edge
266
// (in next element) always needs allocating
267
Node_pt
[
node_count
+
Nx
] =
finite_element_pt
(
element_count
+ 1)
268
->
construct_node
(4, time_stepper_pt);
269
270
// Set pointers to the top/bottom middle nodes
271
// Bottom node
272
finite_element_pt
(
element_count
)->
node_pt
(4) =
Node_pt
[
node_count
];
273
// Top node
274
finite_element_pt
(
element_count
+ 1)->
node_pt
(4) =
275
Node_pt
[
node_count
+
Nx
];
276
277
// Increase the element counter to add top/bottom nodes to
278
// next pair of element on next pass
279
element_count
+= 2;
280
}
// End extra top/bottom node construction
281
282
// Set position of current (Global) Node
283
Node_pt
[
node_count
]->x(0) =
xinit
+
double
(
i
+ 0.5) *
xstep
;
284
Node_pt
[
node_count
]->x(1) =
yinit
+
j
*
ystep
;
285
286
// Add node to any applicable boundaries (node 4's can only be top
287
// or bottom boundaries)
288
if
(
j
== 0)
289
{
290
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
291
add_boundary_node
(0,
Node_pt
[
node_count
]);
292
}
293
if
(
j
==
Ny
)
294
{
295
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
296
add_boundary_node
(2,
Node_pt
[
node_count
]);
297
}
298
299
// Update node_count
300
node_count
++;
301
}
302
}
303
304
// Next stage of additional node implementation involes the middle left
305
// and right nodes (local number 3 on each triangle)
306
307
// Element counter reset for second loop over existing elements
308
element_count
= 0;
309
// Note: j counter reduced by 1 since j axis runs through middle of
310
// elements on y-axis
311
for
(
unsigned
j
= 0;
j
<
Ny
; ++
j
)
312
{
313
for
(
unsigned
i
= 0;
i
<
Nx
+ 1; ++
i
)
314
{
315
if
(
j
<
Ny
&&
i
<
Nx
)
316
{
317
// If on the left hand boundary the node at middle of the left
318
// side needs allocating
319
if
(
i
== 0)
320
{
321
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
322
->
construct_node
(3, time_stepper_pt);
323
}
324
325
// The mid node on the right hand side always needs constructing
326
// within the bounds of the mesh
327
Node_pt
[
node_count
+ 1] =
finite_element_pt
(
element_count
+ 1)
328
->
construct_node
(3, time_stepper_pt);
329
330
// Set pointers from the elements to new nodes
331
finite_element_pt
(
element_count
)->
node_pt
(3) =
Node_pt
[
node_count
];
332
finite_element_pt
(
element_count
+ 1)->
node_pt
(3) =
333
Node_pt
[
node_count
+ 1];
334
335
// Increase element_count by 2
336
element_count
+= 2;
337
}
// End extra left/right node construction
338
339
// Set position of current (Global) Node
340
Node_pt
[
node_count
]->x(0) =
xinit
+
i
*
xstep
;
341
Node_pt
[
node_count
]->x(1) =
yinit
+
double
(
j
+ 0.5) *
ystep
;
342
343
// Add node to any applicable boundaries again - only be left/right
344
if
(
i
== 0)
345
{
346
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
347
add_boundary_node
(3,
Node_pt
[
node_count
]);
348
}
349
if
(
i
==
Nx
)
350
{
351
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
352
add_boundary_node
(1,
Node_pt
[
node_count
]);
353
}
354
355
// Update node_count
356
node_count
++;
357
}
358
}
359
360
// Final stage of inserting extra nodes - inclusion of the local
361
// number 5 (middle of hypot. edge)
362
363
element_count
= 0;
364
// Note: both i,j counters reduced by 1 since j axis runs through middle
365
// of elements in both x,y
366
for
(
unsigned
j
= 0;
j
<
Ny
; ++
j
)
367
{
368
for
(
unsigned
i
= 0;
i
<
Nx
; ++
i
)
369
{
370
// The middle node always needs constructing
371
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
372
->
construct_node
(5, time_stepper_pt);
373
374
// Set pointers from the elements to new nodes
375
finite_element_pt
(
element_count
)->
node_pt
(5) =
Node_pt
[
node_count
];
376
finite_element_pt
(
element_count
+ 1)->
node_pt
(5) =
377
Node_pt
[
node_count
];
378
379
// Increase element_count by 2
380
element_count
+= 2;
381
// End extra left/right node construction
382
383
// Set position of current (Global) Node
384
Node_pt
[
node_count
]->x(0) =
xinit
+
double
(
i
+ 0.5) *
xstep
;
385
Node_pt
[
node_count
]->x(1) =
yinit
+
double
(
j
+ 0.5) *
ystep
;
386
387
// All nodes are internal in this structure so no boundaries
388
// applicable
389
390
// Update node_count
391
node_count
++;
392
}
393
}
394
}
395
// End of extra nodes for 6 noded trianglur elements
396
397
if
(
additional_nnode
== 7)
398
{
399
// Reset element counter to allow looping over existing elements
400
// to add extra nodes.
401
// Note that the node_count is not reset so no entries are overwritten
402
element_count
= 0;
403
for
(
unsigned
j
= 0;
j
<
Ny
+ 1; ++
j
)
404
{
405
// Note: i counter reduced by 1 for implementation of lower element
406
// node 5 and upper element node 6's.
407
for
(
unsigned
i
= 0;
i
<
Nx
; ++
i
)
408
{
409
// The additional nodes will be added in stages for ease of
410
// application. Note: local numbering follows the anti-clockwise
411
// pattern, nodes 3 and 4 equidistant between nodes 0-1, 5 and 6
412
// between 1-2, 7 and 8 between 2-0 and last node 9 located
413
// (internally) at the centroid of the triangle.
414
415
// Restricted to stop creation of additional nodes outside the mesh
416
if
(
j
<
Ny
)
417
{
418
// If on the bottom row middle-left-node at bottom needs allocating
419
if
(
j
== 0)
420
{
421
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
422
->
construct_node
(5, time_stepper_pt);
423
}
424
425
// Due to directions of iteration node at middle left of top box
426
// edge (in next element) always needs allocating
427
Node_pt
[
node_count
+
Nx
] =
finite_element_pt
(
element_count
+ 1)
428
->
construct_node
(6, time_stepper_pt);
429
430
// Set pointers to the top/bottom middle nodes
431
// Bottom node
432
finite_element_pt
(
element_count
)->
node_pt
(5) =
Node_pt
[
node_count
];
433
// Top node
434
finite_element_pt
(
element_count
+ 1)->
node_pt
(6) =
435
Node_pt
[
node_count
+
Nx
];
436
437
// Increase the element counter to add top/bottom nodes to
438
// next pair of element on next pass
439
element_count
+= 2;
440
}
// End extra top/bottom node construction
441
442
// Set position of current (Global) Node
443
Node_pt
[
node_count
]->x(0) =
xinit
+
double
(
i
+ 1.0 / 3.0) *
xstep
;
444
Node_pt
[
node_count
]->x(1) =
yinit
+
j
*
ystep
;
445
446
// Add node to any applicable boundaries (exactly as previous)
447
if
(
j
== 0)
448
{
449
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
450
add_boundary_node
(0,
Node_pt
[
node_count
]);
451
}
452
if
(
j
==
Ny
)
453
{
454
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
455
add_boundary_node
(2,
Node_pt
[
node_count
]);
456
}
457
458
// Update node_count
459
node_count
++;
460
}
461
}
462
463
// Next stage: bottom-middle-right node (node 6 in lower tri.el.)
464
// and top-middle-right node (node 5 in upper tri.el.)
465
466
element_count
= 0;
467
for
(
unsigned
j
= 0;
j
<
Ny
+ 1; ++
j
)
468
{
469
// Note: i counter as for above 5/6's
470
for
(
unsigned
i
= 0;
i
<
Nx
; ++
i
)
471
{
472
// Restricted to stop creation of additional nodes outside the mesh
473
if
(
j
<
Ny
)
474
{
475
// If on the bottom row middle-right-node at bottom needs allocating
476
if
(
j
== 0)
477
{
478
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
479
->
construct_node
(6, time_stepper_pt);
480
}
481
482
// Due to directions of iteration node at middle left of top box
483
// edge (in next element) always needs allocating
484
Node_pt
[
node_count
+
Nx
] =
finite_element_pt
(
element_count
+ 1)
485
->
construct_node
(5, time_stepper_pt);
486
487
// Set pointers to the top/bottom middle nodes
488
// Bottom node
489
finite_element_pt
(
element_count
)->
node_pt
(6) =
Node_pt
[
node_count
];
490
// Top node
491
finite_element_pt
(
element_count
+ 1)->
node_pt
(5) =
492
Node_pt
[
node_count
+
Nx
];
493
494
// Increase the element counter to add top/bottom nodes to
495
// next pair of element on next pass
496
element_count
+= 2;
497
}
// End extra top/bottom node construction
498
499
// Set position of current (Global) Node
500
Node_pt
[
node_count
]->x(0) =
xinit
+
double
(
i
+ 2.0 / 3.0) *
xstep
;
501
Node_pt
[
node_count
]->x(1) =
yinit
+
j
*
ystep
;
502
503
// Add node to any applicable boundaries (exactly as previous)
504
if
(
j
== 0)
505
{
506
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
507
add_boundary_node
(0,
Node_pt
[
node_count
]);
508
}
509
if
(
j
==
Ny
)
510
{
511
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
512
add_boundary_node
(2,
Node_pt
[
node_count
]);
513
}
514
515
// Update node_count
516
node_count
++;
517
}
518
}
519
520
// Next stage of additional node implementation involes node 4 on lower
521
// tri. el. and node 3 on upper tri. el.
522
523
// Element counter reset for next loop over existing elements
524
element_count
= 0;
525
// Note: j counter reduced by 1 similar to others above
526
for
(
unsigned
j
= 0;
j
<
Ny
; ++
j
)
527
{
528
for
(
unsigned
i
= 0;
i
<
Nx
+ 1; ++
i
)
529
{
530
if
(
j
<
Ny
&&
i
<
Nx
)
531
{
532
// If on the left hand boundary the lower middle node of the left
533
// side needs allocating
534
if
(
i
== 0)
535
{
536
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
537
->
construct_node
(4, time_stepper_pt);
538
}
539
540
// The mid node on the right hand side always needs constructing
541
// within the bounds of the mesh
542
Node_pt
[
node_count
+ 1] =
finite_element_pt
(
element_count
+ 1)
543
->
construct_node
(3, time_stepper_pt);
544
545
// Set pointers from the elements to new nodes
546
finite_element_pt
(
element_count
)->
node_pt
(4) =
Node_pt
[
node_count
];
547
finite_element_pt
(
element_count
+ 1)->
node_pt
(3) =
548
Node_pt
[
node_count
+ 1];
549
550
// Increase element_count by 2
551
element_count
+= 2;
552
}
// End extra left/right node construction
553
554
// Set position of current (Global) Node
555
Node_pt
[
node_count
]->x(0) =
xinit
+
i
*
xstep
;
556
Node_pt
[
node_count
]->x(1) =
yinit
+
double
(
j
+ 1.0 / 3.0) *
ystep
;
557
558
// Add node to any applicable boundaries again - only be left/right
559
if
(
i
== 0)
560
{
561
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
562
add_boundary_node
(3,
Node_pt
[
node_count
]);
563
}
564
if
(
i
==
Nx
)
565
{
566
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
567
add_boundary_node
(1,
Node_pt
[
node_count
]);
568
}
569
570
// Update node_count
571
node_count
++;
572
}
573
}
574
575
// Next stage of additional node implementation involes node 3 on lower
576
// tri. el. and node 4 on upper tri. el.
577
578
// Element counter reset for next loop over existing elements
579
element_count
= 0;
580
// Note: j counter reduced by 1 similar to others above
581
for
(
unsigned
j
= 0;
j
<
Ny
; ++
j
)
582
{
583
for
(
unsigned
i
= 0;
i
<
Nx
+ 1; ++
i
)
584
{
585
if
(
j
<
Ny
&&
i
<
Nx
)
586
{
587
// If on the left hand boundary the lower middle node of the left
588
// side needs allocating
589
if
(
i
== 0)
590
{
591
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
592
->
construct_node
(3, time_stepper_pt);
593
}
594
595
// The mid node on the right hand side always needs constructing
596
// within the bounds of the mesh
597
Node_pt
[
node_count
+ 1] =
finite_element_pt
(
element_count
+ 1)
598
->
construct_node
(4, time_stepper_pt);
599
600
// Set pointers from the elements to new nodes
601
finite_element_pt
(
element_count
)->
node_pt
(3) =
Node_pt
[
node_count
];
602
finite_element_pt
(
element_count
+ 1)->
node_pt
(4) =
603
Node_pt
[
node_count
+ 1];
604
605
// Increase element_count by 2
606
element_count
+= 2;
607
}
// End extra left/right node construction
608
609
// Set position of current (Global) Node
610
Node_pt
[
node_count
]->x(0) =
xinit
+
i
*
xstep
;
611
Node_pt
[
node_count
]->x(1) =
yinit
+
double
(
j
+ 2.0 / 3.0) *
ystep
;
612
613
// Add node to any applicable boundaries again - only be left/right
614
if
(
i
== 0)
615
{
616
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
617
add_boundary_node
(3,
Node_pt
[
node_count
]);
618
}
619
if
(
i
==
Nx
)
620
{
621
this->
convert_to_boundary_node
(
Node_pt
[node_count]);
622
add_boundary_node
(1,
Node_pt
[
node_count
]);
623
}
624
625
// Update node_count
626
node_count
++;
627
}
628
}
629
630
// Next is the lower tri. el. totally internal node with local number 9
631
element_count
= 0;
632
// Note: both i,j counters reduced by 1
633
for
(
unsigned
j
= 0;
j
<
Ny
; ++
j
)
634
{
635
for
(
unsigned
i
= 0;
i
<
Nx
; ++
i
)
636
{
637
// The middle node always needs constructing
638
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
639
->
construct_node
(9, time_stepper_pt);
640
641
// Set pointers from the elements to new nodes
642
finite_element_pt
(
element_count
)->
node_pt
(9) =
Node_pt
[
node_count
];
643
644
// Increase element_count by 2
645
element_count
+= 2;
646
647
// Set position of current (Global) Node
648
Node_pt
[
node_count
]->x(0) =
xinit
+
double
(
i
+ 1.0 / 3.0) *
xstep
;
649
Node_pt
[
node_count
]->x(1) =
yinit
+
double
(
j
+ 1.0 / 3.0) *
ystep
;
650
651
// All nodes are internal in this structure so no boundaries
652
// applicable
653
654
// Update node_count
655
node_count
++;
656
}
657
}
658
659
// Next is the bottom hyp. node -
660
// lower tri. el. number 7, upper tri. el. number 8
661
element_count
= 0;
662
// Note: both i,j counters reduced by 1
663
for
(
unsigned
j
= 0;
j
<
Ny
; ++
j
)
664
{
665
for
(
unsigned
i
= 0;
i
<
Nx
; ++
i
)
666
{
667
// The node always needs constructing
668
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
669
->
construct_node
(7, time_stepper_pt);
670
671
// Set pointers from the elements to new nodes
672
finite_element_pt
(
element_count
)->
node_pt
(7) =
Node_pt
[
node_count
];
673
finite_element_pt
(
element_count
+ 1)->
node_pt
(8) =
674
Node_pt
[
node_count
];
675
676
// Increase element_count by 2
677
element_count
+= 2;
678
679
// Set position of current (Global) Node
680
Node_pt
[
node_count
]->x(0) =
xinit
+
double
(
i
+ 2.0 / 3.0) *
xstep
;
681
Node_pt
[
node_count
]->x(1) =
yinit
+
double
(
j
+ 1.0 / 3.0) *
ystep
;
682
683
// All nodes are internal in this structure so no boundaries
684
// applicable
685
686
// Update node_count
687
node_count
++;
688
}
689
}
690
691
// Next is the upper hyp. node -
692
// lower tri. el. number 8, upper tri. el. number 7
693
element_count
= 0;
694
// Note: both i,j counters reduced by 1
695
for
(
unsigned
j
= 0;
j
<
Ny
; ++
j
)
696
{
697
for
(
unsigned
i
= 0;
i
<
Nx
; ++
i
)
698
{
699
// The node always needs constructing
700
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
)
701
->
construct_node
(8, time_stepper_pt);
702
703
// Set pointers from the elements to new nodes
704
finite_element_pt
(
element_count
)->
node_pt
(8) =
Node_pt
[
node_count
];
705
finite_element_pt
(
element_count
+ 1)->
node_pt
(7) =
706
Node_pt
[
node_count
];
707
708
// Increase element_count by 2
709
element_count
+= 2;
710
711
// Set position of current (Global) Node
712
Node_pt
[
node_count
]->x(0) =
xinit
+
double
(
i
+ 1.0 / 3.0) *
xstep
;
713
Node_pt
[
node_count
]->x(1) =
yinit
+
double
(
j
+ 2.0 / 3.0) *
ystep
;
714
715
// All nodes are internal in this structure so no boundaries
716
// applicable
717
718
// Update node_count
719
node_count
++;
720
}
721
}
722
723
// Next is the upper tri. el. totally internal node with local number 9
724
element_count
= 0;
725
// Note: both i,j counters reduced by 1
726
for
(
unsigned
j
= 0;
j
<
Ny
; ++
j
)
727
{
728
for
(
unsigned
i
= 0;
i
<
Nx
; ++
i
)
729
{
730
// The middle node always needs constructing
731
Node_pt
[
node_count
] =
finite_element_pt
(
element_count
+ 1)
732
->
construct_node
(9, time_stepper_pt);
733
734
// Set pointers from the elements to new nodes
735
finite_element_pt
(
element_count
+ 1)->
node_pt
(9) =
736
Node_pt
[
node_count
];
737
738
// Increase element_count by 2
739
element_count
+= 2;
740
741
// Set position of current (Global) Node
742
Node_pt
[
node_count
]->x(0) =
xinit
+
double
(
i
+ 2.0 / 3.0) *
xstep
;
743
Node_pt
[
node_count
]->x(1) =
yinit
+
double
(
j
+ 2.0 / 3.0) *
ystep
;
744
745
// All nodes are internal in this structure so no boundaries
746
// applicable
747
748
// Update node_count
749
node_count
++;
750
}
751
}
752
}
753
}
754
755
}
// namespace oomph
756
#endif
Telements.h
i
cstr elem_len * i
Definition
cfortran.h:603
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::node_pt
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition
elements.h:2179
oomph::FiniteElement::nnode_1d
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overload...
Definition
elements.h:2222
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::convert_to_boundary_node
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this,...
Definition
mesh.cc:2590
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::SimpleRectangularTriMesh::SimpleRectangularTriMesh
SimpleRectangularTriMesh(const unsigned &n_x, const unsigned &n_y, const double &l_x, const double &l_y, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor n_x : number of elements in the x direction; n_y : number of elements in the y direction;...
Definition
simple_rectangular_tri_mesh.template.cc:55
oomph::SimpleRectangularTriMesh::Lx
double Lx
Length of mesh in x-direction.
Definition
simple_rectangular_tri_mesh.h:83
oomph::SimpleRectangularTriMesh::Ny
unsigned Ny
Number of elements in y directions.
Definition
simple_rectangular_tri_mesh.h:80
oomph::SimpleRectangularTriMesh::Nx
unsigned Nx
Number of elements in x direction.
Definition
simple_rectangular_tri_mesh.h:77
oomph::SimpleRectangularTriMesh::Ly
double Ly
Length of mesh in y-direction.
Definition
simple_rectangular_tri_mesh.h:86
oomph::TAdvectionDiffusionReactionElement
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
Definition
Tadvection_diffusion_reaction_elements.h:66
oomph::TimeStepper
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Definition
timesteppers.h:231
oomph
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition
advection_diffusion_elements.cc:30