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-2023 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 
32 namespace 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
59  set_nboundary(3);
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 
77  Vector<double> s(2);
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);
591  QuarterCircleSectorMesh<ELEMENT>::Wall_pt->position(xi, r_br);
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);
606  QuarterCircleSectorMesh<ELEMENT>::Wall_pt->position(xi, r_tl);
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;
621  FiniteElement* el_pt = Mesh::finite_element_pt(ielem);
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;
673  FiniteElement* el_pt = Mesh::finite_element_pt(ielem);
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;
761  FiniteElement* el_pt = Mesh::finite_element_pt(ielem);
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
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
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< GeomObject * > & vector_geom_object_pt(const int &id)
Return vector of geometric objects involved in id-th 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 ...
Vector< double > & vector_ref_value()
Return vector of reference values involved in default (usually first) update function.
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
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
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
/////////////////////////////////////////////////////////////////////
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
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
Definition: nodes.h:1022
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.
GeomObject *& wall_pt()
Access function to GeomObject representing wall.
double Fract_mid
Fraction along wall where outer ring is to be divided.
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.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...