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