my_alg_channel_mesh.h
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 #ifndef OOMPH_MY_ALGEBRAIC_COLLAPSIBLE_CHANNEL_MESH
31 #define OOMPH_MY_ALGEBRAIC_COLLAPSIBLE_CHANNEL_MESH
32 
33 //Include the mesh
34 #include "meshes/collapsible_channel_mesh.h"
35 
36 
37 
38 
39 
40 ////////////////////////////////////////////////////////////////////
41 ////////////////////////////////////////////////////////////////////
42 ////////////////////////////////////////////////////////////////////
43 
44 namespace oomph
45 {
46 
47 
48 //===========start_algebraic_mesh==================================
49 /// Collapsible channel mesh with algebraic node update
50 //=================================================================
51 template<class ELEMENT>
53  public AlgebraicMesh,
54  public virtual CollapsibleChannelMesh<ELEMENT>
55 {
56 
57 public:
58 
59  /// \short Constructor: Pass number of elements in upstream/collapsible/
60  /// downstream segment and across the channel; lengths of upstream/
61  /// collapsible/downstream segments and width of channel, pointer to
62  /// GeomObject that defines the collapsible segment, and pointer to
63  /// TimeStepper (defaults to the default timestepper, Steady).
64  MyAlgebraicCollapsibleChannelMesh(const unsigned& nup,
65  const unsigned& ncollapsible,
66  const unsigned& ndown,
67  const unsigned& ny,
68  const double& lup,
69  const double& lcollapsible,
70  const double& ldown,
71  const double& ly,
72  GeomObject* wall_pt,
73  TimeStepper* time_stepper_pt=
74  &Mesh::Default_TimeStepper) :
75  CollapsibleChannelMesh<ELEMENT>(nup, ncollapsible, ndown, ny,
76  lup, lcollapsible, ldown, ly,
77  wall_pt,
78  time_stepper_pt)
79  {
80  // Setup algebraic node update operations
82  }
83 
84 
85 
86  /// \short Constructor: Pass number of elements in upstream/collapsible/
87  /// downstream segment and across the channel; lengths of upstream/
88  /// collapsible/downstream segments and width of channel, pointer to
89  /// GeomObject that defines the collapsible segment, function pointer
90  /// to "boundary layer squash function", and pointer to
91  /// TimeStepper (defaults to the default timestepper, Steady).
93  const unsigned& nup,
94  const unsigned& ncollapsible,
95  const unsigned& ndown,
96  const unsigned& ny,
97  const double& lup,
98  const double& lcollapsible,
99  const double& ldown,
100  const double& ly,
101  GeomObject* wall_pt,
102  CollapsibleChannelDomain::BLSquashFctPt bl_squash_function_pt,
103  TimeStepper* time_stepper_pt=
104  &Mesh::Default_TimeStepper) :
105  CollapsibleChannelMesh<ELEMENT>(nup, ncollapsible, ndown, ny,
106  lup, lcollapsible, ldown, ly,
107  wall_pt,
108  time_stepper_pt)
109  {
110  // Set boundary layer squash function
111  this->Domain_pt->bl_squash_fct_pt()=bl_squash_function_pt;
112 
113  // Do MacroElement-based node update
114  CollapsibleChannelMesh<ELEMENT>::node_update();
115 
116  // Setup algebraic node update operations
118  }
119 
120 
121  /// \short Destructor: empty
123 
124  /// \short Function pointer for function that squashes
125  /// the mesh near the walls. Default trivial mapping (the identity)
126  /// leaves vertical nodal positions unchanged. Mapping is
127  /// used in underlying CollapsibleChannelDomain.
128  /// This (deliberately broken) function overloads the one
129  /// in the CollapsibleChannelMesh base class.
130  CollapsibleChannelDomain::BLSquashFctPt& bl_squash_fct_pt()
131  {
132  std::ostringstream error_message;
133  error_message
134  << "It does not make sense to set the bl_squash_fct_pt \n"
135  << "outside the constructor as it's only used to set up the \n"
136  << "algebraic remesh data when the algebraic mesh is first built. \n";
137  std::string function_name =
138  "MyAlgebraicCollapsibleChannelMesh::bl_squash_fct_pt()\n";
139 
140  throw OomphLibError(error_message.str(),
141  OOMPH_CURRENT_FUNCTION,
142  OOMPH_EXCEPTION_LOCATION);
143 
144  // Dummy return
145  return Dummy_fct_pt;
146  }
147 
148 
149  /// \short Update nodal position at time level t (t=0: present;
150  /// t>0: previous)
151  void algebraic_node_update(const unsigned& t, AlgebraicNode*& node_pt);
152 
153  /// \short Update the geometric references that are used
154  /// to update node after mesh adaptation.
155  /// Empty -- no update of node update required
156  void update_node_update(AlgebraicNode*& node_pt) {}
157 
158 protected:
159 
160  /// Function to setup the algebraic node update
162 
163 
164  /// Dummy function pointer
165  CollapsibleChannelDomain::BLSquashFctPt Dummy_fct_pt;
166 
167 };
168 
169 
170 
171 
172 
173 ///////////////////////////////////////////////////////////////////////////
174 ///////////////////////////////////////////////////////////////////////////
175 ///////////////////////////////////////////////////////////////////////////
176 
177 
178 
179 //===========start_refineable_algebraic_collapsible_channel_mesh======
180 /// Refineable version of the CollapsibleChannel mesh with
181 /// algebraic node update.
182 //====================================================================
183 template<class ELEMENT>
185  public RefineableQuadMesh<ELEMENT>,
186  public virtual MyAlgebraicCollapsibleChannelMesh<ELEMENT>
187 {
188 
189 public:
190 
191 
192  /// \short Constructor: Pass number of elements in upstream/collapsible/
193  /// downstream segment and across the channel; lengths of upstream/
194  /// collapsible/downstream segments and width of channel, pointer to
195  /// GeomObject that defines the collapsible segment, function pointer
196  /// to "boundary layer squash function", and pointer to
197  /// TimeStepper (defaults to the default timestepper, Steady).
199  const unsigned& ncollapsible,
200  const unsigned& ndown,
201  const unsigned& ny,
202  const double& lup,
203  const double& lcollapsible,
204  const double& ldown,
205  const double& ly,
206  GeomObject* wall_pt,
207  TimeStepper* time_stepper_pt=
208  &Mesh::Default_TimeStepper) :
209  CollapsibleChannelMesh<ELEMENT>(nup, ncollapsible, ndown, ny,
210  lup, lcollapsible, ldown, ly,
211  wall_pt,
212  time_stepper_pt),
213  MyAlgebraicCollapsibleChannelMesh<ELEMENT>(nup, ncollapsible, ndown, ny,
214  lup, lcollapsible, ldown, ly,
215  wall_pt,
216  time_stepper_pt)
217  {
218  // Build quadtree forest
219  this->setup_quadtree_forest();
220  }
221 
222 
223 
224 
225  /// \short Constructor: Pass number of elements in upstream/collapsible/
226  /// downstream segment and across the channel; lengths of upstream/
227  /// collapsible/downstream segments and width of channel, pointer to
228  /// GeomObject that defines the collapsible segment, function pointer
229  /// to "boundary layer squash function", and pointer to
230  /// TimeStepper (defaults to the default timestepper, Steady).
232  const unsigned& nup,
233  const unsigned& ncollapsible,
234  const unsigned& ndown,
235  const unsigned& ny,
236  const double& lup,
237  const double& lcollapsible,
238  const double& ldown,
239  const double& ly,
240  GeomObject* wall_pt,
241  CollapsibleChannelDomain::BLSquashFctPt bl_squash_function_pt,
242  TimeStepper* time_stepper_pt=
243  &Mesh::Default_TimeStepper) :
244  CollapsibleChannelMesh<ELEMENT>(nup, ncollapsible, ndown, ny,
245  lup, lcollapsible, ldown, ly,
246  wall_pt,
247  time_stepper_pt),
248  MyAlgebraicCollapsibleChannelMesh<ELEMENT>(nup, ncollapsible, ndown, ny,
249  lup, lcollapsible, ldown, ly,
250  wall_pt,
251  bl_squash_function_pt,
252  time_stepper_pt)
253  {
254  // Build quadtree forest
255  this->setup_quadtree_forest();
256  }
257 
258 };
259 
260 
261 
262 
263 
264 
265 
266 
267 //============start_setup_algebraic_node_update====================
268 /// Setup algebraic mesh update -- assumes that mesh has
269 /// initially been set up with the wall in its undeformed position.
270 //=================================================================
271 template<class ELEMENT>
273 {
274 
275  // Extract some reference lengths from the CollapsibleChannelDomain.
276  double l_up=this->domain_pt()->l_up();
277  double l_collapsible=this->domain_pt()->l_collapsible();
278 
279  // Loop over all nodes in mesh
280  unsigned nnod=this->nnode();
281  for (unsigned j=0;j<nnod;j++)
282  {
283  // Get pointer to node
284  AlgebraicNode* nod_pt=node_pt(j);
285 
286  // Get coordinates
287  double x=nod_pt->x(0);
288  double y=nod_pt->x(1);
289 
290  // Check if the node is in the collapsible part:
291  if ( (x>=l_up) && (x<=(l_up+l_collapsible)) )
292  {
293 
294  // Get zeta coordinate on the undeformed wall
295  Vector<double> zeta(1);
296  zeta[0]=x-l_up;
297 
298  // Get position vector to wall:
299  Vector<double> r_wall(2);
300  this->Wall_pt->position(zeta,r_wall);
301 
302 
303  // Sanity check: Confirm that the wall is in its undeformed position
304 #ifdef PARANOID
305  if ((std::abs(r_wall[0]-x)>1.0e-15)&&(std::abs(r_wall[1]-y)>1.0e-15))
306  {
307  std::ostringstream error_stream;
308  error_stream
309  << "Wall must be in its undeformed position when\n"
310  << "algebraic node update information is set up!\n "
311  << "x-discrepancy: " << std::abs(r_wall[0]-x) << std::endl
312  << "y-discrepancy: " << std::abs(r_wall[1]-y) << std::endl;
313 
314  throw OomphLibError(
315  error_stream.str(),
316  OOMPH_CURRENT_FUNCTION,
317  OOMPH_EXCEPTION_LOCATION);
318  }
319 #endif
320 
321  // Only a single geometric object is involved in the node update operation
322  Vector<GeomObject*> geom_object_pt(1);
323 
324  // The wall geometric object
325  geom_object_pt[0]=this->Wall_pt;
326 
327  // The update function requires three parameters:
328  Vector<double> ref_value(3);
329 
330  // First reference value: Original x-position on the lower wall
331  ref_value[0]=r_wall[0];
332 
333  // Second reference value: Fractional position along
334  // straight line from the bottom (at the original x-position)
335  // to the point on the wall
336  ref_value[1]=y/r_wall[1];
337 
338  // Third reference value: Zeta coordinate on wall
339  ref_value[2]=zeta[0];
340 
341  // Setup algebraic update for node: Pass update information
342  // to AlgebraicNode:
343  nod_pt->add_node_update_info(
344  this, // mesh
345  geom_object_pt, // vector of geom objects
346  ref_value); // vector of ref. values
347  }
348 
349  }
350 
351 } //end of setup_algebraic_node_update
352 
353 
354 //=============start_of_algebraic_node_update======================
355 /// Perform algebraic mesh update at time level t (t=0: present;
356 /// t>0: previous)
357 //=================================================================
358 template<class ELEMENT>
360  const unsigned& t, AlgebraicNode*& node_pt)
361 {
362 
363  // Extract reference values for update by copy construction
364  Vector<double> ref_value(node_pt->vector_ref_value());
365 
366  // Extract geometric objects for update by copy construction
367  Vector<GeomObject*> geom_object_pt(node_pt->vector_geom_object_pt());
368 
369  // First reference value: Original x-position
370  double x_bottom=ref_value[0];
371 
372  // Second reference value: Fractional position along
373  // straight line from the bottom (at the original x-position)
374  // to the point on the wall
375  double fract=ref_value[1];
376 
377  // Third reference value: Zeta coordinate on wall
378  Vector<double> zeta(1);
379  zeta[0]=ref_value[2];
380 
381  // Pointer to wall geom object
382  GeomObject* wall_pt=geom_object_pt[0];
383 
384  // Get position vector to wall at previous timestep t
385  Vector<double> r_wall(2);
386  wall_pt->position(t,zeta,r_wall);
387 
388  // Assign new nodal coordinates
389  node_pt->x(t,0)=x_bottom+fract*(r_wall[0]-x_bottom);
390  node_pt->x(t,1)= fract* r_wall[1];
391 
392 }
393 
394 
395 
396 
397 }
398 
399 
400 
401 
402 
403 
404 
405 
406 #endif
MyAlgebraicCollapsibleChannelMesh(const unsigned &nup, const unsigned &ncollapsible, const unsigned &ndown, const unsigned &ny, const double &lup, const double &lcollapsible, const double &ldown, const double &ly, GeomObject *wall_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in upstream/collapsible/ downstream segment and across the chann...
void update_node_update(AlgebraicNode *&node_pt)
Update the geometric references that are used to update node after mesh adaptation. Empty – no update of node update required.
CollapsibleChannelDomain::BLSquashFctPt & bl_squash_fct_pt()
Function pointer for function that squashes the mesh near the walls. Default trivial mapping (the ide...
void setup_algebraic_node_update()
Function to setup the algebraic node update.
MyRefineableAlgebraicCollapsibleChannelMesh(const unsigned &nup, const unsigned &ncollapsible, const unsigned &ndown, const unsigned &ny, const double &lup, const double &lcollapsible, const double &ldown, const double &ly, GeomObject *wall_pt, CollapsibleChannelDomain::BLSquashFctPt bl_squash_function_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in upstream/collapsible/ downstream segment and across the chann...
Collapsible channel mesh with algebraic node update.
MyAlgebraicCollapsibleChannelMesh(const unsigned &nup, const unsigned &ncollapsible, const unsigned &ndown, const unsigned &ny, const double &lup, const double &lcollapsible, const double &ldown, const double &ly, GeomObject *wall_pt, CollapsibleChannelDomain::BLSquashFctPt bl_squash_function_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in upstream/collapsible/ downstream segment and across the chann...
virtual ~MyAlgebraicCollapsibleChannelMesh()
Destructor: empty.
CollapsibleChannelDomain::BLSquashFctPt Dummy_fct_pt
Dummy function pointer.
MyRefineableAlgebraicCollapsibleChannelMesh(const unsigned &nup, const unsigned &ncollapsible, const unsigned &ndown, const unsigned &ny, const double &lup, const double &lcollapsible, const double &ldown, const double &ly, GeomObject *wall_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in upstream/collapsible/ downstream segment and across the chann...
void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Update nodal position at time level t (t=0: present; t>0: previous)