macro_element_node_update_element.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_MACRO_ELEMENT_NODE_UPDATE_ELEMENTS_HEADER
31 #define OOMPH_MACRO_ELEMENT_NODE_UPDATE_ELEMENTS_HEADER
32 
33 #include "geom_objects.h"
34 #include "mesh.h"
35 #include "elements.h"
37 #include "domain.h"
38 
39 namespace oomph
40 {
41 
42 ///////////////////////////////////////////////////////////////////////
43 ///////////////////////////////////////////////////////////////////////
44 // MacroElementNodeUpdate nodes
45 ///////////////////////////////////////////////////////////////////////
46 ///////////////////////////////////////////////////////////////////////
47 
48 
49 
50 //========================================================================
51 /// MacroElementNodeUpdate nodes are nodes with a positional update
52 /// function, based on their element's MacroElement representation.
53 //========================================================================
55 {
56 
57 
58 public:
59 
60  /// \short Constructor for steady node of spatial
61  /// dimension n_dim, with n_position_type generalised coordinates
62  /// and with initial_nvalue dofs.
63  MacroElementNodeUpdateNode(const unsigned &n_dim,
64  const unsigned &n_position_type,
65  const unsigned &initial_nvalue) :
66  Node(n_dim,n_position_type,initial_nvalue)
67  {
68  // By default, only the nodal position is updated and no auxiliary
69  // updates of function values are performed.
70  }
71 
72  ///\short Constructor for bog-standard node of spatial
73  /// dimension n_dim, with n_position_type generalised coordinates,
74  /// with initial_nvalue dofs and with time dependence.
76  const unsigned &n_dim,
77  const unsigned &n_position_type,
78  const unsigned &initial_nvalue) :
79  Node(time_stepper_pt,n_dim,n_position_type,initial_nvalue)
80  {
81  // By default, only the nodal position is updated and no auxiliary
82  // updates of function values are performed.
83  }
84 
85  /// Broken copy constructor
87  {
88  BrokenCopy::broken_copy("MacroElementNodeUpdateNode");
89  }
90 
91  /// Broken assignment operator
92 //Commented out broken assignment operator because this can lead to a conflict warning
93 //when used in the virtual inheritence hierarchy. Essentially the compiler doesn't
94 //realise that two separate implementations of the broken function are the same and so,
95 //quite rightly, it shouts.
96  /*void operator=(const MacroElementNodeUpdateNode&)
97  {
98  BrokenCopy::broken_assign("MacroElementNodeUpdateNode");
99  }*/
100 
101 
102  ///\short Destructor (empty)
104 
105  /// \short Update the current nodal position. If
106  /// required, perform the auxiliary update of nodal values.
107  /// If update_all_time_levels_for_new_node==true, previous
108  /// positions are also updated -- as indicated by the name
109  /// of this flag, this should only be done for newly
110  /// created nodes, when this function is called from
111  /// MacroElementNodeUpdateElementBase::build_macro_element_node_update_node(...)
112  void node_update(const bool& update_all_time_levels_for_new_node=false);
113 
114  /// \short Pointer to finite element that performs the update by referring
115  /// to its macro-element representation (Access required...)
117  {
118  return Node_update_element_pt;
119  }
120 
121 
122  /// \short Vector of local coordinates of node with the finite element that
123  /// performs the MacroElement-based node update operation
125  {
127  }
128 
129  /// \short Number of geometric objects involved in node update function
130  unsigned ngeom_object() const
131  {
132  return Geom_object_pt.size();
133  }
134 
135  /// \short Vector of (pointers to) geometric objects involved in
136  /// node update function
138  {
139  return Geom_object_pt;
140  }
141 
142 
143  /// \short Pointer to i-th geometric object involved in
144  /// node update function
145  GeomObject* geom_object_pt(const unsigned& i)
146  {
147  return Geom_object_pt[i];
148  }
149 
150 
151  /// \short Return vector of geometric objects involved in
152  /// node update function
154  {
155  return Geom_object_pt;
156  }
157 
158  /// \short Return all geometric objects that affect the node update
160  {
161  if(Geom_object_pt.size() > 0) {return &(Geom_object_pt[0]);}
162  else {return 0;}
163  }
164 
165  /// \short Set node update information for node:
166  /// Pass the pointer to the element that performs the update operation,
167  /// the vector containing the node's local coordinates in that
168  /// element and the vector of (pointers to) the geometric objects
169  /// that affect the node update.
173  {
177  }
178 
179 
180 private:
181 
182  /// \short Pointer to finite element that performs the node update
183  /// by referring to its macro-element representation
185 
186  /// \short Vector containing the node's local coordinates in node update
187  /// element.
189 
190  /// \short Vector of geometric objects that are involved
191  /// in the node update operation
193 
194 };
195 
196 
197 
198 ///////////////////////////////////////////////////////////////////////
199 ///////////////////////////////////////////////////////////////////////
200 // MacroElementNodeUpdate elements
201 ///////////////////////////////////////////////////////////////////////
202 ///////////////////////////////////////////////////////////////////////
203 
204 
205 
206 //========================================================================
207 /// Base class for elements that allow MacroElement-based node update
208 //========================================================================
210 {
211 
212  public:
213 
214  /// Constructor (empty)
216 
217  /// Broken copy constructor
219  {
220  BrokenCopy::broken_copy("MacroElementNodeUpdateElementBase");
221  }
222 
223  /// Broken assignment operator
225  {
226  BrokenCopy::broken_assign("MacroElementNodeUpdateElementBase");
227  }
228 
229  /// Virtual destructor (empty)
231 
232  /// \short Set node update information:
233  /// Pass the vector of (pointers to) the geometric objects
234  /// that affect the node update. This gets passed on to all nodes in
235  /// the element.
237 
238  /// \short Number of geometric objects involved in node update function
239  inline unsigned ngeom_object() {return Geom_object_pt.size();}
240 
241  /// \short Vector of (pointers to) geometric objects involved in
242  /// node update function
244 
245  /// \short Pointer to i-th geometric object involved in
246  /// node update function
247  GeomObject* geom_object_pt(const unsigned& i) {return Geom_object_pt[i];}
248 
249 
250  protected:
251 
252  /// \short Vector of geometric objects that are involved
253  /// in the node update operation
255 
256 };
257 
258 
259 
260 
261 //========================================================================
262 /// MacroElementNodeUpdate elements are elements that can not only be updated
263 /// via their MacroElement representation (in princple any FiniteElement
264 /// could do that...) but also allows the geometric Data contained
265 /// in the GeomObjects that affect the MacroElement-based node update
266 /// operations to be unknowns in the overall Problem.
267 ///
268 /// The element wraps around the ELEMENT specified by the template
269 /// parameter and computes the derivatives of the residual vector
270 /// with respect to the geometric Data (needed in the setup of
271 /// the element's Jacobian matrix) by finite differencing.
272 /// Otherwise the element behaves exactly like the templace element.
273 //========================================================================
274 template<class ELEMENT>
276 public ElementWithSpecificMovingNodes<ELEMENT,MacroElementNodeUpdateNode>,
278 {
279 
280  public:
281 
282  /// Constructor: Call constructor of underlying element
286  { }
287 
288  /// Constructor used for face elements
290  const int &face_index) :
292  element_pt,face_index),
294  { }
295 
296  /// Broken copy constructor
298  {
299  BrokenCopy::broken_copy("MacroElementNodeUpdateElement");
300  }
301 
302  /// Empty destructor to clean up allocated memory
304 
305  /// Broken assignment operator
306  /*void operator=(const MacroElementNodeUpdateElement&)
307  {
308  BrokenCopy::broken_assign("MacroElementNodeUpdateElement");
309  }*/
310 
311  /// \short Set node update information:
312  /// Pass the vector of (pointers to) the geometric objects
313  /// that affect the node update. This gets passed on to all nodes in
314  /// the element.
316  {
317  // Store local copy of geom object vector, so it can be passed on
318  // to son elements (and their nodes) during refinement
319  unsigned ngeom_object=geom_object_pt.size();
320  Geom_object_pt.resize(ngeom_object);
321  for (unsigned i=0;i<ngeom_object;i++)
322  {
323  Geom_object_pt[i]=geom_object_pt[i];
324  }
325 
326  // Loop over nodes in element
327  unsigned n_node = this->nnode();
328  for (unsigned j=0;j<n_node;j++)
329  {
330  // Get local coordinate in element (Vector sets its own size)
332  this->local_coordinate_of_node(j,s_in_node_update_element);
333 
334  // Pass the lot to the node
335  static_cast<MacroElementNodeUpdateNode*>(this->node_pt(j))->
336  set_node_update_info(this,s_in_node_update_element,geom_object_pt);
337  }
338  }
339 
340 
341  /// \short Rebuild after unrefinement: Reset the node update information
342  /// for all nodes so that the nodes get updated by this element.
343  /// If we don't do that, some nodes might still want to be updated
344  /// by elements that no longer exist which leads to the most wonderful
345  /// seg fault... Afterwards, call the template element's own
346  /// rebuild_from_son() function (if it's a RefineableElement)
347  void rebuild_from_sons(Mesh* &mesh_pt)
348  {
349  // First call the element's own rebuild_from_sons() function
350  ELEMENT::rebuild_from_sons(mesh_pt);
351 
352  // Now loop over nodes in element
353  unsigned n_node =this->nnode();
354  for (unsigned j=0;j<n_node;j++)
355  {
356  // Get local coordinate in element (Vector sets its own size)
358  this->local_coordinate_of_node(j,s_in_node_update_element);
359 
360  // Pass the lot to the node
361  static_cast<MacroElementNodeUpdateNode*>(this->node_pt(j))->
362  set_node_update_info(this,s_in_node_update_element,Geom_object_pt);
363  }
364  }
365 
366 
367 };
368 
369 
370 
371 //========================================================================
372 /// MacroElementNodeUpdateMeshes contain MacroElementNodeUpdateNodes
373 /// which have their own node update functions. When the node's
374 /// node_update() function is called, they also perform
375 /// any auxiliary update functions, e.g. to update no-slip boundary
376 /// conditions on moving domain boundaries.
377 //========================================================================
378 class MacroElementNodeUpdateMesh : public virtual Mesh
379 {
380 
381  public:
382 
383  /// Constructor (empty)
385 
386  /// Virtual destructor (empty)
388 
389  /// Broken copy constructor
391  {
392  BrokenCopy::broken_copy("MacroElementNodeUpdateMesh");
393  }
394 
395  /// Broken assignment operator
396  /*void operator=(const MacroElementNodeUpdateMesh&)
397  {
398  BrokenCopy::broken_assign("MacroElementNodeUpdateMesh");
399  }*/
400 
401  /// Access to Macro_domain_pt for MacroElementNodeUpdateMesh; this
402  /// must be filled in by any mesh which inherits from here
404  {
405  return Macro_domain_pt;
406  }
407 
408  /// \short Update all nodal positions via sparse MacroElement-based
409  /// update functions. If a Node is hanging its position is updated
410  /// after updating the position of its masters first.
411  /// [Doesn't make sense to use this mesh with SolidElements anyway,
412  /// so we buffer the case if update_all_solid_nodes is set to
413  /// true.]
414  void node_update(const bool& update_all_solid_nodes=false)
415  {
416 #ifdef PARANOID
417  if (update_all_solid_nodes)
418  {
419  std::string error_message =
420  "Doesn't make sense to use an MacroElementNodeUpdateMesh with\n";
421  error_message +=
422  "SolidElements so specifying update_all_solid_nodes=true\n";
423  error_message += "doesn't make sense either\n";
424 
425  throw OomphLibError(error_message,
426  OOMPH_CURRENT_FUNCTION,
427  OOMPH_EXCEPTION_LOCATION);
428  }
429 #endif
430 
431  // Loop over all nodes and update their positions -- hanging nodes
432  // are updated via their masters; auxiliary update function
433  // is performed by node, too
434  unsigned n_node = nnode();
435  for (unsigned n=0;n<n_node;n++)
436  {
437  MacroElementNodeUpdateNode* nod_pt=dynamic_cast
438  <MacroElementNodeUpdateNode*>(node_pt(n));
439 #ifdef PARANOID
440  if (nod_pt==0)
441  {
442  std::ostringstream error_message;
443  error_message
444  << "Failed to cast to MacroElementNodeUpdateNode.\n"
445  << "Node is of type: " << typeid(node_pt(n)).name() << std::endl;
446 
447  throw OomphLibError(error_message.str(),
448  OOMPH_CURRENT_FUNCTION,
449  OOMPH_EXCEPTION_LOCATION);
450  }
451 #endif
452  nod_pt->node_update();
453  }
454 
455 #ifdef OOMPH_HAS_MPI
456  // Update positions for external halo nodes attached to this mesh
457  // Loop over processors
458  for (std::map<unsigned,Vector<Node*> >::iterator it=
459  External_halo_node_pt.begin();it!=External_halo_node_pt.end();it++)
460  {
461  int iproc=(*it).first;
462  unsigned n_ext_halo_node=nexternal_halo_node(iproc);
463  for (unsigned n=0;n<n_ext_halo_node;n++)
464  {
465  MacroElementNodeUpdateNode* nod_pt=dynamic_cast
466  <MacroElementNodeUpdateNode*>(external_halo_node_pt(iproc,n));
467 #ifdef PARANOID
468  if (nod_pt==0)
469  {
470  std::ostringstream error_message;
471  error_message
472  << "Failed to cast (ext. halo) to MacroElementNodeUpdateNode.\n"
473  << "Node is of type: " << typeid(node_pt(n)).name() << std::endl;
474 
475  throw OomphLibError(error_message.str(),
476  OOMPH_CURRENT_FUNCTION,
477  OOMPH_EXCEPTION_LOCATION);
478  }
479 #endif
480  nod_pt->node_update();
481  }
482  } // end loop over processors
483 #endif // (ifdef OOMPH_HAS_MPI)
484  }
485 
486 #ifdef OOMPH_HAS_MPI
487  /// \short Overload the base class distribute function to deal
488  /// with halo nodes on halo elements that may have pointers
489  /// to macro elements that no longer exist
491  const Vector<unsigned>& element_domain,
492  Vector<GeneralisedElement*>& deleted_element_pt,
493  DocInfo& doc_info,
494  const bool& report_stats,
495  const bool& overrule_keep_as_halo_element_status)
496  {
497  // Call underlying Mesh::distribute first
498  Mesh::distribute(comm_pt,element_domain,deleted_element_pt,
499  doc_info,report_stats,
500  overrule_keep_as_halo_element_status);
501 
502  // Storage for number of processors
503  int n_proc=comm_pt->nproc();
504 
505  // The original call to set_node_update_info on the
506  // non-distributed problem may have set a macro element which no
507  // longer exists for some halo nodes which are on halo elements
508  // within the distributed Mesh; this deals with the problem by
509  // recalling the set_node_update_info for every halo element
510  for (int iproc=0;iproc<n_proc;iproc++)
511  {
512  Vector<GeneralisedElement*> halo_el_pt=halo_element_pt(iproc);
513  unsigned n_halo_el=halo_el_pt.size();
514  for (unsigned e=0;e<n_halo_el;e++)
515  {
516  // Cast to a MacroElementNodeUpdateElement
518  dynamic_cast<MacroElementNodeUpdateElementBase*>(halo_el_pt[e]);
519 
520  // The vector of GeomObjects should not change!
522 
523  // So we can just call set_node_update_info for the element!
524  macro_el_pt->set_node_update_info(geom_object_pt);
525  }
526  }
527 
528  }
529 #endif
530 
531  /// \short Set geometric objects associated with MacroElementNodeUpdateMesh;
532  /// this must also be called from the constructor of each derived mesh
533  void set_geom_object_vector_pt(Vector<GeomObject*> geom_object_vector_pt)
534  {
535  Geom_object_vector_pt=geom_object_vector_pt;
536  }
537 
538  /// \short Access function to the vector of GeomObject
540  {
541  return Geom_object_vector_pt;
542  }
543 
544  private:
545 
546  /// \short Vector of GeomObject associated with MacroElementNodeUpdateNodeMesh
548 
549  /// \short Domain associated with MacroElementNodeUpdateNodeMesh
551 
552 };
553 
554 
555 ///////////////////////////////////////////////////////////////////////
556 ///////////////////////////////////////////////////////////////////////
557 ///////////////////////////////////////////////////////////////////////
558 
559 
560 
561 //=======================================================================
562 /// Explicit definition of the face geometry of MacroElementNodeUpdateElements,
563 /// which is the same as the face geometry of the underlying element
564 //=======================================================================
565 template<class ELEMENT>
567 public virtual FaceGeometry<ELEMENT>
568 {
569  public:
570 
571  /// Constructor calls the constructor of the underlying ELEMENT.
572  FaceGeometry() : FaceGeometry<ELEMENT>() {}
573 
574 };
575 
576 }
577 
578 #endif
579 
580 
virtual void distribute(OomphCommunicator *comm_pt, const Vector< unsigned > &element_domain, Vector< GeneralisedElement *> &deleted_element_pt, DocInfo &doc_info, const bool &report_stats, const bool &overrule_keep_as_halo_element_status)
Distribute the problem and doc; make this virtual to allow overloading for particular meshes where fu...
Definition: mesh.cc:4620
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
Vector< double > S_in_node_update_element
Vector containing the node&#39;s local coordinates in node update element.
MacroElementNodeUpdateMesh(const MacroElementNodeUpdateMesh &)
Broken copy constructor.
void node_update(const bool &update_all_solid_nodes=false)
Update all nodal positions via sparse MacroElement-based update functions. If a Node is hanging its p...
virtual ~MacroElementNodeUpdateNode()
Broken assignment operator.
unsigned ngeom_object()
Number of geometric objects involved in node update function.
Vector< double > & s_in_node_update_element()
Vector of local coordinates of node with the finite element that performs the MacroElement-based node...
Information for documentation of results: Directory and file number to enable output in the form RESL...
cstr elem_len * i
Definition: cfortran.h:607
virtual ~MacroElementNodeUpdateMesh()
Virtual destructor (empty)
Vector< GeomObject * > Geom_object_pt
Vector of geometric objects that are involved in the node update operation.
MacroElementNodeUpdateElementBase(const MacroElementNodeUpdateElementBase &)
Broken copy constructor.
Domain * Macro_domain_pt
Domain associated with MacroElementNodeUpdateNodeMesh.
void set_node_update_info(const Vector< GeomObject *> &geom_object_pt)
Broken assignment operator.
FaceGeometry()
Constructor calls the constructor of the underlying ELEMENT.
A general Finite Element class.
Definition: elements.h:1274
GeomObject * geom_object_pt(const unsigned &i)
Pointer to i-th geometric object involved in node update function.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:852
Vector< GeomObject * > & vector_geom_object_pt()
Return vector of geometric objects involved in node update function.
~MacroElementNodeUpdateElement()
Empty destructor to clean up allocated memory.
e
Definition: cfortran.h:575
Vector< GeomObject * > Geom_object_pt
Vector of geometric objects that are involved in the node update operation.
unsigned ngeom_object() const
Number of geometric objects involved in node update function.
void rebuild_from_sons(Mesh *&mesh_pt)
Rebuild after unrefinement: Reset the node update information for all nodes so that the nodes get upd...
void node_update(const bool &update_all_time_levels_for_new_node=false)
Update the current nodal position. If required, perform the auxiliary update of nodal values...
FiniteElement * Node_update_element_pt
Pointer to finite element that performs the node update by referring to its macro-element representat...
void operator=(const MacroElementNodeUpdateElementBase &)
Broken assignment operator.
Domain *& macro_domain_pt()
Broken assignment operator.
GeomObject * geom_object_pt(const unsigned &i)
Pointer to i-th geometric object involved in node update function.
GeomObject ** all_geom_object_pt()
Return all geometric objects that affect the node update.
FiniteElement *& node_update_element_pt()
Pointer to finite element that performs the update by referring to its macro-element representation (...
Vector< GeomObject * > & geom_object_pt()
Vector of (pointers to) geometric objects involved in node update function.
MacroElementNodeUpdateNode(const unsigned &n_dim, const unsigned &n_position_type, const unsigned &initial_nvalue)
Constructor for steady node of spatial dimension n_dim, with n_position_type generalised coordinates ...
void distribute(OomphCommunicator *comm_pt, const Vector< unsigned > &element_domain, Vector< GeneralisedElement *> &deleted_element_pt, DocInfo &doc_info, const bool &report_stats, const bool &overrule_keep_as_halo_element_status)
Overload the base class distribute function to deal with halo nodes on halo elements that may have po...
void set_node_update_info(FiniteElement *node_update_element_pt, const Vector< double > &s_in_node_update_element, const Vector< GeomObject *> &geom_object_pt)
Set node update information for node: Pass the pointer to the element that performs the update operat...
Base class for elements that allow MacroElement-based node update.
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
MacroElementNodeUpdateElement(const MacroElementNodeUpdateElement &)
Broken copy constructor.
virtual void set_node_update_info(const Vector< GeomObject *> &geom_object_pt)=0
Set node update information: Pass the vector of (pointers to) the geometric objects that affect the n...
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:246
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn&#39;t been defined.
MacroElementNodeUpdateElement(FiniteElement *const &element_pt, const int &face_index)
Constructor used for face elements.
void set_geom_object_vector_pt(Vector< GeomObject *> geom_object_vector_pt)
Set geometric objects associated with MacroElementNodeUpdateMesh; this must also be called from the c...
Vector< GeomObject * > Geom_object_vector_pt
Vector of GeomObject associated with MacroElementNodeUpdateNodeMesh.
Vector< GeomObject * > & geom_object_pt()
Vector of (pointers to) geometric objects involved in node update function.
Base class for Domains with curvilinear and/or time-dependent boundaries. Domain boundaries are typic...
Definition: domain.h:71
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Definition: timesteppers.h:219
virtual ~MacroElementNodeUpdateElementBase()
Virtual destructor (empty)
MacroElementNodeUpdateNode(TimeStepper *time_stepper_pt, const unsigned &n_dim, const unsigned &n_position_type, const unsigned &initial_nvalue)
Constructor for bog-standard node of spatial dimension n_dim, with n_position_type generalised coordi...
Vector< GeomObject * > geom_object_vector_pt()
Access function to the vector of GeomObject.
A general mesh class.
Definition: mesh.h:74
MacroElementNodeUpdateNode(const MacroElementNodeUpdateNode &)
Broken copy constructor.
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
Definition: communicator.h:57
MacroElementNodeUpdateElement()
Constructor: Call constructor of underlying element.