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
Installation
Installation guide
Copyright
About
People
Contact/Get involved
Publications
Acknowledgements
Picture show
Go
src
meshes
channel_with_leaflet_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-2024 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
27
#ifndef OOMPH_CHANNEL_WITH_LEAFLET_MESH_TEMPLATE_CC
28
#define OOMPH_CHANNEL_WITH_LEAFLET_MESH_TEMPLATE_CC
29
30
31
// Include the headers file
32
#include "
channel_with_leaflet_mesh.template.h
"
33
34
35
namespace
oomph
36
{
37
//===================================================================
38
/// Constructor: Pass pointer to GeomObject that represents the leaflet,
39
/// the length of the domain to left and right of the leaflet, the
40
/// height of the leaflet and the overall height of the channel,
41
/// the number of element columns to the left and right of the leaflet,
42
/// the number of rows of elements from the bottom of the channel to
43
/// the end of the leaflet, the number of rows of elements above the
44
/// end of the leaflet. Timestepper defaults to Steady default
45
/// Timestepper defined in the Mesh base class
46
//===================================================================
47
template
<
class
ELEMENT>
48
ChannelWithLeafletMesh<ELEMENT>::ChannelWithLeafletMesh
(
49
GeomObject
* leaflet_pt,
50
const
double
& lleft,
51
const
double
& lright,
52
const
double
& hleaflet,
53
const
double
& htot,
54
const
unsigned
& nleft,
55
const
unsigned
& nright,
56
const
unsigned
&
ny1
,
57
const
unsigned
&
ny2
,
58
TimeStepper
*
time_stepper_pt
)
59
:
SimpleRectangularQuadMesh
<
ELEMENT
>(
60
nright + nleft,
ny1
+
ny2
, lright + lleft, htot,
time_stepper_pt
)
61
{
62
// Mesh can only be built with 2D Qelements.
63
MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
64
65
// Copy pointer to leaflet into private storage
66
Leaflet_pt
= leaflet_pt;
67
68
// Create the ChannelWithLeafletDomain with the wall
69
// represented by the geometric object
70
Domain_pt
=
new
ChannelWithLeafletDomain
(
71
leaflet_pt, lleft, lright, hleaflet, htot, nleft, nright,
ny1
,
ny2
);
72
73
74
// Total number of (macro/finite)elements
75
unsigned
nmacro
= (
ny1
+
ny2
) * (nleft + nright);
76
77
// Loop over all elements and set macro element pointer
78
for
(
unsigned
e
= 0;
e
<
nmacro
;
e
++)
79
{
80
// Get pointer to finite element
81
FiniteElement
*
el_pt
= this->
finite_element_pt
(
e
);
82
83
// Set pointer to macro element
84
el_pt
->set_macro_elem_pt(this->
Domain_pt
->macro_element_pt(
e
));
85
}
86
87
// Update the nodal positions corresponding to their
88
// macro element representations.
89
this->node_update();
90
91
// Change the numbers of boundaries
92
this->
set_nboundary
(7);
93
94
// Remove the nodes of boundary 0
95
this->
remove_boundary_nodes
(0);
96
97
// Get the number of nodes along the element edge from first element
98
unsigned
nnode_1d
= this->
finite_element_pt
(0)->nnode_1d();
99
100
// Boundary 0 will be before the wall, boundary 6 after it
101
for
(
unsigned
e
= 0;
e
< nleft;
e
++)
102
{
103
for
(
unsigned
i
= 0;
i
<
nnode_1d
;
i
++)
104
{
105
Node
*
nod_pt
= this->
finite_element_pt
(
e
)->node_pt(
i
);
106
// do not add the last node : it will go to boundary 6
107
if
(
e
!= nleft - 1 ||
i
!= 2)
108
{
109
this->
add_boundary_node
(0,
nod_pt
);
110
}
111
}
112
}
113
114
for
(
unsigned
e
= nleft;
e
< nleft + nright;
e
++)
115
{
116
for
(
unsigned
i
= 0;
i
<
nnode_1d
;
i
++)
117
{
118
Node
*
nod_pt
= this->
finite_element_pt
(
e
)->node_pt(
i
);
119
this->
add_boundary_node
(6,
nod_pt
);
120
}
121
}
122
123
// Vector of Lagrangian coordinates used as boundary coordinate
124
Vector<double>
zeta
(1);
125
126
// Set the wall as a boundary
127
for
(
unsigned
k
= 0;
k
<
ny1
;
k
++)
128
{
129
unsigned
e
= (nleft + nright) *
k
+ nleft - 1;
130
for
(
unsigned
i
= 0;
i
<
nnode_1d
;
i
++)
131
{
132
Node
*
nod_pt
=
133
this->
finite_element_pt
(
e
)->node_pt((
i
+ 1) *
nnode_1d
- 1);
134
this->
convert_to_boundary_node
(
nod_pt
);
135
this->
add_boundary_node
(4,
nod_pt
);
136
137
// Set coordinates
138
zeta
[0] =
double
(
k
) * hleaflet /
double
(
ny1
) +
139
double
(
i
) * hleaflet /
double
(
ny1
) /
double
(
nnode_1d
- 1);
140
nod_pt
->set_coordinates_on_boundary(4,
zeta
);
141
}
142
}
143
144
145
// Duplicate the nodes of the wall and assign then as a boundary.
146
// This will make one boundary for the east of the elements at the
147
// left of the wall, and one for the west of the elements at the right
148
// of the wall.
149
// This is necessary to use TaylorHoodElements, because it will allow
150
// a discontinuity of the pressure accross the wall.
151
// We separate the lower element from the rest as we do not want to
152
// add the same node twice to the boundary, and the upper element as its
153
// upper node must be the same one than the node of the upper element
154
// at the right of the wall
155
156
// Lower element
157
unsigned
e
= nleft - 1;
158
159
// Allocate storage for newly created node outside
160
// so we can refer to the most recently created one below.
161
Node
*
nod_pt
= 0;
162
163
// duplicate the east nodes and add them to the 6th boundary
164
// Add the first node to the 0th boundary (horizontal)
165
for
(
unsigned
i
= 0;
i
<
nnode_1d
;
i
++)
166
{
167
nod_pt
= this->
finite_element_pt
(
e
)->construct_boundary_node(
168
(
i
+ 1) *
nnode_1d
- 1,
time_stepper_pt
);
169
this->
add_boundary_node
(5,
nod_pt
);
170
if
(
i
== 0)
171
{
172
this->
add_boundary_node
(0,
nod_pt
);
173
}
174
this->
add_node_pt
(
nod_pt
);
175
// Set coordinates
176
zeta
[0] =
i
* hleaflet /
double
(
ny1
) /
double
(
nnode_1d
- 1);
177
nod_pt
->set_coordinates_on_boundary(5,
zeta
);
178
}
179
180
181
// Other elements just at the left of the wall
182
for
(
unsigned
k
= 1;
k
<
ny1
;
k
++)
183
{
184
e
= (nleft + nright) *
k
+ nleft - 1;
185
186
// add the upper node of the previous element
187
this->
finite_element_pt
(
e
)->node_pt(
nnode_1d
- 1) =
nod_pt
;
188
this->
add_boundary_node
(5,
nod_pt
);
189
// Set coordinates
190
zeta
[0] =
k
* hleaflet /
double
(
ny1
);
191
nod_pt
->set_coordinates_on_boundary(5,
zeta
);
192
193
// Loop over other nodes on element's eastern edge
194
for
(
unsigned
i
= 1;
i
<
nnode_1d
;
i
++)
195
{
196
// Don't duplicate the node at the very top of the "obstacle"
197
if
((
k
==
ny1
- 1) && (
i
==
nnode_1d
- 1))
198
{
199
// Get the node but don't do anything else
200
nod_pt
= this->
finite_element_pt
(
e
)->node_pt(
nnode_1d
*
nnode_1d
- 1);
201
}
202
else
203
{
204
// Overwrite the node with a boundary node
205
nod_pt
= this->
finite_element_pt
(
e
)->construct_boundary_node(
206
(
i
+ 1) *
nnode_1d
- 1,
time_stepper_pt
);
207
this->
add_node_pt
(
nod_pt
);
208
}
209
210
// Add node to boundary
211
this->
add_boundary_node
(5,
nod_pt
);
212
// Set coordinates
213
zeta
[0] =
double
(
k
) * hleaflet /
double
(
ny1
) +
214
double
(
i
) * hleaflet /
double
(
ny1
) /
double
(
nnode_1d
- 1);
215
nod_pt
->set_coordinates_on_boundary(5,
zeta
);
216
}
217
}
218
219
this->node_update();
220
221
// Re-setup lookup scheme that establishes which elements are located
222
// on the mesh boundaries (doesn't need to be wiped)
223
this->setup_boundary_element_info();
224
225
// We have parametrised boundary 4 and 5
226
this->
Boundary_coordinate_exists
[4] =
true
;
227
this->
Boundary_coordinate_exists
[5] =
true
;
228
229
}
// end of constructor
230
231
232
/// ////////////////////////////////////////////////////////////////////
233
/// ///////////////////////////////////////////////////////////////////
234
/// ////////////////////////////////////////////////////////////////////
235
236
237
//=================================================================
238
/// Setup algebraic node update. Leaflet is
239
/// assumed to be in its undeformed (straight vertical) position!
240
//=================================================================
241
template
<
class
ELEMENT>
242
void
AlgebraicChannelWithLeafletMesh<ELEMENT>::setup_algebraic_node_update
()
243
{
244
// Extract some reference lengths from the Domain.
245
double
hleaflet = this->domain_pt()->hleaflet();
246
double
htot = this->domain_pt()->htot();
247
double
lleft = this->domain_pt()->lleft();
248
double
lright = this->domain_pt()->lright();
249
250
// Loop over all nodes in mesh
251
unsigned
nnod
= this->
nnode
();
252
for
(
unsigned
j
= 0;
j
<
nnod
;
j
++)
253
{
254
// Get pointer to node
255
AlgebraicNode
*
nod_pt
=
node_pt
(
j
);
256
257
// Get coordinates
258
double
x =
nod_pt
->x(0);
259
double
y =
nod_pt
->x(1);
260
261
// Quick check to know if the wall is in its undeformed position
262
// It actually checks that the top of the wall is in (x_0,hleaflet)
263
Vector<double>
zeta
(1);
264
Vector<double>
r
(2);
265
zeta
[0] = Hleaflet;
266
this->Leaflet_pt->position(
zeta
,
r
);
267
if
((
r
[0] != X_0) || (
r
[1] != hleaflet))
268
{
269
std::ostringstream
error_stream
;
270
error_stream
<<
"Wall must be in its undeformed position when\n"
271
<<
"algebraic node update information is set up!\n "
272
<<
r
[0] <<
" "
<< X_0 <<
" "
<<
r
[1] <<
" "
<< hleaflet
273
<< std::endl;
274
throw
OomphLibError
(
275
error_stream
.str(),
OOMPH_CURRENT_FUNCTION
,
OOMPH_EXCEPTION_LOCATION
);
276
}
277
278
279
// The update function requires four parameters:
280
Vector<double>
ref_value
(4);
281
282
// Part I
283
if
((x <= X_0) && (y <= hleaflet))
284
{
285
// First reference value: y0
286
ref_value
[0] = y;
287
288
// zeta coordinate on wall : fourth reference value
289
//(needed for adaptativity)
290
Vector<double>
zeta
(1);
291
zeta
[0] = y;
292
ref_value
[3] =
zeta
[0];
293
294
// Sub-geomobject corresponding to the zeta coordinate on the wall
295
GeomObject
*
geom_obj_pt
;
296
Vector<double>
s
(1);
297
this->Leaflet_pt->locate_zeta(
zeta
,
geom_obj_pt
,
s
);
298
299
// Create vector of geomobject for add_node_update_info()
300
Vector<GeomObject*>
geom_object_pt
(1);
301
geom_object_pt
[0] =
geom_obj_pt
;
302
303
// Second reference value: Reference local coordinate
304
// in the sub-geomobject
305
ref_value
[1] =
s
[0];
306
307
// Third reference value:fraction of the horizontal line
308
// between the edge and the wall
309
ref_value
[2] = (lleft + x - X_0) / lleft;
310
311
312
// Setup algebraic update for node: Pass update information
313
// to AlgebraicNode:
314
nod_pt
->add_node_update_info(1,
// ID
315
this
,
// mesh
316
geom_object_pt
,
// vector of geom objects
317
ref_value
);
// vector of ref. values
318
}
319
// Part II
320
if
((x >= X_0) && (y <= hleaflet))
321
{
322
// First reference value: y0
323
ref_value
[0] = y;
324
325
// zeta coordinate on wall: fourth reference value
326
//(needed for adaptativity)
327
Vector<double>
zeta
(1);
328
zeta
[0] = y;
329
ref_value
[3] =
zeta
[0];
330
331
// Sub-geomobject corresponding to the zeta coordinate on the wall
332
GeomObject
*
geom_obj_pt
;
333
Vector<double>
s
(1);
334
this->Leaflet_pt->locate_zeta(
zeta
,
geom_obj_pt
,
s
);
335
336
// Create vector of geomobject for add_node_update_info()
337
Vector<GeomObject*>
geom_object_pt
(1);
338
geom_object_pt
[0] =
geom_obj_pt
;
339
340
// Second reference value: Reference local coordinate
341
// in the sub-geomobject
342
ref_value
[1] =
s
[0];
343
344
// Third reference value:fraction of the horizontal line
345
// between the edge and the wall
346
ref_value
[2] = (x - X_0) / lright;
347
348
// Setup algebraic update for node: Pass update information
349
// to AlgebraicNode:
350
nod_pt
->add_node_update_info(2,
// ID
351
this
,
// mesh
352
geom_object_pt
,
// vector of geom objects
353
ref_value
);
// vector of ref. values
354
}
355
// Part III
356
if
((x <= X_0) && (y >= hleaflet))
357
{
358
// First reference value: y0
359
ref_value
[0] = y;
360
361
// Second reference value: zeta coordinate on the middle line
362
ref_value
[1] = (y - hleaflet) / (htot - hleaflet);
363
364
// Third reference value:fraction of the horizontal line
365
// between the edge and the middle line
366
ref_value
[2] = (lleft + x - X_0) / lleft;
367
368
// geomobject
369
Vector<GeomObject*>
geom_object_pt
(1);
370
geom_object_pt
[0] = this->Leaflet_pt;
371
372
// Setup algebraic update for node: Pass update information
373
// to AlgebraicNode:
374
nod_pt
->add_node_update_info(3,
// ID
375
this
,
// mesh
376
geom_object_pt
,
// vector of geom objects
377
ref_value
);
// vector of ref. values
378
}
379
// Part IV
380
if
((x >= X_0) && (y >= hleaflet))
381
{
382
// First reference value: y0
383
ref_value
[0] = y;
384
385
// Second reference value: zeta coordinate on wall
386
ref_value
[1] = (y - hleaflet) / (htot - hleaflet);
387
388
// Third reference value:fraction of the horizontal line
389
// between the edge and the wall
390
ref_value
[2] = (x - X_0) / lright;
391
392
// geomobject
393
Vector<GeomObject*>
geom_object_pt
(1);
394
geom_object_pt
[0] = this->Leaflet_pt;
395
396
// Setup algebraic update for node: Pass update information
397
// to AlgebraicNode:
398
nod_pt
->add_node_update_info(4,
// ID
399
this
,
// mesh
400
geom_object_pt
,
// vector of geom objects
401
ref_value
);
// vector of ref. values
402
}
403
}
404
405
}
// end of setup_algebraic_node_update
406
407
408
//=================================================================
409
/// Perform algebraic node update
410
//=================================================================
411
template
<
class
ELEMENT>
412
void
AlgebraicChannelWithLeafletMesh<ELEMENT>::algebraic_node_update
(
413
const
unsigned
&
t
,
AlgebraicNode
*&
node_pt
)
414
{
415
unsigned
id
=
node_pt
->node_update_fct_id();
416
417
switch
(
id
)
418
{
419
case
1:
420
node_update_I(
t
,
node_pt
);
421
break
;
422
423
case
2:
424
node_update_II(
t
,
node_pt
);
425
break
;
426
427
case
3:
428
node_update_III(
t
,
node_pt
);
429
break
;
430
431
case
4:
432
node_update_IV(
t
,
node_pt
);
433
break
;
434
435
default
:
436
std::ostringstream
error_message
;
437
error_message
<<
"The node update fct id is "
<<
id
438
<<
", but it should only be one of "
<< 1 <<
", "
<< 2
439
<<
", "
<< 3 <<
" or "
<< 4 << std::endl;
440
std::string
function_name
=
441
"AlgebraicChannelWithLeafletMesh::algebraic_node_update()"
;
442
443
throw
OomphLibError
(
error_message
.str(),
444
OOMPH_CURRENT_FUNCTION
,
445
OOMPH_EXCEPTION_LOCATION
);
446
}
447
448
}
// end of algebraic_node_update()
449
450
451
//=================================================================
452
/// Node update for region I
453
//=================================================================
454
template
<
class
ELEMENT>
455
void
AlgebraicChannelWithLeafletMesh<ELEMENT>::node_update_I
(
456
const
unsigned
&
t
,
AlgebraicNode
*&
node_pt
)
457
{
458
// relevant data of the domain for part I
459
double
lleft = this->domain_pt()->lleft();
460
461
// Extract reference values for update by copy construction
462
Vector<double>
ref_value
(
node_pt
->vector_ref_value());
463
464
// Extract geometric objects for update by copy construction
465
Vector<GeomObject*>
geom_object_pt
(
node_pt
->vector_geom_object_pt());
466
467
// Pointer to wall geom object
468
GeomObject
* leaflet_pt =
geom_object_pt
[0];
469
470
// Coordinates of the steady node on the left boundary
471
// corresponding to the current node
472
double
y0
=
ref_value
[0];
473
double
x0
= -lleft + X_0;
474
475
// second reference value: local coordinate on wall
476
Vector<double>
s
(1);
477
s
[0] =
ref_value
[1];
478
479
480
// Get position vector to wall at timestep t
481
Vector<double>
r_wall
(2);
482
leaflet_pt->position(
t
,
s
,
r_wall
);
483
484
485
// Third reference value : fraction of the horizontal line
486
// between the edge and the wall
487
double
r
=
ref_value
[2];
488
489
490
// Assign new nodal coordinates
491
node_pt
->x(
t
, 0) =
x0
+
r
* (
r_wall
[0] -
x0
);
492
node_pt
->x(
t
, 1) =
y0
+
r
* (
r_wall
[1] -
y0
);
493
}
494
495
496
//=================================================================
497
/// Node update for region II
498
//=================================================================
499
template
<
class
ELEMENT>
500
void
AlgebraicChannelWithLeafletMesh<ELEMENT>::node_update_II
(
501
const
unsigned
&
t
,
AlgebraicNode
*&
node_pt
)
502
{
503
// relevant data of the domain for part II
504
double
lright = this->domain_pt()->lright();
505
506
// Extract reference values for update by copy construction
507
Vector<double>
ref_value
(
node_pt
->vector_ref_value());
508
509
// Extract geometric objects for update by copy construction
510
Vector<GeomObject*>
geom_object_pt
(
node_pt
->vector_geom_object_pt());
511
512
// Pointer to wall geom object
513
GeomObject
* leaflet_pt =
geom_object_pt
[0];
514
515
// Coordinates of the steady node on the right boundary
516
// corresponding to the current node
517
double
y0
=
ref_value
[0];
518
double
x0
= X_0 + lright;
519
520
// Second reference value: Zeta coordinate on wall
521
Vector<double>
s
(1);
522
s
[0] =
ref_value
[1];
523
524
// Get position vector to wall at timestep t
525
Vector<double>
r_wall
(2);
526
leaflet_pt->position(
t
,
s
,
r_wall
);
527
528
// Third reference value : fraction of the horizontal line
529
// between the wall and the right edge
530
double
r
=
ref_value
[2];
531
532
// Assign new nodal coordinates
533
node_pt
->x(
t
, 0) =
r_wall
[0] +
r
* (
x0
-
r_wall
[0]);
534
node_pt
->x(
t
, 1) =
r_wall
[1] +
r
* (
y0
-
r_wall
[1]);
535
}
536
537
538
//=================================================================
539
/// Slanted bound : helper function
540
//=================================================================
541
template
<
class
ELEMENT>
542
void
AlgebraicChannelWithLeafletMesh<ELEMENT>::slanted_bound_up
(
543
const
unsigned
&
t
,
const
Vector<double>
&
zeta
,
Vector<double>
&
r
)
544
{
545
/// Coordinates of the point on the boundary beetween the upper
546
/// and the lower part, in the same column, at the east.
547
double
htot = this->domain_pt()->htot();
548
549
Vector<double>
xi
(1);
550
xi
[0] = Hleaflet;
551
552
Vector<double>
r_join
(2);
553
554
this->Leaflet_pt->position(
t
,
xi
,
r_join
);
555
556
r
[0] =
r_join
[0] +
zeta
[0] * (X_0 -
r_join
[0]);
557
r
[1] =
r_join
[1] +
zeta
[0] * (htot -
r_join
[1]);
558
}
559
560
//=================================================================
561
/// Node update for region III
562
//=================================================================
563
template
<
class
ELEMENT>
564
void
AlgebraicChannelWithLeafletMesh<ELEMENT>::node_update_III
(
565
const
unsigned
&
t
,
AlgebraicNode
*&
node_pt
)
566
{
567
// relevant data of the domain for part I
568
double
lleft = this->domain_pt()->lleft();
569
570
// Extract reference values for update by copy construction
571
Vector<double>
ref_value
(
node_pt
->vector_ref_value());
572
573
// Coordinates of the steady node on the left boundary
574
// corresponding to the current node
575
double
y0
=
ref_value
[0];
576
double
x0
= -lleft + X_0;
577
578
Vector<double>
s
(1);
579
s
[0] =
ref_value
[1];
580
581
// Get position vector
582
Vector<double>
r_line
(2);
583
slanted_bound_up(
t
,
s
,
r_line
);
584
585
// Third reference value : fraction of the horizontal line
586
// between the edge and the middle line
587
double
r
=
ref_value
[2];
588
589
// Assign new nodal coordinates
590
node_pt
->x(
t
, 0) =
x0
+
r
* (
r_line
[0] -
x0
);
591
node_pt
->x(
t
, 1) =
y0
+
r
* (
r_line
[1] -
y0
);
592
}
593
594
//=================================================================
595
/// Node update for region IV
596
//=================================================================
597
template
<
class
ELEMENT>
598
void
AlgebraicChannelWithLeafletMesh<ELEMENT>::node_update_IV
(
599
const
unsigned
&
t
,
AlgebraicNode
*&
node_pt
)
600
{
601
// relevant data of the domain for part I
602
double
lright = this->domain_pt()->lright();
603
604
// Extract reference values for update by copy construction
605
Vector<double>
ref_value
(
node_pt
->vector_ref_value());
606
607
// Coordinates of the steady node on the left boundary
608
// corresponding to the current node
609
double
y0
=
ref_value
[0];
610
double
x0
= X_0 + lright;
611
612
// Second reference value: Zeta coordinate on the middle line
613
Vector<double>
s
(1);
614
s
[0] =
ref_value
[1];
615
616
// Get position vector at timestep t
617
Vector<double>
r_line
(2);
618
slanted_bound_up(
t
,
s
,
r_line
);
619
620
// Third reference value : fraction of the horizontal line
621
// between the middle line and the right edge
622
double
r
=
ref_value
[2];
623
624
// Assign new nodal coordinates
625
node_pt
->x(
t
, 0) =
r_line
[0] +
r
* (
x0
-
r_line
[0]);
626
node_pt
->x(
t
, 1) =
r_line
[1] +
r
* (
y0
-
r_line
[1]);
627
}
628
629
630
/// ////////////////////////////////////////////////////////////////////////
631
/// ////////////////////////////////////////////////////////////////////////
632
/// ////////////////////////////////////////////////////////////////////////
633
634
635
//===================================================================
636
/// Update the node update functions
637
//===================================================================
638
template
<
class
ELEMENT>
639
void
RefineableAlgebraicChannelWithLeafletMesh<ELEMENT>::update_node_update
(
640
AlgebraicNode
*&
node_pt
)
641
{
642
// Extract ID
643
unsigned
id
=
node_pt
->node_update_fct_id();
644
645
if
((
id
== 1) || (
id
== 2))
646
{
647
// Extract reference values for node update by copy construction
648
Vector<double>
ref_value
(
node_pt
->vector_ref_value());
649
650
// Get zeta coordinate on wall
651
Vector<double>
zeta_wall
(1);
652
zeta_wall
[0] =
ref_value
[3];
653
654
// Get the sub-geomobject and the local coordinate
655
Vector<double>
s
(1);
656
GeomObject
*
geom_obj_pt
;
657
this->Leaflet_pt->locate_zeta(
zeta_wall
,
geom_obj_pt
,
s
);
658
659
// Extract geometric objects for update by copy construction
660
Vector<GeomObject*>
geom_object_pt
(
node_pt
->vector_geom_object_pt());
661
662
// Update the pointer to the (sub-)GeomObject within which the
663
// reference point is located. (If the wall is simple GeomObject
664
// this is the same as Leaflet_pt; if it's a compound GeomObject
665
// this points to the sub-object)
666
geom_object_pt
[0] =
geom_obj_pt
;
667
668
// Update second reference value: Reference local coordinate
669
// in wall sub-element
670
ref_value
[1] =
s
[0];
671
672
673
if
(
id
== 1)
674
{
675
// Kill the existing node update info
676
node_pt
->kill_node_update_info(1);
677
678
// Setup algebraic update for node: Pass update information
679
node_pt
->add_node_update_info(1,
// id
680
this
,
// mesh
681
geom_object_pt
,
// vector of geom objects
682
ref_value
);
// vector of ref. values
683
}
684
else
if
(
id
== 2)
685
{
686
// Kill the existing node update info
687
node_pt
->kill_node_update_info(2);
688
689
// Setup algebraic update for node: Pass update information
690
node_pt
->add_node_update_info(2,
// id
691
this
,
// mesh
692
geom_object_pt
,
// vector of geom objects
693
ref_value
);
// vector of ref. values
694
}
695
}
696
}
697
698
}
// namespace oomph
699
700
#endif
channel_with_leaflet_mesh.template.h
oomph::AlgebraicChannelWithLeafletMesh::setup_algebraic_node_update
void setup_algebraic_node_update()
Function to setup the algebraic node update.
Definition
channel_with_leaflet_mesh.template.cc:242
oomph::AlgebraicChannelWithLeafletMesh::algebraic_node_update
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
Definition
channel_with_leaflet_mesh.template.cc:412
oomph::AlgebraicChannelWithLeafletMesh::node_update_I
void node_update_I(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in lower left region (I)
Definition
channel_with_leaflet_mesh.template.cc:455
oomph::AlgebraicChannelWithLeafletMesh::node_update_III
void node_update_III(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in upper left region (III)
Definition
channel_with_leaflet_mesh.template.cc:564
oomph::AlgebraicChannelWithLeafletMesh::node_update_II
void node_update_II(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in lower right region (II)
Definition
channel_with_leaflet_mesh.template.cc:500
oomph::AlgebraicChannelWithLeafletMesh::slanted_bound_up
void slanted_bound_up(const unsigned &t, const Vector< double > &zeta, Vector< double > &r)
Helper function.
Definition
channel_with_leaflet_mesh.template.cc:542
oomph::AlgebraicChannelWithLeafletMesh::node_update_IV
void node_update_IV(const unsigned &t, AlgebraicNode *&node_pt)
Update function for nodes in upper right region (IV)
Definition
channel_with_leaflet_mesh.template.cc:598
oomph::ChannelWithLeafletDomain
Rectangular domain with a leaflet blocking the lower half.
Definition
channel_with_leaflet_domain.h:42
oomph::ChannelWithLeafletMesh::Domain_pt
ChannelWithLeafletDomain * Domain_pt
Pointer to domain.
Definition
channel_with_leaflet_mesh.template.h:89
oomph::ChannelWithLeafletMesh::Leaflet_pt
GeomObject * Leaflet_pt
Pointer to GeomObject that represents the leaflet.
Definition
channel_with_leaflet_mesh.template.h:92
oomph::ChannelWithLeafletMesh::ChannelWithLeafletMesh
ChannelWithLeafletMesh(GeomObject *leaflet_pt, const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to GeomObject that represents the leaflet, the length of the domain to left...
Definition
channel_with_leaflet_mesh.template.cc:48
oomph::GeompackQuadMesh
Quadrilateral mesh generator; Uses input from Geompack++. See: http://members.shaw....
Definition
geompack_mesh.template.h:42
oomph::RefineableAlgebraicChannelWithLeafletMesh::update_node_update
void update_node_update(AlgebraicNode *&node_pt)
Update the node update data for specified node following any mesh adapation.
Definition
channel_with_leaflet_mesh.template.cc:639
oomph::SimpleRectangularQuadMesh
Simple rectangular 2D Quad mesh class. Nx : number of elements in the x direction.
Definition
simple_rectangular_quadmesh.template.h:58
oomph
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Definition
annular_domain.h:35