quarter_circle_sector_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-2022 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_QUARTER_CIRCLE_SECTOR_MESH_TEMPLATE_CC
27#define OOMPH_QUARTER_CIRCLE_SECTOR_MESH_TEMPLATE_CC
28
29
31
32namespace oomph
33{
34 //====================================================================
35 /// Constructor for deformable 2D Ring mesh class. Pass pointer to
36 /// geometric object that specifies the wall, start and end coordinates on the
37 /// geometric object, and the fraction along
38 /// which the dividing line is to be placed, and the timestepper
39 /// (defaults to (Steady) default timestepper defined in Mesh).
40 /// Nodal positions are determined via macro-element-based representation
41 /// of the Domain (as a QuarterCircleSectorDomain).
42 //====================================================================
43 template<class ELEMENT>
45 GeomObject* wall_pt,
46 const double& xi_lo,
47 const double& fract_mid,
48 const double& xi_hi,
49 TimeStepper* time_stepper_pt)
50 : Wall_pt(wall_pt), Xi_lo(xi_lo), Fract_mid(fract_mid), Xi_hi(xi_hi)
51 {
52 // Mesh can only be built with 2D Qelements.
53 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
54
55 // Build macro element-based domain
56 Domain_pt = new QuarterCircleSectorDomain(wall_pt, xi_lo, fract_mid, xi_hi);
57
58 // Set the number of boundaries
60
61 // We have only bothered to parametrise boundary 1
63
64 // Allocate the store for the elements
65 Element_pt.resize(3);
66
67 // Create first element
68 Element_pt[0] = new ELEMENT;
69
70 // Read out the number of linear points in the element
71 unsigned n_p = dynamic_cast<ELEMENT*>(finite_element_pt(0))->nnode_1d();
72
73 // Can now allocate the store for the nodes
74 Node_pt.resize(n_p * n_p + (n_p - 1) * n_p + (n_p - 1) * (n_p - 1));
75
76
78 Vector<double> r(2);
79
80 // Storage for the intrinsic boundary coordinate
81 Vector<double> zeta(1);
82
83
84 // Set up geometrical data
85 //------------------------
86
87 // Initialise node counter
88 unsigned long node_count = 0;
89
90
91 // Now assign the topology
92 // Boundaries are numbered 0 1 2 from the bottom proceeding anticlockwise
93
94
95 // FIRST ELEMENT (lower left corner)
96 //
97
98 // Set the corner node (on boundaries 0 and 2)
99 //-------------------------------------------
100
101 // Create the ll node
102 Node_pt[node_count] =
103 finite_element_pt(0)->construct_boundary_node(0, time_stepper_pt);
104
105 // Set the pointer from the element to the node
106 finite_element_pt(0)->node_pt(0) = Node_pt[node_count];
107
108 // Set the position of the ll node
109 s[0] = -1.0;
110 s[1] = -1.0;
112 Node_pt[node_count]->x(0) = r[0];
113 Node_pt[node_count]->x(1) = r[1];
114
115 // Add the node to the boundaries
116 add_boundary_node(0, Node_pt[node_count]);
117 add_boundary_node(2, Node_pt[node_count]);
118
119 // Increment the node number
120 node_count++;
121
122 // First row is on boundary 0:
123 //---------------------------
124 for (unsigned l1 = 1; l1 < n_p; l1++)
125 {
126 // Local node number
127 unsigned jnod_local = l1;
128
129 // Create the node
131 jnod_local, time_stepper_pt);
132
133 // Set the pointer from the element to the node
134 finite_element_pt(0)->node_pt(jnod_local) = Node_pt[node_count];
135
136 // Set the position of the node
137 s[0] = -1.0 + 2.0 * double(l1) / double(n_p - 1);
138 s[1] = -1.0;
140 Node_pt[node_count]->x(0) = r[0];
141 Node_pt[node_count]->x(1) = r[1];
142
143 // Add the node to the boundary
144 add_boundary_node(0, Node_pt[node_count]);
145
146 // Increment the node number
147 node_count++;
148 }
149
150
151 // Loop over the other rows of nodes
152 //------------------------------------
153 for (unsigned l2 = 1; l2 < n_p; l2++)
154 {
155 // First node in this row is on boundary 2:
156 //-----------------------------------------
157
158 // Local node number
159 unsigned jnod_local = n_p * l2;
160
161 // Create the node
163 jnod_local, time_stepper_pt);
164
165 // Set the pointer from the element to the node
166 finite_element_pt(0)->node_pt(jnod_local) = Node_pt[node_count];
167
168
169 // Set the position of the node
170 s[0] = -1.0;
171 s[1] = -1.0 + 2.0 * double(l2) / double(n_p - 1);
172 ;
174 Node_pt[node_count]->x(0) = r[0];
175 Node_pt[node_count]->x(1) = r[1];
176
177 // Add the node to the boundary
178 add_boundary_node(2, Node_pt[node_count]);
179
180 // Increment the node number
181 node_count++;
182
183
184 // The other nodes are in the interior
185 //------------------------------------
186 // Loop over the other node columns
187 for (unsigned l1 = 1; l1 < n_p; l1++)
188 {
189 // Local node number
190 unsigned jnod_local = l1 + n_p * l2;
191
192 // Create the node
193 Node_pt[node_count] =
194 finite_element_pt(0)->construct_node(jnod_local, time_stepper_pt);
195
196 // Set the pointer from the element to the node
197 finite_element_pt(0)->node_pt(jnod_local) = Node_pt[node_count];
198
199 // Set the position of the node
200 s[0] = -1.0 + 2.0 * double(l1) / double(n_p - 1);
201 s[1] = -1.0 + 2.0 * double(l2) / double(n_p - 1);
203 Node_pt[node_count]->x(0) = r[0];
204 Node_pt[node_count]->x(1) = r[1];
205
206 // Increment the node number
207 node_count++;
208 }
209 }
210
211 // SECOND ELEMENT (lower right corner)
212 //
213 // Create element
214 Element_pt[1] = new ELEMENT;
215
216 // Loop over the first column (already exists!)
217 //---------------------------------------------
218 for (unsigned l2 = 0; l2 < n_p; l2++)
219 {
220 // Node number in existing element
221 unsigned jnod_local_old = (n_p - 1) + l2 * n_p;
222
223 // Set the pointer from the element to the node
224 finite_element_pt(1)->node_pt(l2 * n_p) =
225 finite_element_pt(0)->node_pt(jnod_local_old);
226 }
227
228 // Loop over the other node columns (apart from last one)
229 //------------------------------------------------------
230 for (unsigned l1 = 1; l1 < n_p - 1; l1++)
231 {
232 // First node is at the bottom (on boundary 0)
233 //--------------------------------------------
234
235 // Local node number
236 unsigned jnod_local = l1;
237
238 // Create the node
240 jnod_local, time_stepper_pt);
241
242 // Set the pointer from the element to the node
243 finite_element_pt(1)->node_pt(jnod_local) = Node_pt[node_count];
244
245 // Set the position of the node
246 s[0] = -1.0 + 2.0 * double(l1) / double(n_p - 1);
247 s[1] = -1.0;
249 Node_pt[node_count]->x(0) = r[0];
250 Node_pt[node_count]->x(1) = r[1];
251
252 // Add the node to the boundary
253 add_boundary_node(0, Node_pt[node_count]);
254
255 // Increment the node number
256 node_count++;
257
258 // Now loop over the interior nodes in this column
259 //-------------------------------------------------
260 for (unsigned l2 = 1; l2 < n_p; l2++)
261 {
262 // Local node number
263 unsigned jnod_local = l1 + l2 * n_p;
264
265 // Create the node
266 Node_pt[node_count] =
267 finite_element_pt(1)->construct_node(jnod_local, time_stepper_pt);
268
269 // Set the pointer from the element to the node
270 finite_element_pt(1)->node_pt(jnod_local) = Node_pt[node_count];
271
272 // Set the position of the node
273 s[0] = -1.0 + 2.0 * double(l1) / double(n_p - 1);
274 s[1] = -1.0 + 2.0 * double(l2) / double(n_p - 1);
276 Node_pt[node_count]->x(0) = r[0];
277 Node_pt[node_count]->x(1) = r[1];
278
279 // Increment the node number
280 node_count++;
281 }
282 }
283
284 // Last column (on boundary 1)
285 //----------------------------
286
287 // First node is at the bottom (and hence also on boundary 0)
288 //-----------------------------------------------------------
289
290 // Local node number
291 unsigned jnod_local = n_p - 1;
292
293 // Create the node
295 jnod_local, time_stepper_pt);
296
297 // Set the pointer from the element to the node
298 finite_element_pt(1)->node_pt(jnod_local) = Node_pt[node_count];
299
300 // Set the position of the node
301 s[0] = 1.0;
302 s[1] = -1.0;
304 Node_pt[node_count]->x(0) = r[0];
305 Node_pt[node_count]->x(1) = r[1];
306
307 // Add the node to the boundaries
308 add_boundary_node(0, Node_pt[node_count]);
309 add_boundary_node(1, Node_pt[node_count]);
310
311 // Set the intrinsic coordinate on the boundary 1
312 zeta[0] = Xi_lo + 0.5 * (1.0 + s[1]) * Fract_mid * (Xi_hi - Xi_lo);
313 Node_pt[node_count]->set_coordinates_on_boundary(1, zeta);
314
315 // Increment the node number
316 node_count++;
317
318 // Now do the remaining nodes in last column (only on boundary 1)
319 //---------------------------------------------------------------
320 for (unsigned l2 = 1; l2 < n_p; l2++)
321 {
322 // Local node number
323 unsigned jnod_local = (n_p - 1) + l2 * n_p;
324
325 // Create the node
327 jnod_local, time_stepper_pt);
328
329 // Set the pointer from the element to the node
330 finite_element_pt(1)->node_pt(jnod_local) = Node_pt[node_count];
331
332 // Set the position of the node
333 s[0] = 1.0;
334 s[1] = -1.0 + 2.0 * double(l2) / double(n_p - 1);
336 Node_pt[node_count]->x(0) = r[0];
337 Node_pt[node_count]->x(1) = r[1];
338
339 // Add the node to the boundary
340 add_boundary_node(1, Node_pt[node_count]);
341
342 // Set the intrinsic coordinate on the boundary 1
343 zeta[0] = Xi_lo + 0.5 * (1.0 + s[1]) * Fract_mid * (Xi_hi - Xi_lo);
344 Node_pt[node_count]->set_coordinates_on_boundary(1, zeta);
345
346
347 // Increment the node number
348 node_count++;
349 }
350
351
352 // THIRD ELEMENT (upper left corner)
353 //
354 // Create element
355 Element_pt[2] = new ELEMENT;
356
357 // Loop over the first row (has already been created via element 0)
358 //-----------------------------------------------------------------
359 for (unsigned l1 = 0; l1 < n_p; l1++)
360 {
361 // Node number in existing element
362 unsigned jnod_local_old = n_p * (n_p - 1) + l1;
363
364 // Local node number here
365 unsigned jnod_local = l1;
366
367 // Set the pointer from the element to the node
368 finite_element_pt(2)->node_pt(jnod_local) =
369 finite_element_pt(0)->node_pt(jnod_local_old);
370 }
371
372
373 // Loop over the remaining nodes in the last column (has already
374 //--------------------------------------------------------------
375 // been created via element 1)
376 //----------------------------
377 for (unsigned l2 = 1; l2 < n_p; l2++)
378 {
379 // Node number in existing element
380 unsigned jnod_local_old = n_p * (n_p - 1) + l2;
381
382 // Local node number here
383 unsigned jnod_local = (n_p - 1) + l2 * n_p;
384
385 // Set the pointer from the element to the node
386 finite_element_pt(2)->node_pt(jnod_local) =
387 finite_element_pt(1)->node_pt(jnod_local_old);
388 }
389
390
391 // Loop over the nodes in rows (apart from last one which is on boundary 1)
392 //-------------------------------------------------------------------------
393 for (unsigned l2 = 1; l2 < n_p - 1; l2++)
394 {
395 // First node in this row is on boundary 2:
396 //-----------------------------------------
397
398 // Local node number
399 unsigned jnod_local = n_p * l2;
400
401 // Create the node
403 jnod_local, time_stepper_pt);
404
405 // Set the pointer from the element to the node
406 finite_element_pt(2)->node_pt(jnod_local) = Node_pt[node_count];
407
408 // Set the position of the node
409 s[0] = -1.0;
410 s[1] = -1.0 + 2.0 * double(l2) / double(n_p - 1);
411 ;
413 Node_pt[node_count]->x(0) = r[0];
414 Node_pt[node_count]->x(1) = r[1];
415
416 // Add the node to the boundary
417 add_boundary_node(2, Node_pt[node_count]);
418
419 // Increment the node number
420 node_count++;
421
422 // The other nodes are in the interior
423 //------------------------------------
424 // Loop over the other node columns
425 for (unsigned l1 = 1; l1 < n_p - 1; l1++)
426 {
427 // Local node number
428 unsigned jnod_local = l1 + n_p * l2;
429
430 // Create the node
431 Node_pt[node_count] =
432 finite_element_pt(2)->construct_node(jnod_local, time_stepper_pt);
433
434 // Set the pointer from the element to the node
435 finite_element_pt(2)->node_pt(jnod_local) = Node_pt[node_count];
436
437 // Set the position of the node
438 s[0] = -1.0 + 2.0 * double(l1) / double(n_p - 1);
439 s[1] = -1.0 + 2.0 * double(l2) / double(n_p - 1);
441 Node_pt[node_count]->x(0) = r[0];
442 Node_pt[node_count]->x(1) = r[1];
443
444 // Increment the node number
445 node_count++;
446 }
447 }
448
449
450 // Top left corner is on boundaries 1 and 2:
451 //------------------------------------------
452
453 // Local node number
454 jnod_local = n_p * (n_p - 1);
455
456 // Create the node
458 jnod_local, time_stepper_pt);
459
460 // Set the pointer from the element to the node
461 finite_element_pt(2)->node_pt(jnod_local) = Node_pt[node_count];
462
463 // Set the position of the node
464 s[0] = -1.0;
465 s[1] = 1.0;
467 Node_pt[node_count]->x(0) = r[0];
468 Node_pt[node_count]->x(1) = r[1];
469
470 // Add the node to the boundaries
471 add_boundary_node(1, Node_pt[node_count]);
472 add_boundary_node(2, Node_pt[node_count]);
473
474 // Set the intrinsic coordinate on the boundary 1
475 zeta[0] = Xi_hi + 0.5 * (s[0] + 1.0) * (1.0 - Fract_mid) * (Xi_lo - Xi_hi);
476 Node_pt[node_count]->set_coordinates_on_boundary(1, zeta);
477
478
479 // Increment the node number
480 node_count++;
481
482 // Rest of top row is on boundary 1 only:
483 //---------------------------------------
484 for (unsigned l1 = 1; l1 < n_p - 1; l1++)
485 {
486 // Local node number
487 unsigned jnod_local = n_p * (n_p - 1) + l1;
488
489 // Create the node
491 jnod_local, time_stepper_pt);
492
493 // Set the pointer from the element to the node
494 finite_element_pt(2)->node_pt(jnod_local) = Node_pt[node_count];
495
496 // Set the position of the node
497 s[0] = -1.0 + 2.0 * double(l1) / double(n_p - 1);
498 s[1] = 1.0;
500 Node_pt[node_count]->x(0) = r[0];
501 Node_pt[node_count]->x(1) = r[1];
502
503 // Add the node to the boundary
504 add_boundary_node(1, Node_pt[node_count]);
505
506 // Set the intrinsic coordinate on the boundary 1
507 zeta[0] =
508 Xi_hi + 0.5 * (s[0] + 1.0) * (1.0 - Fract_mid) * (Xi_lo - Xi_hi);
509 Node_pt[node_count]->set_coordinates_on_boundary(1, zeta);
510
511 // Increment the node number
512 node_count++;
513 }
514
515 // Loop over all elements and set macro element pointer
516 // to enable MacroElement-based node update
517 unsigned n_element = this->nelement();
518 for (unsigned e = 0; e < n_element; e++)
519 {
520 // Get pointer to full element type
521 ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
522
523 // Set pointer to macro element
524 el_pt->set_macro_elem_pt(this->Domain_pt->macro_element_pt(e));
525 }
526
527 // Setup boundary element lookup schemes
529 }
530
531
532 /// ////////////////////////////////////////////////////////////////////
533 /// ////////////////////////////////////////////////////////////////////
534 // Algebraic-mesh-version of RefineableQuarterCircleSectorMesh
535 /// ////////////////////////////////////////////////////////////////////
536 /// ////////////////////////////////////////////////////////////////////
537
538
539 //======================================================================
540 /// Setup algebraic update operation, based on individual
541 /// blocks. Mesh is suspended from the `wall' GeomObject pointed to
542 /// by wall_pt. The lower right corner of the mesh is located at the
543 /// wall's coordinate xi_lo, the upper left corner at xi_hi;
544 /// The dividing line between the two blocks at the outer ring
545 /// is located at the fraction fract_mid between these two coordinates.
546 /// Node updating strategy:
547 /// - the shape of the central box remains rectangular; the position
548 /// of its top right corner is located at a fixed fraction
549 /// of the width and height of the domain. Nodes in this region
550 /// are located at fixed horizontal and vertical fractions of the box.
551 /// - Nodes in the two outer "ring" elements (bottom right and top left)
552 /// are located on straight lines running from the edges of the
553 /// central box to the outer wall.
554 //======================================================================
555 template<class ELEMENT>
557 ELEMENT>::setup_algebraic_node_update()
558 {
559#ifdef PARANOID
560 /// Pointer to algebraic element in central box
561 AlgebraicElementBase* central_box_pt =
562 dynamic_cast<AlgebraicElementBase*>(Mesh::element_pt(0));
563
564 if (central_box_pt == 0)
565 {
566 std::ostringstream error_message;
567 error_message
568 << "Element in AlgebraicRefineableQuarterCircleSectorMesh must be\n ";
569 error_message << "derived from AlgebraicElementBase\n";
570 error_message << "but it is of type: "
571 << typeid(Mesh::element_pt(0)).name() << std::endl;
572 std::string function_name =
573 "AlgebraicRefineableQuarterCircleSectorMesh::";
574 function_name += "setup_algebraic_node_update()";
575 throw OomphLibError(
576 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
577 }
578#endif
579
580 // Number of nodes in elements
581 unsigned nnodes = Mesh::finite_element_pt(0)->nnode();
582
583 // Coordinates of central box
584 double x_box = Mesh::finite_element_pt(0)->node_pt(nnodes - 1)->x(0);
585 double y_box = Mesh::finite_element_pt(0)->node_pt(nnodes - 1)->x(1);
586
587 // Get wall position in bottom right corner
588 Vector<double> r_br(2);
589 Vector<double> xi(1);
592
593 // Establish fractional width of central box
594 Lambda_x = x_box / r_br[0];
595
596 // Find corresponding wall element/local coordinate
597 GeomObject* obj_br_pt;
598 Vector<double> s_br(1);
599 this->Wall_pt->locate_zeta(xi, obj_br_pt, s_br);
600
601 obj_br_pt->position(s_br, r_br);
602
603 // Get wall position in top left corner
604 Vector<double> r_tl(2);
607
608 // Establish fractional height of central box
609 Lambda_y = y_box / r_tl[1];
610
611 // Find corresponding wall element/local coordinate
612 GeomObject* obj_tl_pt;
613 Vector<double> s_tl(1);
614 this->Wall_pt->locate_zeta(xi, obj_tl_pt, s_tl);
615
616
617 // Element 0: central box
618 //-----------------------
619 {
620 unsigned ielem = 0;
622
623 // Loop over all nodes in the element and give them the update
624 // info appropriate for the current element
625 for (unsigned jnod = 0; jnod < nnodes; jnod++)
626 {
627 // Nodal coordinates in undeformed mesh
628 double x = Mesh::finite_element_pt(ielem)->node_pt(jnod)->x(0);
629 double y = Mesh::finite_element_pt(ielem)->node_pt(jnod)->x(1);
630
631 // The update function requires two geometric objects
632 Vector<GeomObject*> geom_object_pt(2);
633
634 // The update function requires four parameters:
635 Vector<double> ref_value(4);
636
637 // First reference value: fractional x-position inside box
638 ref_value[0] = x / x_box;
639
640 // Second reference value: fractional y-position inside box
641 ref_value[1] = y / y_box;
642
643 // Wall element at bottom right end of wall mesh:
644 geom_object_pt[0] = obj_br_pt;
645
646 // Local coordinate in this wall element (Note:
647 // we'll have to recompute this reference
648 // when the mesh is refined as we might fall off the element otherwise)
649 ref_value[2] = s_br[0];
650
651
652 // Wall element at top left end of wall mesh:
653 geom_object_pt[1] = obj_tl_pt;
654
655 // Local coordinate in this wall element. Note:
656 // we'll have to recompute this reference
657 // when the mesh is refined as we might fall off the element otherwise)
658 ref_value[3] = s_tl[0];
659
660 // Setup algebraic update for node: Pass update information
661 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(jnod))
662 ->add_node_update_info(Central_box, // enumerated ID
663 this, // mesh
664 geom_object_pt, // vector of geom objects
665 ref_value); // vector of ref. values
666 }
667 }
668
669 // Element 1: Bottom right box
670 //----------------------------
671 {
672 unsigned ielem = 1;
674
675 // Loop over all nodes in the element and give them the update
676 // info appropriate for the current element
677
678 // Double loop over nodes
679 unsigned nnod_lin =
680 dynamic_cast<ELEMENT*>(Mesh::finite_element_pt(ielem))->nnode_1d();
681 for (unsigned i0 = 0; i0 < nnod_lin; i0++)
682 {
683 // Fraction in the s_0-direction
684 double rho_0 = double(i0) / double(nnod_lin - 1);
685
686 for (unsigned i1 = 0; i1 < nnod_lin; i1++)
687 {
688 // Fraction in the s_1-direction
689 double rho_1 = double(i1) / double(nnod_lin - 1);
690
691 // Node number
692 unsigned jnod = i0 + i1 * nnod_lin;
693
694 // The update function requires three geometric objects
695 Vector<GeomObject*> geom_object_pt(3);
696
697 // The update function requires five parameters:
698 Vector<double> ref_value(5);
699
700 // First reference value: fractional s0-position inside box
701 ref_value[0] = rho_0;
702
703 // Second reference value: fractional s1-position inside box
704 ref_value[1] = rho_1;
705
706 // Wall element at bottom right end of wall mesh:
707 geom_object_pt[0] = obj_br_pt;
708
709 // Local coordinate in this wall element. Note:
710 // We'll have to recompute this reference
711 // when the mesh is refined as we might fall off the element
712 // otherwise
713 ref_value[2] = s_br[0];
714
715 // Wall element at top left end of wall mesh:
716 geom_object_pt[1] = obj_tl_pt;
717
718 // Local coordinate in this wall element. Note:
719 // We'll have to recompute this reference
720 // when the mesh is refined as we might fall off the element
721 // otherwise
722 ref_value[3] = s_tl[0];
723
724 // Reference point on wall
725 Vector<double> xi_wall(1);
730
731 // Identify wall element number and local coordinate of
732 // reference point on wall
733 GeomObject* obj_wall_pt;
734 Vector<double> s_wall(1);
735 this->Wall_pt->locate_zeta(xi_wall, obj_wall_pt, s_wall);
736
737 // Wall element at that contians reference point:
738 geom_object_pt[2] = obj_wall_pt;
739
740 // Local coordinate in this wall element. Note:
741 // We'll have to recompute this reference
742 // when the mesh is refined as we might fall off the element
743 // otherwise
744 ref_value[4] = s_wall[0];
745
746 // Setup algebraic update for node: Pass update information
747 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(jnod))
748 ->add_node_update_info(Lower_right_box, // enumerated ID
749 this, // mesh
750 geom_object_pt, // vector of geom objects
751 ref_value); // vector of ref. vals
752 }
753 }
754 }
755
756
757 // Element 2: Top left box
758 //---------------------------
759 {
760 unsigned ielem = 2;
762
763 // Double loop over nodes
764 unsigned nnod_lin =
765 dynamic_cast<ELEMENT*>(Mesh::finite_element_pt(ielem))->nnode_1d();
766
767 for (unsigned i0 = 0; i0 < nnod_lin; i0++)
768 {
769 // Fraction in the s_0-direction
770 double rho_0 = double(i0) / double(nnod_lin - 1);
771
772 for (unsigned i1 = 0; i1 < nnod_lin; i1++)
773 {
774 // Fraction in the s_1-direction
775 double rho_1 = double(i1) / double(nnod_lin - 1);
776
777 // Node number
778 unsigned jnod = i0 + i1 * nnod_lin;
779
780 // The update function requires three geometric objects
781 Vector<GeomObject*> geom_object_pt(3);
782
783 // The update function requires five parameters:
784 Vector<double> ref_value(5);
785
786 // First reference value: fractional s0-position inside box
787 ref_value[0] = rho_0;
788
789 // Second reference value: fractional s1-position inside box
790 ref_value[1] = rho_1;
791
792 // Wall element at bottom right end of wall mesh:
793 geom_object_pt[0] = obj_br_pt;
794
795 // Local coordinate in this wall element. Note:
796 // We'll have to recompute this reference
797 // when the mesh is refined as we might fall off the element
798 // otherwise
799 ref_value[2] = s_br[0];
800
801 // Wall element at top left end of wall mesh:
802 geom_object_pt[1] = obj_tl_pt;
803
804 // Local coordinate in this wall element. Note:
805 // We'll have to recompute this reference
806 // when the mesh is refined as we might fall off the element
807 // otherwise
808 ref_value[3] = s_tl[0];
809
810 // Reference point on wall
811 Vector<double> xi_wall(1);
813 rho_0 *
817
818 // Identify wall element number and local coordinate of
819 // reference point on wall
820 GeomObject* obj_wall_pt;
821 Vector<double> s_wall(1);
822 this->Wall_pt->locate_zeta(xi_wall, obj_wall_pt, s_wall);
823
824 // Wall element at that contians reference point:
825 geom_object_pt[2] = obj_wall_pt;
826
827 // Local coordinate in this wall element. Note:
828 // We'll have to recompute this reference
829 // when the mesh is refined as we might fall off the element
830 // otherwise
831 ref_value[4] = s_wall[0];
832
833 // Setup algebraic update for node: Pass update information
834 dynamic_cast<AlgebraicNode*>(el_pt->node_pt(jnod))
835 ->add_node_update_info(Upper_left_box, // Enumerated ID
836 this, // mesh
837 geom_object_pt, // vector of geom objects
838 ref_value); // vector of ref. vals
839 }
840 }
841 }
842 }
843
844
845 //======================================================================
846 /// Algebraic update function: Update in central box according
847 /// to wall shape at time level t (t=0: present; t>0: previous)
848 //======================================================================
849 template<class ELEMENT>
851 ELEMENT>::node_update_in_central_box(const unsigned& t,
852 AlgebraicNode*& node_pt)
853 {
854#ifdef PARANOID
855 // We're updating the nodal positions (!) at time level t
856 // and determine them by evaluating the wall GeomObject's
857 // position at that gime level. I believe this only makes sense
858 // if the t-th history value in the positional timestepper
859 // actually represents previous values (rather than some
860 // generalised quantity). Hence if this function is called with
861 // t>nprev_values(), we issue a warning and terminate the execution.
862 // It *might* be possible that the code still works correctly
863 // even if this condition is violated (e.g. if the GeomObject's
864 // position() function returns the appropriate "generalised"
865 // position value that is required by the timestepping scheme but it's
866 // probably worth flagging this up and forcing the user to manually switch
867 // off this warning if he/she is 100% sure that this is kosher.
868 if (t > node_pt->position_time_stepper_pt()->nprev_values())
869 {
870 std::string error_message =
871 "Trying to update the nodal position at a time level\n";
872 error_message += "beyond the number of previous values in the nodes'\n";
873 error_message += "position timestepper. This seems highly suspect!\n";
874 error_message += "If you're sure the code behaves correctly\n";
875 error_message += "in your application, remove this warning \n";
876 error_message += "or recompile with PARNOID switched off.\n";
877
878 std::string function_name =
879 "AlgebraicRefineableQuarterCircleSectorMesh::";
880 function_name += "node_update_in_central_box()",
881 throw OomphLibError(
882 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
883 }
884#endif
885
886 // Extract references for update in central box by copy construction
887 Vector<double> ref_value(node_pt->vector_ref_value(Central_box));
888
889 // Extract geometric objects for update in central box by copy construction
890 Vector<GeomObject*> geom_object_pt(
891 node_pt->vector_geom_object_pt(Central_box));
892
893 // First reference value: fractional x-position of node inside box
894 double rho_x = ref_value[0];
895
896 // Second reference value: fractional y-position of node inside box
897 double rho_y = ref_value[1];
898
899
900 // Wall position in bottom right corner:
901
902 // Pointer to wall element:
903 GeomObject* obj_br_pt = geom_object_pt[0];
904
905 // Eulerian dimension
906 unsigned n_dim = obj_br_pt->ndim();
907
908 // Local coordinate:
909 Vector<double> s_br(1);
910 s_br[0] = ref_value[2];
911
912 // Get wall position
913 Vector<double> r_br(n_dim);
914 obj_br_pt->position(t, s_br, r_br);
915
916 // Wall position in top left corner:
917
918 // Pointer to wall element:
919 GeomObject* obj_tl_pt = geom_object_pt[1];
920
921 // Local coordinate:
922 Vector<double> s_tl(1);
923 s_tl[0] = ref_value[3];
924
925 Vector<double> r_tl(n_dim);
926 obj_tl_pt->position(t, s_tl, r_tl);
927
928 // Assign new nodal coordinate
929 node_pt->x(t, 0) = r_br[0] * Lambda_x * rho_x;
930 node_pt->x(t, 1) = r_tl[1] * Lambda_y * rho_y;
931 }
932
933
934 //====================================================================
935 /// Algebraic update function: Update in lower right box according
936 /// to wall shape at time level t (t=0: present; t>0: previous)
937 //====================================================================
938 template<class ELEMENT>
940 ELEMENT>::node_update_in_lower_right_box(const unsigned& t,
941 AlgebraicNode*& node_pt)
942 {
943#ifdef PARANOID
944 // We're updating the nodal positions (!) at time level t
945 // and determine them by evaluating the wall GeomObject's
946 // position at that gime level. I believe this only makes sense
947 // if the t-th history value in the positional timestepper
948 // actually represents previous values (rather than some
949 // generalised quantity). Hence if this function is called with
950 // t>nprev_values(), we issue a warning and terminate the execution.
951 // It *might* be possible that the code still works correctly
952 // even if this condition is violated (e.g. if the GeomObject's
953 // position() function returns the appropriate "generalised"
954 // position value that is required by the timestepping scheme but it's
955 // probably worth flagging this up and forcing the user to manually switch
956 // off this warning if he/she is 100% sure that this is kosher.
957 if (t > node_pt->position_time_stepper_pt()->nprev_values())
958 {
959 std::string error_message =
960 "Trying to update the nodal position at a time level";
961 error_message += "beyond the number of previous values in the nodes'";
962 error_message += "position timestepper. This seems highly suspect!";
963 error_message += "If you're sure the code behaves correctly";
964 error_message += "in your application, remove this warning ";
965 error_message += "or recompile with PARNOID switched off.";
966
967 std::string function_name =
968 "AlgebraicRefineableQuarterCircleSectorMesh::";
969 function_name += "node_update_in_lower_right_box()",
970 throw OomphLibError(
971 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
972 }
973#endif
974
975 // Extract references for update in central box by copy construction
976 Vector<double> ref_value(node_pt->vector_ref_value(Lower_right_box));
977
978 // Extract geometric objects for update in central box by copy construction
979 Vector<GeomObject*> geom_object_pt(
980 node_pt->vector_geom_object_pt(Lower_right_box));
981
982 // First reference value: fractional s0-position of node inside box
983 double rho_0 = ref_value[0];
984
985 // Second reference value: fractional s1-position of node inside box
986 double rho_1 = ref_value[1];
987
988 // Wall position in bottom right corner:
989
990 // Pointer to wall element:
991 GeomObject* obj_br_pt = geom_object_pt[0];
992
993 // Eulerian dimension
994 unsigned n_dim = obj_br_pt->ndim();
995
996 // Local coordinate:
997 Vector<double> s_br(1);
998 s_br[0] = ref_value[2];
999
1000 // Get wall position
1001 Vector<double> r_br(n_dim);
1002 obj_br_pt->position(t, s_br, r_br);
1003
1004 // Wall position in top left corner:
1005
1006 // Pointer to wall element:
1007 GeomObject* obj_tl_pt = geom_object_pt[1];
1008
1009 // Local coordinate:
1010 Vector<double> s_tl(1);
1011 s_tl[0] = ref_value[3];
1012
1013 Vector<double> r_tl(n_dim);
1014 obj_tl_pt->position(t, s_tl, r_tl);
1015
1016 // Position of the corner of the central box
1017 Vector<double> r_box(n_dim);
1018 r_box[0] = Lambda_x * r_br[0];
1019 r_box[1] = Lambda_y * r_tl[1];
1020
1021 // Position Vector to left end of box
1022 Vector<double> r_left(n_dim);
1023 r_left[0] = Lambda_x * r_br[0] + rho_1 * (r_box[0] - Lambda_x * r_br[0]);
1024 r_left[1] = Lambda_x * r_br[1] + rho_1 * (r_box[1] - Lambda_x * r_br[1]);
1025
1026 // Wall position
1027
1028 // Pointer to wall element:
1029 GeomObject* obj_wall_pt = geom_object_pt[2];
1030
1031 // Local coordinate:
1032 Vector<double> s_wall(1);
1033 s_wall[0] = ref_value[4];
1034
1035 Vector<double> r_wall(n_dim);
1036 obj_wall_pt->position(t, s_wall, r_wall);
1037
1038 // Assign new nodal coordinate
1039 node_pt->x(t, 0) = r_left[0] + rho_0 * (r_wall[0] - r_left[0]);
1040 node_pt->x(t, 1) = r_left[1] + rho_0 * (r_wall[1] - r_left[1]);
1041 }
1042 //====================================================================
1043 /// Algebraic update function: Update in upper left box according
1044 /// to wall shape at time level t (t=0: present; t>0: previous)
1045 //====================================================================
1046 template<class ELEMENT>
1048 ELEMENT>::node_update_in_upper_left_box(const unsigned& t,
1049 AlgebraicNode*& node_pt)
1050 {
1051#ifdef PARANOID
1052 // We're updating the nodal positions (!) at time level t
1053 // and determine them by evaluating the wall GeomObject's
1054 // position at that gime level. I believe this only makes sense
1055 // if the t-th history value in the positional timestepper
1056 // actually represents previous values (rather than some
1057 // generalised quantity). Hence if this function is called with
1058 // t>nprev_values(), we issue a warning and terminate the execution.
1059 // It *might* be possible that the code still works correctly
1060 // even if this condition is violated (e.g. if the GeomObject's
1061 // position() function returns the appropriate "generalised"
1062 // position value that is required by the timestepping scheme but it's
1063 // probably worth flagging this up and forcing the user to manually switch
1064 // off this warning if he/she is 100% sure that this is kosher.
1065 if (t > node_pt->position_time_stepper_pt()->nprev_values())
1066 {
1067 std::string error_message =
1068 "Trying to update the nodal position at a time level";
1069 error_message += "beyond the number of previous values in the nodes'";
1070 error_message += "position timestepper. This seems highly suspect!";
1071 error_message += "If you're sure the code behaves correctly";
1072 error_message += "in your application, remove this warning ";
1073 error_message += "or recompile with PARNOID switched off.";
1074
1075 std::string function_name =
1076 "AlgebraicRefineableQuarterCircleSectorMesh::";
1077 function_name += "node_update_in_upper_left_box()";
1078
1079 throw OomphLibError(
1080 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1081 }
1082#endif
1083
1084 // Extract references for update in central box by copy construction
1085 Vector<double> ref_value(node_pt->vector_ref_value(Upper_left_box));
1086
1087 // Extract geometric objects for update in central box by copy construction
1088 Vector<GeomObject*> geom_object_pt(
1089 node_pt->vector_geom_object_pt(Upper_left_box));
1090
1091 // First reference value: fractional s0-position of node inside box
1092 double rho_0 = ref_value[0];
1093
1094 // Second reference value: fractional s1-position of node inside box
1095 double rho_1 = ref_value[1];
1096
1097 // Wall position in bottom right corner:
1098
1099 // Pointer to wall element:
1100 GeomObject* obj_br_pt = geom_object_pt[0];
1101
1102 // Eulerian dimension
1103 unsigned n_dim = obj_br_pt->ndim();
1104
1105 // Local coordinate:
1106 Vector<double> s_br(1);
1107 s_br[0] = ref_value[2];
1108
1109 // Get wall position
1110 Vector<double> r_br(n_dim);
1111 obj_br_pt->position(t, s_br, r_br);
1112
1113 // Wall position in top left corner:
1114
1115 // Pointer to wall element:
1116 GeomObject* obj_tl_pt = node_pt->geom_object_pt(1);
1117
1118 // Local coordinate:
1119 Vector<double> s_tl(1);
1120 s_tl[0] = node_pt->ref_value(3);
1121
1122 Vector<double> r_tl(n_dim);
1123 obj_tl_pt->position(t, s_tl, r_tl);
1124
1125 // Position of the corner of the central box
1126 Vector<double> r_box(n_dim);
1127 r_box[0] = Lambda_x * r_br[0];
1128 r_box[1] = Lambda_y * r_tl[1];
1129
1130 // Position Vector to top face of central box
1131 Vector<double> r_top(n_dim);
1132 r_top[0] = Lambda_y * r_tl[0] + rho_0 * (r_box[0] - Lambda_y * r_tl[0]);
1133 r_top[1] = Lambda_y * r_tl[1] + rho_0 * (r_box[1] - Lambda_y * r_tl[1]);
1134
1135 // Wall position
1136
1137 // Pointer to wall element:
1138 GeomObject* obj_wall_pt = node_pt->geom_object_pt(2);
1139
1140 // Local coordinate:
1141 Vector<double> s_wall(1);
1142 s_wall[0] = node_pt->ref_value(4);
1143
1144 Vector<double> r_wall(n_dim);
1145 obj_wall_pt->position(t, s_wall, r_wall);
1146
1147
1148 // Assign new nodal coordinate
1149 node_pt->x(t, 0) = r_top[0] + rho_1 * (r_wall[0] - r_top[0]);
1150 node_pt->x(t, 1) = r_top[1] + rho_1 * (r_wall[1] - r_top[1]);
1151 }
1152
1153
1154 //======================================================================
1155 /// Update algebraic update function for nodes in lower right box.
1156 //======================================================================
1157 template<class ELEMENT>
1159 ELEMENT>::update_node_update_in_lower_right_box(AlgebraicNode*& node_pt)
1160 {
1161 // Extract references for update in central box by copy construction
1162 Vector<double> ref_value(node_pt->vector_ref_value(Lower_right_box));
1163
1164 // Extract geometric objects for updatein central box by copy construction
1165 Vector<GeomObject*> geom_object_pt(
1166 node_pt->vector_geom_object_pt(Lower_right_box));
1167
1168
1169 // Now remove the update info to allow overwriting below
1170 node_pt->kill_node_update_info(Lower_right_box);
1171
1172 // Fixed reference value: Start coordinate on wall
1174
1175 // Fixed reference value: Fractional position of dividing line
1177
1178 // Fixed reference value: End coordinate on wall
1180
1181 // Second reference value: fractional s1-position of node inside box
1182 double rho_1 = ref_value[1];
1183
1184
1185 // Update reference to wall point in bottom right corner
1186 //------------------------------------------------------
1187
1188 // Wall position in bottom right corner:
1189 Vector<double> xi(1);
1190 xi[0] = xi_lo;
1191
1192 // Find corresponding wall element/local coordinate
1193 GeomObject* obj_br_pt;
1194 Vector<double> s_br(1);
1195 this->Wall_pt->locate_zeta(xi, obj_br_pt, s_br);
1196
1197 // Wall element at bottom right end of wall mesh:
1198 geom_object_pt[0] = obj_br_pt;
1199
1200 // Local coordinate in this wall element. Note:
1201 // We'll have to recompute this reference
1202 // when the mesh is refined as we might fall off the element otherwise
1203 ref_value[2] = s_br[0];
1204
1205
1206 // Update reference to wall point in upper left corner
1207 //----------------------------------------------------
1208
1209 // Wall position in top left corner
1210 xi[0] = xi_hi;
1211
1212 // Find corresponding wall element/local coordinate
1213 GeomObject* obj_tl_pt;
1214 Vector<double> s_tl(1);
1215 this->Wall_pt->locate_zeta(xi, obj_tl_pt, s_tl);
1216
1217 // Wall element at top left end of wall mesh:
1218 geom_object_pt[1] = obj_tl_pt;
1219
1220 // Local coordinate in this wall element. Note:
1221 // We'll have to recompute this reference
1222 // when the mesh is refined as we might fall off the element otherwise
1223 ref_value[3] = s_tl[0];
1224
1225
1226 // Update reference to reference point on wall
1227 //--------------------------------------------
1228
1229 // Reference point on wall
1230 Vector<double> xi_wall(1);
1231 xi_wall[0] = xi_lo + rho_1 * fract_mid * (xi_hi - xi_lo);
1232
1233 // Identify wall element number and local coordinate of
1234 // reference point on wall
1235 GeomObject* obj_wall_pt;
1236 Vector<double> s_wall(1);
1237 this->Wall_pt->locate_zeta(xi_wall, obj_wall_pt, s_wall);
1238
1239 // Wall element at that contians reference point:
1240 geom_object_pt[2] = obj_wall_pt;
1241
1242 // Local coordinate in this wall element. Note:
1243 // We'll have to recompute this reference
1244 // when the mesh is refined as we might fall off the element otherwise
1245 ref_value[4] = s_wall[0];
1246
1247 // Setup algebraic update for node: Pass update information
1248 node_pt->add_node_update_info(Lower_right_box, // Enumerated ID
1249 this, // mesh
1250 geom_object_pt, // vector of geom objects
1251 ref_value); // vector of ref. vals
1252 }
1253
1254 //======================================================================
1255 /// Update algebraic update function for nodes in upper left box
1256 //======================================================================
1257 template<class ELEMENT>
1259 ELEMENT>::update_node_update_in_upper_left_box(AlgebraicNode*& node_pt)
1260 {
1261 // Extract references for update in central box by copy construction
1262 Vector<double> ref_value(node_pt->vector_ref_value(Upper_left_box));
1263
1264 // Extract geometric objects for update in central box by copy construction
1265 Vector<GeomObject*> geom_object_pt(
1266 node_pt->vector_geom_object_pt(Upper_left_box));
1267
1268 // Now remove the update info to allow overwriting below
1269 node_pt->kill_node_update_info(Upper_left_box);
1270
1271 // Fixed reference value: Start coordinate on wall
1273
1274 // Fixed reference value: Fractional position of dividing line
1276
1277 // Fixed reference value: End coordinate on wall
1279
1280 // First reference value: fractional s0-position of node inside box
1281 double rho_0 = ref_value[0];
1282
1283 // Update reference to wall point in bottom right corner
1284 //------------------------------------------------------
1285
1286 // Wall position in bottom right corner:
1287 Vector<double> xi(1);
1288 xi[0] = xi_lo;
1289
1290 // Find corresponding wall element/local coordinate
1291 GeomObject* obj_br_pt;
1292 Vector<double> s_br(1);
1293 this->Wall_pt->locate_zeta(xi, obj_br_pt, s_br);
1294
1295 // Wall element at bottom right end of wall mesh:
1296 geom_object_pt[0] = obj_br_pt;
1297
1298 // Local coordinate in this wall element. Note:
1299 // We'll have to recompute this reference
1300 // when the mesh is refined as we might fall off the element otherwise
1301 ref_value[2] = s_br[0];
1302
1303 // Update reference to wall point in upper left corner
1304 //----------------------------------------------------
1305
1306 // Wall position in top left corner
1307 xi[0] = xi_hi;
1308
1309 // Find corresponding wall element/local coordinate
1310 GeomObject* obj_tl_pt;
1311 Vector<double> s_tl(1);
1312 this->Wall_pt->locate_zeta(xi, obj_tl_pt, s_tl);
1313
1314 // Wall element at top left end of wall mesh:
1315 geom_object_pt[1] = obj_tl_pt;
1316
1317 // Local coordinate in this wall element. Note:
1318 // We'll have to recompute this reference
1319 // when the mesh is refined as we might fall off the element otherwise
1320 ref_value[3] = s_tl[0];
1321
1322
1323 // Update reference to reference point on wall
1324 //--------------------------------------------
1325
1326 // Reference point on wall
1327 Vector<double> xi_wall(1);
1328 xi_wall[0] = xi_hi + rho_0 * (1.0 - fract_mid) * (xi_lo - xi_hi);
1329
1330 // Identify reference point on wall
1331 GeomObject* obj_wall_pt;
1332 Vector<double> s_wall(1);
1333 this->Wall_pt->locate_zeta(xi_wall, obj_wall_pt, s_wall);
1334
1335 // Wall element at that contians reference point:
1336 geom_object_pt[2] = obj_wall_pt;
1337
1338 // Local coordinate in this wall element. Note:
1339 // We'll have to recompute this reference
1340 // when the mesh is refined as we might fall off the element otherwise
1341 ref_value[4] = s_wall[0];
1342
1343 // Setup algebraic update for node: Pass update information
1344 node_pt->add_node_update_info(Upper_left_box, // Enumerated ID
1345 this, // mesh
1346 geom_object_pt, // vector of geom objects
1347 ref_value); // vector of ref. vals
1348 }
1349
1350
1351} // namespace oomph
1352#endif
e
Definition: cfortran.h:571
static char t char * s
Definition: cfortran.h:568
char t
Definition: cfortran.h:568
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
Vector< GeomObject * > & vector_geom_object_pt(const int &id)
Return vector of geometric objects involved in id-th update function.
GeomObject * geom_object_pt(const unsigned &i)
Return pointer to i-th geometric object involved in default (usually first) update function.
double ref_value(const unsigned &i)
Return i-th reference value involved in default (usually first) update function.
void kill_node_update_info(const int &id=0)
Erase algebraic node update information for id-th node update function. Id defaults to 0.
Vector< double > & vector_ref_value()
Return vector of reference values involved in default (usually first) update function.
void add_node_update_info(const int &id, AlgebraicMesh *mesh_pt, const Vector< GeomObject * > &geom_object_pt, const Vector< double > &ref_value, const bool &called_from_constructor=false)
Add algebraic update information for node: What's the ID of the mesh update function (typically used ...
Algebraic version of RefineableQuarterCircleSectorMesh.
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
Definition: domain.h:116
A general Finite Element class.
Definition: elements.h:1313
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object.
Definition: elements.h:2509
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
virtual Node * construct_boundary_node(const unsigned &n)
Construct the local node n as a boundary node; that is a node that MAY be placed on a mesh boundary a...
Definition: elements.h:2538
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
/////////////////////////////////////////////////////////////////////
Definition: geom_objects.h:101
unsigned ndim() const
Access function to # of Eulerian coordinates.
Definition: geom_objects.h:177
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
void macro_map(const Vector< double > &s, Vector< double > &r)
The mapping from local to global coordinates at the current time : r(s)
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Definition: mesh.cc:243
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:183
std::vector< bool > Boundary_coordinate_exists
Vector of boolean data that indicates whether the boundary coordinates have been set for the boundary...
Definition: mesh.h:190
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Definition: mesh.h:473
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Definition: mesh.h:505
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition: mesh.h:460
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
Definition: nodes.h:1022
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 setup_boundary_element_info()
Setup lookup schemes which establish whic elements are located next to mesh's boundaries (wrapper to ...
Definition: quad_mesh.h:73
Circular sector as domain. Domain is bounded by curved boundary which is represented by a GeomObject....
2D quarter ring mesh class. The domain is specified by the GeomObject that identifies boundary 1.
double Fract_mid
Fraction along wall where outer ring is to be divided.
GeomObject *& wall_pt()
Access function to GeomObject representing wall.
double Xi_hi
Upper limit for the (1D) coordinates along the wall.
QuarterCircleSectorMesh(GeomObject *wall_pt, const double &xi_lo, const double &fract_mid, const double &xi_hi, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object that specifies the wall, start and end coordinates on t...
QuarterCircleSectorDomain * Domain_pt
Pointer to Domain.
double Xi_lo
Lower limit for the (1D) coordinates along the wall.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Definition: timesteppers.h:231
virtual unsigned nprev_values() const =0
Number of previous values available: 0 for static, 1 for BDF<1>,...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...