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