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