cylinder_with_flag_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_CYLINDER_WITH_FLAG_MESH_TEMPLATE_HEADER
27#define OOMPH_CYLINDER_WITH_FLAG_MESH_TEMPLATE_HEADER
28
29#ifndef OOMPH_CYLINDER_WITH_FLAG_MESH_HEADER
30#error __FILE__ should only be included from cylinder_with_flag_mesh.h.
31#endif // OOMPH_CYLINDER_WITH_FLAG_MESH_HEADER
32
33// Include the headers file
34
35namespace oomph
36{
37 //=============================================================
38 /// Constructor. Pass the pointers to the GeomObjects that parametrise
39 /// the cylinder, the three edges of the flag, the length and height of the
40 /// domain, the length and height of the flag, the coordinates of the
41 /// centre of the cylinder and its radius. Timestepper defaults to Steady
42 /// default timestepper.
43 //=============================================================
44 template<class ELEMENT>
46 Circle* cylinder_pt,
47 GeomObject* top_flag_pt,
48 GeomObject* bottom_flag_pt,
49 GeomObject* tip_flag_pt,
50 const double& length,
51 const double& height,
52 const double& flag_length,
53 const double& flag_height,
54 const double& centre_x,
55 const double& centre_y,
56 const double& a,
57 TimeStepper* time_stepper_pt)
58 {
59 // Mesh can only be built with 2D Qelements.
60 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
61
62 // Create the domain
63 Domain_pt = new CylinderWithFlagDomain(cylinder_pt,
64 top_flag_pt,
65 bottom_flag_pt,
66 tip_flag_pt,
67 length,
68 height,
73 a);
74
75 // Initialise the node counter
76 unsigned long node_count = 0;
77
78 // Vectors used to get data from domains
81
82 // Setup temporary storage for the Node
84
85 // Now blindly loop over the macro elements and associate and finite
86 // element with each
87 unsigned nmacro_element = Domain_pt->nmacro_element();
88 for (unsigned e = 0; e < nmacro_element; e++)
89 {
90 // Create the FiniteElement and add to the Element_pt Vector
91 Element_pt.push_back(new ELEMENT);
92
93 // Read out the number of linear points in the element
94 unsigned np =
95 dynamic_cast<ELEMENT*>(this->finite_element_pt(e))->nnode_1d();
96
97 // Loop over nodes in the column
98 for (unsigned l1 = 0; l1 < np; l1++)
99 {
100 // Loop over the nodes in the row
101 for (unsigned l2 = 0; l2 < np; l2++)
102 {
103 // Allocate the memory for the node
104 tmp_node_pt.push_back(
105 this->finite_element_pt(e)->construct_boundary_node(
106 l1 * np + l2, time_stepper_pt));
107
108 // Read out the position of the node from the macro element
109 s[0] = -1.0 + 2.0 * (double)l2 / (double)(np - 1);
110 s[1] = -1.0 + 2.0 * (double)l1 / (double)(np - 1);
111 Domain_pt->macro_element_pt(e)->macro_map(s, r);
112
113 // Set the position of the node
114 tmp_node_pt[node_count]->x(0) = r[0];
115 tmp_node_pt[node_count]->x(1) = r[1];
116
117 // Increment the node number
118 node_count++;
119 }
120 }
121 } // End of loop over macro elements
122
123 // Now the elements have been created, but there will be nodes in
124 // common, need to loop over the common edges and sort it, by reassigning
125 // pointers and the deleting excess nodes
126
127 // Read out the number of linear points in the element
128 unsigned np =
129 dynamic_cast<ELEMENT*>(this->finite_element_pt(0))->nnode_1d();
130
131 // Edge between Elements 0 and 1
132 for (unsigned n = 0; n < np; n++)
133 {
134 // Set the nodes in element 1 to be the same as in element 0
135 this->finite_element_pt(1)->node_pt(n * np) =
136 this->finite_element_pt(0)->node_pt((np - 1) * np + np - 1 - n);
137
138 // Remove the nodes in element 1 from the temporaray node list
139 delete tmp_node_pt[np * np + n * np];
140 tmp_node_pt[np * np + n * np] = 0;
141 }
142
143 // Edge between Elements 1 and 2
144 for (unsigned n = 0; n < np; n++)
145 {
146 // Set the nodes in element 2 to be the same as in element 1
147 this->finite_element_pt(2)->node_pt(n * np) =
148 this->finite_element_pt(1)->node_pt(np * n + np - 1);
149
150 // Remove the nodes in element 2 from the temporaray node list
151 delete tmp_node_pt[2 * np * np + n * np];
152 tmp_node_pt[2 * np * np + n * np] = 0;
153 }
154
155 // Edge between Element 2 and 3
156 for (unsigned n = 0; n < np; n++)
157 {
158 // Set the nodes in element 3 to be the same as in element 2
159 this->finite_element_pt(3)->node_pt(np * (np - 1) + n) =
160 this->finite_element_pt(2)->node_pt(np * n + np - 1);
161
162 // Remove the nodes in element 3 from the temporaray node list
163 delete tmp_node_pt[3 * np * np + np * (np - 1) + n];
164 tmp_node_pt[3 * np * np + np * (np - 1) + n] = 0;
165 }
166
167 // Edge between Element 5 and 4
168 for (unsigned n = 0; n < np; n++)
169 {
170 // Set the nodes in element 4 to be the same as in element 5
171 this->finite_element_pt(4)->node_pt(n) =
172 this->finite_element_pt(5)->node_pt(np * (np - n - 1) + np - 1);
173
174 // Remove the nodes in element 4 from the temporaray node list
175 delete tmp_node_pt[4 * np * np + n];
176 tmp_node_pt[4 * np * np + n] = 0;
177 }
178
179 // Edge between Elements 6 and 5
180 for (unsigned n = 0; n < np; n++)
181 {
182 // Set the nodes in element 5 to be the same as in element 6
183 this->finite_element_pt(5)->node_pt(n * np) =
184 this->finite_element_pt(6)->node_pt(np * n + np - 1);
185
186 // Remove the nodes in element 5 from the temporaray node list
187 delete tmp_node_pt[5 * np * np + n * np];
188 tmp_node_pt[5 * np * np + n * np] = 0;
189 }
190
191 // Edge between Elements 0 and 6
192 for (unsigned n = 0; n < np; n++)
193 {
194 // Set the nodes in element 6 to be the same as in element 0
195 this->finite_element_pt(6)->node_pt(n * np) =
196 this->finite_element_pt(0)->node_pt(n);
197
198 // Remove the nodes in element 6 from the temporaray node list
199 delete tmp_node_pt[6 * np * np + n * np];
200 tmp_node_pt[6 * np * np + n * np] = 0;
201 }
202
203 // Edge between Elements 2 and 7
204 for (unsigned n = 0; n < np; n++)
205 {
206 // Set the nodes in element 7 to be the same as in element 2
207 this->finite_element_pt(7)->node_pt(n * np) =
208 this->finite_element_pt(2)->node_pt((np - 1) * np + np - 1 - n);
209
210 // Remove the nodes in element 7 from the temporaray node list
211 delete tmp_node_pt[7 * np * np + n * np];
212 tmp_node_pt[7 * np * np + n * np] = 0;
213 }
214
215 // Edge between Elements 3 and 8
216 for (unsigned n = 0; n < np; n++)
217 {
218 // Set the nodes in element 8 to be the same as in element 3
219 this->finite_element_pt(8)->node_pt(n * np) =
220 this->finite_element_pt(3)->node_pt(np * n + np - 1);
221
222 // Remove the nodes in element 8 from the temporaray node list
223 delete tmp_node_pt[8 * np * np + n * np];
224 tmp_node_pt[8 * np * np + n * np] = 0;
225 }
226
227 // Edge between Elements 4 and 9
228 for (unsigned n = 0; n < np; n++)
229 {
230 // Set the nodes in element 9 to be the same as in element 4
231 this->finite_element_pt(9)->node_pt(n * np) =
232 this->finite_element_pt(4)->node_pt(np * n + np - 1);
233
234 // Remove the nodes in element 9 from the temporaray node list
235 delete tmp_node_pt[9 * np * np + n * np];
236 tmp_node_pt[9 * np * np + n * np] = 0;
237 }
238
239 // Edge between Elements 5 and 10
240 for (unsigned n = 0; n < np; n++)
241 {
242 // Set the nodes in element 10 to be the same as in element 5
243 this->finite_element_pt(10)->node_pt(n * np) =
244 this->finite_element_pt(5)->node_pt(n);
245
246 // Remove the nodes in element 10 from the temporaray node list
247 delete tmp_node_pt[10 * np * np + n * np];
248 tmp_node_pt[10 * np * np + n * np] = 0;
249 }
250
251 // Edge between Elements 7 and 11
252 for (unsigned n = 0; n < np; n++)
253 {
254 // Set the nodes in element 11 to be the same as in element 7
255 this->finite_element_pt(11)->node_pt(n * np) =
256 this->finite_element_pt(7)->node_pt(np * n + np - 1);
257
258 // Remove the nodes in element 11 from the temporaray node list
259 delete tmp_node_pt[11 * np * np + n * np];
260 tmp_node_pt[11 * np * np + n * np] = 0;
261 }
262
263 // Edge between Elements 8 and 12
264 for (unsigned n = 0; n < np; n++)
265 {
266 // Set the nodes in element 12 to be the same as in element 8
267 this->finite_element_pt(12)->node_pt(n * np) =
268 this->finite_element_pt(8)->node_pt(np * n + np - 1);
269
270 // Remove the nodes in element 12 from the temporaray node list
271 delete tmp_node_pt[12 * np * np + n * np];
272 tmp_node_pt[12 * np * np + n * np] = 0;
273 }
274
275 // Edge between Elements 9 and 13
276 for (unsigned n = 0; n < np; n++)
277 {
278 // Set the nodes in element 13 to be the same as in element 9
279 this->finite_element_pt(13)->node_pt(n * np) =
280 this->finite_element_pt(9)->node_pt(np * n + np - 1);
281
282 // Remove the nodes in element 13 from the temporaray node list
283 delete tmp_node_pt[13 * np * np + n * np];
284 tmp_node_pt[13 * np * np + n * np] = 0;
285 }
286
287 // Edge between Elements 10 and 14
288 for (unsigned n = 0; n < np; n++)
289 {
290 // Set the nodes in element 14 to be the same as in element 10
291 this->finite_element_pt(14)->node_pt(n * np) =
292 this->finite_element_pt(10)->node_pt(np * n + np - 1);
293
294 // Remove the nodes in element 14 from the temporaray node list
295 delete tmp_node_pt[14 * np * np + n * np];
296 tmp_node_pt[14 * np * np + n * np] = 0;
297 }
298
299 // Edge between Elements 7 and 8
300 for (unsigned n = 0; n < np; n++)
301 {
302 // Set the nodes in element 8 to be the same as in element 7
303 this->finite_element_pt(8)->node_pt(np * (np - 1) + n) =
304 this->finite_element_pt(7)->node_pt(n);
305
306 // Remove the nodes in element 8 from the temporaray node list
307 delete tmp_node_pt[8 * np * np + np * (np - 1) + n];
308 tmp_node_pt[8 * np * np + np * (np - 1) + n] = 0;
309 }
310
311 // Edge between Elements 9 and 10
312 for (unsigned n = 0; n < np; n++)
313 {
314 // Set the nodes in element 10 to be the same as in element 9
315 this->finite_element_pt(10)->node_pt(np * (np - 1) + n) =
316 this->finite_element_pt(9)->node_pt(n);
317
318 // Remove the nodes in element 10 from the temporaray node list
319 delete tmp_node_pt[10 * np * np + np * (np - 1) + n];
320 tmp_node_pt[10 * np * np + np * (np - 1) + n] = 0;
321 }
322
323 // Edge between Elements 11 and 15
324 for (unsigned n = 0; n < np; n++)
325 {
326 // Set the nodes in element 15 to be the same as in element 11
327 this->finite_element_pt(15)->node_pt(n * np) =
328 this->finite_element_pt(11)->node_pt(np * n + np - 1);
329
330 // Remove the nodes in element 15 from the temporaray node list
331 delete tmp_node_pt[15 * np * np + n * np];
332 tmp_node_pt[15 * np * np + n * np] = 0;
333 }
334
335 // Edge between Elements 12 and 16
336 for (unsigned n = 0; n < np; n++)
337 {
338 // Set the nodes in element 16 to be the same as in element 12
339 this->finite_element_pt(16)->node_pt(n * np) =
340 this->finite_element_pt(12)->node_pt(np * n + np - 1);
341
342 // Remove the nodes in element 16 from the temporaray node list
343 delete tmp_node_pt[16 * np * np + n * np];
344 tmp_node_pt[16 * np * np + n * np] = 0;
345 }
346
347 // Edge between Elements 13 and 17
348 for (unsigned n = 0; n < np; n++)
349 {
350 // Set the nodes in element 17 to be the same as in element 13
351 this->finite_element_pt(17)->node_pt(n * np) =
352 this->finite_element_pt(13)->node_pt(np * n + np - 1);
353
354 // Remove the nodes in element 17 from the temporaray node list
355 delete tmp_node_pt[17 * np * np + n * np];
356 tmp_node_pt[17 * np * np + n * np] = 0;
357 }
358
359 // Edge between Elements 14 and 18
360 for (unsigned n = 0; n < np; n++)
361 {
362 // Set the nodes in element 18 to be the same as in element 14
363 this->finite_element_pt(18)->node_pt(n * np) =
364 this->finite_element_pt(14)->node_pt(np * n + np - 1);
365
366 // Remove the nodes in element 18 from the temporaray node list
367 delete tmp_node_pt[18 * np * np + n * np];
368 tmp_node_pt[18 * np * np + n * np] = 0;
369 }
370
371 // Edge between Elements 11 and 12
372 for (unsigned n = 0; n < np; n++)
373 {
374 // Set the nodes in element 12 to be the same as in element 11
375 this->finite_element_pt(12)->node_pt(np * (np - 1) + n) =
376 this->finite_element_pt(11)->node_pt(n);
377
378 // Remove the nodes in element 12 from the temporaray node list
379 delete tmp_node_pt[12 * np * np + np * (np - 1) + n];
380 tmp_node_pt[12 * np * np + np * (np - 1) + n] = 0;
381 }
382
383 // Edge between Elements 13 and 14
384 for (unsigned n = 0; n < np; n++)
385 {
386 // Set the nodes in element 14 to be the same as in element 13
387 this->finite_element_pt(14)->node_pt(np * (np - 1) + n) =
388 this->finite_element_pt(13)->node_pt(n);
389
390 // Remove the nodes in element 14 from the temporaray node list
391 delete tmp_node_pt[14 * np * np + np * (np - 1) + n];
392 tmp_node_pt[14 * np * np + np * (np - 1) + n] = 0;
393 }
394
395 // Edge between Element 15 and 19
396 for (unsigned n = 0; n < np; n++)
397 {
398 // Set the nodes in element 19 to be the same as in element 15
399 this->finite_element_pt(19)->node_pt(np * (np - 1) + n) =
400 this->finite_element_pt(15)->node_pt(np * n + np - 1);
401
402 // Remove the nodes in element 19 from the temporaray node list
403 delete tmp_node_pt[19 * np * np + np * (np - 1) + n];
404 tmp_node_pt[19 * np * np + np * (np - 1) + n] = 0;
405 }
406
407 // Edge between Elements 19 and 16
408 for (unsigned n = 0; n < np; n++)
409 {
410 // Set the nodes in element 19 to be the same as in element 16
411 this->finite_element_pt(16)->node_pt(np * n + np - 1) =
412 this->finite_element_pt(19)->node_pt(n * np);
413
414 // Remove the nodes in element 16 from the temporaray node list
415 delete tmp_node_pt[16 * np * np + np * (np - 1) + n];
416 tmp_node_pt[16 * np * np + np * (np - 1) + n] = 0;
417 }
418
419 // Edge between Elements 15 and 16
420 for (unsigned n = 0; n < np; n++)
421 {
422 // Set the nodes in element 16 to be the same as in element 15
423 this->finite_element_pt(16)->node_pt(np * (np - 1) + n) =
424 this->finite_element_pt(15)->node_pt(n);
425
426 // Remove the nodes in element 16 from the temporaray node list
427 delete tmp_node_pt[16 * np * np + np * (np - 1) + n];
428 tmp_node_pt[16 * np * np + np * (np - 1) + n] = 0;
429 }
430
431 // Edge between Element 18 and 20
432 for (unsigned n = 0; n < np; n++)
433 {
434 // Set the nodes in element 20 to be the same as in element 18
435 this->finite_element_pt(20)->node_pt(n) =
436 this->finite_element_pt(18)->node_pt(np * (np - n - 1) + np - 1);
437
438 // Remove the nodes in element 20 from the temporaray node list
439 delete tmp_node_pt[20 * np * np + n];
440 tmp_node_pt[20 * np * np + n] = 0;
441 }
442
443 // Edge between Elements 17 and 20
444 for (unsigned n = 0; n < np; n++)
445 {
446 // Set the nodes in element 20 to be the same as in element 17
447 this->finite_element_pt(20)->node_pt(n * np) =
448 this->finite_element_pt(17)->node_pt(np * n + np - 1);
449
450 // Remove the nodes in element 20 from the temporaray node list
451 delete tmp_node_pt[20 * np * np + n * np];
452 tmp_node_pt[20 * np * np + n * np] = 0;
453 }
454
455 // Edge between Elements 17 and 18
456 for (unsigned n = 0; n < np; n++)
457 {
458 // Set the nodes in element 18 to be the same as in element 17
459 this->finite_element_pt(18)->node_pt(np * (np - 1) + n) =
460 this->finite_element_pt(17)->node_pt(n);
461
462 // Remove the nodes in element 18 from the temporaray node list
463 delete tmp_node_pt[18 * np * np + np * (np - 1) + n];
464 tmp_node_pt[18 * np * np + np * (np - 1) + n] = 0;
465 }
466
467 // Edge between Elements 19 and 21
468 for (unsigned n = 0; n < np; n++)
469 {
470 // Set the nodes in element 21 to be the same as in element 19
471 this->finite_element_pt(21)->node_pt(n * np) =
472 this->finite_element_pt(19)->node_pt(np * n + np - 1);
473
474 // Remove the nodes in element 21 from the temporaray node list
475 delete tmp_node_pt[21 * np * np + n * np];
476 tmp_node_pt[21 * np * np + n * np] = 0;
477 }
478
479 // Edge between Elements 21 and 22
480 for (unsigned n = 0; n < np; n++)
481 {
482 // Set the nodes in element 22 to be the same as in element 21
483 this->finite_element_pt(22)->node_pt(np * (np - 1) + n) =
484 this->finite_element_pt(21)->node_pt(n);
485
486 // Remove the nodes in element 22 from the temporaray node list
487 delete tmp_node_pt[22 * np * np + np * (np - 1) + n];
488 tmp_node_pt[22 * np * np + np * (np - 1) + n] = 0;
489 }
490
491 // Edge between Elements 20 and 23
492 for (unsigned n = 0; n < np; n++)
493 {
494 // Set the nodes in element 23 to be the same as in element 20
495 this->finite_element_pt(23)->node_pt(n * np) =
496 this->finite_element_pt(20)->node_pt(np * n + np - 1);
497
498 // Remove the nodes in element 23 from the temporaray node list
499 delete tmp_node_pt[23 * np * np + n * np];
500 tmp_node_pt[23 * np * np + n * np] = 0;
501 }
502
503 // Edge between Elements 23 and 22
504 for (unsigned n = 0; n < np; n++)
505 {
506 // Set the nodes in element 22 to be the same as in element 23
507 this->finite_element_pt(22)->node_pt(n) =
508 this->finite_element_pt(23)->node_pt(np * (np - 1) + n);
509
510 // Remove the nodes in element 22 from the temporaray node list
511 delete tmp_node_pt[22 * np * np + np * (np - 1) + n];
512 tmp_node_pt[22 * np * np + np * (np - 1) + n] = 0;
513 }
514
515 // Edge between Elements 21 and 24
516 for (unsigned n = 0; n < np; n++)
517 {
518 // Set the nodes in element 24 to be the same as in element 21
519 this->finite_element_pt(24)->node_pt(n * np) =
520 this->finite_element_pt(21)->node_pt(np * n + np - 1);
521
522 // Remove the nodes in element 24 from the temporaray node list
523 delete tmp_node_pt[24 * np * np + n * np];
524 tmp_node_pt[24 * np * np + n * np] = 0;
525 }
526
527 // Edge between Elements 22 and 25
528 for (unsigned n = 0; n < np; n++)
529 {
530 // Set the nodes in element 25 to be the same as in element 22
531 this->finite_element_pt(25)->node_pt(n * np) =
532 this->finite_element_pt(22)->node_pt(np * n + np - 1);
533
534 // Remove the nodes in element 25 from the temporaray node list
535 delete tmp_node_pt[25 * np * np + n * np];
536 tmp_node_pt[25 * np * np + n * np] = 0;
537 }
538
539 // Edge between Elements 23 and 26
540 for (unsigned n = 0; n < np; n++)
541 {
542 // Set the nodes in element 26 to be the same as in element 23
543 this->finite_element_pt(26)->node_pt(n * np) =
544 this->finite_element_pt(23)->node_pt(np * n + np - 1);
545
546 // Remove the nodes in element 26 from the temporaray node list
547 delete tmp_node_pt[26 * np * np + n * np];
548 tmp_node_pt[26 * np * np + n * np] = 0;
549 }
550
551 // Edge between Elements 24 and 25
552 for (unsigned n = 0; n < np; n++)
553 {
554 // Set the nodes in element 25 to be the same as in element 24
555 this->finite_element_pt(25)->node_pt(np * (np - 1) + n) =
556 this->finite_element_pt(24)->node_pt(n);
557
558 // Remove the nodes in element 25 from the temporaray node list
559 delete tmp_node_pt[25 * np * np + np * (np - 1) + n];
560 tmp_node_pt[25 * np * np + np * (np - 1) + n] = 0;
561 }
562
563 // Edge between Elements 25 and 26
564 for (unsigned n = 0; n < np; n++)
565 {
566 // Set the nodes in element 26 to be the same as in element 25
567 this->finite_element_pt(26)->node_pt(np * (np - 1) + n) =
568 this->finite_element_pt(25)->node_pt(n);
569
570 // Remove the nodes in element 26 from the temporaray node list
571 delete tmp_node_pt[26 * np * np + np * (np - 1) + n];
572 tmp_node_pt[26 * np * np + np * (np - 1) + n] = 0;
573 }
574
575 // Edge between Element 24 and 27
576 for (unsigned n = 0; n < np; n++)
577 {
578 // Set the nodes in element 27 to be the same as in element 24
579 this->finite_element_pt(27)->node_pt(np * (np - 1) + n) =
580 this->finite_element_pt(24)->node_pt(np * n + np - 1);
581
582 // Remove the nodes in element 27 from the temporaray node list
583 delete tmp_node_pt[27 * np * np + np * (np - 1) + n];
584 tmp_node_pt[27 * np * np + np * (np - 1) + n] = 0;
585 }
586
587 // Edge between Elements 25 and 27
588 for (unsigned n = 0; n < np; n++)
589 {
590 // Set the nodes in element 27 to be the same as in element 25
591 this->finite_element_pt(27)->node_pt(n * np) =
592 this->finite_element_pt(25)->node_pt(np * n + np - 1);
593
594 // Remove the nodes in element 27 from the temporaray node list
595 delete tmp_node_pt[27 * np * np + n * np];
596 tmp_node_pt[27 * np * np + n * np] = 0;
597 }
598
599 // Edge between Element 26 and 27
600 for (unsigned n = 0; n < np; n++)
601 {
602 // Set the nodes in element 27 to be the same as in element 26
603 this->finite_element_pt(27)->node_pt(n) =
604 this->finite_element_pt(26)->node_pt(np * (np - n - 1) + np - 1);
605
606 // Remove the nodes in element 27 from the temporaray node list
607 delete tmp_node_pt[27 * np * np + n];
608 tmp_node_pt[27 * np * np + n] = 0;
609 }
610
611 // Edge between Elements 27 and 28
612 for (unsigned n = 0; n < np; n++)
613 {
614 // Set the nodes in element 28 to be the same as in element 27
615 this->finite_element_pt(28)->node_pt(n * np) =
616 this->finite_element_pt(27)->node_pt(np * n + np - 1);
617
618 // Remove the nodes in element 28 from the temporaray node list
619 delete tmp_node_pt[28 * np * np + n * np];
620 tmp_node_pt[28 * np * np + n * np] = 0;
621 }
622
623 // Edge between Elements 28 and 29
624 for (unsigned n = 0; n < np; n++)
625 {
626 // Set the nodes in element 29 to be the same as in element 28
627 this->finite_element_pt(29)->node_pt(n * np) =
628 this->finite_element_pt(28)->node_pt(np * n + np - 1);
629
630 // Remove the nodes in element 29 from the temporaray node list
631 delete tmp_node_pt[29 * np * np + n * np];
632 tmp_node_pt[29 * np * np + n * np] = 0;
633 }
634
635 // Edge between Elements 29 and 30
636 for (unsigned n = 0; n < np; n++)
637 {
638 // Set the nodes in element 30 to be the same as in element 29
639 this->finite_element_pt(30)->node_pt(n * np) =
640 this->finite_element_pt(29)->node_pt(np * n + np - 1);
641
642 // Remove the nodes in element 30 from the temporaray node list
643 delete tmp_node_pt[30 * np * np + n * np];
644 tmp_node_pt[30 * np * np + n * np] = 0;
645 }
646
647 // Now set the actual true nodes
648 for (unsigned long n = 0; n < node_count; n++)
649 {
650 if (tmp_node_pt[n] != 0)
651 {
652 Node_pt.push_back(tmp_node_pt[n]);
653 }
654 }
655
656 // Finally set the nodes on the boundaries
657 this->set_nboundary(8);
658
659 for (unsigned n = 0; n < np; n++)
660 {
661 // Left hand side
662 this->add_boundary_node(3, this->finite_element_pt(0)->node_pt(n * np));
663 // Right hand side
664 this->add_boundary_node(
665 1, this->finite_element_pt(30)->node_pt(n * np + np - 1));
666
667 // First part of lower boundary
668 this->add_boundary_node(0, this->finite_element_pt(6)->node_pt(n));
669
670 // First part of upper boundary
671 this->add_boundary_node(
672 2, this->finite_element_pt(1)->node_pt(np * (np - 1) + n));
673
674 // First part of hole boundary
675 this->add_boundary_node(4, this->finite_element_pt(3)->node_pt(np * n));
676
677 // First part of lower flag
678 this->add_boundary_node(
679 5, this->finite_element_pt(4)->node_pt(np * (np - 1) + n));
680
681 // First part of upper flag
682 this->add_boundary_node(6, this->finite_element_pt(3)->node_pt(n));
683
684 // Right part of flag
685 this->add_boundary_node(7, this->finite_element_pt(22)->node_pt(n * np));
686 }
687
688 for (unsigned n = 1; n < np; n++)
689 {
690 // Second part of lower boundary
691 this->add_boundary_node(0, this->finite_element_pt(10)->node_pt(n));
692
693 // Second part of upper boundary
694 this->add_boundary_node(
695 2, this->finite_element_pt(7)->node_pt(np * (np - 1) + n));
696
697 // Next part of lower flag
698 this->add_boundary_node(
699 5, this->finite_element_pt(9)->node_pt(np * (np - 1) + n));
700
701 // Next part of upper flag
702 this->add_boundary_node(6, this->finite_element_pt(8)->node_pt(n));
703 }
704
705 for (unsigned n = np - 2; n > 0; n--)
706 {
707 // Next part of hole
708 this->add_boundary_node(4, this->finite_element_pt(2)->node_pt(n));
709 }
710
711 for (unsigned n = 1; n < np; n++)
712 {
713 // Next part of lower boundary
714 this->add_boundary_node(0, this->finite_element_pt(14)->node_pt(n));
715
716 // Next part of upper boundary
717 this->add_boundary_node(
718 2, this->finite_element_pt(11)->node_pt(np * (np - 1) + n));
719
720 // Next part of lower flag
721 this->add_boundary_node(
722 5, this->finite_element_pt(13)->node_pt(np * (np - 1) + n));
723
724 // Next part of upper flag
725 this->add_boundary_node(6, this->finite_element_pt(12)->node_pt(n));
726 }
727
728 for (unsigned n = np - 1; n > 0; n--)
729 {
730 // Next part of hole
731 this->add_boundary_node(4, this->finite_element_pt(1)->node_pt(n));
732 }
733
734 for (unsigned n = 1; n < np; n++)
735 {
736 // Next part of lower boundary
737 this->add_boundary_node(0, this->finite_element_pt(18)->node_pt(n));
738 // Next part of upper boundary
739 this->add_boundary_node(
740 2, this->finite_element_pt(15)->node_pt(np * (np - 1) + n));
741
742 // Next part of lower flag
743 this->add_boundary_node(
744 5, this->finite_element_pt(17)->node_pt(np * (np - 1) + n));
745
746 // Next part of upper flag
747 this->add_boundary_node(6, this->finite_element_pt(16)->node_pt(n));
748 }
749
750 for (unsigned n = np - 1; n > 0; n--)
751 {
752 // Next part of hole
753 this->add_boundary_node(
754 4, this->finite_element_pt(0)->node_pt(n * np + np - 1));
755 }
756
757 for (unsigned n = 1; n < np; n++)
758 {
759 // Next part of lower boundary
760 this->add_boundary_node(0, this->finite_element_pt(23)->node_pt(n));
761 // Next part of upper boundary
762 this->add_boundary_node(
763 2, this->finite_element_pt(21)->node_pt(np * (np - 1) + n));
764
765 // Next part of hole
766 this->add_boundary_node(
767 4, this->finite_element_pt(6)->node_pt(np * (np - 1) + n));
768
769 // Next part of lower flag
770 this->add_boundary_node(
771 5, this->finite_element_pt(20)->node_pt(np * (np - 1) + n));
772
773 // Next part of upper flag
774 this->add_boundary_node(6, this->finite_element_pt(19)->node_pt(n));
775 }
776
777 for (unsigned n = 0; n < np; n++)
778 {
779 // Next part of hole
780 this->add_boundary_node(
781 4, this->finite_element_pt(6)->node_pt(np * (np - 1) + n));
782 }
783
784 for (unsigned n = 1; n < np; n++)
785 {
786 // Next part of lower boundary
787 this->add_boundary_node(0, this->finite_element_pt(26)->node_pt(n));
788 // Next part of upper boundary
789 this->add_boundary_node(
790 2, this->finite_element_pt(24)->node_pt(np * (np - 1) + n));
791
792 // Next part of hole
793 this->add_boundary_node(
794 4, this->finite_element_pt(5)->node_pt(np * (np - 1) + n));
795 }
796
797 for (unsigned n = 1; n < np; n++)
798 {
799 // Next part of lower boundary
800 this->add_boundary_node(0, this->finite_element_pt(28)->node_pt(n));
801 // Next part of upper boundary
802 this->add_boundary_node(
803 2, this->finite_element_pt(28)->node_pt(np * (np - 1) + n));
804
805 // Next part of hole
806 this->add_boundary_node(4, this->finite_element_pt(4)->node_pt(np * n));
807 }
808
809 for (unsigned n = 1; n < np; n++)
810 {
811 // Next part of lower boundary
812 this->add_boundary_node(0, this->finite_element_pt(29)->node_pt(n));
813 // Next part of upper boundary
814 this->add_boundary_node(
815 2, this->finite_element_pt(29)->node_pt(np * (np - 1) + n));
816 }
817
818 for (unsigned n = 1; n < np; n++)
819 {
820 // Next part of lower boundary
821 this->add_boundary_node(0, this->finite_element_pt(30)->node_pt(n));
822 // Next part of upper boundary
823 this->add_boundary_node(
824 2, this->finite_element_pt(30)->node_pt(np * (np - 1) + n));
825 }
826
827 this->node_update();
828 setup_boundary_element_info();
829
830 // Set boundary coordinates on the flag
831
832 // Vector of Lagrangian coordinates used as boundary coordinate
834
835 // loop on nodes of boundary 5
836 unsigned nnode = this->nboundary_node(5);
837 for (unsigned k = 0; k < nnode; k++)
838 {
839 Node* nod_pt = this->boundary_node_pt(5, k);
840 zeta[0] = double(k) * flag_length / double(nnode - 1);
841 nod_pt->set_coordinates_on_boundary(5, zeta);
842 }
843
844 // loop on nodes of boundary 6
845 nnode = this->nboundary_node(6);
846 for (unsigned k = 0; k < nnode; k++)
847 {
848 Node* nod_pt = this->boundary_node_pt(6, k);
849 zeta[0] = double(k) * flag_length / double(nnode - 1);
850 nod_pt->set_coordinates_on_boundary(6, zeta);
851 }
852
853 // loop on nodes of boundary 7
854 nnode = this->nboundary_node(7);
855 for (unsigned k = 0; k < nnode; k++)
856 {
857 Node* nod_pt = this->boundary_node_pt(7, k);
858 zeta[0] = -flag_height / 2. + double(k) / double(nnode - 1) * flag_height;
859 nod_pt->set_coordinates_on_boundary(7, zeta);
860 }
861
862 // We have parametrised boundary 5,6 and 7
863 this->set_boundary_coordinate_exists(5);
864 this->set_boundary_coordinate_exists(6);
865 this->set_boundary_coordinate_exists(7);
866
867 // Loop over all elements and set macro element pointer
868 for (unsigned e = 0; e < 31; e++)
869 {
870 dynamic_cast<ELEMENT*>(this->element_pt(e))
871 ->set_macro_elem_pt(this->Domain_pt->macro_element_pt(e));
872 }
873 }
874
875
876 //////////////////////////////////////////////////////////////////////////
877 //////////////////////////////////////////////////////////////////////////
878 //////////////////////////////////////////////////////////////////////////
879
880 //=================================================================
881 /// Setup algebraic node update
882 //=================================================================
883 template<class ELEMENT>
885 {
886 // The update function requires six parameters in some cases:
887 Vector<double> ref_value(6);
888 for (unsigned i = 0; i < 5; i++)
889 {
890 ref_value[i] = 0.0;
891 }
892
893 // Part I : macro elements 8,12,16
894 for (unsigned k = 0; k < 3; k++)
895 {
896 FiniteElement* el_pt = this->finite_element_pt(8 + k * 4);
897 unsigned nnode = el_pt->nnode();
898 for (unsigned i = 0; i < nnode; i++)
899 {
900 // Get local coordinates
903
904 // First reference value : horizontal fraction
905 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
906
907 // Second reference value : vertical fraction
908 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
909
910 // Third reference value : zeta coordinate on flag
911 ref_value[2] = double(k + 1) / 5. * Flag_length +
912 ref_value[0] * 1. / 5. * Flag_length;
913
914 // Sub-geomobject corresponding to the zeta coordinate on the flag
916 Vector<double> s(1);
918 zeta[0] = ref_value[2];
919 Top_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
920
921 // Create vector of geomobject for add_node_update_info()
922 Vector<GeomObject*> geom_object_pt(1);
923 geom_object_pt[0] = geom_obj_pt;
924
925 // Fourth reference value : local coordinate in the sub geomobject
926 ref_value[3] = s[0];
927
928 // Fifth reference value : x coordinate
929 ref_value[4] = el_pt->node_pt(i)->x(0);
930
931 // Setup algebraic update for node: Pass update information
932 // to AlgebraicNode:
933 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
934 ->add_node_update_info(1, // ID
935 this, // mesh
936 geom_object_pt, // vector of geom objects
937 ref_value); // vector of ref. values
938 }
939 }
940
941 // Part II : macro elements 9,13,17
942 for (unsigned k = 0; k < 3; k++)
943 {
944 FiniteElement* el_pt = this->finite_element_pt(9 + k * 4);
945 unsigned nnode = el_pt->nnode();
946 for (unsigned i = 0; i < nnode; i++)
947 {
948 // Get local coordinates
951
952 // First reference value : horizontal fraction
953 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
954
955 // Second reference value : vertical fraction
956 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
957
958 // Third reference value : zeta coordinate on flag
959 ref_value[2] = double(k + 1) / 5. * Flag_length +
960 ref_value[0] * 1. / 5. * Flag_length;
961
962 // Sub-geomobject corresponding to the zeta coordinate on the flag
964 Vector<double> s(1);
966 zeta[0] = ref_value[2];
967 Bottom_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
968
969 // Create vector of geomobject for add_node_update_info()
970 Vector<GeomObject*> geom_object_pt(1);
971 geom_object_pt[0] = geom_obj_pt;
972
973 // Fourth reference value : local coordinate in the sub geomobject
974 ref_value[3] = s[0];
975
976 // Fifth reference value : x coordinate
977 ref_value[4] = el_pt->node_pt(i)->x(0);
978
979 // Setup algebraic update for node: Pass update information
980 // to AlgebraicNode:
981 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
982 ->add_node_update_info(2, // ID
983 this, // mesh
984 geom_object_pt, // vector of geom objects
985 ref_value); // vector of ref. values
986 }
987 }
988
989 // Part III : macro element 22
990 FiniteElement* el_pt = this->finite_element_pt(22);
991 unsigned nnode = el_pt->nnode();
992 for (unsigned i = 0; i < nnode; i++)
993 {
994 // Get local coordinates
997
998 // First reference value : horizontal fraction
999 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
1000
1001 // Second reference value : vertical fraction
1002 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
1003
1004 // Third reference value : zeta coordinate on flag
1005 ref_value[2] = coord_loc[1] * Flag_height / 2.;
1006
1007 // Sub-geomobject corresponding to the zeta coordinate on the flag
1009 Vector<double> s(1);
1011 zeta[0] = ref_value[2];
1012 Tip_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1013
1014 // Create vector of geomobject for add_node_update_info()
1015 Vector<GeomObject*> geom_object_pt(1);
1016 geom_object_pt[0] = geom_obj_pt;
1017
1018 // Fourth reference value : local coordinate in the sub geomobject
1019 ref_value[3] = s[0];
1020
1021 // Setup algebraic update for node: Pass update information
1022 // to AlgebraicNode:
1023 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
1024 ->add_node_update_info(3, // ID
1025 this, // mesh
1026 geom_object_pt, // vector of geom objects
1027 ref_value); // vector of ref. values
1028 }
1029
1030 // Part IV : macro element 21
1031 el_pt = this->finite_element_pt(21);
1032 nnode = el_pt->nnode();
1033 for (unsigned i = 0; i < nnode; i++)
1034 {
1035 // Get local coordinates
1038
1039 // First reference value : horizontal fraction
1040 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
1041
1042 // Second reference value : vertical fraction
1043 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
1044
1045 // Sub-geomobject corresponding to the tip of the Tip_flag
1047 Vector<double> s(1);
1049 zeta[0] = Flag_height / 2.;
1050 Tip_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1051
1052 // Create vector of geomobject for add_node_update_info()
1053 Vector<GeomObject*> geom_object_pt(1);
1054 geom_object_pt[0] = geom_obj_pt;
1055
1056 // Third reference value : local coordinate in the sub geomobject
1057 ref_value[2] = s[0];
1058
1059 // Setup algebraic update for node: Pass update information
1060 // to AlgebraicNode:
1061 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
1062 ->add_node_update_info(4, // ID
1063 this, // mesh
1064 geom_object_pt, // vector of geom objects
1065 ref_value); // vector of ref. values
1066 }
1067
1068 // Part V : macro element 23
1069 el_pt = this->finite_element_pt(23);
1070 nnode = el_pt->nnode();
1071 for (unsigned i = 0; i < nnode; i++)
1072 {
1073 // Get local coordinates
1076
1077 // First reference value : horizontal fraction
1078 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
1079
1080 // Second reference value : vertical fraction
1081 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
1082
1083 // Sub-geomobject corresponding to the tip of the Tip_flag
1085 Vector<double> s(1);
1087 zeta[0] = -Flag_height / 2.;
1088 Tip_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1089
1090 // Create vector of geomobject for add_node_update_info()
1091 Vector<GeomObject*> geom_object_pt(1);
1092 geom_object_pt[0] = geom_obj_pt;
1093
1094 // Third reference value : local coordinate in the sub geomobject
1095 ref_value[2] = s[0];
1096
1097 // Setup algebraic update for node: Pass update information
1098 // to AlgebraicNode:
1099 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
1100 ->add_node_update_info(5, // ID
1101 this, // mesh
1102 geom_object_pt, // vector of geom objects
1103 ref_value); // vector of ref. values
1104 }
1105
1106 // Part VI = macro element 19
1107 el_pt = this->finite_element_pt(19);
1108 nnode = el_pt->nnode();
1109 for (unsigned i = 0; i < nnode; i++)
1110 {
1111 // Get local coordinates
1114
1115 // First reference value : horizontal fraction
1116 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
1117
1118 // Second reference value : vertical fraction
1119 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
1120
1121 // Third reference value : zeta coordinate on the flag
1122 ref_value[2] =
1123 4. / 5. * Flag_length + ref_value[0] * 1. / 5. * Flag_length;
1124
1125 // Sub-geomobject
1127 Vector<double> s(1);
1129 zeta[0] = ref_value[2];
1130 Top_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1131
1132 // Create vector of geomobject for add_node_update_info()
1133 Vector<GeomObject*> geom_object_pt(1);
1134 geom_object_pt[0] = geom_obj_pt;
1135
1136 // Third reference value : local coordinate in the sub geomobject
1137 ref_value[3] = s[0];
1138
1139 // Setup algebraic update for node: Pass update information
1140 // to AlgebraicNode:
1141 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
1142 ->add_node_update_info(6, // ID
1143 this, // mesh
1144 geom_object_pt, // vector of geom objects
1145 ref_value); // vector of ref. values
1146 }
1147
1148 // Part VII = macro element 20
1149 el_pt = this->finite_element_pt(20);
1150 nnode = el_pt->nnode();
1151 for (unsigned i = 0; i < nnode; i++)
1152 {
1153 // Get local coordinates
1156
1157 // First reference value : horizontal fraction
1158 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
1159
1160 // Second reference value : vertical fraction
1161 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
1162
1163 // Third reference value : zeta coordinate on the flag
1164 ref_value[2] =
1165 4. / 5. * Flag_length + ref_value[0] * 1. / 5. * Flag_length;
1166
1167 // Sub-geomobject
1169 Vector<double> s(1);
1171 zeta[0] = ref_value[2];
1172 Bottom_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1173
1174 // Create vector of geomobject for add_node_update_info()
1175 Vector<GeomObject*> geom_object_pt(1);
1176 geom_object_pt[0] = geom_obj_pt;
1177
1178 // Third reference value : local coordinate in the sub geomobject
1179 ref_value[3] = s[0];
1180
1181 // Setup algebraic update for node: Pass update information
1182 // to AlgebraicNode:
1183 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
1184 ->add_node_update_info(7, // ID
1185 this, // mesh
1186 geom_object_pt, // vector of geom objects
1187 ref_value); // vector of ref. values
1188 }
1189
1190 // Part VIII : macro element 3
1191 el_pt = this->finite_element_pt(3);
1192 nnode = el_pt->nnode();
1193 for (unsigned i = 0; i < nnode; i++)
1194 {
1195 // Get local coordinates
1198
1199 // First reference value : horizontal fraction
1200 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
1201
1202 // Second reference value : vertical fraction
1203 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
1204
1205 // Third reference value : zeta coordinate on flag at reference point
1206 ref_value[2] = ref_value[0] * 1. / 5. * Flag_length;
1207
1208 // Sub-geomobject corresponding to the zeta coordinate on the flag
1209 // at the reference point
1211 Vector<double> s(1);
1213 zeta[0] = ref_value[2];
1214 Top_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1215
1216 // Fourth reference value : local coordinate in the sub geomobject
1217 ref_value[3] = s[0];
1218
1219 // Create vector of geomobject for add_node_update_info()
1220 Vector<GeomObject*> geom_object_pt(2);
1221 geom_object_pt[0] = geom_obj_pt;
1222
1223 // Fifth reference value : zeta coordinate on flag at end of macro element
1224 ref_value[4] = 1. / 5. * Flag_length;
1225
1226 // Sub-geomobject corresponding to the zeta coordinate on the flag
1227 // at the end of the macro element
1228 zeta[0] = ref_value[4];
1229 Top_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1230
1231 // Add geom object
1232 geom_object_pt[1] = geom_obj_pt;
1233
1234 // Sixth reference value : local coordinate in the sub geomobject
1235 ref_value[5] = s[0];
1236
1237 // Setup algebraic update for node: Pass update information
1238 // to AlgebraicNode:
1239 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
1240 ->add_node_update_info(8, // ID
1241 this, // mesh
1242 geom_object_pt, // vector of geom objects
1243 ref_value); // vector of ref. values
1244 }
1245
1246 // Part IX : macro element 4
1247 el_pt = this->finite_element_pt(4);
1248 nnode = el_pt->nnode();
1249 for (unsigned i = 0; i < nnode; i++)
1250 {
1251 // Get local coordinates
1252 Vector<double> coord_loc(2); /**set the size ??*/
1254
1255 // First reference value : horizontal fraction
1256 ref_value[0] = 0.5 * (coord_loc[0] + 1.0);
1257
1258 // Second reference value : vertical fraction
1259 ref_value[1] = 0.5 * (coord_loc[1] + 1.0);
1260
1261 // Third reference value : zeta coordinate on flag
1262 ref_value[2] = ref_value[0] * 1. / 5. * Flag_length;
1263
1264 // Sub-geomobject corresponding to the zeta coordinate on the flag
1265 // at the reference point
1267 Vector<double> s(1);
1269 zeta[0] = ref_value[2];
1270 Bottom_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1271
1272 // Fourth reference value : local coordinate in the sub geomobject
1273 ref_value[3] = s[0];
1274
1275 // Create vector of geomobject for add_node_update_info()
1276 Vector<GeomObject*> geom_object_pt(2);
1277 geom_object_pt[0] = geom_obj_pt;
1278
1279 // Fifth reference value : zeta coordinate on flag at end of macro element
1280 ref_value[4] = 1. / 5. * Flag_length;
1281
1282 // Sub-geomobject corresponding to the zeta coordinate on the flag
1283 // at the end of the macro element
1284 zeta[0] = ref_value[4];
1285 Bottom_flag_pt->locate_zeta(zeta, geom_obj_pt, s);
1286
1287 // Add geom object
1288 geom_object_pt[1] = geom_obj_pt;
1289
1290 // Sixth reference value : local coordinate in the sub geomobject
1291 ref_value[5] = s[0];
1292
1293 // Setup algebraic update for node: Pass update information
1294 // to AlgebraicNode:
1295 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(i))
1296 ->add_node_update_info(9, // ID
1297 this, // mesh
1298 geom_object_pt, // vector of geom objects
1299 ref_value); // vector of ref. values
1300 }
1301
1302 } // end of setup_algebraic_node_update
1303
1304 //=================================================================
1305 /// The algebraic node update function
1306 //=================================================================
1307 template<class ELEMENT>
1309 const unsigned& t, AlgebraicNode*& node_pt)
1310 {
1311 unsigned id = node_pt->node_update_fct_id();
1312
1313 switch (id)
1314 {
1315 case 1:
1316 node_update_I(t, node_pt);
1317 break;
1318
1319 case 2:
1320 node_update_II(t, node_pt);
1321 break;
1322
1323 case 3:
1324 node_update_III(t, node_pt);
1325 break;
1326
1327 case 4:
1328 node_update_IV(t, node_pt);
1329 break;
1330
1331 case 5:
1332 node_update_V(t, node_pt);
1333 break;
1334
1335 case 6:
1336 node_update_VI(t, node_pt);
1337 break;
1338
1339 case 7:
1340 node_update_VII(t, node_pt);
1341 break;
1342
1343 case 8:
1344 node_update_VIII(t, node_pt);
1345 break;
1346
1347 case 9:
1348 node_update_IX(t, node_pt);
1349 break;
1350
1351 default:
1352 std::ostringstream error_message;
1353 error_message << "Wrong id " << id << std::endl;
1354 throw OomphLibError(error_message.str(),
1357 }
1358
1359 } // end of algebraic_node_update()
1360
1361 //=================================================================
1362 /// Node update for region I
1363 //=================================================================
1364 template<class ELEMENT>
1366 const unsigned& t, AlgebraicNode*& node_pt)
1367 {
1368 // Extract reference values for update by copy construction
1369 Vector<double> ref_value(node_pt->vector_ref_value());
1370
1371 // Extract geometric objects for update by copy construction
1372 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1373
1374 // Pointer to geom object
1375 GeomObject* flag_pt = geom_object_pt[0];
1376
1377 // Point on the line y=p11[1] corresponding to the initial x.
1379 ref_point[0] = ref_value[4];
1380 ref_point[1] = 0.778024390 * Height;
1381
1382 // Point on the flag
1385 zeta[0] = ref_value[3];
1387
1388 // Third reference value : fraction of the vertical line
1389 // between the straight line y = p11[1] and the flag
1390 double r = ref_value[1];
1391
1392 // Assign new nodal coordinates
1393 node_pt->x(t, 0) =
1394 ref_point[0] + (1.0 - r) * (flag_point[0] - ref_point[0]);
1395 node_pt->x(t, 1) =
1396 ref_point[1] + (1.0 - r) * (flag_point[1] - ref_point[1]);
1397 }
1398
1399 //=================================================================
1400 /// Node update for region II
1401 //=================================================================
1402 template<class ELEMENT>
1404 const unsigned& t, AlgebraicNode*& node_pt)
1405 {
1406 // Extract reference values for update by copy construction
1407 Vector<double> ref_value(node_pt->vector_ref_value());
1408
1409 // Extract geometric objects for update by copy construction
1410 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1411
1412 // Pointer to geom object
1413 GeomObject* flag_pt = geom_object_pt[0];
1414
1415 // Point on the line y=p37[1] corresponding to the initial x.
1417 ref_point[0] = ref_value[4];
1418 ref_point[1] = 0.197585366 * Height;
1419
1420 // Point on the flag
1423 zeta[0] = ref_value[3];
1425
1426 // Third reference value : fraction of the vertical line
1427 // between the straight line y = p11[1] and the flag
1428 double r = ref_value[1];
1429
1430 // Assign new nodal coordinates
1431 node_pt->x(t, 0) = ref_point[0] + r * (flag_point[0] - ref_point[0]);
1432 node_pt->x(t, 1) = ref_point[1] + r * (flag_point[1] - ref_point[1]);
1433 }
1434
1435 //=================================================================
1436 /// Node update for region III
1437 //=================================================================
1438 template<class ELEMENT>
1440 const unsigned& t, AlgebraicNode*& node_pt)
1441 {
1442 // useful points
1443 Vector<double> p15(2);
1444 Vector<double> p35(2);
1445
1446 p15[0] = 0.285123967 * Length;
1447 p15[1] = 0.625 * Height;
1448
1449 p35[0] = 0.285123967 * Length;
1450 p35[1] = 0.350609756 * Height;
1451
1452 // Extract reference values for update by copy construction
1453 Vector<double> ref_value(node_pt->vector_ref_value());
1454
1455 // Extract geometric objects for update by copy construction
1456 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1457
1458 // Pointer to geom object
1459 GeomObject* flag_pt = geom_object_pt[0];
1460
1461 // Point on the line x=p15[0]
1463 ref_point[0] = p15[0];
1464 ref_point[1] = p35[1] + ref_value[1] * (p15[1] - p35[1]);
1465
1466 // Point on the flag
1469 zeta[0] = ref_value[3];
1471
1472 // Third reference value : fraction of the horizontal line
1473 // between the flag and the horizontal straight line in x=p15[0]
1474 double r = ref_value[0];
1475
1476 // Assign new nodal coordinates
1477 node_pt->x(t, 0) = flag_point[0] + r * (ref_point[0] - flag_point[0]);
1478 node_pt->x(t, 1) = flag_point[1] + r * (ref_point[1] - flag_point[1]);
1479 }
1480
1481 //=================================================================
1482 /// Node update for region IV
1483 //=================================================================
1484 template<class ELEMENT>
1486 const unsigned& t, AlgebraicNode*& node_pt)
1487 {
1488 // Useful points
1489 Vector<double> p15(2);
1490 Vector<double> p25(2);
1492
1493 p15[0] = 0.285123967 * Length;
1494 p15[1] = 0.625 * Height;
1495
1496 p25[0] = Centre_x +
1497 A * sqrt(1.0 - Flag_height * Flag_height / (4.0 * A * A)) +
1498 Flag_length;
1499 p25[1] = Centre_y + Flag_height / 2.0;
1500
1501 // Extract reference values for update by copy construction
1502 Vector<double> ref_value(node_pt->vector_ref_value());
1503
1504 // Extract geometric objects for update by copy construction
1505 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1506
1507 // Pointer to geom object
1508 GeomObject* flag_pt = geom_object_pt[0];
1509
1511 zeta[0] = ref_value[2];
1513
1514 // point on the line linking p15 et top_flag
1515 Vector<double> p1(2);
1516 p1[0] = top_flag[0] + ref_value[0] * (p15[0] - top_flag[0]);
1517 p1[1] = top_flag[1] + ref_value[0] * (p15[1] - top_flag[1]);
1518
1519 // Point on the line y = Height;
1520 Vector<double> p2(2);
1521 p2[0] = p25[0] + ref_value[0] * (p15[0] - p25[0]);
1522 p2[1] = Height;
1523
1524 // Connect those points with the vertical fraction ref_value[1]
1525 node_pt->x(t, 0) = p1[0] + ref_value[1] * (p2[0] - p1[0]);
1526 node_pt->x(t, 1) = p1[1] + ref_value[1] * (p2[1] - p1[1]);
1527 }
1528
1529 //=================================================================
1530 /// Node update for region V
1531 //=================================================================
1532 template<class ELEMENT>
1534 const unsigned& t, AlgebraicNode*& node_pt)
1535 {
1536 // Useful points
1537 Vector<double> p31(2);
1538 Vector<double> p35(2);
1540
1541 p31[0] = Centre_x +
1542 A * sqrt(1.0 - Flag_height * Flag_height / (4.0 * A * A)) +
1543 Flag_length;
1544 p31[1] = Centre_y - Flag_height / 2.;
1545
1546 p35[0] = 0.285123967 * Length;
1547 p35[1] = 0.350609756 * Height;
1548
1549 // Extract reference values for update by copy construction
1550 Vector<double> ref_value(node_pt->vector_ref_value());
1551
1552 // Extract geometric objects for update by copy construction
1553 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1554
1555 // Pointer to geom object
1556 GeomObject* flag_pt = geom_object_pt[0];
1557
1559 zeta[0] = ref_value[2];
1560
1562
1563 // point on the line linking p35 et top_flag
1564 Vector<double> p1(2);
1565 p1[0] = top_flag[0] + ref_value[0] * (p35[0] - top_flag[0]);
1566 p1[1] = top_flag[1] + ref_value[0] * (p35[1] - top_flag[1]);
1567
1568 // Point on the line y = 0.0;
1569 Vector<double> p2(2);
1570 p2[0] = p31[0] + ref_value[0] * (p35[0] - p31[0]);
1571 p2[1] = 0.;
1572
1573 // Connect those points with the vertical fraction ref_value[1]
1574 node_pt->x(t, 0) = p2[0] + ref_value[1] * (p1[0] - p2[0]);
1575 node_pt->x(t, 1) = p2[1] + ref_value[1] * (p1[1] - p2[1]);
1576 }
1577
1578 //=================================================================
1579 /// Node update for region VI
1580 //=================================================================
1581 template<class ELEMENT>
1583 const unsigned& t, AlgebraicNode*& node_pt)
1584 {
1585 // Extract reference values for update by copy construction
1586 Vector<double> ref_value(node_pt->vector_ref_value());
1587
1588 // Useful points
1589 Vector<double> p14(2);
1590 Vector<double> p5(2);
1592
1593 p14[0] = 0.211596 * Length;
1594 p14[1] = 0.778024390 * Height;
1595
1596 p5[0] = 0.239596 * Length;
1597 p5[1] = Height;
1598
1599 // Extract geometric objects for update by copy construction
1600 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1601
1602 // Pointer to geom object
1603 GeomObject* flag_pt = geom_object_pt[0];
1604
1606 zeta[0] = ref_value[3];
1608
1609 // point on the line linking p14 et p5
1610 Vector<double> p1(2);
1611 p1[0] = p14[0] + ref_value[0] * (p5[0] - p14[0]);
1612 p1[1] = p14[1] + ref_value[0] * (p5[1] - p14[1]);
1613
1614 // Connect those points with the vertical fraction ref_value[1]
1615 node_pt->x(t, 0) = point_flag[0] + ref_value[1] * (p1[0] - point_flag[0]);
1616 node_pt->x(t, 1) = point_flag[1] + ref_value[1] * (p1[1] - point_flag[1]);
1617 }
1618
1619 //=================================================================
1620 /// Node update for region VII
1621 //=================================================================
1622 template<class ELEMENT>
1624 const unsigned& t, AlgebraicNode*& node_pt)
1625 {
1626 // Extract reference values for update by copy construction
1627 Vector<double> ref_value(node_pt->vector_ref_value());
1628
1629 // Useful points
1630 Vector<double> p40(2);
1631 Vector<double> p45(2);
1633
1634 p40[0] = 0.211596 * Length;
1635 p40[1] = 0.197585366 * Height;
1636
1637 p45[0] = 0.239596 * Length;
1638 p45[1] = 0.0;
1639
1640 // Extract geometric objects for update by copy construction
1641 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1642
1643 // Pointer to geom object
1644 GeomObject* flag_pt = geom_object_pt[0];
1645
1647 zeta[0] = ref_value[3];
1649
1650 // point on the line linking p40 et p45
1651 Vector<double> p1(2);
1652 p1[0] = p40[0] + ref_value[0] * (p45[0] - p40[0]);
1653 p1[1] = p40[1] + ref_value[0] * (p45[1] - p40[1]);
1654
1655 // Connect those points with the vertical fraction ref_value[1]
1656 node_pt->x(t, 0) =
1657 point_flag[0] + (1 - ref_value[1]) * (p1[0] - point_flag[0]);
1658 node_pt->x(t, 1) =
1659 point_flag[1] + (1 - ref_value[1]) * (p1[1] - point_flag[1]);
1660 }
1661
1662 //=================================================================
1663 /// Node update for region VIII
1664 //=================================================================
1665 template<class ELEMENT>
1667 const unsigned& t, AlgebraicNode*& node_pt)
1668 {
1669 // Useful point
1670 Vector<double> p11(2);
1671 p11[0] = 0.127596 * Length;
1672 p11[1] = 0.778024390 * Height;
1673
1674 /// Extreme angles on circle
1675 double zeta_circle_top = atan(1.0);
1676 double zeta_circle_bot = asin(Flag_height / 2. / A);
1677
1678 // Extract reference values for update by copy construction
1679 Vector<double> ref_value(node_pt->vector_ref_value());
1680
1681 // Extract geometric objects for update by copy construction
1682 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1683
1684 // Pointer to geom object containing the reference point
1685 GeomObject* flag_ref_pt = geom_object_pt[0];
1686
1687 // Pointer to geom object containing the end of the macro element
1688 GeomObject* flag_end_pt = geom_object_pt[1];
1689
1690 double omega_horizontal = ref_value[0];
1691 double omega_vertical = ref_value[1];
1692
1693 // end of the macro element on the flag
1696 zeta[0] = ref_value[5];
1698
1700
1701 // Get reference point on circle
1703 zeta[0] =
1705 Cylinder_pt->position(zeta, ref_point_on_circle);
1706
1707 // Get reference point on right line
1709 ref_point_on_right_line[0] = // flag_end[0];
1710 outer_point[0] + (flag_end[0] - outer_point[0]) * (1.0 - omega_vertical);
1712 outer_point[1] + (flag_end[1] - outer_point[1]) * (1.0 - omega_vertical);
1713
1714 // Get reference point on flag
1716 zeta[0] = ref_value[3];
1718
1719 // Get bottom-most point on circle
1721 zeta[0] = zeta_circle_bot;
1722 Cylinder_pt->position(zeta, circle_bot);
1723
1724 // Get reference point on horizontal fraction of straight line
1725 // connecting the two bottom most reference points
1727 r_bot[0] = circle_bot[0] + (flag_end[0] - circle_bot[0]) * omega_horizontal;
1728 r_bot[1] = circle_bot[1] + (flag_end[1] - circle_bot[1]) * omega_horizontal;
1729
1730 // Place point on horizontal fraction of straight line
1731 // connecting reference points -- this won't match the
1732 // curved top boundary adjacent to the flag
1733 node_pt->x(t, 0) =
1736 node_pt->x(t, 1) =
1739
1740 // Correct by scaled difference between bottom straight line
1741 // and bent flag
1742 node_pt->x(t, 0) +=
1743 (ref_point_on_flag[0] - r_bot[0]) * (1.0 - omega_vertical);
1744 node_pt->x(t, 1) +=
1745 (ref_point_on_flag[1] - r_bot[1]) * (1.0 - omega_vertical);
1746 }
1747
1748 //=================================================================
1749 /// Node update for region IX
1750 //=================================================================
1751 template<class ELEMENT>
1753 const unsigned& t, AlgebraicNode*& node_pt)
1754 {
1755 // Useful point
1756 Vector<double> p37(2);
1757 p37[0] = 0.127596 * Length;
1758 p37[1] = 0.197585366 * Height;
1759
1760 /// Extreme angles on circle
1761 double zeta_circle_top = -asin(Flag_height / 2. / A);
1762 double zeta_circle_bot = -atan(1.0);
1763
1764 // Extract reference values for update by copy construction
1765 Vector<double> ref_value(node_pt->vector_ref_value());
1766
1767 // Extract geometric objects for update by copy construction
1768 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1769
1770 // Pointer to geom object containing the reference point
1771 GeomObject* flag_ref_pt = geom_object_pt[0];
1772
1773 // Pointer to geom object containing the end of macro element
1774 GeomObject* flag_end_pt = geom_object_pt[1];
1775
1776 double omega_horizontal = ref_value[0];
1777 double omega_vertical = ref_value[1];
1778
1779 // end of the macro element on the flag
1782 zeta[0] = ref_value[5];
1784
1786
1787 // Get reference point on circle
1789 zeta[0] =
1791 Cylinder_pt->position(zeta, ref_point_on_circle);
1792
1793 // Get reference point on right line
1795 ref_point_on_right_line[0] = // flag_end[0];
1799
1800 // Get reference point on flag
1802 zeta[0] = ref_value[3];
1804
1805 // Get top-most point on circle
1807 zeta[0] = zeta_circle_top;
1808 Cylinder_pt->position(zeta, circle_top);
1809
1810 // Get reference point on horizontal fraction of straight line
1811 // connecting the two top most reference points
1813 r_top[0] = circle_top[0] + (flag_end[0] - circle_top[0]) * omega_horizontal;
1814 r_top[1] = circle_top[1] + (flag_end[1] - circle_top[1]) * omega_horizontal;
1815
1816 // Place point on horizontal fraction of straight line
1817 // connecting reference points -- this won't match the
1818 // curved top boundary adjacent to the flag
1819 node_pt->x(t, 0) =
1822 node_pt->x(t, 1) =
1825
1826 // Correct by scaled difference between top straight line
1827 // and bent flag
1828 node_pt->x(t, 0) += (ref_point_on_flag[0] - r_top[0]) * omega_vertical;
1829 node_pt->x(t, 1) += (ref_point_on_flag[1] - r_top[1]) * omega_vertical;
1830 }
1831
1832
1833 ///////////////////////////////////////////////////////////////////////////
1834 ///////////////////////////////////////////////////////////////////////////
1835 ///////////////////////////////////////////////////////////////////////////
1836
1837 //===================================================================
1838 /// Update the node update functions
1839 //===================================================================
1840 template<class ELEMENT>
1842 AlgebraicNode*& node_pt)
1843 {
1844 // Extract ID
1845 unsigned id = node_pt->node_update_fct_id();
1846
1847 if (id == 8)
1848 {
1849 // Extract geometric objects for update by copy construction
1850 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1851
1852 // Extract reference values for node update by copy construction
1853 Vector<double> ref_value(node_pt->vector_ref_value());
1854
1855 // Get zeta coordinate of reference point
1857 zeta_ref_flag[0] = ref_value[2];
1858
1859 // Get the sub-geomobject and the local coordinate containing the
1860 // reference point
1861 Vector<double> s(1);
1863 this->Top_flag_pt->locate_zeta(zeta_ref_flag, geom_obj_pt, s);
1864
1865 // Update the pointer to the (sub-)GeomObject within which the
1866 // reference point is located.
1867 geom_object_pt[0] = geom_obj_pt;
1868
1869 // Update second reference value: Reference local coordinate
1870 // in flag sub-element
1871 ref_value[3] = s[0];
1872
1873 // Get zeta coordinate of point at end of macro element
1875 zeta_end_flag[0] = ref_value[4];
1876
1877 // Get the sub-geomobject and the local coordinate containing the
1878 // point at the end of the macro element
1879 this->Top_flag_pt->locate_zeta(zeta_end_flag, geom_obj_pt, s);
1880
1881 // Update the pointer to the (sub-)GeomObject within which the
1882 // point at the end of the macro element is located
1883 geom_object_pt[1] = geom_obj_pt;
1884
1885 // Update second reference value: Reference local coordinate
1886 // in flag sub-element
1887 ref_value[5] = s[0];
1888
1889 // Kill the existing node update info
1890 node_pt->kill_node_update_info(8);
1891
1892 // Setup algebraic update for node: Pass update information
1893 node_pt->add_node_update_info(8, // id
1894 this, // mesh
1895 geom_object_pt, // vector of geom objects
1896 ref_value); // vector of ref. values
1897 }
1898 else if (id == 9)
1899 {
1900 // Extract geometric objects for update by copy construction
1901 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1902
1903 // Extract reference values for node update by copy construction
1904 Vector<double> ref_value(node_pt->vector_ref_value());
1905
1906 // Get zeta coordinate of reference point
1908 zeta_ref_flag[0] = ref_value[2];
1909
1910 // Get the sub-geomobject and the local coordinate containing the
1911 // reference point
1912 Vector<double> s(1);
1914 this->Bottom_flag_pt->locate_zeta(zeta_ref_flag, geom_obj_pt, s);
1915
1916 // Update the pointer to the (sub-)GeomObject within which the
1917 // reference point is located.
1918 geom_object_pt[0] = geom_obj_pt;
1919
1920 // Update second reference value: Reference local coordinate
1921 // in flag sub-element
1922 ref_value[3] = s[0];
1923
1924 // Get zeta coordinate of point at end of macro element
1926 zeta_end_flag[0] = ref_value[4];
1927
1928 // Get the sub-geomobject and the local coordinate containing the
1929 // point at the end of the macro element
1930 this->Bottom_flag_pt->locate_zeta(zeta_end_flag, geom_obj_pt, s);
1931
1932 // Update the pointer to the (sub-)GeomObject within which the
1933 // point at the end of the macro element is located
1934 geom_object_pt[1] = geom_obj_pt;
1935
1936 // Update second reference value: Reference local coordinate
1937 // in flag sub-element
1938 ref_value[5] = s[0];
1939
1940 // Kill the existing node update info
1941 node_pt->kill_node_update_info(9);
1942
1943 // Setup algebraic update for node: Pass update information
1944 node_pt->add_node_update_info(9, // id
1945 this, // mesh
1946 geom_object_pt, // vector of geom objects
1947 ref_value); // vector of ref. values
1948 }
1949
1950 if ((id == 1) || (id == 6))
1951 {
1952 // Extract reference values for node update by copy construction
1953 Vector<double> ref_value(node_pt->vector_ref_value());
1954
1955 // Get zeta coordinate on flag
1957 zeta_flag[0] = ref_value[2];
1958
1959 // Get the sub-geomobject and the local coordinate
1960 Vector<double> s(1);
1962 this->Top_flag_pt->locate_zeta(zeta_flag, geom_obj_pt, s);
1963
1964 // Extract geometric objects for update by copy construction
1965 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
1966
1967 // Update the pointer to the (sub-)GeomObject within which the
1968 // reference point is located. (If the flag is simple GeomObject
1969 // this is the same as Leaflet_pt; if it's a compound GeomObject
1970 // this points to the sub-object)
1971 geom_object_pt[0] = geom_obj_pt;
1972
1973 // Update second reference value: Reference local coordinate
1974 // in flag sub-element
1975 ref_value[3] = s[0];
1976
1977 if (id == 1)
1978 {
1979 // Kill the existing node update info
1980 node_pt->kill_node_update_info(1);
1981
1982 // Setup algebraic update for node: Pass update information
1983 node_pt->add_node_update_info(1, // id
1984 this, // mesh
1985 geom_object_pt, // vector of geom objects
1986 ref_value); // vector of ref. values
1987 }
1988 else if (id == 6)
1989 {
1990 // Kill the existing node update info
1991 node_pt->kill_node_update_info(6);
1992
1993 // Setup algebraic update for node: Pass update information
1994 node_pt->add_node_update_info(6, // id
1995 this, // mesh
1996 geom_object_pt, // vector of geom objects
1997 ref_value); // vector of ref. values
1998 }
1999 }
2000
2001 if ((id == 2) || (id == 7))
2002 {
2003 // Extract reference values for node update by copy construction
2004 Vector<double> ref_value(node_pt->vector_ref_value());
2005
2006 // Get zeta coordinate on flag
2008 zeta_flag[0] = ref_value[2];
2009
2010 // Get the sub-geomobject and the local coordinate
2011 Vector<double> s(1);
2013 this->Bottom_flag_pt->locate_zeta(zeta_flag, geom_obj_pt, s);
2014
2015 // Extract geometric objects for update by copy construction
2016 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
2017
2018 // Update the pointer to the (sub-)GeomObject within which the
2019 // reference point is located. (If the flag is simple GeomObject
2020 // this is the same as Leaflet_pt; if it's a compound GeomObject
2021 // this points to the sub-object)
2022 geom_object_pt[0] = geom_obj_pt;
2023
2024 // Update second reference value: Reference local coordinate
2025 // in flag sub-element
2026 ref_value[3] = s[0];
2027
2028 if (id == 2)
2029 {
2030 // Kill the existing node update info
2031 node_pt->kill_node_update_info(2);
2032
2033 // Setup algebraic update for node: Pass update information
2034 node_pt->add_node_update_info(2, // id
2035 this, // mesh
2036 geom_object_pt, // vector of geom objects
2037 ref_value); // vector of ref. values
2038 }
2039 else if (id == 7)
2040 {
2041 // Kill the existing node update info
2042 node_pt->kill_node_update_info(7);
2043
2044 // Setup algebraic update for node: Pass update information
2045 node_pt->add_node_update_info(7, // id
2046 this, // mesh
2047 geom_object_pt, // vector of geom objects
2048 ref_value); // vector of ref. values
2049 }
2050 }
2051
2052 if ((id == 3) || (id == 4) || (id == 5))
2053 {
2054 // Extract reference values for node update by copy construction
2055 Vector<double> ref_value(node_pt->vector_ref_value());
2056
2057 // Get zeta coordinate on flag
2059 if (id == 3)
2060 {
2061 zeta_flag[0] = ref_value[2];
2062 }
2063 else if (id == 4)
2064 {
2065 zeta_flag[0] = this->Flag_height / 2.;
2066 }
2067 else if (id == 5)
2068 {
2069 zeta_flag[0] = -this->Flag_height / 2.;
2070 }
2071
2072 // Get the sub-geomobject and the local coordinate
2073 Vector<double> s(1);
2075 this->Tip_flag_pt->locate_zeta(zeta_flag, geom_obj_pt, s);
2076
2077 // Extract geometric objects for update by copy construction
2078 Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
2079
2080 // Update the pointer to the (sub-)GeomObject within which the
2081 // reference point is located. (If the flag is simple GeomObject
2082 // this is the same as Leaflet_pt; if it's a compound GeomObject
2083 // this points to the sub-object)
2084 geom_object_pt[0] = geom_obj_pt;
2085
2086 if (id == 3)
2087 {
2088 // Update second reference value: Reference local coordinate
2089 // in flag sub-element
2090 ref_value[3] = s[0];
2091
2092 // Kill the existing node update info
2093 node_pt->kill_node_update_info(3);
2094
2095 // Setup algebraic update for node: Pass update information
2096 node_pt->add_node_update_info(3, // id
2097 this, // mesh
2098 geom_object_pt, // vector of geom objects
2099 ref_value); // vector of ref. values
2100 }
2101 else if (id == 4)
2102 {
2103 // Update second reference value: Reference local coordinate
2104 // in flag sub-element
2105 ref_value[2] = s[0];
2106
2107 // Kill the existing node update info
2108 node_pt->kill_node_update_info(4);
2109
2110 // Setup algebraic update for node: Pass update information
2111 node_pt->add_node_update_info(4, // id
2112 this, // mesh
2113 geom_object_pt, // vector of geom objects
2114 ref_value); // vector of ref. values
2115 }
2116 else if (id == 5)
2117 {
2118 // Update second reference value: Reference local coordinate
2119 // in flag sub-element
2120 ref_value[2] = s[0];
2121
2122 // Kill the existing node update info
2123 node_pt->kill_node_update_info(5);
2124
2125 // Setup algebraic update for node: Pass update information
2126 node_pt->add_node_update_info(5, // id
2127 this, // mesh
2128 geom_object_pt, // vector of geom objects
2129 ref_value); // vector of ref. values
2130 }
2131 }
2132 }
2133
2134} // namespace oomph
2135
2136#endif
e
Definition cfortran.h:571
static char t char * s
Definition cfortran.h:568
cstr elem_len * i
Definition cfortran.h:603
char t
Definition cfortran.h:568
void node_update_V(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
void node_update_II(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
void node_update_III(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)
void node_update_IV(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
void node_update_I(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
void node_update_VIII(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
void node_update_VI(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
void node_update_VII(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
void setup_algebraic_node_update()
Function to setup the algebraic node update.
void node_update_IX(const unsigned &t, AlgebraicNode *&node_pt)
Helper function.
Algebraic nodes are nodes with an algebraic positional update function.
Circle in 2D space.
Domain for cylinder with flag as in Turek benchmark.
CylinderWithFlagMesh(Circle *cylinder_pt, GeomObject *top_flag_pt, GeomObject *bottom_flag_pt, GeomObject *tip_flag_pt, const double &length, const double &height, const double &flag_length, const double &flag_height, const double &centre_x, const double &centre_y, const double &a, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor. Pass the pointers to the GeomObjects that parametrise the cylinder, the three edges of t...
A general Finite Element class.
Definition elements.h:1317
virtual void set_macro_elem_pt(MacroElement *macro_elem_pt)
Set pointer to macro element – can be overloaded in derived elements to perform additional tasks.
Definition elements.h:1876
void position(const Vector< double > &zeta, Vector< double > &r) const
Return the parametrised position of the FiniteElement in its incarnation as a GeomObject,...
Definition elements.h:2680
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size (broken virtual)
Definition elements.h:1846
void locate_zeta(const Vector< double > &zeta, GeomObject *&geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
For a given value of zeta, the "global" intrinsic coordinate of a mesh of FiniteElements represented ...
Definition elements.cc:4764
unsigned nnode() const
Return the number of nodes.
Definition elements.h:2214
Node ** Node_pt
Storage for pointers to the nodes in the element.
Definition elements.h:1323
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition elements.h:2179
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
virtual void node_update()
Update the positions of all nodes in the element using each node update function. The default impleme...
Definition elements.cc:5102
A geometric object is an object that provides a parametrised description of its shape via the functio...
TimeStepper *& time_stepper_pt()
Access function for pointer to time stepper: Null if object is not time-dependent.
virtual void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
A geometric object may be composed of may sub-objects (e.g. a finite-element representation of a boun...
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition nodes.h:906
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition nodes.h:1060
An OomphLibError object which should be thrown when an run-time error is encountered....
void update_node_update(AlgebraicNode *&node_pt)
Update the node update data for specified node following any mesh adapation.
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
TAdvectionDiffusionReactionElement()
Constructor: Call constructors for TElement and AdvectionDiffusionReaction equations.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).