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: 1182 $
7 //LIC//
8 //LIC// $LastChangedDate: 2016-05-20 16:50:20 +0100 (Fri, 20 May 2016) $
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
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  {
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)
867  void add_geom_object_list_pt(GeomObject* geom_object_pt)
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
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 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...
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:194
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:590
virtual void update_node_update(AlgebraicNode *&node_pt)=0
Update the node update info for given node, following mesh adaptation. Must be implemented for every ...
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're assigning a default node update fct id of 0.
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 th...
Definition: nodes.h:1509
unsigned nref_value(const int &id)
Number of reference values involved in id-th update function.
unsigned nexternal_halo_node()
Total number of external halo nodes in this Mesh.
Definition: mesh.h:1997
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:1271
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.
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 self_test()
Self-test: Check elements and nodes. Return 0 for OK.
Definition: mesh.cc:715
void setup_algebraic_node_update(Node *&node_pt, const Vector< double > &s_father, FiniteElement *father_el_pt) const
Set up node update info for (newly created) algebraic node: I.e. work out its node update information...
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's the ID of the mesh update function (typically used ...
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
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...
virtual void algebraic_node_update(const unsigned &t, AlgebraicNode *&node_pt)=0
Update the nodal position posn at time level t (t=0: present; t>0: previous). Must be implemented for...
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 nmaster() const
Return the number of master nodes.
Definition: nodes.h:733
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.
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't make sense to use this mesh w...
bool is_hanging() const
Test whether the node is geometrically hanging.
Definition: nodes.h:1207
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...
Node *& external_halo_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th external halo node in this Mesh whose non-halo external counterpart is held on...
Definition: mesh.h:2064
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.
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
Definition: nodes.h:753
AlgebraicNode(const AlgebraicNode &)
Broken copy constructor.
unsigned ngeom_object() const
Number of geometric objects involved in default (usually first) update function.
AlgebraicElementBase()
Empty constructor.
int Default_node_update_fct_id
Default node update function ID.
std::map< unsigned, Vector< Node * > > External_halo_node_pt
Map of vectors holding the pointers to the external halo nodes.
Definition: mesh.h:146
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'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's 116th node update fct. There'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)...
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:992
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's 116th node update fct. There'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...