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-2022 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
35namespace 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 {
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.
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 {
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
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 {
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
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
/////////////////////////////////////////////////////////////////////
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 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.
Vector< GeomObject * > & geom_object_pt()
Vector of (pointers to) geometric objects involved in node update function.
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...
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_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 * > & vector_geom_object_pt()
Return vector of geometric objects involved in node update function.
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.
GeomObject ** all_geom_object_pt()
Return all geometric objects that affect the node update.
GeomObject * geom_object_pt(const unsigned &i)
Pointer to i-th geometric object 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 ...
Vector< double > & s_in_node_update_element()
Vector of local coordinates of node with the finite element that performs the MacroElement-based node...
MacroElementNodeUpdateNode(TimeStepper *time_stepper_pt, const unsigned &n_dim, const unsigned &n_position_type, const unsigned &initial_nvalue)
Constructor for bog-standard node of spatial dimension n_dim, with n_position_type generalised coordi...
Vector< double > S_in_node_update_element
Vector containing the node's local coordinates in node update element.
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.
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...
FiniteElement *& node_update_element_pt()
Pointer to finite element that performs the update by referring to its macro-element representation (...
A general mesh class.
Definition: mesh.h:67
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 nexternal_halo_node()
Total number of external halo nodes in this Mesh.
Definition: mesh.h:2308
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition: mesh.h:436
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
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
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
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.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...