algebraic_elements.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_ALGEBRAIC_ELEMENTS_HEADER
31 #define OOMPH_ALGEBRAIC_ELEMENTS_HEADER
32 
33 #include "geom_objects.h"
34 #include "mesh.h"
35 #include "elements.h"
36 #include "domain.h"
38 
39 namespace oomph
40 {
41 
42 
43 // forward references
44 class AlgebraicMesh;
45 class AlgebraicElementBase;
46 class DummyAlgebraicMesh;
47 
48 
49 ///////////////////////////////////////////////////////////////////////
50 ///////////////////////////////////////////////////////////////////////
51 // Algebraic nodes
52 ///////////////////////////////////////////////////////////////////////
53 ///////////////////////////////////////////////////////////////////////
54 
55 
56 
57 //========================================================================
58 /// Algebraic nodes are nodes with an algebraic positional update
59 /// function.
60 //========================================================================
61 class AlgebraicNode : public Node
62 {
63 
64 
65 public:
66 
67  /// \short Default Constructor
69 
70  /// \short Constructor for steady algebraic node of spatial
71  /// dimension n_dim, with n_position_type generalised coordinates
72  /// and with initial_nvalue dofs.
73  AlgebraicNode(const unsigned &n_dim,
74  const unsigned &n_position_type,
75  const unsigned &initial_nvalue) :
76  Node(n_dim,n_position_type,initial_nvalue)
77  {
78 #ifdef LEAK_CHECK
80 #endif
81 
82  // Add default node update info
83  add_node_update_info(Dummy_node_update_fct_id, // dummy remesh fct ID
84  Dummy_mesh_pt, // dummy mesh
85  Dummy_geom_object_pt, // dummy geom object vector
86  Dummy_ref_value, // dummy ref vector
87  true); // flag indicating call from
88  // constructor
89  }
90 
91 
92  ///\short Constructor for bog-standard algebraic node of spatial
93  /// dimension n_dim, with n_position_type generalised coordinates,
94  /// with initial_nvalue dofs and with time dependence.
96  const unsigned &n_dim,
97  const unsigned &n_position_type,
98  const unsigned &initial_nvalue) :
99  Node(time_stepper_pt,n_dim,n_position_type,initial_nvalue)
100  {
101 #ifdef LEAK_CHECK
103 #endif
104 
105  // Add default node update info
106  add_node_update_info(Dummy_node_update_fct_id, // dummy remesh fct ID
107  Dummy_mesh_pt, // dummy mesh
108  Dummy_geom_object_pt, // dummy geom object vector
109  Dummy_ref_value, // dummy ref vector
110  true); // flag indicating call from
111  // constructor
112  }
113 
114  ///\short Destructor (empty)
115  virtual ~AlgebraicNode()
116  {
117 #ifdef LEAK_CHECK
119 #endif
120  }
121 
122  /// Broken copy constructor
124  {
125  BrokenCopy::broken_copy("AlgebraicNode");
126  }
127 
128  /// Broken assignment operator
129 //Commented out broken assignment operator because this can lead to a conflict warning
130 //when used in the virtual inheritence hierarchy. Essentially the compiler doesn't
131 //realise that two separate implementations of the broken function are the same and so,
132 //quite rightly, it shouts.
133  /*void operator=(const AlgebraicNode&)
134  {
135  BrokenCopy::broken_assign("AlgebraicNode");
136  }*/
137 
138 
139  /// \short Update the current nodal position, using the first
140  /// (default) update function if there are multiple ones. If
141  /// required perform the auxiliary update of nodal values.
142  /// If update_all_time_levels_for_new_node==true, previous
143  /// positions are also updated -- as indicated by the name
144  /// of this flag, this should only be done for newly
145  /// created nodes, when this function is called from
146  /// AlgebraicElementBase::setup_algebraic_node_update(...)
147  void node_update(const bool& update_all_time_levels_for_new_node=false);
148 
149 
150  /// Number of node update fcts
151  unsigned nnode_update_fcts()
152  {
153  // Note: We could read this information out from any one of
154  // various maps that that store the information for the
155  // different node update functions...
156  return Mesh_pt.size();
157  }
158 
159 
160  /// Default (usually first if there are multiple ones) node update fct id
162  {
164  }
165 
166  /// \short Return vector of node update fct ids (vector is
167  /// resized to contain the correct number of entries). Somewhat costly
168  /// to call as map needs to be copied into vector.
170  {
171  // Resize vector
172  id.resize(0);
173 
174  // Loop over all entries and copy them across (again, we could
175  // get this information from any of the maps...)
176  typedef std::map<int,AlgebraicMesh* >::iterator IT;
177  for (IT it=Mesh_pt.begin();it!=Mesh_pt.end();it++)
178  {
179  id.push_back(it->first);
180  }
181  }
182 
183 
184  /// \short Default (usually first) mesh that implements update function
186  {
187  return Default_it_mesh_pt->second;
188  }
189 
190 
191  /// \short Mesh that implements the id-th node update function
192  AlgebraicMesh* mesh_pt(const int& id)
193  {
194  return Mesh_pt[id];
195  }
196 
197 
198  /// \short Number of geometric objects involved in id-th update function
199  unsigned ngeom_object(const int& id)
200  {
201  return Geom_object_pt[id].size();
202  }
203 
204 
205  /// \short Number of geometric objects involved in default (usually first)
206  /// update function
207  unsigned ngeom_object() const
208  {
209  return Default_it_geom_object_pt->second.size();
210  }
211 
212 
213  /// \short Return vector of geometric objects involved in
214  /// id-th update function
216  {
217  return Geom_object_pt[id];
218  }
219 
220 
221  /// \short Return vector of geometric objects involved in
222  /// default (usually first) update function
224  {
225  return Default_it_geom_object_pt->second;
226  }
227 
228 
229  /// \short Return the vector of all geometric objects
231  {
232  if(this->ngeom_object()==0) {return 0;}
233  else {return &(Default_it_geom_object_pt->second[0]);}
234  }
235 
236  /// \short Return pointer to i-th geometric object involved in
237  /// default (usually first) update function
238  GeomObject* geom_object_pt(const unsigned& i)
239  {
240  return Default_it_geom_object_pt->second[i];
241  }
242 
243  /// Number of reference values involved in id-th update function
244  unsigned nref_value(const int& id)
245  {
246  return Ref_value[id].size();
247  }
248 
249 
250  /// \short Number of reference values involved in default
251  /// (usually first) update function
252  unsigned nref_value()
253  {
254  return Default_it_ref_value->second.size();
255  }
256 
257 
258  /// \short Return vector of reference values involved in
259  /// default (usually first) update function
261  {
262  return Default_it_ref_value->second;
263  }
264 
265 
266  /// \short Return vector of reference values involved in
267  /// id-th update function
269  {
270  return Ref_value[id];
271  }
272 
273 
274  /// \short Return i-th reference value involved in
275  /// default (usually first) update function
276  double ref_value(const unsigned& i)
277  {
278  return Default_it_ref_value->second[i];
279  }
280 
281  /// \short Add algebraic update information for node: What's the
282  /// ID of the mesh update function (typically used within the mesh)
283  /// Which Mesh implements the update operation? Also,
284  /// pass the vector of geometric objects and
285  /// the vectors of reference values that are
286  /// needed for the update operation. Negative values for ID are only
287  /// allowed when called from node constructor, as indicated
288  /// by the final argument which defaults to false.
289  void add_node_update_info(const int& id,
292  const Vector<double>& ref_value,
293  const bool& called_from_constructor=false)
294  {
295  // Sanity check
296  if (id<0)
297  {
298  if (!called_from_constructor)
299  {
300  std::ostringstream error_message;
301  error_message
302  << "\nNegative ID, " << id
303  << ", only allowed if called from constructor and\n"
304  << "indicated as such by optional boolean flag."
305  << std::endl;
306  throw OomphLibError(error_message.str(),
307  OOMPH_CURRENT_FUNCTION,
308  OOMPH_EXCEPTION_LOCATION);
309  }
310  }
311 
312  // If there's just one entry -- check if it's the default dummy one
313  if (Mesh_pt.size()==1)
314  {
315  if (Mesh_pt.begin()->second==Dummy_mesh_pt)
316  {
317  if (Default_it_mesh_pt->second==Dummy_mesh_pt)
318  {
320  }
321  }
322  }
323 
324  // Now insert the actual info
325  Mesh_pt.insert(std::make_pair(id,mesh_pt));
326  Geom_object_pt.insert(std::make_pair(id,geom_object_pt));
327  Ref_value.insert(std::make_pair(id,ref_value));
328 
329  // Always use the "first" update fct as default -- can be overwritten
330  // outside (usually only done for self test)
331  set_default_node_update(Mesh_pt.begin()->first);
332  }
333 
334 
335 
336  /// \short Add algebraic update information for node:
337  /// Which Mesh implements the update operation? Also,
338  /// pass the vector of geometric objects and
339  /// the vectors of reference values that are
340  /// needed for the update operation. We're assigning a default
341  /// node update fct id of 0.
344  const Vector<double>& ref_value)
345  {
346  // No update fct id supplied: Use a default assignment of 0.
347  unsigned id=0;
348 
349  // If there's just one entry -- check if it's the default dummy one
350  if (Mesh_pt.size()==1)
351  {
352  // Do we still have dummy default assignment stored as the one
353  // and only entry?
354  if (Mesh_pt.begin()->second==Dummy_mesh_pt)
355  {
356  if (Default_it_mesh_pt->second==Dummy_mesh_pt)
357  {
359  }
360  }
361  }
362 
363  // Now insert the actual info
364  Mesh_pt.insert(std::make_pair(id,mesh_pt));
365  Geom_object_pt.insert(std::make_pair(id,geom_object_pt));
366  Ref_value.insert(std::make_pair(id,ref_value));
367 
368  // Always use the "first" update fct as default -- can be overwritten
369  // outside (usually only done for self test)
370  set_default_node_update(Mesh_pt.begin()->first);
371 
372  }
373 
374 
375  /// \short Erase algebraic node update information for id-th
376  /// node update function. Id defaults to 0.
377  void kill_node_update_info(const int& id=0)
378  {
379  Mesh_pt.erase(Mesh_pt.find(id));
380  Geom_object_pt.erase(Geom_object_pt.find(id));
381  Ref_value.erase(Ref_value.find(id));
382  }
383 
384 
385  /// \short Perform self test: If the node has multiple node
386  /// update functions, check that they all give the same result.
387  /// Return 1/0 for failure/success. (Failure if
388  /// max. difference between the nodal positions for different
389  /// update functions exceeds
390  /// AlgebraicNode::Max_allowed_difference_between_node_update_fcts
391  unsigned self_test();
392 
393 
394 private:
395 
396  /// Make id-th node update function the default
397  void set_default_node_update(const int& id)
398  {
399 
400  // Set default node update fct id
402 
403 
404  // Set iterators for default entry
405 
406  // Iterator to default mesh:
407  Default_it_mesh_pt=Mesh_pt.find(id);
408 #ifdef PARANOID
409  if (Default_it_mesh_pt==Mesh_pt.end())
410  {
411  std::ostringstream error_message;
412  error_message <<
413  "There is no reference mesh for node update fct id" << id << std::endl;
414  throw OomphLibError(error_message.str(),
415  OOMPH_CURRENT_FUNCTION,
416  OOMPH_EXCEPTION_LOCATION);
417  }
418 #endif
419 
420  // Iterator to default GeomObject vector
422 #ifdef PARANOID
423  if (Default_it_geom_object_pt==Geom_object_pt.end())
424  {
425  std::ostringstream error_message;
426  error_message <<
427  "There is no Geom_object_pt for node update fct id" << id << std::endl;
428  throw OomphLibError(error_message.str(),
429  OOMPH_CURRENT_FUNCTION,
430  OOMPH_EXCEPTION_LOCATION);
431  }
432 #endif
433 
434  // Iterator to default values vector
436 #ifdef PARANOID
437  if (Default_it_ref_value==Ref_value.end())
438  {
439  std::ostringstream error_message;
440  error_message <<
441  "There is no Ref_value for node update fct id" << id << std::endl;
442  throw OomphLibError(error_message.str(),
443  OOMPH_CURRENT_FUNCTION,
444  OOMPH_EXCEPTION_LOCATION);
445  }
446 #endif
447 
448  }
449 
450  /// \short Pointer to mesh that performs the specified node update operation
451  /// (Map because this node may only use the Mesh's 116th node update fct.
452  /// There's no point in wasting an entire vector for the non-existing entries)
453  std::map<int,AlgebraicMesh* > Mesh_pt;
454 
455  /// \short Vector of geometric objects that are involved
456  /// in the specified node update operation.
457  /// (Map because this node may only use the Mesh's 116th node update fct.
458  /// There's no point in wasting an entire vector for the non-existing entries)
459  std::map<int,Vector<GeomObject*> > Geom_object_pt;
460 
461  /// \short Vector of reference values that are required
462  /// for the specified node update operation.
463  /// (Map because this node may only use the Mesh's 116th node update fct.
464  /// There's no point in wasting an entire vector for the non-existing entries)
465  std::map<int,Vector<double> > Ref_value;
466 
467  /// Default iterator for mesh: This mesh performs the default update
468  std::map<int,AlgebraicMesh*>::iterator Default_it_mesh_pt;
469 
470  /// \short Default iterator for vector of geom objects. These
471  /// GeomObjects are involved in the default update.
472  std::map<int,Vector<GeomObject*> >::iterator
474 
475  /// Default iterator for vector of ref values. These
476  /// reference values are involved in the default update.
477  std::map<int,Vector<double> >::iterator
479 
480  /// Default node update function ID.
482 
483  /// What it says: Used in self-test to check if different
484  /// node update functions produce the same result.
486 
487  /// \short Default (negative!) remesh fct id for nodes for which no remesh
488  /// fct is defined
490 
491  /// \short Default dummy mesh to point to for nodes for which no remesh
492  /// fct is defined
494 
495  /// \short Static Dummy mesh to which the pointer is addressed
497 
498  /// \short Default dummy vector of geom objects to point to for nodes
499  /// for which no remesh fct is defined
501 
502  /// \short Default dummy vector of reference values
503  /// to point to for nodes for which no remesh fct is defined
505 };
506 
507 
508 ///////////////////////////////////////////////////////////////////////
509 ///////////////////////////////////////////////////////////////////////
510 // Algebraic elements
511 ///////////////////////////////////////////////////////////////////////
512 ///////////////////////////////////////////////////////////////////////
513 
514 
515 
516 //========================================================================
517 /// Base class for algebraic elements.
518 ///
519 //========================================================================
521 {
522 
523  public:
524 
525  /// Empty constructor
527 
528  /// Broken copy constructor
530  {
531  BrokenCopy::broken_copy("AlgebraicElementBase");
532  }
533 
534  /// Broken assignment operator
536  {
537  BrokenCopy::broken_assign("AlgebraicElementBase");
538  }
539 
540  /// \short Set up node update info for (newly created) algebraic node:
541  /// I.e. work out its node update information by interpolation from
542  /// the father element. Pass pointer to father element and the
543  /// newly created node's local coordinate in the father element.
544  void setup_algebraic_node_update(Node*& node_pt,
545  const Vector<double>& s_father,
546  FiniteElement* father_el_pt) const;
547 
548 };
549 
550 
551 
552 
553 //========================================================================
554 /// Algebraic elements are elements that have AlgebraicNodes whose
555 /// position is determined by the geometric Data in the GeomObjects
556 /// that are involved in their node update functions.
557 /// Algebraic Elements include the derivatives w.r.t. any unknowns
558 /// that are stored in this geometric Data into the element's
559 /// Jacobian matrix. Otherwise they behave exactly like the templace
560 /// element.
561 //========================================================================
562 template<class ELEMENT>
564 public ElementWithSpecificMovingNodes<ELEMENT,AlgebraicNode>,
566 {
567 
568  public:
569 
570  /// \short Constructor -- simply calls the constructor of the
571  /// underlying ELEMENT.
575  { }
576 
577  /// Constructor for face elements
578  AlgebraicElement(FiniteElement* const &element_pt,
579  const int &face_index) :
581  element_pt,face_index),
583  { }
584 
585  /// Broken copy constructor
587  {
588  BrokenCopy::broken_copy("AlgebraicElement");
589  }
590 
591  /// Broken assignment operator
592  /*void operator=(const AlgebraicElement&)
593  {
594  BrokenCopy::broken_assign("AlgebraicElement");
595  }*/
596 
597 
598  ///Empty Destructor must clean up the allocated memory
600 
601 };
602 
603 
604 
605 //=======================================================================
606 /// \short Explicit definition of the face geometry of algebraic elements:
607 /// the same as the face geometry of the underlying element
608 //=======================================================================
609 template<class ELEMENT>
611 public virtual FaceGeometry<ELEMENT>
612 {
613  public:
614 
615  /// Constructor
616  FaceGeometry() : FaceGeometry<ELEMENT>() {}
617 
618  protected:
619 };
620 
621 
622 
623 ///////////////////////////////////////////////////////////////////////
624 ///////////////////////////////////////////////////////////////////////
625 // Algebraic meshes
626 ///////////////////////////////////////////////////////////////////////
627 ///////////////////////////////////////////////////////////////////////
628 
629 
630 //========================================================================
631 /// Algebraic meshes contain AlgebraicElements and AlgebraicNodes.
632 /// They implement the node update functions that are used
633 /// by the AlgebraicNodes to update their positions.
634 //========================================================================
635 class AlgebraicMesh : public virtual Mesh
636 {
637 
638  public:
639 
640  /// Constructor: create a null zeroth entry in the Geom_object_list_pt
641  /// Vector (each AlgebraicMesh's constructor should add any other
642  /// geometric objects to this list)
644  {
645  add_geom_object_list_pt(0);
646  }
647 
648  /// Broken copy constructor
650  {
651  BrokenCopy::broken_copy("AlgebraicMesh");
652  }
653 
654  /// Broken assignment operator
655  /*void operator=(const AlgebraicMesh&)
656  {
657  BrokenCopy::broken_assign("AlgebraicMesh");
658  }*/
659 
660  /// Surely a proper destructor is required... ?
662 
663  /// Return a pointer to the n-th global AlgebraicNode
664  //Can safely cast the nodes to AlgebraicNodes
665  AlgebraicNode* node_pt(const unsigned long &n)
666  {
667 #ifdef PARANOID
668  if(!dynamic_cast<AlgebraicNode*>(Node_pt[n]))
669  {
670  std::ostringstream error_stream;
671  error_stream << "Error: Node " << n << "is a "
672  << typeid(Node_pt[n]).name()
673  << ", not an AlgebraicNode" << std::endl;
674  throw OomphLibError(error_stream.str(),
675  OOMPH_CURRENT_FUNCTION,
676  OOMPH_EXCEPTION_LOCATION);
677  }
678 #endif
679  //Return a cast to the Node_pt
680  return (dynamic_cast<AlgebraicNode*>(Node_pt[n]));
681  }
682 
683 
684  /// \short Update the nodal position posn at time level t (t=0: present;
685  /// t>0: previous). Must be implemented for every specific algebraic mesh.
686  virtual void algebraic_node_update(const unsigned& t,
687  AlgebraicNode*& node_pt)=0;
688 
689  /// \short Update the node update info for given node, following
690  /// mesh adaptation. Must be implemented for every specific algebraic
691  /// mesh, though it may, of course, be left empty.
692  virtual void update_node_update(AlgebraicNode*& node_pt)=0;
693 
694 
695  /// \short Update all nodal positions via algebraic node update functions
696  /// [Doesn't make sense to use this mesh with SolidElements anyway,
697  /// so we buffer the case if update_all_solid_nodes is set to
698  /// true.]
699  void node_update(const bool& update_all_solid_nodes=false)
700  {
701 #ifdef PARANOID
702  if (update_all_solid_nodes)
703  {
704  std::string error_message =
705  "Doesn't make sense to use an AlgebraicMesh with\n";
706  error_message +=
707  "SolidElements so specifying update_all_solid_nodes=true\n";
708  error_message += "doesn't make sense either\n";
709 
710  throw OomphLibError(error_message,
711  OOMPH_CURRENT_FUNCTION,
712  OOMPH_EXCEPTION_LOCATION);
713  }
714 #endif
715  // Initial loop over ALL nodes to setup (need to place at least
716  // all master nodes before we can update the position of the
717  // hanging ones)
718  AlgebraicNode* alg_nod_pt=0;
719  unsigned n_node=nnode();
720 
721  // In parallel there may be no nodes on a particular process
722  if (n_node>0)
723  {
724  for (unsigned n=0;n<n_node;n++)
725  {
726  alg_nod_pt=static_cast<AlgebraicNode*>(node_pt(n));
727  alg_nod_pt->node_update();
728  }
729 
730  // Figure out spatial dimension of node
731  unsigned n_dim = alg_nod_pt->ndim();
732 
733  // Now loop over hanging nodes and adjust their nodal positions
734  // to reflect the hanging node constraints
735  for (unsigned n=0;n<n_node;n++)
736  {
737  Node* nod_pt=node_pt(n);
738  if (nod_pt->is_hanging())
739  {
740  // Initialise
741  Vector<double> x(n_dim);
742  for (unsigned i=0;i<n_dim;i++)
743  {
744  x[i]=0.0;
745  }
746 
747  //Loop over master nodes
748  unsigned nmaster=nod_pt->hanging_pt()->nmaster();
749  for (unsigned imaster=0;imaster<nmaster;imaster++)
750  {
751  // Loop over directions
752  for (unsigned i=0;i<n_dim;i++)
753  {
754  x[i]+=nod_pt->hanging_pt()->
755  master_node_pt(imaster)->x(i)*
756  nod_pt->hanging_pt()->master_weight(imaster);
757  }
758  }
759 
760  // Copy across
761  for (unsigned i=0;i<n_dim;i++)
762  {
763  nod_pt->x(i)=x[i];
764  }
766  }
767  }
768  } // end if (n_node>0)
769 
770 #ifdef OOMPH_HAS_MPI
771  // Update positions for external halo nodes attached to this mesh
772  // Loop over processors
773  for (std::map<unsigned,Vector<Node*> >::iterator it=
774  External_halo_node_pt.begin();it!=External_halo_node_pt.end();it++)
775  {
776  int iproc=(*it).first;
777  AlgebraicNode* alg_nod_pt=0;
778  unsigned n_ext_halo_node=nexternal_halo_node(iproc);
779  // Only act if there are any external halo nodes
780  if (n_ext_halo_node>0)
781  {
782  for (unsigned n=0;n<n_ext_halo_node;n++)
783  {
784  alg_nod_pt=static_cast<AlgebraicNode*>
785  (external_halo_node_pt(iproc,n));
786  alg_nod_pt->node_update();
787  }
788 
789  // Figure out spatial dimension of node
790  unsigned n_dim = alg_nod_pt->ndim();
791 
792  // Now loop over hanging nodes and adjust their nodal positions
793  // to reflect the hanging node constraints
794  for (unsigned n=0;n<n_ext_halo_node;n++)
795  {
796  Node* nod_pt=external_halo_node_pt(iproc,n);
797  if (nod_pt->is_hanging())
798  {
799  // Initialise
800  Vector<double> x(n_dim);
801  for (unsigned i=0;i<n_dim;i++)
802  {
803  x[i]=0.0;
804  }
805 
806  //Loop over master nodes
807  unsigned nmaster=nod_pt->hanging_pt()->nmaster();
808  for (unsigned imaster=0;imaster<nmaster;imaster++)
809  {
810  // Loop over directions
811  for (unsigned i=0;i<n_dim;i++)
812  {
813  x[i]+=nod_pt->hanging_pt()->
814  master_node_pt(imaster)->x(i)*
815  nod_pt->hanging_pt()->master_weight(imaster);
816  }
817  }
818 
819  // Copy across
820  for (unsigned i=0;i<n_dim;i++)
821  {
822  nod_pt->x(i)=x[i];
823  }
824  }
825  }
826  }
827 
828  } // end loop over processors
829 #endif
830 
831  }
832 
833  /// \short Self test: check consistentency of multiple node updates.
834  unsigned self_test()
835  {
836 
837  // Initialise
838  bool passed=true;
839 
840  unsigned test=Mesh::self_test();
841  if (test!=0)
842  {
843  passed=false;
844  }
845 
846  //Loop over nodes
847  unsigned n_node=nnode();
848  for (unsigned n=0;n<n_node;n++)
849  {
850  if (static_cast<AlgebraicNode*>(node_pt(n))->self_test()!=0)
851  {
852  passed=false;
853  }
854  }
855 
856  oomph_info << "Done algnode selftest in mesh" << std::endl;
857 
858  // Return verdict
859  if (passed) {return 0;}
860  else {return 1;}
861 
862  }
863 
864  /// \short Add the specified GeomObject to the list of geometric objects
865  /// associated with this AlgebraicMesh; remembering that the zeroth entry
866  /// is null (set in the constructor above)
868  {
869  Geom_object_list_pt.push_back(geom_object_pt);
870  }
871 
872  /// \short Return number of geometric objects associated with AlgebraicMesh
874  {
875  return Geom_object_list_pt.size();
876  }
877 
878  /// \short Access function to the ith GeomObject
879  GeomObject* geom_object_list_pt(const unsigned& i)
880  {
881  // Probably should be a range check in here...
882  return Geom_object_list_pt[i];
883  }
884 
885  private:
886 
887  /// \short Vector of GeomObjects associated with this AlgebraicMesh
888  /// The zeroth entry is null, proper entries from the 1st index onwards...
890 
891 };
892 
893 
894 
895 ///////////////////////////////////////////////////////////////////////
896 ///////////////////////////////////////////////////////////////////////
897 // Dummy algebraic mesh
898 ///////////////////////////////////////////////////////////////////////
899 ///////////////////////////////////////////////////////////////////////
900 
901 
902 //========================================================================
903 /// Dummy algebraic mesh -- used for default assignements
904 //========================================================================
905 class DummyAlgebraicMesh : public virtual AlgebraicMesh
906 {
907 
908  public:
909 
910  /// Empty constructor
912 
913  /// Broken copy constructor
915  {
916  BrokenCopy::broken_copy("DummyAlgebraicMesh");
917  }
918 
919  /// Broken assignment operator
920  /*void operator=(const DummyAlgebraicMesh&)
921  {
922  BrokenCopy::broken_assign("DummyAlgebraicMesh");
923  }*/
924 
925  /// \short Update the nodal position posn at time level t (t=0: present;
926  /// t>0: previous). Do nothing
927  virtual void algebraic_node_update(const unsigned& t,
928  AlgebraicNode*& node_pt) {}
929 
930 
931  /// \short Update the node update info for given node, following
932  /// mesh adaptation. Must be implemented for every specific algebraic
933  /// mesh, though it may, of course, be left empty which is exactly
934  /// what we do here
935  virtual void update_node_update(AlgebraicNode*& node_pt){}
936 
937  /// \short Setup algebraic node update for specified node;
938  /// do nothing in this dummy version
940 
941 
942 
943 
944 };
945 
946 
947 
948 
949 }
950 
951 #endif
952 
953 
AlgebraicElement()
Constructor – simply calls the constructor of the underlying ELEMENT.
~AlgebraicElement()
Broken assignment operator.
void node_update(const bool &update_all_time_levels_for_new_node=false)
Broken assignment operator.
AlgebraicNode * node_pt(const unsigned long &n)
Return a pointer to the n-th global AlgebraicNode.
void add_node_update_info(AlgebraicMesh *mesh_pt, const Vector< GeomObject *> &geom_object_pt, const Vector< double > &ref_value)
Add algebraic update information for node: Which Mesh implements the update operation? Also, pass the vector of geometric objects and the vectors of reference values that are needed for the update operation. We&#39;re assigning a default node update fct id of 0.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
GeomObject * geom_object_pt(const unsigned &i)
Return pointer to i-th geometric object involved in default (usually first) update function...
HangInfo *const & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
Definition: nodes.h:1148
DummyAlgebraicMesh()
Empty constructor.
AlgebraicNode()
Default Constructor.
void kill_node_update_info(const int &id=0)
Erase algebraic node update information for id-th node update function. Id defaults to 0...
cstr elem_len * i
Definition: cfortran.h:607
static Vector< GeomObject * > Dummy_geom_object_pt
Default dummy vector of geom objects to point to for nodes for which no remesh fct is defined...
Vector< double > & vector_ref_value(const int &id)
Return vector of reference values involved in id-th update function.
void perform_auxiliary_node_update_fct()
Execute auxiliary update function (if any) – this can be used to update any nodal values following t...
Definition: nodes.h:1510
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&#39;s the ID of the mesh update function (typically used ...
unsigned nref_value(const int &id)
Number of reference values involved in id-th update function.
static AlgebraicMesh * Dummy_mesh_pt
Default dummy mesh to point to for nodes for which no remesh fct is defined.
A general Finite Element class.
Definition: elements.h:1274
AlgebraicElement(FiniteElement *const &element_pt, const int &face_index)
Constructor for face elements.
void add_geom_object_list_pt(GeomObject *geom_object_pt)
Add the specified GeomObject to the list of geometric objects associated with this AlgebraicMesh; rem...
char t
Definition: cfortran.h:572
GeomObject ** all_geom_object_pt()
Return the vector of all geometric objects.
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
Definition: nodes.h:753
AlgebraicMesh * mesh_pt()
Default (usually first) mesh that implements 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
unsigned nmaster() const
Return the number of master nodes.
Definition: nodes.h:733
unsigned self_test()
Self-test: Check elements and nodes. Return 0 for OK.
Definition: mesh.cc:715
OomphInfo oomph_info
AlgebraicNode(const unsigned &n_dim, const unsigned &n_position_type, const unsigned &initial_nvalue)
Constructor for steady algebraic node of spatial dimension n_dim, with n_position_type generalised co...
bool is_hanging() const
Test whether the node is geometrically hanging.
Definition: nodes.h:1207
unsigned ngeom_object() const
Number of geometric objects involved in default (usually first) update function.
GeomObject * geom_object_list_pt(const unsigned &i)
Access function to the ith GeomObject.
int node_update_fct_id()
Default (usually first if there are multiple ones) node update fct id.
unsigned self_test()
Self test: check consistentency of multiple node updates.
Vector< double > & vector_ref_value()
Return vector of reference values involved in default (usually first) update function.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:992
Vector< GeomObject * > & vector_geom_object_pt()
Return vector of geometric objects involved in default (usually first) update function.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:995
void node_update(const bool &update_all_solid_nodes=false)
Update all nodal positions via algebraic node update functions [Doesn&#39;t make sense to use this mesh w...
unsigned nref_value()
Number of reference values involved in default (usually first) update function.
std::map< int, AlgebraicMesh * >::iterator Default_it_mesh_pt
Default iterator for mesh: This mesh performs the default update.
std::map< int, AlgebraicMesh *> Mesh_pt
Pointer to mesh that performs the specified node update operation (Map because this node may only use...
DummyAlgebraicMesh(const DummyAlgebraicMesh &)
Broken copy constructor.
AlgebraicNode(TimeStepper *time_stepper_pt, const unsigned &n_dim, const unsigned &n_position_type, const unsigned &initial_nvalue)
Constructor for bog-standard algebraic node of spatial dimension n_dim, with n_position_type generali...
static double Max_allowed_difference_between_node_update_fcts
unsigned self_test()
Perform self test: If the node has multiple node update functions, check that they all give the same ...
virtual void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)
Broken assignment operator.
AlgebraicNode(const AlgebraicNode &)
Broken copy constructor.
AlgebraicElementBase()
Empty constructor.
int Default_node_update_fct_id
Default node update function ID.
AlgebraicElementBase(const AlgebraicElementBase &)
Broken copy constructor.
AlgebraicElement(const AlgebraicElement &)
Broken copy constructor.
virtual ~AlgebraicNode()
Destructor (empty)
double ref_value(const unsigned &i)
Return i-th reference value involved in default (usually first) update function.
unsigned ngeom_object_list_pt()
Return number of geometric objects associated with AlgebraicMesh.
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
Dummy algebraic mesh – used for default assignements.
void set_default_node_update(const int &id)
Make id-th node update function the default.
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:246
AlgebraicMesh(const AlgebraicMesh &)
Broken copy constructor.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn&#39;t been defined.
unsigned ngeom_object(const int &id)
Number of geometric objects involved in id-th update function.
static DummyAlgebraicMesh Dummy_mesh
Static Dummy mesh to which the pointer is addressed.
static int Dummy_node_update_fct_id
Default (negative!) remesh fct id for nodes for which no remesh fct is defined.
std::map< int, Vector< double > > Ref_value
Vector of reference values that are required for the specified node update operation. (Map because this node may only use the Mesh&#39;s 116th node update fct. There&#39;s no point in wasting an entire vector for the non-existing entries)
void node_update_fct_id(Vector< int > &id)
Return vector of node update fct ids (vector is resized to contain the correct number of entries)...
virtual void update_node_update(AlgebraicNode *&node_pt)
Update the node update info for given node, following mesh adaptation. Must be implemented for every ...
virtual void setup_algebraic_node_update(AlgebraicNode *&nod_pt)
Setup algebraic node update for specified node; do nothing in this dummy version. ...
void operator=(const AlgebraicElementBase &)
Broken assignment operator.
AlgebraicMesh * mesh_pt(const int &id)
Mesh that implements the id-th node update function.
Vector< GeomObject * > Geom_object_list_pt
Vector of GeomObjects associated with this AlgebraicMesh The zeroth entry is null, proper entries from the 1st index onwards...
~AlgebraicMesh()
Broken assignment operator.
std::map< int, Vector< double > >::iterator Default_it_ref_value
std::map< int, Vector< GeomObject * > > Geom_object_pt
Vector of geometric objects that are involved in the specified node update operation. (Map because this node may only use the Mesh&#39;s 116th node update fct. There&#39;s no point in wasting an entire vector for the non-existing entries)
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Definition: timesteppers.h:219
Vector< GeomObject * > & vector_geom_object_pt(const int &id)
Return vector of geometric objects involved in id-th update function.
A general mesh class.
Definition: mesh.h:74
unsigned nnode_update_fcts()
Number of node update fcts.
std::map< int, Vector< GeomObject * > >::iterator Default_it_geom_object_pt
Default iterator for vector of geom objects. These GeomObjects are involved in the default update...
static Vector< double > Dummy_ref_value
Default dummy vector of reference values to point to for nodes for which no remesh fct is defined...