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