mesh.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-2025 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// Header file for general mesh classes
27
28// Include guards to prevent multiple inclusion of the header
29#ifndef OOMPH_GENERIC_MESH_HEADER
30#define OOMPH_GENERIC_MESH_HEADER
31
32// Config header
33#ifdef HAVE_CONFIG_H
34#include <oomph-lib-config.h>
35#endif
36
37#ifdef OOMPH_HAS_MPI
38#include "mpi.h"
39#endif
40
41#include <float.h>
42#include <list>
43#include <typeinfo>
44#include <string>
45
46// oomph-lib headers
47#include "Vector.h"
48#include "nodes.h"
49#include "elements.h"
50#include "timesteppers.h"
52#include "matrices.h"
53#include "refineable_elements.h"
54
55namespace oomph
56{
57 //=================================================================
58 /// A general mesh class.
59 ///
60 /// The main components of a Mesh are:
61 /// - pointers to its Nodes
62 /// - pointers to its Elements
63 /// - pointers to its boundary Nodes
64 ///
65 //=================================================================
66 class Mesh
67 {
68 public:
69 /// Problem is a friend
70 friend class Problem;
71
72
73 /// Default Steady Timestepper, to be used in default arguments
74 /// to Mesh constructors
76
77
78 protected:
79 /// Vector of Vector of pointers to nodes on the boundaries:
80 /// Boundary_node_pt(b,n). Note that this is private to force
81 /// the use of the add_boundary_node() function, which ensures
82 /// that the reverse look-up schemes for the nodes are set up.
84
85 /// Flag to indicate that the lookup schemes for elements that are adjacent
86 /// to the boundaries has been set up.
88
89 /// Vector of Vector of pointers to elements on the boundaries:
90 /// Boundary_element_pt(b,e)
92
93 /// For the e-th finite element on boundary b, this is the index of
94 /// the face that lies along that boundary
96
97#ifdef OOMPH_HAS_MPI
98
99 /// Map of vectors holding the pointers to the root halo elements
100 std::map<unsigned, Vector<GeneralisedElement*>> Root_halo_element_pt;
101
102 /// Map of vectors holding the pointers to the root haloed elements
103 std::map<unsigned, Vector<GeneralisedElement*>> Root_haloed_element_pt;
104
105 /// Map of vectors holding the pointers to the halo nodes
106 std::map<unsigned, Vector<Node*>> Halo_node_pt;
107
108 /// Map of vectors holding the pointers to the haloed nodes
109 std::map<unsigned, Vector<Node*>> Haloed_node_pt;
110
111 /// Map of vectors holding the pointers to the shared nodes.
112 /// These are all the nodes that are on two "neighbouring" processes
113 /// (the halo(ed) lookup scheme depends upon which processor is in charge
114 /// - a node which is on 3 processors, for example, will not feature in
115 /// the halo(ed) lookup scheme between the two lowest-numbered processors)
116 std::map<unsigned, Vector<Node*>> Shared_node_pt;
117
118 /// Pointer to communicator -- set to NULL if mesh is not distributed
120
121 /// External halo(ed) elements are created as and when they are needed
122 /// to act as source elements for the particular process's mesh.
123 /// The storage is wiped and rebuilt every time the mesh is refined.
124
125 /// Map of vectors holding the pointers to the external halo elements
126 std::map<unsigned, Vector<GeneralisedElement*>> External_halo_element_pt;
127
128 /// Map of vectors holding the pointers to the external haloed elements
129 std::map<unsigned, Vector<GeneralisedElement*>> External_haloed_element_pt;
130
131
132 // External halo(ed) nodes are on the external halo(ed) elements
133
134 /// Map of vectors holding the pointers to the external halo nodes
135 std::map<unsigned, Vector<Node*>> External_halo_node_pt;
136
137 /// Map of vectors holding the pointers to the external haloed nodes
138 std::map<unsigned, Vector<Node*>> External_haloed_node_pt;
139
140 /// bool to indicate whether to keep all elements in a mesh as halos or not
142
143 /// Set this to true to suppress resizing of halo nodes (at your own risk!)
145
146 /// Setup shared node scheme
148
149#endif
150
151 /// Assign the global equation numbers in the Data stored at the
152 /// nodes and also internal element Data. Also, build (via push_back) the
153 /// Vector of pointers to the dofs (variables).
154 unsigned long assign_global_eqn_numbers(Vector<double*>& Dof_pt);
155
156 /// Function to describe the dofs of the Mesh. The ostream
157 /// specifies the output stream to which the description
158 /// is written; the string stores the currently
159 /// assembled output that is ultimately written to the
160 /// output stream by Data::describe_dofs(...); it is typically
161 /// built up incrementally as we descend through the
162 /// call hierarchy of this function when called from
163 /// Problem::describe_dofs(...)
164 void describe_dofs(std::ostream& out,
165 const std::string& current_string) const;
166
167 /// Function to describe the local dofs of the elements. The ostream
168 /// specifies the output stream to which the description
169 /// is written; the string stores the currently
170 /// assembled output that is ultimately written to the
171 /// output stream by Data::describe_dofs(...); it is typically
172 /// built up incrementally as we descend through the
173 /// call hierarchy of this function when called from
174 /// Problem::describe_dofs(...)
175 void describe_local_dofs(std::ostream& out,
176 const std::string& current_string) const;
177
178 /// Assign the local equation numbers in all elements
179 /// If the boolean argument is true then also store pointers to dofs
181
182 /// Vector of pointers to nodes
184
185 /// Vector of pointers to generalised elements
187
188
189 /// A function that upgrades an ordinary node to a boundary node
190 /// We shouldn't ever really use this, but it does make life that
191 /// bit easier for the lazy mesh writer. The pointer to the node is
192 /// replaced by a pointer to the new boundary node in all element look-up
193 /// schemes and in the mesh's Node_pt vector. The new node is also
194 /// addressed by node_pt on return from the function.
197
199
200
201 private:
202 /// Indicate whether the boundary coordinates have been set for the
203 /// specified boundary. Note: Vector of unsigneds to avoid problems with
204 /// vector<bool> 0 = false; 1= true.
206
207
208 public:
209#ifdef OOMPH_HAS_MPI
210
211
212 /// Helper function that resizes halo nodes to the same
213 /// size as their non-halo counterparts if required. (A discrepancy
214 /// can arise if a FaceElement that introduces additional unknowns
215 /// are attached to a bulk element that shares a node with a haloed element.
216 /// In that case the joint node between haloed and non-haloed element
217 /// is resized on that processor but not on the one that holds the
218 /// halo counterpart (because no FaceElement is attached to the halo
219 /// element)
220 void resize_halo_nodes();
221
222#endif
223
224
225 /// Typedef for function pointer to function that computes
226 /// steady exact solution
229
230 /// Typedef for function pointer to function that computes unsteady
231 /// exact solution
234
235 /// Boolean used to control warning about empty mesh level
236 /// timestepper function
238
239 /// Default constructor
241 {
242 // Lookup scheme hasn't been setup yet
244#ifdef OOMPH_HAS_MPI
245 // Set defaults for distributed meshes
246
247 // Mesh hasn't been distributed: Null out pointer to communicator
248 Comm_pt = 0;
249 // Don't keep all objects as halos
251 // Don't output halo elements
252 Output_halo_elements = false;
253 // Don't suppress automatic resizing of halo nodes
255#endif
256 }
257
258 /// Constructor builds combined mesh from the meshes specified.
259 /// Note: This simply merges the meshes' elements and nodes (ignoring
260 /// duplicates; no boundary information etc. is created).
262 {
263#ifdef OOMPH_HAS_MPI
264 // Mesh hasn't been distributed: Null out pointer to communicator
265 Comm_pt = 0;
266#endif
267 // Now merge the meshes
269 }
270
271 /// Merge meshes.
272 /// Note: This simply merges the meshes' elements and nodes (ignoring
273 /// duplicates; no boundary information etc. is created).
275
276 /// Interface for function that is used to setup the boundary
277 /// information (Empty virtual function -- implement this for specific
278 /// Mesh classes)
280
281 /// Setup lookup schemes which establish whic elements are located
282 /// next to mesh's boundaries. Doc in outfile (if it's open).
283 /// (Empty virtual function -- implement this for specific
284 /// Mesh classes)
285 virtual void setup_boundary_element_info(std::ostream& outfile) {}
286
287 /// Virtual function to perform the reset boundary elements info rutines
292 {
293 std::ostringstream error_stream;
294 error_stream << "Empty default reset boundary element info function"
295 << "called.\n";
296 error_stream << "This should be overloaded in a specific "
297 << "TriangleMeshBase\n";
298 throw OomphLibError(error_stream.str(),
299 "Mesh::reset_boundary_element_info()",
301 }
302
303 /// Output boundary coordinates on boundary b -- template argument
304 /// specifies the bulk element type (needed to create FaceElement
305 /// of appropriate type on mesh boundary).
306 template<class BULK_ELEMENT>
307 void doc_boundary_coordinates(const unsigned& b, std::ofstream& the_file)
308 {
309 if (nelement() == 0) return;
311 {
312 oomph_info << "No boundary coordinates were set up for boundary " << b
313 << std::endl;
314 return;
315 }
316
317 // Get spatial dimension
318 unsigned dim = finite_element_pt(0)->node_pt(0)->ndim();
319
320 // Loop over all elements on boundaries
321 unsigned nel = this->nboundary_element(b);
322
323 // Loop over the bulk elements adjacent to boundary b
324 for (unsigned e = 0; e < nel; e++)
325 {
326 // Get pointer to the bulk element that is adjacent to boundary b
328
329 // Find the index of the face of element e along boundary b
330 int face_index = this->face_index_at_boundary(b, e);
331
332 // Create new face element
335
336 // Specify boundary id in bulk mesh (needed to extract
337 // boundary coordinate)
338 el_pt->set_boundary_number_in_bulk_mesh(b);
339
340 // Doc boundary coordinate
341 Vector<double> s(dim - 1);
342 Vector<double> zeta(dim - 1);
343 Vector<double> x(dim);
344 unsigned n_plot = 5;
346
347 // Loop over plot points
349 for (unsigned iplot = 0; iplot < num_plot_points; iplot++)
350 {
351 // Get local coordinates of plot point
355 for (unsigned i = 0; i < dim; i++)
356 {
357 the_file << x[i] << " ";
358 }
359 for (unsigned i = 0; i < (dim - 1); i++)
360 {
361 the_file << zeta[i] << " ";
362 }
363
364 the_file << std::endl;
365 }
367
368 // Cleanup
369 delete el_pt;
370 }
371 }
372
373
374 /// Scale all nodal coordinates by given factor. Virtual
375 /// so it can be overloaded in SolidMesh class where it also
376 /// re-assigns the Lagrangian coordinates.
377 virtual void scale_mesh(const double& factor)
378 {
379 unsigned nnod = this->nnode();
380 unsigned dim = this->node_pt(0)->ndim();
381 for (unsigned j = 0; j < nnod; j++)
382 {
383 Node* nod_pt = this->node_pt(j);
384 for (unsigned i = 0; i < dim; i++)
385 {
386 nod_pt->x(i) *= factor;
387 }
388 }
389 }
390
391 /// Broken copy constructor
392 Mesh(const Mesh& dummy) = delete;
393
394 /// Broken assignment operator
395 void operator=(const Mesh&) = delete;
396
397 /// Virtual Destructor to clean up all memory
398 virtual ~Mesh();
399
400
401 /// Flush storage for elements and nodes by emptying the
402 /// vectors that store the pointers to them. This is
403 /// useful if a particular mesh is only built to generate
404 /// a small part of a bigger mesh. Once the elements and
405 /// nodes have been created, they are typically copied
406 /// into the new mesh and the auxiliary mesh can be
407 /// deleted. However, if we simply call the destructor
408 /// of the auxiliary mesh, it will also wipe out
409 /// the nodes and elements, because it still "thinks"
410 /// it's in charge of these...
416
417 /// Flush storage for elements (only) by emptying the
418 /// vectors that store the pointers to them. This is
419 /// useful if a particular mesh is only built to generate
420 /// a small part of a bigger mesh. Once the elements and
421 /// nodes have been created, they are typically copied
422 /// into the new mesh and the auxiliary mesh can be
423 /// deleted. However, if we simply call the destructor
424 /// of the auxiliary mesh, it will also wipe out
425 /// the nodes and elements, because it still "thinks"
426 /// it's in charge of these...
428 {
429 Element_pt.clear();
430 }
431
432 /// Flush storage for nodes (only) by emptying the
433 /// vectors that store the pointers to them.
435 {
436 Node_pt.clear();
437 }
438
439 /// Return pointer to global node n
440 Node*& node_pt(const unsigned long& n)
441 {
442 return Node_pt[n];
443 }
444
445 /// Return pointer to global node n (const version)
446 Node* node_pt(const unsigned long& n) const
447 {
448 return Node_pt[n];
449 }
450
451 /// Return pointer to element e
452 GeneralisedElement*& element_pt(const unsigned long& e)
453 {
454 return Element_pt[e];
455 }
456
457 /// Return pointer to element e (const version)
458 GeneralisedElement* element_pt(const unsigned long& e) const
459 {
460 return Element_pt[e];
461 }
462
463 /// Return reference to the Vector of elements
465 {
466 return Element_pt;
467 }
468
469 /// Return reference to the Vector of elements
474
475 /// Upcast (downcast?) to FiniteElement
476 /// (needed to access FiniteElement member functions).
477 FiniteElement* finite_element_pt(const unsigned& e) const
478 {
479#ifdef PARANOID
480 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
481 if (el_pt == 0)
482 {
483 // Error
484 throw OomphLibError("Failed cast to FiniteElement* ",
487 // Dummy return to keep intel compiler happy
488 return el_pt;
489 }
490 return el_pt;
491#else
492 return dynamic_cast<FiniteElement*>(Element_pt[e]);
493#endif
494 }
495
496 /// Return pointer to node n on boundary b
497 Node*& boundary_node_pt(const unsigned& b, const unsigned& n)
498 {
499 return Boundary_node_pt[b][n];
500 }
501
502 /// Return pointer to node n on boundary b
503 Node* boundary_node_pt(const unsigned& b, const unsigned& n) const
504 {
505 return Boundary_node_pt[b][n];
506 }
507
508 /// Set the number of boundaries in the mesh
509 void set_nboundary(const unsigned& nbound)
510 {
511 Boundary_node_pt.resize(nbound);
512
513 // 0 is proxy for false
515 }
516
517 /// Clear all pointers to boundary nodes
519
520 /// Remove all information about nodes stored on the b-th
521 /// boundary of the mesh
522 void remove_boundary_nodes(const unsigned& b);
523
524 /// Remove a node from the boundary b
525 void remove_boundary_node(const unsigned& b, Node* const& node_pt);
526
527 /// Add a (pointer to) a node to the b-th boundary
528 void add_boundary_node(const unsigned& b, Node* const& node_pt);
529
530 /// Replace existing boundary node lookup schemes with new schemes created
531 /// using the boundary data stored in the nodes.
533 {
534 // Clear existing boundary data
535 Boundary_node_pt.clear();
536
537 // Loop over nodes adding them to the appropriate boundary lookup schemes
538 // in the mesh.
539 const unsigned n_node = nnode();
540 for (unsigned nd = 0; nd < n_node; nd++)
541 {
542 Node* nd_pt = node_pt(nd);
543
544 if (nd_pt->is_on_boundary())
545 {
546 // Get set of boundaries that the node is on
547 std::set<unsigned>* boundaries_pt;
548 nd_pt->get_boundaries_pt(boundaries_pt);
549
550 // If needed then add more boundaries to this mesh
551 unsigned max_boundary_n =
552 1 + *std::max_element(boundaries_pt->begin(), boundaries_pt->end());
554 {
556 }
557
558 // Add node pointer to the appropriate Boundary_node_pt vectors
559 std::set<unsigned>::const_iterator it;
560 for (it = boundaries_pt->begin(); it != boundaries_pt->end(); it++)
561 {
562 Boundary_node_pt[*it].push_back(nd_pt);
563 }
564 }
565 }
566 }
567
568 /// Indicate whether the i-th boundary has an intrinsic coordinate.
569 // By default, if the array Boundary_coordinate has not been resized,
570 // return false
571 bool boundary_coordinate_exists(const unsigned& i) const
572 {
574 {
575 return false;
576 }
577
578 // 1 is proxy for true
580 }
581
582
583 /// Set boundary coordinate on the i-th boundary to be existing
584 void set_boundary_coordinate_exists(const unsigned& i)
585 {
586 // 1 is proxy for true
588 }
589
590 /// Set boundary coordinate on the i-th boundary to be non-existing
592 {
593 // 0 is proxy for false
595 }
596
597 /// Return number of elements in the mesh
598 unsigned long nelement() const
599 {
600 return Element_pt.size();
601 }
602
603 /// Return number of nodes in the mesh
604 unsigned long nnode() const
605 {
606 return Node_pt.size();
607 }
608
609 /// Return number of dof types in mesh
610 unsigned ndof_types() const;
611
612 /// Return number of elemental dimension in mesh
613 unsigned elemental_dimension() const;
614
615 /// Return number of nodal dimension in mesh
616 unsigned nodal_dimension() const;
617
618 /// Add a (pointer to a) node to the mesh
620 {
621 Node_pt.push_back(node_pt);
622 }
623
624 /// Add a (pointer to) an element to the mesh
626 {
627 Element_pt.push_back(element_pt);
628 }
629
630 /// Update nodal positions in response to changes in the domain
631 /// shape. Uses the FiniteElement::get_x(...) function for FiniteElements
632 /// and doesn't do anything for other element types.
633 /// If a MacroElement pointer has been set for a FiniteElement,
634 /// the MacroElement representation is used to update the
635 /// nodal positions; if not get_x(...) uses the FE interpolation
636 /// and thus leaves the nodal positions unchanged.
637 /// Virtual, so it can be overloaded by specific meshes,
638 /// such as AlgebraicMeshes or SpineMeshes.
639 /// Generally, this function updates the position of all nodes
640 /// in response to changes in the boundary position.
641 /// However, we ignore all SolidNodes since their
642 /// position is computed as part of the solution -- unless
643 /// the bool flag is set to true. Such calls are typically made
644 /// when the initial mesh is created and/or after a mesh has been
645 /// refined repeatedly before the start of the computation.
646 virtual void node_update(const bool& update_all_solid_nodes = false);
647
648 /// Re-order nodes in the order in which they appear in elements --
649 /// can be overloaded for more efficient re-ordering
650 virtual void reorder_nodes(const bool& use_old_ordering = true);
651
652 /// Get a reordering of the nodes in the order in which they
653 /// appear in elements -- can be overloaded for more efficient
654 /// re-ordering
656 const bool& use_old_ordering = true) const;
657
658 /// Constuct a Mesh of FACE_ELEMENTs along the b-th boundary
659 /// of the mesh (which contains elements of type BULK_ELEMENT)
660 template<class BULK_ELEMENT, template<class> class FACE_ELEMENT>
661 void build_face_mesh(const unsigned& b, Mesh* const& face_mesh_pt)
662 {
663 // Find the number of nodes on the boundary
664 unsigned nbound_node = nboundary_node(b);
665 // Loop over the boundary nodes and add them to face mesh node pointer
666 for (unsigned n = 0; n < nbound_node; n++)
667 {
668 face_mesh_pt->add_node_pt(boundary_node_pt(b, n));
669 }
670
671 // Find the number of elements next to the boundary
672 unsigned nbound_element = nboundary_element(b);
673 // Loop over the elements adjacent to boundary b
674 for (unsigned e = 0; e < nbound_element; e++)
675 {
676 // Create the FaceElement
677 FACE_ELEMENT<BULK_ELEMENT>* face_element_pt =
680
681 // Add the face element to the face mesh
682 face_mesh_pt->add_element_pt(face_element_pt);
683 }
684
685#ifdef OOMPH_HAS_MPI
686 // If the bulk mesh has been distributed then the face mesh is too
687 if (this->is_mesh_distributed())
688 {
689 face_mesh_pt->set_communicator_pt(this->communicator_pt());
690 }
691#endif
692 }
693
694 /// Self-test: Check elements and nodes. Return 0 for OK
695 unsigned self_test();
696
697
698 /// Determine max and min area for all FiniteElements in the mesh
699 /// (non-FiniteElements are ignored)
701 {
702 max_size = 0.0;
704 unsigned nel = nelement();
705 for (unsigned e = 0; e < nel; e++)
706 {
707 max_size = std::max(max_size, finite_element_pt(e)->size());
708 min_size = std::min(min_size, finite_element_pt(e)->size());
709 }
710 }
711
712
713 /// Determine the sum of all "sizes" of the FiniteElements in the
714 /// mesh (non-FiniteElements are ignored). This gives the length/area/volume
715 /// occupied by the mesh
716 double total_size()
717 {
718 double size = 0.0;
719 unsigned nel = nelement();
720 for (unsigned e = 0; e < nel; e++)
721 {
723 if (fe_pt != 0)
724 {
725 size += fe_pt->size();
726 }
727 }
728 return size;
729 }
730
731
732 /// Check for inverted elements and report outcome
733 /// in boolean variable. This visits all elements at their
734 /// integration points and checks if the Jacobian of the
735 /// mapping between local and global coordinates is positive --
736 /// using the same test that would be carried out (but only in PARANOID
737 /// mode) during the assembly of the elements' Jacobian matrices.
738 /// Inverted elements are output in inverted_element_file (if the
739 /// stream is open).
741 std::ofstream& inverted_element_file);
742
743
744 /// Check for inverted elements and report outcome
745 /// in boolean variable. This visits all elements at their
746 /// integration points and checks if the Jacobian of the
747 /// mapping between local and global coordinates is positive --
748 /// using the same test that would be carried out (but only in PARANOID
749 /// mode) during the assembly of the elements' Jacobian matrices.
756
757
758 /// Check for repeated nodes within a given spatial tolerance.
759 /// Return (0/1) for (pass/fail).
760 unsigned check_for_repeated_nodes(const double& epsilon = 1.0e-12)
761 {
762 oomph_info << "\n\nStarting check for repeated nodes...";
763 bool failed = false;
764 unsigned nnod = nnode();
765 for (unsigned j = 0; j < nnod; j++)
766 {
767 Node* nod1_pt = this->node_pt(j);
768 unsigned dim = nod1_pt->ndim();
769 for (unsigned k = j + 1; k < nnod; k++)
770 {
771 Node* nod2_pt = this->node_pt(k);
772 double dist = 0.0;
773 for (unsigned i = 0; i < dim; i++)
774 {
775 dist += pow((nod1_pt->x(i) - nod2_pt->x(i)), 2);
776 }
777 dist = sqrt(dist);
778 if (dist < epsilon)
779 {
780 oomph_info << "\n\nRepeated node!" << std::endl;
781 oomph_info << "Distance between nodes " << j << " and " << k
782 << std::endl;
783 oomph_info << "is " << dist << " which is less than the"
784 << std::endl;
785 oomph_info << "permitted distance of " << epsilon << std::endl
786 << std::endl;
787 oomph_info << "The offending nodes are located at: " << std::endl;
788 for (unsigned i = 0; i < dim; i++)
789 {
790 oomph_info << nod1_pt->x(i) << " ";
791 }
792 if (nod1_pt->is_a_copy() || nod2_pt->is_a_copy())
793 {
794 oomph_info << "\n\n[NOTE: message issued as diagonistic rather "
795 "than an error\n"
796 << " because at least one of the nodes is a copy; you "
797 "may still\n"
798 << " want to check this out. BACKGROUND: Copied nodes "
799 "share the same Data but\n"
800 << " will, in general, have different spatial "
801 "positions (e.g. when used\n"
802 << " as periodic nodes); however there are cases when "
803 "they are located\n"
804 << " at the same spatial position (e.g. in "
805 "oomph-lib's annular mesh which\n"
806 << " is a rolled-around version of the rectangular "
807 "quadmesh). In such cases,\n"
808 << " the nodes could have been deleted and completely "
809 "replaced by \n"
810 << " pointers to existing nodes, but may have been "
811 "left there for convenience\n"
812 << " or out of laziness...]\n";
813 }
814 else
815 {
816 failed = true;
817 }
818 oomph_info << std::endl << std::endl;
819 }
820 }
821 }
822 if (failed) return 1;
823
824 // If we made it to here, we must have passed the test.
825 oomph_info << "...done: Test passed!" << std::endl << std::endl;
826 return 0;
827 }
828
829 /// Prune nodes. Nodes that have been marked as obsolete are removed
830 /// from the mesh (and its boundary-node scheme). Returns vector
831 /// of pointers to deleted nodes.
833
834 /// Return number of boundaries
835 unsigned nboundary() const
836 {
837 return Boundary_node_pt.size();
838 }
839
840 /// Return number of nodes on a particular boundary
841 unsigned long nboundary_node(const unsigned& ibound) const
842 {
843 return Boundary_node_pt[ibound].size();
844 }
845
846
847 /// Return pointer to e-th finite element on boundary b
849 const unsigned& e) const
850 {
851#ifdef PARANOID
853 {
854 throw OomphLibError("Lookup scheme for elements next to boundary "
855 "hasn't been set up yet!\n",
858 }
859#endif
860 return Boundary_element_pt[b][e];
861 }
862
863
864 /// Find a node not on any boundary in mesh_pt (useful for pinning
865 /// a single node in a purely Neumann problem so that it is fully
866 /// determined).
868 {
869 for (unsigned nd = 0, nnd = nnode(); nd < nnd; nd++)
870 {
871 if (!(node_pt(nd)->is_on_boundary()))
872 {
873 return node_pt(nd);
874 }
875 }
876
877 std::ostringstream error_msg;
878 error_msg << "No non-boundary nodes in the mesh.";
879 throw OomphLibError(
881 // Never get here!
882 return 0;
883 }
884
885 /// Return number of finite elements that are adjacent to boundary b
886 unsigned nboundary_element(const unsigned& b) const
887 {
888#ifdef PARANOID
890 {
891 throw OomphLibError("Lookup scheme for elements next to boundary "
892 "hasn't been set up yet!\n",
895 }
896#endif
897 return Boundary_element_pt[b].size();
898 }
899
900
901 /// For the e-th finite element on boundary b, return int to indicate
902 /// the face_index of the face adjacent to the boundary. This is consistent
903 /// with input required during the generation of FaceElements.
904 int face_index_at_boundary(const unsigned& b, const unsigned& e) const
905 {
906#ifdef PARANOID
908 {
909 throw OomphLibError("Lookup scheme for elements next to boundary "
910 "hasn't been set up yet!\n",
913 }
914#endif
915 return Face_index_at_boundary[b][e];
916 }
917
918 /// Dump the data in the mesh into a file for restart
919 virtual void dump(std::ofstream& dump_file,
920 const bool& use_old_ordering = true) const;
921
922 /// Dump the data in the mesh into a file for restart
923 void dump(const std::string& dump_file_name,
924 const bool& use_old_ordering = true) const
925 {
926 std::ofstream dump_stream(dump_file_name.c_str());
927#ifdef PARANOID
928 if (!dump_stream.is_open())
929 {
930 std::string err = "Couldn't open file " + dump_file_name;
931 throw OomphLibError(
933 }
934#endif
936 }
937
938 /// Read solution from restart file
939 virtual void read(std::ifstream& restart_file);
940
941
942 /// Output in paraview format into specified file. Breaks up each
943 /// element into sub-elements for plotting purposes. We assume
944 /// that all elements are of the same type (fct will break
945 /// break (in paranoid mode) if paraview output fcts of the
946 /// elements are inconsistent).
947 void output_paraview(std::ofstream& file_out, const unsigned& nplot) const;
948
949 /// Output in paraview format into specified file. Breaks up each
950 /// element into sub-elements for plotting purposes. We assume
951 /// that all elements are of the same type (fct will break
952 /// break (in paranoid mode) if paraview output fcts of the
953 /// elements are inconsistent).
955 std::ofstream& file_out,
956 const unsigned& nplot,
958
959 /// Output in paraview format into specified file. Breaks up each
960 /// element into sub-elements for plotting purposes. We assume
961 /// that all elements are of the same type (fct will break
962 /// break (in paranoid mode) if paraview output fcts of the
963 /// elements are inconsistent).
965 std::ofstream& file_out,
966 const unsigned& nplot,
967 const double& time,
969
970 /// Output for all elements
971 void output(std::ostream& outfile);
972
973 /// Output at f(n_plot) points in each element
974 void output(std::ostream& outfile, const unsigned& n_plot);
975
976 /// Output for all elements (C-style output)
977 void output(FILE* file_pt);
978
979 /// Output at f(n_plot) points in each element (C-style output)
980 void output(FILE* file_pt, const unsigned& nplot);
981
982 /// Output for all elements
983 void output(const std::string& output_filename)
984 {
985 std::ofstream outfile;
986 outfile.open(output_filename.c_str());
988 outfile.close();
989 }
990
991 /// Output at f(n_plot) points in each element
992 void output(const std::string& output_filename, const unsigned& n_plot)
993 {
994 std::ofstream outfile;
995 outfile.open(output_filename.c_str());
997 outfile.close();
998 }
999
1000 /// Output a given Vector function at f(n_plot) points in each element
1001 void output_fct(std::ostream& outfile,
1002 const unsigned& n_plot,
1004
1005 /// Output a given time-dep. Vector function at f(n_plot) points in
1006 /// each element
1007 void output_fct(std::ostream& outfile,
1008 const unsigned& n_plot,
1009 const double& time,
1011
1012 /// Output the nodes on the boundaries (into separate tecplot zones)
1013 void output_boundaries(std::ostream& outfile);
1014
1015 /// Output the nodes on the boundaries (into separate tecplot zones).
1016 /// Specify filename
1017 void output_boundaries(const std::string& output_filename)
1018 {
1019 std::ofstream outfile;
1020 outfile.open(output_filename.c_str());
1022 outfile.close();
1023 }
1024
1025 /// Assign initial values for an impulsive start
1027
1028 /// Shift time-dependent data along for next timestep:
1029 /// Deal with nodal Data/positions and the element's internal
1030 /// Data
1031 void shift_time_values();
1032
1033
1034 /// Calculate predictions for all Data and positions associated
1035 /// with the mesh, usually used in adaptive time-stepping.
1036 void calculate_predictions();
1037
1038 /// Set the timestepper associated with all nodal and elemental
1039 /// data stored in the mesh.
1041 TimeStepper* const& time_stepper_pt, const bool& preserve_existing_data)
1042 {
1043 this->set_nodal_time_stepper(time_stepper_pt, preserve_existing_data);
1044 this->set_elemental_internal_time_stepper(time_stepper_pt,
1046 }
1047
1048 /// Function that can be used to set any additional timestepper data
1049 /// stored at the Mesh (as opposed to nodal and elemental) levels. This
1050 /// is virtual so that it can be overloaded in the appropriate Meshes.
1051 /// Examples include the SpineMeshes and adaptive triangle and tet meshes
1052 virtual void set_mesh_level_time_stepper(
1053 TimeStepper* const& time_stepper_pt, const bool& preserve_existing_data);
1054
1055 /// Set consistent values for pinned data in continuation
1058
1059 /// Does the double pointer correspond to any mesh data
1061
1062 /// Set the timestepper associated with the nodal data in the mesh
1063 void set_nodal_time_stepper(TimeStepper* const& time_stepper_pt,
1064 const bool& preserve_existing_data);
1065
1066 /// Set the timestepper associated with the internal data stored
1067 /// within elements in the meah
1069 TimeStepper* const& time_stepper_pt, const bool& preserve_existing_data);
1070
1071 /// Compute norm of solution by summing contributions of
1072 /// compute_norm(...) for all constituent elements in the mesh.
1073 /// What that norm means depends on what's defined in the element's
1074 /// function; may need to take the square root afterwards if the elements
1075 /// compute the square of the L2 norm, say.
1076 virtual void compute_norm(double& norm)
1077 {
1078 // Initialse the norm
1079 norm = 0.0;
1080
1081 // Per-element norm
1082 double el_norm = 0;
1083
1084 // Loop over the elements
1085 unsigned long n_element = Element_pt.size();
1086 for (unsigned long e = 0; e < n_element; e++)
1087 {
1089
1090#ifdef OOMPH_HAS_MPI
1091 // Compute error for each non-halo element
1092 if (!(el_pt->is_halo()))
1093#endif
1094 {
1096 }
1097 norm += el_norm;
1098 }
1099 }
1100
1101
1102 /// Compute norm of solution by summing contributions of
1103 /// compute_norm(...) for all constituent elements in the mesh.
1104 /// What that norm means depends on what's defined in the element's
1105 /// function; may need to take the square root afterwards if the elements
1106 /// compute the square of the L2 norm, say.
1107 virtual void compute_norm(Vector<double>& norm)
1108 {
1109 // How many unknowns are there?
1110 unsigned n_entry = norm.size();
1111
1112 // Initialse the norm
1113 norm.initialise(0.0);
1114
1115 // Per-element norm
1117
1118 // How many elements are there?
1119 unsigned long n_element = Element_pt.size();
1120
1121 // Loop over the elements
1122 for (unsigned long e = 0; e < n_element; e++)
1123 {
1124 // Get a pointer to the e-th generalised element
1126
1127#ifdef OOMPH_HAS_MPI
1128 // Compute error for each non-halo element
1129 if (!(el_pt->is_halo()))
1130#endif
1131 {
1132 // Compute the elemental norm
1134 }
1135
1136 // Loop over the norm vector entries
1137 for (unsigned i = 0; i < n_entry; i++)
1138 {
1139 // Update the norm of the i-th component
1140 norm[i] += el_norm[i];
1141 }
1142 } // for (unsigned long e=0;e<n_element;e++)
1143 } // End of compute_norm
1144
1145
1146 /// Plot error when compared against a given exact solution.
1147 /// Also returns the norm of the error and that of the exact solution
1148 virtual void compute_error(
1149 std::ostream& outfile,
1151 const double& time,
1152 double& error,
1153 double& norm)
1154 {
1155 // Initialse the norm and error
1156 norm = 0.0;
1157 error = 0.0;
1158 // Per-element norm and error
1159 double el_error, el_norm;
1160
1161 // Loop over the elements
1162 unsigned long Element_pt_range = Element_pt.size();
1163 for (unsigned long e = 0; e < Element_pt_range; e++)
1164 {
1165 // Try to cast to FiniteElement
1166 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1167 if (el_pt == 0)
1168 {
1169 throw OomphLibError(
1170 "Can't execute compute_error(...) for non FiniteElements",
1173 }
1174
1175 // Reset elemental errors and norms
1176 el_norm = 0.0;
1177 el_error = 0.0;
1178#ifdef OOMPH_HAS_MPI
1179 // Compute error for each non-halo element
1180 if (!(el_pt->is_halo()))
1181#endif
1182 {
1184 }
1185 // Add each element error to the global errors
1186 norm += el_norm;
1187 error += el_error;
1188 }
1189 }
1190
1191 /// Plot error when compared against a given time-depdendent
1192 /// exact solution. Also returns the norm of the error and
1193 /// that of the exact solution
1194 virtual void compute_error(
1195 std::ostream& outfile,
1197 double& error,
1198 double& norm)
1199 {
1200 // Initialise norm and error
1201 norm = 0.0;
1202 error = 0.0;
1203 // Per-element norm and error
1204 double el_error, el_norm;
1205
1206 // Loop over the elements
1207 unsigned long Element_pt_range = Element_pt.size();
1208 for (unsigned long e = 0; e < Element_pt_range; e++)
1209 {
1210 // Try to cast to FiniteElement
1211 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1212 if (el_pt == 0)
1213 {
1214 throw OomphLibError(
1215 "Can't execute compute_error(...) for non FiniteElements",
1218 }
1219 // Reset elemental errors and norms
1220 el_norm = 0.0;
1221 el_error = 0.0;
1222 // Calculate the elemental errors for each non-halo element
1223#ifdef OOMPH_HAS_MPI
1224 if (!(el_pt->is_halo()))
1225#endif
1226 {
1228 }
1229 // Add each elemental error to the global error
1230 norm += el_norm;
1231 error += el_error;
1232 }
1233 }
1234
1235
1236 /// Plot error when compared against a given time-dependent
1237 /// exact solution. Also returns the norm of the error and
1238 /// that of the exact solution
1239 virtual void compute_error(
1241 double& error,
1242 double& norm)
1243 {
1244 // Initialise norm and error
1245 norm = 0.0;
1246 error = 0.0;
1247
1248 // Per-element norm and error
1249 double el_error, el_norm;
1250
1251 // Loop over the elements
1252 unsigned long Element_pt_range = Element_pt.size();
1253 for (unsigned long e = 0; e < Element_pt_range; e++)
1254 {
1255 // Try to cast to FiniteElement
1256 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1257 if (el_pt == 0)
1258 {
1259 throw OomphLibError(
1260 "Can't execute compute_error(...) for non FiniteElements",
1263 }
1264
1265 // Reset elemental errors and norms
1266 el_norm = 0.0;
1267 el_error = 0.0;
1268
1269 // Calculate the elemental errors for each non-halo element
1270#ifdef OOMPH_HAS_MPI
1271 if (!(el_pt->is_halo()))
1272#endif
1273 {
1275 }
1276
1277 // Add each elemental error to the global error
1278 norm += el_norm;
1279 error += el_error;
1280 }
1281 } // End of compute_error
1282
1283
1284 /// Plot error when compared against a given time-dependent
1285 /// exact solution. Also returns the norm of the error and
1286 /// that of the exact solution
1287 virtual void compute_error(
1290 Vector<double>& norm)
1291 {
1292 // Initialise norm vector entries
1293 norm.initialise(0.0);
1294
1295 // Initialise error vector entries
1296 error.initialise(0.0);
1297
1298 // Norm vector size
1299 unsigned n_norm = norm.size();
1300
1301 // Error vector size
1302 unsigned n_error = error.size();
1303
1304 // Per-element norm and error
1306
1307 // Per-element norm and error
1309
1310 // How many elements are there?
1311 unsigned long element_pt_range = Element_pt.size();
1312
1313 // Loop over the elements
1314 for (unsigned long e = 0; e < element_pt_range; e++)
1315 {
1316 // Try to cast to FiniteElement
1317 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1318 if (el_pt == 0)
1319 {
1320 throw OomphLibError(
1321 "Can't execute compute_error(...) for non FiniteElements",
1324 }
1325
1326 // Re-initialise norm vector entries
1327 el_norm.initialise(0.0);
1328
1329 // Re-initialise error vector entries
1330 el_error.initialise(0.0);
1331
1332 // Calculate the elemental errors for each non-halo element
1333#ifdef OOMPH_HAS_MPI
1334 if (!(el_pt->is_halo()))
1335#endif
1336 {
1338 }
1339
1340 // Add each elemental norm contribution to the global norm
1341 for (unsigned i = 0; i < n_norm; i++)
1342 {
1343 norm[i] += el_norm[i];
1344 }
1345
1346 // Add each elemental error contribution to the global error
1347 for (unsigned i = 0; i < n_error; i++)
1348 {
1349 error[i] += el_error[i];
1350 }
1351 } // for (unsigned long e=0;e<element_pt_range;e++)
1352 } // End of compute_error
1353
1354
1355 /// Plot error when compared against a given time-depdendent
1356 /// exact solution. Also returns the norm of the error and
1357 /// that of the exact solution. Version with vectors of norms and errors so
1358 /// that different variables' norms and errors can be returned individually
1359 virtual void compute_error(
1360 std::ostream& outfile,
1362 const double& time,
1364 Vector<double>& norm)
1365 {
1366 // Initialise norm and error
1367 unsigned n_error = error.size();
1368 unsigned n_norm = norm.size();
1369 for (unsigned i = 0; i < n_error; i++)
1370 {
1371 error[i] = 0.0;
1372 }
1373 for (unsigned i = 0; i < n_norm; i++)
1374 {
1375 norm[i] = 0.0;
1376 }
1377 // Per-element norm and error
1379
1380 // Loop over the elements
1381 unsigned long Element_pt_range = Element_pt.size();
1382 for (unsigned long e = 0; e < Element_pt_range; e++)
1383 {
1384 // Try to cast to FiniteElement
1385 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1386 if (el_pt == 0)
1387 {
1388 throw OomphLibError(
1389 "Can't execute compute_error(...) for non FiniteElements",
1392 }
1393 // Reset elemental errors and norms
1394 for (unsigned i = 0; i < n_error; i++)
1395 {
1396 el_error[i] = 0.0;
1397 }
1398 for (unsigned i = 0; i < n_norm; i++)
1399 {
1400 el_norm[i] = 0.0;
1401 }
1402 // Calculate the elemental errors for each non-halo element
1403#ifdef OOMPH_HAS_MPI
1404 if (!(el_pt->is_halo()))
1405#endif
1406 {
1408 }
1409 // Add each elemental error to the global error
1410 for (unsigned i = 0; i < n_error; i++)
1411 {
1412 error[i] += el_error[i];
1413 }
1414 for (unsigned i = 0; i < n_norm; i++)
1415 {
1416 norm[i] += el_norm[i];
1417 }
1418 }
1419 }
1420
1421 /// Plot error when compared against a given time-depdendent
1422 /// exact solution. Also returns the norm of the error and
1423 /// that of the exact solution. Version with vectors of norms and errors so
1424 /// that different variables' norms and errors can be returned individually
1425 virtual void compute_error(
1426 std::ostream& outfile,
1429 Vector<double>& norm)
1430 {
1431 // Initialise norm and error
1432 unsigned n_error = error.size();
1433 unsigned n_norm = norm.size();
1434 for (unsigned i = 0; i < n_error; i++)
1435 {
1436 error[i] = 0.0;
1437 }
1438 for (unsigned i = 0; i < n_norm; i++)
1439 {
1440 norm[i] = 0.0;
1441 }
1442 // Per-element norm and error
1444
1445 // Loop over the elements
1446 unsigned long Element_pt_range = Element_pt.size();
1447 for (unsigned long e = 0; e < Element_pt_range; e++)
1448 {
1449 // Try to cast to FiniteElement
1450 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1451 if (el_pt == 0)
1452 {
1453 throw OomphLibError(
1454 "Can't execute compute_error(...) for non FiniteElements",
1457 }
1458 // Reset elemental errors and norms
1459 for (unsigned i = 0; i < n_error; i++)
1460 {
1461 el_error[i] = 0.0;
1462 }
1463 for (unsigned i = 0; i < n_norm; i++)
1464 {
1465 el_norm[i] = 0.0;
1466 }
1467 // Calculate the elemental errors for each non-halo element
1468#ifdef OOMPH_HAS_MPI
1469 if (!(el_pt->is_halo()))
1470#endif
1471 {
1473 }
1474 // Add each elemental error to the global error
1475 for (unsigned i = 0; i < n_error; i++)
1476 {
1477 error[i] += el_error[i];
1478 }
1479 for (unsigned i = 0; i < n_norm; i++)
1480 {
1481 norm[i] += el_norm[i];
1482 }
1483 }
1484 }
1485
1486 /// Returns the norm of the error and that of the exact solution
1487 virtual void compute_error(
1489 const double& time,
1490 double& error,
1491 double& norm)
1492 {
1493 // Initialse the norm and error
1494 norm = 0.0;
1495 error = 0.0;
1496 // Per-element norm and error
1497 double el_error, el_norm;
1498
1499 // Loop over the elements
1500 unsigned long Element_pt_range = Element_pt.size();
1501 for (unsigned long e = 0; e < Element_pt_range; e++)
1502 {
1503 // Try to cast to FiniteElement
1504 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1505 if (el_pt == 0)
1506 {
1507 throw OomphLibError(
1508 "Can't execute compute_error(...) for non FiniteElements",
1511 }
1512
1513 // Reset elemental errors and norms
1514 el_norm = 0.0;
1515 el_error = 0.0;
1516#ifdef OOMPH_HAS_MPI
1517 // Compute error for each non-halo element
1518 if (!(el_pt->is_halo()))
1519#endif
1520 {
1522 }
1523 // Add each element error to the global errors
1524 norm += el_norm;
1525 error += el_error;
1526 }
1527 }
1528
1529
1530 /// Returns the norm of the error and that of the exact solution.
1531 /// Version with vectors of norms and errors so that different variables'
1532 /// norms and errors can be returned individually
1533 virtual void compute_error(
1535 const double& time,
1537 Vector<double>& norm)
1538 {
1539 // Initialise norm and error
1540 unsigned n_error = error.size();
1541 unsigned n_norm = norm.size();
1542 for (unsigned i = 0; i < n_error; i++)
1543 {
1544 error[i] = 0.0;
1545 }
1546 for (unsigned i = 0; i < n_norm; i++)
1547 {
1548 norm[i] = 0.0;
1549 }
1550 // Per-element norm and error
1552
1553 // Loop over the elements
1554 unsigned long Element_pt_range = Element_pt.size();
1555 for (unsigned long e = 0; e < Element_pt_range; e++)
1556 {
1557 // Try to cast to FiniteElement
1558 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1559 if (el_pt == 0)
1560 {
1561 throw OomphLibError(
1562 "Can't execute compute_error(...) for non FiniteElements",
1565 }
1566 // Reset elemental errors and norms
1567 for (unsigned i = 0; i < n_error; i++)
1568 {
1569 el_error[i] = 0.0;
1570 }
1571 for (unsigned i = 0; i < n_norm; i++)
1572 {
1573 el_norm[i] = 0.0;
1574 }
1575 // Calculate the elemental errors for each non-halo element
1576#ifdef OOMPH_HAS_MPI
1577 if (!(el_pt->is_halo()))
1578#endif
1579 {
1581 }
1582 // Add each elemental error to the global error
1583 for (unsigned i = 0; i < n_error; i++)
1584 {
1585 error[i] += el_error[i];
1586 }
1587 for (unsigned i = 0; i < n_norm; i++)
1588 {
1589 norm[i] += el_norm[i];
1590 }
1591 } // for (unsigned long e=0;e<Element_pt_range;e++)
1592 } // End of compute_error
1593
1594
1595 /// Boolean to indicate if Mesh has been distributed
1597 {
1598#ifdef OOMPH_HAS_MPI
1599 return communicator_pt() != 0;
1600#else
1601 // Can't be distributed without mpi
1602 return false;
1603#endif
1604 }
1605
1606 /// Read-only access fct to communicator (Null if mesh is not distributed,
1607 /// i.e. if we don't have mpi).
1609 {
1610#ifdef OOMPH_HAS_MPI
1611 return Comm_pt;
1612#else
1613 return 0;
1614#endif
1615 }
1616
1617
1618#ifdef OOMPH_HAS_MPI
1619
1620 /// Function to set communicator (mesh is assumed to be distributed if the
1621 /// communicator pointer is non-null). Only defined if mpi is enabled
1622 /// becaus Comm_pt itself is only defined when mpi is enabled.
1624 {
1625 Comm_pt = comm_pt;
1626 }
1627
1628 /// Call this function to keep all the elements as halo elements
1633
1634 /// Calll this function to unset the flag that keeps all elements
1635 /// in the mesh as halo elements
1640
1641 /// Distribute the problem and doc; make this virtual to allow
1642 /// overloading for particular meshes where further work is required.
1643 /// Add to vector of pointers to deleted elements.
1644 virtual void distribute(OomphCommunicator* comm_pt,
1647 DocInfo& doc_info,
1648 const bool& report_stats,
1650
1651 /// Distribute the problem
1652 /// Add to vector of pointers to deleted elements.
1656 const bool& report_stats = false)
1657 {
1658 DocInfo doc_info;
1659 doc_info.disable_doc();
1661 return distribute(comm_pt,
1664 doc_info,
1667 }
1668
1669 /// (Irreversibly) prune halo(ed) elements and nodes, usually
1670 /// after another round of refinement, to get rid of
1671 /// excessively wide halo layers. Note that the current
1672 /// mesh will be now regarded as the base mesh and no unrefinement
1673 /// relative to it will be possible once this function
1674 /// has been called.
1677 const bool& report_stats = false)
1678 {
1679 DocInfo doc_info;
1680 doc_info.disable_doc();
1682 }
1683
1684
1685 /// (Irreversibly) prune halo(ed) elements and nodes, usually
1686 /// after another round of refinement, to get rid of
1687 /// excessively wide halo layers. Note that the current
1688 /// mesh will be now regarded as the base mesh and no unrefinement
1689 /// relative to it will be possible once this function
1690 /// has been called.
1693 DocInfo& doc_info,
1694 const bool& report_stats);
1695
1696 /// Get efficiency of mesh distribution: In an ideal distribution
1697 /// without halo overhead, each processor would only hold its own
1698 /// elements. Efficieny per processor = (number of non-halo elements)/
1699 /// (total number of elements).
1701 double& max_efficiency,
1702 double& min_efficiency);
1703
1704 /// Doc the mesh distribution, to be processed with tecplot macros
1705 void doc_mesh_distribution(DocInfo& doc_info);
1706
1707 /// Check halo and shared schemes on the mesh
1708 void check_halo_schemes(DocInfo& doc_info,
1710
1711 /// Classify the halo and haloed nodes in the mesh. Virtual
1712 /// so it can be overloaded to perform additional functionality
1713 /// (such as synchronising hanging nodes) in refineable meshes, say.
1714 virtual void classify_halo_and_haloed_nodes(DocInfo& doc_info,
1715 const bool& report_stats);
1716
1717 /// Classify the halo and haloed nodes in the mesh. Virtual
1718 /// so it can be overloaded to perform additional functionality
1719 /// (such as synchronising hanging nodes) in refineable meshes, say.
1721 const bool& report_stats = false)
1722 {
1723 DocInfo doc_info;
1724 doc_info.disable_doc();
1726 }
1727
1728 /// Synchronise shared node lookup schemes to cater for the
1729 /// the case where:
1730 /// (1) a certain node on the current processor is halo with proc p
1731 /// (i.e. its non-halo counterpart lives on processor p)
1732 /// (2) that node is also exists (also as a halo) on another processor
1733 /// (q, say) where its non-halo counter part is also known to be
1734 /// on processor p.
1735 /// However, without calling this function the current processor does not
1736 /// necessarily know that it shares a node with processor q. This
1737 /// information can be required, e.g. when synchronising hanging node
1738 /// schemes over all processors.
1739 void synchronise_shared_nodes(const bool& report_stats);
1740
1741
1742 /// Get all the halo data stored in the mesh and add pointers to
1743 /// the data to the map, indexed by global equation number
1744 void get_all_halo_data(std::map<unsigned, double*>& map_of_halo_data);
1745
1746 /// Return vector of halo elements in this Mesh
1747 /// whose non-halo counterpart is held on processor p.
1749 {
1750 // Prepare vector
1752
1753 // Loop over all root halo elements
1754 unsigned nelem = nroot_halo_element(p);
1755 for (unsigned e = 0; e < nelem; e++)
1756 {
1758
1759 // Is it a refineable element?
1761 if (ref_el_pt != 0)
1762 {
1763 // Vector of pointers to leaves in tree emanating from
1764 // current root halo element
1766 ref_el_pt->tree_pt()->stick_leaves_into_vector(leaf_pt);
1767
1768 // Loop over leaves and add their objects (the finite elements)
1769 // to vector
1770 unsigned nleaf = leaf_pt.size();
1771 for (unsigned l = 0; l < nleaf; l++)
1772 {
1773 vec_el_pt.push_back(leaf_pt[l]->object_pt());
1774 }
1775 }
1776 else
1777 {
1778 vec_el_pt.push_back(el_pt);
1779 }
1780 }
1781 return vec_el_pt;
1782 }
1783
1784
1785 /// Return vector of haloed elements in this Mesh
1786 /// whose haloing counterpart is held on processor p.
1788 {
1789 // Prepare vector
1791
1792 // Loop over all root haloed elements
1793 unsigned nelem = nroot_haloed_element(p);
1794 for (unsigned e = 0; e < nelem; e++)
1795 {
1797
1798 // Is it a refineable element?
1800 if (ref_el_pt != 0)
1801 {
1802 // Vector of pointers to leaves in tree emanating from
1803 // current root haloed element
1805 ref_el_pt->tree_pt()->stick_leaves_into_vector(leaf_pt);
1806
1807 // Loop over leaves and add their objects (the finite elements)
1808 // to vector
1809 unsigned nleaf = leaf_pt.size();
1810 for (unsigned l = 0; l < nleaf; l++)
1811 {
1812 vec_el_pt.push_back(leaf_pt[l]->object_pt());
1813 }
1814 }
1815 else
1816 {
1817 vec_el_pt.push_back(el_pt);
1818 }
1819 }
1820 return vec_el_pt;
1821 }
1822
1823 /// Total number of non-halo elements in this mesh (Costly call
1824 /// computes result on the fly)
1826 {
1827 unsigned count = 0;
1828 unsigned n = nelement();
1829 for (unsigned e = 0; e < n; e++)
1830 {
1831 if (!(element_pt(e)->is_halo())) count++;
1832 }
1833 return count;
1834 }
1835
1836
1837 /// Total number of root halo elements in this Mesh
1839 {
1840 unsigned n = 0;
1841 for (std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
1842 Root_halo_element_pt.begin();
1843 it != Root_halo_element_pt.end();
1844 it++)
1845 {
1846 n += it->second.size();
1847 }
1848 return n;
1849 }
1850
1851
1852 /// Number of root halo elements in this Mesh whose non-halo
1853 /// counterpart is held on processor p.
1854 unsigned nroot_halo_element(const unsigned& p)
1855 {
1856 return Root_halo_element_pt[p].size();
1857 }
1858
1859
1860 /// Vector of pointers to root halo elements in this Mesh
1861 /// whose non-halo counterpart is held on processor p.
1863 {
1864 return Root_halo_element_pt[p];
1865 }
1866
1867
1868 /// Access fct to the e-th root halo element in this Mesh
1869 /// whose non-halo counterpart is held on processor p.
1871 const unsigned& e)
1872 {
1873 return Root_halo_element_pt[p][e];
1874 }
1875
1876
1877 /// Add root halo element whose non-halo counterpart is held
1878 /// on processor p to this Mesh.
1880 {
1881 Root_halo_element_pt[p].push_back(el_pt);
1882 el_pt->set_halo(p);
1883 }
1884
1885 /// Total number of halo nodes in this Mesh
1886 unsigned nhalo_node()
1887 {
1888 unsigned n = 0;
1889 for (std::map<unsigned, Vector<Node*>>::iterator it =
1890 Halo_node_pt.begin();
1891 it != Halo_node_pt.end();
1892 it++)
1893 {
1894 n += it->second.size();
1895 }
1896 return n;
1897 }
1898
1899 /// Number of halo nodes in this Mesh whose non-halo counterpart
1900 /// is held on processor p.
1901 unsigned nhalo_node(const unsigned& p)
1902 {
1903 // Memory saving version of: return Halo_node_pt[p].size();
1904 std::map<unsigned, Vector<Node*>>::iterator it = Halo_node_pt.find(p);
1905 if (it == Halo_node_pt.end())
1906 {
1907 return 0;
1908 }
1909 return (*it).second.size();
1910 }
1911
1912 /// Add halo node whose non-halo counterpart is held
1913 /// on processor p to the storage scheme for halo nodes.
1914 void add_halo_node_pt(const unsigned& p, Node*& nod_pt)
1915 {
1916 Halo_node_pt[p].push_back(nod_pt);
1917 }
1918
1919
1920 /// Access fct to the j-th halo node in this Mesh
1921 /// whose non-halo counterpart is held on processor p.
1922 Node* halo_node_pt(const unsigned& p, const unsigned& j)
1923 {
1924 return Halo_node_pt[p][j];
1925 }
1926
1927
1928 /// Total number of root haloed elements in this Mesh
1930 {
1931 unsigned n = 0;
1932 for (std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
1933 Root_haloed_element_pt.begin();
1934 it != Root_haloed_element_pt.end();
1935 it++)
1936 {
1937 n += it->second.size();
1938 }
1939 return n;
1940 }
1941
1942 /// Number of root haloed elements in this Mesh whose non-halo
1943 /// counterpart is held on processor p.
1944 unsigned nroot_haloed_element(const unsigned& p)
1945 {
1946 // Memory saving version of: return Root_haloed_element_pt[p].size();
1947 std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
1949 if (it == Root_haloed_element_pt.end())
1950 {
1951 return 0;
1952 }
1953 return (*it).second.size();
1954 }
1955
1956
1957 /// Vector of pointers to root haloed elements in this Mesh
1958 /// whose non-halo counterpart is held on processor p.
1960 {
1961 // Memory saving version of: return Root_haloed_element_pt[p];
1962 std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
1964 if (it == Root_haloed_element_pt.end())
1965 {
1967 return tmp;
1968 }
1969 return (*it).second;
1970 }
1971
1972 /// Access fct to the e-th root haloed element in this Mesh
1973 /// whose non-halo counterpart is held on processor p.
1975 const unsigned& e)
1976 {
1977 return Root_haloed_element_pt[p][e];
1978 }
1979
1980 /// Add root haloed element whose non-halo counterpart is held
1981 /// on processor p to the storage scheme for haloed elements.
1982 /// Note: This does not add the element to the storage scheme
1983 /// for elements as it's understood to naturally live on this
1984 /// processor anyway!
1985 void add_root_haloed_element_pt(const unsigned& p,
1987 {
1988 Root_haloed_element_pt[p].push_back(el_pt);
1989 }
1990
1991
1992 /// Total number of haloed nodes in this Mesh
1993 unsigned nhaloed_node()
1994 {
1995 unsigned n = 0;
1996 for (std::map<unsigned, Vector<Node*>>::iterator it =
1997 Haloed_node_pt.begin();
1998 it != Haloed_node_pt.end();
1999 it++)
2000 {
2001 n += it->second.size();
2002 }
2003 return n;
2004 }
2005
2006
2007 /// Number of haloed nodes in this Mesh whose haloed counterpart
2008 /// is held on processor p.
2009 unsigned nhaloed_node(const unsigned& p)
2010 {
2011 // Memory saving version of: return Haloed_node_pt[p].size();
2012 std::map<unsigned, Vector<Node*>>::iterator it = Haloed_node_pt.find(p);
2013 if (it == Haloed_node_pt.end())
2014 {
2015 return 0;
2016 }
2017 return (*it).second.size();
2018 }
2019
2020 /// Access fct to the j-th haloed node in this Mesh
2021 /// whose halo counterpart is held on processor p.
2022 Node* haloed_node_pt(const unsigned& p, const unsigned& j)
2023 {
2024 return Haloed_node_pt[p][j];
2025 }
2026
2027 /// Add haloed node whose halo counterpart is held
2028 /// on processor p to the storage scheme for haloed nodes.
2029 void add_haloed_node_pt(const unsigned& p, Node*& nod_pt)
2030 {
2031 Haloed_node_pt[p].push_back(nod_pt);
2032 }
2033
2034 /// Bool for output of halo elements
2036
2037
2038 /// Function to suppress resizing of halo nodes -- optmisation
2039 /// but call it at your own risk!
2044
2045
2046 /// Function to (re-)enable resizing of halo nodes -- this returns
2047 /// things to the default behaviour.
2052
2053 /// Function to disable halo element output
2055 {
2056 Output_halo_elements = false;
2057 }
2058
2059 /// Function to enable halo element output
2061 {
2062 Output_halo_elements = true;
2063 }
2064
2065 /// Total number of shared nodes in this Mesh
2066 unsigned nshared_node()
2067 {
2068 unsigned n = 0;
2069 for (std::map<unsigned, Vector<Node*>>::iterator it =
2070 Shared_node_pt.begin();
2071 it != Shared_node_pt.end();
2072 it++)
2073 {
2074 n += it->second.size();
2075 }
2076 return n;
2077 }
2078
2079 /// Doc shared nodes
2081 {
2082 for (std::map<unsigned, Vector<Node*>>::iterator it =
2083 Shared_node_pt.begin();
2084 it != Shared_node_pt.end();
2085 it++)
2086 {
2087 unsigned n = it->second.size();
2088 for (unsigned j = 0; j < n; j++)
2089 {
2090 oomph_info << "Shared node with proc " << it->first << " ";
2091 Node* nod_pt = it->second[j];
2092 unsigned ndim = nod_pt->ndim();
2093 for (unsigned i = 0; i < ndim; i++)
2094 {
2095 oomph_info << nod_pt->x(i) << " ";
2096 }
2097 oomph_info << nod_pt->is_hanging() << " ";
2098 oomph_info << j << " " << nod_pt << std::endl;
2099 }
2100 }
2101 }
2102
2103 /// Number of shared nodes in this Mesh who have a counterpart
2104 /// on processor p.
2105 unsigned nshared_node(const unsigned& p)
2106 {
2107 // Memory saving version of: return Shared_node_pt[p].size();
2108 std::map<unsigned, Vector<Node*>>::iterator it = Shared_node_pt.find(p);
2109 if (it == Shared_node_pt.end())
2110 {
2111 return 0;
2112 }
2113 return (*it).second.size();
2114 }
2115
2116 /// Access fct to the j-th shared node in this Mesh
2117 /// who has a counterpart on processor p.
2118 Node* shared_node_pt(const unsigned& p, const unsigned& j)
2119 {
2120 return Shared_node_pt[p][j];
2121 }
2122
2123 /// Get vector of pointers to shared nodes with processor p.
2124 /// Required for faster search in
2125 /// Missing_masters_functions::add_external_haloed_node_helper() and
2126 /// Missing_masters_functions::add_external_haloed_master_node_helper()
2128 {
2129 unsigned np = nshared_node(p);
2131 for (unsigned j = 0; j < np; j++)
2132 {
2134 }
2135 }
2136
2137
2138 /// Add shared node whose counterpart is held
2139 /// on processor p to the storage scheme for shared nodes.
2140 /// (NB: ensure that this routine is called twice, once for each process)
2141 void add_shared_node_pt(const unsigned& p, Node*& nod_pt)
2142 {
2143 Shared_node_pt[p].push_back(nod_pt);
2144 }
2145
2146 /// Get halo node stats for this distributed mesh:
2147 /// Average/max/min number of halo nodes over all processors.
2148 /// \b Careful: Involves MPI Broadcasts and must therefore
2149 /// be called on all processors!
2150 void get_halo_node_stats(double& av_number,
2151 unsigned& max_number,
2152 unsigned& min_number);
2153
2154 /// Get haloed node stats for this distributed mesh:
2155 /// Average/max/min number of haloed nodes over all processors.
2156 /// \b Careful: Involves MPI Broadcasts and must therefore
2157 /// be called on all processors!
2158 void get_haloed_node_stats(double& av_number,
2159 unsigned& max_number,
2160 unsigned& min_number);
2161
2162 // External halo(ed) elements are "source/other" elements which are
2163 // on different processes to the element for which they are the source
2164
2165 /// Output all external halo elements
2167 const unsigned& n_plot = 5)
2168 {
2169 for (std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
2172 it++)
2173 {
2174 unsigned p = (*it).first;
2176 }
2177 }
2178
2179 /// Output all external halo elements with processor p
2180 void output_external_halo_elements(const unsigned& p,
2181 std::ostream& outfile,
2182 const unsigned& n_plot = 5)
2183 {
2184 unsigned nel = External_halo_element_pt[p].size();
2185 for (unsigned e = 0; e < nel; e++)
2186 {
2188 dynamic_cast<FiniteElement*>(External_halo_element_pt[p][e]);
2189 if (fe_pt != 0)
2190 {
2192 }
2193 }
2194 }
2195
2196
2197 /// Output all external haloed elements
2199 const unsigned& n_plot = 5)
2200 {
2201 for (std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
2204 it++)
2205 {
2206 unsigned p = (*it).first;
2208 }
2209 }
2210
2211 /// Output all external haloed elements with processor p
2213 std::ostream& outfile,
2214 const unsigned& n_plot = 5)
2215 {
2216 unsigned nel = External_haloed_element_pt[p].size();
2217 for (unsigned e = 0; e < nel; e++)
2218 {
2220 dynamic_cast<FiniteElement*>(External_haloed_element_pt[p][e]);
2221 if (fe_pt != 0)
2222 {
2224 }
2225 }
2226 }
2227
2228
2229 /// Total number of external halo elements in this Mesh
2231 {
2232 unsigned n = 0;
2233 for (std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
2236 it++)
2237 {
2238 n += it->second.size();
2239 }
2240 return n;
2241 }
2242
2243 /// Number of external halo elements in this Mesh whose non-halo
2244 /// counterpart is held on processor p.
2245 unsigned nexternal_halo_element(const unsigned& p)
2246 {
2247 // Memory saving version of: return External_halo_element_pt[p].size();
2248 std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
2250 if (it == External_halo_element_pt.end())
2251 {
2252 return 0;
2253 }
2254 return (*it).second.size();
2255 }
2256
2257 /// Access fct to the e-th external halo element in this Mesh
2258 /// whose non-halo counterpart is held on processor p.
2260 const unsigned& e)
2261 {
2262 return External_halo_element_pt[p][e];
2263 }
2264
2265 /// Add external halo element whose non-halo counterpart is held
2266 /// on processor p to this Mesh.
2267 void add_external_halo_element_pt(const unsigned& p,
2269 {
2270 External_halo_element_pt[p].push_back(el_pt);
2271 el_pt->set_halo(p);
2272 }
2273
2274 /// Total number of external haloed elements in this Mesh
2276 {
2277 unsigned n = 0;
2278 for (std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
2281 it++)
2282 {
2283 n += it->second.size();
2284 }
2285 return n;
2286 }
2287
2288 /// Number of external haloed elements in this Mesh whose non-halo
2289 /// counterpart is held on processor p.
2290 unsigned nexternal_haloed_element(const unsigned& p)
2291 {
2292 // Memory saving version of: return External_haloed_element_pt[p].size();
2293 std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
2295 if (it == External_haloed_element_pt.end())
2296 {
2297 return 0;
2298 }
2299 return (*it).second.size();
2300 }
2301
2302 /// Access fct to the e-th external haloed element in this Mesh
2303 /// whose non-halo counterpart is held on processor p.
2305 const unsigned& e)
2306 {
2308 }
2309
2310 /// Add external haloed element whose non-halo counterpart is held
2311 /// on processor p to the storage scheme for haloed elements.
2312 unsigned add_external_haloed_element_pt(const unsigned& p,
2314
2315 /// Total number of external halo nodes in this Mesh
2317 {
2318 unsigned n = 0;
2319 for (std::map<unsigned, Vector<Node*>>::iterator it =
2320 External_halo_node_pt.begin();
2321 it != External_halo_node_pt.end();
2322 it++)
2323 {
2324 n += it->second.size();
2325 }
2326 return n;
2327 }
2328
2329
2330 /// Get vector of pointers to all external halo nodes
2332 {
2333 unsigned n_total = nexternal_halo_node();
2335 for (std::map<unsigned, Vector<Node*>>::iterator it =
2336 External_halo_node_pt.begin();
2337 it != External_halo_node_pt.end();
2338 it++)
2339 {
2340 unsigned np = (it->second).size();
2341 for (unsigned j = 0; j < np; j++)
2342 {
2343 external_halo_node_pt.push_back((it->second)[j]);
2344 }
2345 }
2346#ifdef PARANOID
2347 if (external_halo_node_pt.size() != n_total)
2348 {
2349 std::ostringstream error_stream;
2350 error_stream << "Total number of external halo nodes, " << n_total
2351 << " doesn't match number of entries \n in vector, "
2352 << external_halo_node_pt.size() << std::endl;
2353 throw OomphLibError(
2355 }
2356#endif
2357 }
2358
2359
2360 /// Number of external halo nodes in this Mesh whose non-halo
2361 /// (external) counterpart is held on processor p.
2362 unsigned nexternal_halo_node(const unsigned& p)
2363 {
2364 // Memory saving version of: return External_halo_node_pt[p].size();
2365 std::map<unsigned, Vector<Node*>>::iterator it =
2367 if (it == External_halo_node_pt.end())
2368 {
2369 return 0;
2370 }
2371 return (*it).second.size();
2372 }
2373
2374 /// Add external halo node whose non-halo (external) counterpart
2375 /// is held on processor p to the storage scheme for halo nodes.
2376 void add_external_halo_node_pt(const unsigned& p, Node*& nod_pt)
2377 {
2378 External_halo_node_pt[p].push_back(nod_pt);
2379 nod_pt->set_halo(p);
2380 }
2381
2382
2383 /// Access fct to the j-th external halo node in this Mesh
2384 /// whose non-halo external counterpart is held on processor p.
2385 Node*& external_halo_node_pt(const unsigned& p, const unsigned& j)
2386 {
2387 return External_halo_node_pt[p][j];
2388 }
2389
2390 /// Access fct to vector of external halo node in this Mesh
2391 /// whose non-halo external counterpart is held on processor p. (read only)
2393 {
2394 std::map<unsigned, Vector<Node*>>::iterator it =
2396 if (it == External_halo_node_pt.end())
2397 {
2399 return tmp;
2400 }
2401 return (*it).second;
2402 }
2403
2404 /// Set vector of external halo node in this Mesh
2405 /// whose non-halo external counterpart is held on processor p.
2411
2412 /// Null out specified external halo node (used when deleting duplicates)
2413 void null_external_halo_node(const unsigned& p, Node* nod_pt);
2414
2415 /// Consolidate external halo node storage by removing nulled out
2416 /// pointes in external halo and haloed schemes
2418
2419 /// Total number of external haloed nodes in this Mesh
2421 {
2422 unsigned n = 0;
2423 for (std::map<unsigned, Vector<Node*>>::iterator it =
2425 it != External_haloed_node_pt.end();
2426 it++)
2427 {
2428 n += it->second.size();
2429 }
2430 return n;
2431 }
2432
2433 /// Number of external haloed nodes in this Mesh
2434 /// whose halo (external) counterpart is held on processor p.
2435 unsigned nexternal_haloed_node(const unsigned& p)
2436 {
2437 // Memory saving version of: return External_haloed_node_pt[p].size();
2438 std::map<unsigned, Vector<Node*>>::iterator it =
2440 if (it == External_haloed_node_pt.end())
2441 {
2442 return 0;
2443 }
2444 return (*it).second.size();
2445 }
2446
2447 /// Access fct to the j-th external haloed node in this Mesh
2448 /// whose halo external counterpart is held on processor p.
2449 Node*& external_haloed_node_pt(const unsigned& p, const unsigned& j)
2450 {
2451 return External_haloed_node_pt[p][j];
2452 }
2453
2454 /// Add external haloed node whose halo (external) counterpart
2455 /// is held on processor p to the storage scheme for haloed nodes.
2456 unsigned add_external_haloed_node_pt(const unsigned& p, Node*& nod_pt);
2457
2458 /// Access fct to vector of external haloed node in this Mesh
2459 /// whose halo external counterpart is held on processor p. (read only)
2461 {
2462 std::map<unsigned, Vector<Node*>>::iterator it =
2464 if (it == External_haloed_node_pt.end())
2465 {
2467 return tmp;
2468 }
2469 return (*it).second;
2470 }
2471
2472 /// Set vector of external haloed node in this Mesh
2473 /// whose halo external counterpart is held on processor p.
2479
2480 /// Return the set of processors that hold external halo nodes. This
2481 /// is required to avoid having to pass a communicator into the node_update
2482 /// functions for Algebraic-based and MacroElement-based Meshes
2483 std::set<int> external_halo_proc()
2484 {
2485 std::set<int> procs;
2486 for (std::map<unsigned, Vector<Node*>>::iterator it =
2487 External_halo_node_pt.begin();
2488 it != External_halo_node_pt.end();
2489 it++)
2490 {
2491 procs.insert((*it).first);
2492 }
2493 return procs;
2494 }
2495
2496 /// Creates the shared boundaries, only used in unstructured meshes
2497 /// In this case with the "TriangleMesh" class
2499 OomphCommunicator* comm_pt,
2503 std::map<Data*, std::set<unsigned>>& processors_associated_with_data,
2505 {
2506 std::ostringstream error_stream;
2507 error_stream << "Empty default create_shared_boundaries() method"
2508 << "called.\n";
2509 error_stream << "This should be overloaded in a specific "
2510 << "TriangleMeshBase\n";
2511 throw OomphLibError(error_stream.str(),
2512 "Mesh::create_shared_boundaries()",
2514 }
2515
2516 // Check if necessary to add the element as haloed or if it has been
2517 // previously added to the haloed scheme
2519 const unsigned& p, GeneralisedElement*& el_pt)
2520 {
2521 std::ostringstream error_stream;
2522 error_stream << "Empty default try_to_add_root_haloed_element_pt() method"
2523 << "called.\n";
2524 error_stream << "This should be overloaded in a specific "
2525 << "TriangleMeshBase\n";
2526 throw OomphLibError(error_stream.str(),
2527 "Mesh::try_to_add_root_haloed_element_pt()",
2529 }
2530
2531 // Check if necessary to add the node as haloed or if it has been
2532 // previously added to the haloed scheme
2533 virtual unsigned try_to_add_haloed_node_pt(const unsigned& p, Node*& nod_pt)
2534 {
2535 std::ostringstream error_stream;
2536 error_stream << "Empty default try_to_add_haloed_node_pt() method"
2537 << "called.\n";
2538 error_stream << "This should be overloaded in a specific "
2539 << "TriangleMeshBase\n";
2540 throw OomphLibError(error_stream.str(),
2541 "Mesh::try_to_add_haloed_node_pt()",
2543 }
2544
2545#endif
2546
2547 /// Wipe the storage for all externally-based elements
2549 };
2550
2551
2552 //////////////////////////////////////////////////////////////////////////
2553 //////////////////////////////////////////////////////////////////////////
2554 //////////////////////////////////////////////////////////////////////////
2555
2556 class SolidICProblem;
2557
2558 //========================================================================
2559 /// General SolidMesh class.
2560 ///
2561 /// Solid meshes contain SolidFiniteElements which contain
2562 /// SolidNodes. This class simply overloads the appropriate access
2563 /// functions from the underlying Mesh class.
2564 //
2565 // Needs to be derived from Mesh with virtual so that
2566 // solid meshes can be derived from general meshes, without
2567 // multiple copies of Mesh objects
2568 //========================================================================
2569 class SolidMesh : public virtual Mesh
2570 {
2571 public:
2572 /// Default constructor
2574
2575 /// Broken copy constructor
2576 SolidMesh(const SolidMesh& dummy) = delete;
2577
2578 /// Broken assignment operator
2579 void operator=(const SolidMesh&) = delete;
2580
2581 /// Constructor builds combined mesh from the meshes specified.
2582 /// Note: This simply merges the meshes' elements and nodes (ignoring
2583 /// duplicates; no boundary information etc. is created).
2585 {
2586#ifdef OOMPH_HAS_MPI
2587 // Mesh hasn't been distributed: Null out pointer to communicator
2588 Comm_pt = 0;
2589#endif
2590
2591 unsigned n = sub_mesh_pt.size();
2593 for (unsigned i = 0; i < n; i++)
2594 {
2595 sub_mesh_mesh_pt[i] = static_cast<Mesh*>(sub_mesh_pt[i]);
2596 }
2598 }
2599
2600 /// Return a pointer to the n-th global SolidNode
2601 // Can safely cast the nodes to SolidNodes
2602 SolidNode* node_pt(const unsigned long& n)
2603 {
2604#ifdef PARANOID
2605 if (!dynamic_cast<SolidNode*>(Node_pt[n]))
2606 {
2607 std::ostringstream error_stream;
2608 error_stream << "Error: Node " << n << "is a "
2609 << typeid(Node_pt[n]).name() << ", not an SolidNode"
2610 << std::endl;
2611 throw OomphLibError(
2613 }
2614#endif
2615 // Return a static cast to the Node_pt
2616 return (static_cast<SolidNode*>(Node_pt[n]));
2617 }
2618
2619 /// Return n-th SolidNodes on b-th boundary
2620 SolidNode* boundary_node_pt(const unsigned& b, const unsigned& n)
2621 {
2622#ifdef PARANOID
2623 if (!dynamic_cast<SolidNode*>(Mesh::boundary_node_pt(b, n)))
2624 {
2625 std::ostringstream error_stream;
2626 error_stream << "Error: Node " << n << "is a "
2627 << typeid(Mesh::boundary_node_pt(b, n)).name()
2628 << ", not an SolidNode" << std::endl;
2629 throw OomphLibError(
2631 }
2632#endif
2633 return static_cast<SolidNode*>(Mesh::boundary_node_pt(b, n));
2634 }
2635
2636 /// Return the n-th local SolidNode in elemnet e.
2637 /// This is required to cast the nodes in a solid mesh to be
2638 /// SolidNodes and therefore allow access to the extra SolidNode data
2639 SolidNode* element_node_pt(const unsigned long& e, const unsigned& n)
2640 {
2641#ifdef PARANOID
2642 // Try to cast to FiniteElement
2643 FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
2644 if (el_pt == 0)
2645 {
2646 // Error
2647 throw OomphLibError("Failed cast to FiniteElement* ",
2650 }
2651 if (!dynamic_cast<SolidNode*>(el_pt->node_pt(n)))
2652 {
2653 std::ostringstream error_message;
2654 Node* np = el_pt->node_pt(n);
2655 error_message << "Error: Node " << n << " of element " << e << "is a "
2656 << typeid(*np).name() << ", not an SolidNode"
2657 << std::endl;
2658
2659 throw OomphLibError(error_message.str(),
2662 }
2663#endif
2664 // Return a cast to an SolidNode
2665 return (static_cast<SolidNode*>(
2666 dynamic_cast<FiniteElement*>(Element_pt[e])->node_pt(n)));
2667 }
2668
2669 /// Make the current configuration the undeformed one by
2670 /// setting the nodal Lagrangian coordinates to their current
2671 /// Eulerian ones
2673
2674
2675 /// Scale all nodal coordinates by given factor and re-assign the
2676 /// Lagrangian coordinates
2677 void scale_mesh(const double& factor)
2678 {
2680
2681 // Re-assign the Lagrangian coordinates
2683 }
2684 /// Static problem that can be used to assign initial conditions
2685 /// on a given solid mesh (need to define this as a static problem
2686 /// somewhere because deleting the problem would wipe out the mesh too!)
2688 };
2689
2690
2691 ///////////////////////////////////////////////////////////////////////////
2692 ///////////////////////////////////////////////////////////////////////////
2693 ///////////////////////////////////////////////////////////////////////////
2694
2695
2696 //===================================================
2697 /// Edge class
2698 //===================================================
2699 class Edge
2700 {
2701 public:
2702 /// Constructor: Pass in the two vertex nodes
2704 {
2705 if (node1_pt == node2_pt)
2706 {
2707#ifdef PARANOID
2708 std::ostringstream error_stream;
2709 error_stream << "Edge cannot have two identical vertex nodes\n";
2710 throw OomphLibError(
2712#endif
2713 }
2714
2715
2716 // Sort lexicographically based on pointer address of nodes
2717 if (node1_pt > node2_pt)
2718 {
2721 }
2722 else
2723 {
2726 }
2727 }
2728
2729
2730 /// Access to the first vertex node
2732 {
2733 return Node1_pt;
2734 }
2735
2736 /// Access to the second vertex node
2738 {
2739 return Node2_pt;
2740 }
2741
2742 /// Comparison operator
2743 bool operator==(const Edge& other) const
2744 {
2745 if ((Node1_pt == other.node1_pt()) && (Node2_pt == other.node2_pt()))
2746
2747 {
2748 return true;
2749 }
2750 else
2751 {
2752 return false;
2753 }
2754 }
2755
2756
2757 /// Less-than operator
2758 bool operator<(const Edge& other) const
2759 {
2760 if (Node1_pt < other.node1_pt())
2761 {
2762 return true;
2763 }
2764 else if (Node1_pt == other.node1_pt())
2765 {
2766 if (Node2_pt < other.node2_pt())
2767 {
2768 return true;
2769 }
2770 else
2771 {
2772 return false;
2773 }
2774 }
2775 else
2776 {
2777 return false;
2778 }
2779 }
2780
2781 /// Test whether the Edge lies on a boundary. Relatively simple
2782 /// test, based on both vertices lying on (some) boundary.
2783 bool is_on_boundary() const
2784 {
2786 }
2787
2788
2789 /// Test whether the Edge is a boundary edge, i.e. does it
2790 /// connnect two boundary nodes?
2791 bool is_boundary_edge() const
2792 {
2793 return ((dynamic_cast<BoundaryNodeBase*>(Node1_pt) != 0) &&
2794 (dynamic_cast<BoundaryNodeBase*>(Node2_pt) != 0));
2795 }
2796
2797 private:
2798 /// First vertex node
2800
2801 /// Second vertex node
2803 };
2804
2805
2806 ///////////////////////////////////////////////////////////////////////
2807 ///////////////////////////////////////////////////////////////////////
2808 ///////////////////////////////////////////////////////////////////////
2809
2810
2811 //=================================================================
2812 /// Namespace with helper function to check element type in mesh
2813 /// constructors (say).
2814 //=================================================================
2815 namespace MeshChecker
2816 {
2817 //=================================================================
2818 /// Helper function to assert that finite element of type ELEMENT
2819 /// can be cast to base class of type GEOM_ELEMENT_BASE -- useful
2820 /// to avoid confusion if a mesh that was written for a specific
2821 /// element type (e.g. a QElement) is used with another one (e.g.
2822 /// a TElement. First argument specifies the required spatial dimension
2823 /// of the element (i.e. the number of local coordinates). The optional
2824 /// second argument specifies the required nnode_1d (i.e. the number
2825 /// of nodes along a 1D element edge). Can be omitted if the mesh
2826 /// can handle any number in which case this test is skipped.
2827 //=================================================================
2828 template<class GEOM_ELEMENT_BASE, class ELEMENT>
2829 void assert_geometric_element(const unsigned& dim,
2830 const unsigned& nnode_1d = 0)
2831 {
2832 // Only do tests in paranoia mode
2833#ifndef PARANOID
2834 return;
2835#endif
2836
2837 // Instantiate element
2838 ELEMENT* el_pt = new ELEMENT;
2839
2840 // Can we cast to required geometric element base type
2841 if (dynamic_cast<GEOM_ELEMENT_BASE*>(el_pt) == 0)
2842 {
2843 std::stringstream error_message;
2844 error_message << "You have specified an illegal element type! Element "
2845 "is of type \n\n"
2846 << typeid(el_pt).name()
2847 << "\n\nand cannot be cast to type \n\n "
2848 << typeid(GEOM_ELEMENT_BASE).name() << "\n\n";
2849 throw OomphLibError(error_message.str(),
2852 }
2853
2854 // Does the dimension match?
2855 if (dim != el_pt->dim())
2856 {
2857 std::stringstream error_message;
2858 error_message << "You have specified an illegal element type! Element "
2859 "is of type \n\n"
2860 << typeid(el_pt).name()
2861 << "\n\nand has dimension = " << el_pt->dim()
2862 << " but we need dim = " << dim << std::endl;
2863 throw OomphLibError(error_message.str(),
2866 }
2867
2868 // Does nnode_1d match?
2869 if (nnode_1d != 0)
2870 {
2871 if (nnode_1d != el_pt->nnode_1d())
2872 {
2873 std::stringstream error_message;
2874 error_message << "You have specified an illegal element type! "
2875 "Element is of type \n\n"
2876 << typeid(el_pt).name()
2877 << "\n\nand has nnode_1d = " << el_pt->nnode_1d()
2878 << " but we need nnode_1d = " << nnode_1d << std::endl;
2879 throw OomphLibError(error_message.str(),
2882 }
2883 }
2884
2885 // Clean up
2886 delete el_pt;
2887 }
2888
2889 } // namespace MeshChecker
2890
2891
2892 ///////////////////////////////////////////////////////////////////////
2893 ///////////////////////////////////////////////////////////////////////
2894 ///////////////////////////////////////////////////////////////////////
2895
2896
2897 //=================paraview_helper=================================
2898 /// Namespace for paraview-style output helper functions
2899 //=================================================================
2900 namespace ParaviewHelper
2901 {
2902 /// Write the pvd file header
2903 extern void write_pvd_header(std::ofstream& pvd_file);
2904
2905 /// Add name of output file and associated continuous time
2906 /// to pvd file.
2907 extern void write_pvd_information(std::ofstream& pvd_file,
2908 const std::string& output_filename,
2909 const double& time);
2910
2911 /// Write the pvd file footer
2912 extern void write_pvd_footer(std::ofstream& pvd_file);
2913
2914 } // namespace ParaviewHelper
2915
2916 ////////////////////////////////////////////////////////////////
2917 ////////////////////////////////////////////////////////////////
2918 ////////////////////////////////////////////////////////////////
2919
2920 namespace NodeOrdering
2921 {
2922 /// Function for ordering nodes. Return true if first node's position is
2923 /// "before" second nodes. Dimension 0 checked first, then... until they
2924 /// are different (by more than tol=1e-10). If they are both in exactly
2925 /// the same place an error is thrown.
2927 {
2928 unsigned ndim = nd1_pt->ndim();
2929
2930 unsigned j;
2931 for (j = 0; j < ndim; j++)
2932 {
2933 if (std::abs(nd1_pt->x(j) - nd2_pt->x(j)) > 1e-10)
2934 {
2935 if (nd1_pt->x(j) < nd2_pt->x(j))
2936 {
2937 return true;
2938 }
2939 else
2940 {
2941 return false;
2942 }
2943 }
2944 // otherwise they are the same in this dimension, check next one.
2945 }
2946
2947 std::string err = "Nodes are at the same point to ~ 1e-10!";
2948 err += " difference is " +
2949 StringConversion::to_string(std::abs(nd1_pt->x(j) - nd2_pt->x(j)));
2950 throw OomphLibError(
2952 }
2953 } // namespace NodeOrdering
2954
2955
2956} // namespace oomph
2957
2958#endif
e
Definition cfortran.h:571
static char t char * s
Definition cfortran.h:568
cstr elem_len * i
Definition cfortran.h:603
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
void compute_norm(double &norm)
Compute norm of the solution: sum of squares of the L2 norm for each reagent.
A class that contains the information required by Nodes that are located on Mesh boundaries....
Definition nodes.h:1996
GeneralisedTimestepper used to store the arclength derivatives and pervious solutions required in con...
A class that represents a collection of data; each Data object may contain many different individual ...
Definition nodes.h:86
Information for documentation of results: Directory and file number to enable output in the form RESL...
void disable_doc()
Disable documentation.
Edge class.
Definition mesh.h:2700
Node * node2_pt() const
Access to the second vertex node.
Definition mesh.h:2737
bool is_on_boundary() const
Test whether the Edge lies on a boundary. Relatively simple test, based on both vertices lying on (so...
Definition mesh.h:2783
Node * node1_pt() const
Access to the first vertex node.
Definition mesh.h:2731
bool is_boundary_edge() const
Test whether the Edge is a boundary edge, i.e. does it connnect two boundary nodes?
Definition mesh.h:2791
Node * Node1_pt
First vertex node.
Definition mesh.h:2799
Edge(Node *node1_pt, Node *node2_pt)
Constructor: Pass in the two vertex nodes.
Definition mesh.h:2703
bool operator<(const Edge &other) const
Less-than operator.
Definition mesh.h:2758
Node * Node2_pt
Second vertex node.
Definition mesh.h:2802
bool operator==(const Edge &other) const
Comparison operator.
Definition mesh.h:2743
A general Finite Element class.
Definition elements.h:1317
virtual std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction")
Definition elements.h:3165
void interpolated_zeta(const Vector< double > &s, Vector< double > &zeta) const
Calculate the interpolated value of zeta, the intrinsic coordinate of the element when viewed as a co...
Definition elements.cc:4705
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition elements.cc:4320
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
Definition elements.cc:3992
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
Definition elements.h:2615
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as .
Definition elements.h:1763
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Get cector of local coordinates of plot point i (when plotting nplot points in each "coordinate direc...
Definition elements.h:3152
virtual unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction")
Definition elements.h:3190
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition elements.h:2179
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overload...
Definition elements.h:2222
virtual void write_tecplot_zone_footer(std::ostream &outfile, const unsigned &nplot) const
Add tecplot zone "footer" to output stream (when plotting nplot points in each "coordinate direction"...
Definition elements.h:3178
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Function pointer for function that computes Vector-valued time-dependent function as .
Definition elements.h:1769
A Generalised Element class.
Definition elements.h:73
bool is_halo() const
Is this element a halo?
Definition elements.h:1150
void set_halo(const unsigned &non_halo_proc_ID)
Label the element as halo and specify processor that holds non-halo counterpart.
Definition elements.h:1138
unsigned ndim() const
Access function to # of Eulerian coordinates.
A general mesh class.
Definition mesh.h:67
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Definition mesh.cc:243
void set_external_halo_node_pt(const unsigned &p, const Vector< Node * > &external_halo_node_pt)
Set vector of external halo node in this Mesh whose non-halo external counterpart is held on processo...
Definition mesh.h:2406
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
Definition mesh.h:841
void(FiniteElement::* SteadyExactSolutionFctPt)(const Vector< double > &x, Vector< double > &soln)
Typedef for function pointer to function that computes steady exact solution.
Definition mesh.h:227
Vector< Node * > external_haloed_node_pt(const unsigned &p)
Access fct to vector of external haloed node in this Mesh whose halo external counterpart is held on ...
Definition mesh.h:2460
GeneralisedElement * element_pt(const unsigned long &e) const
Return pointer to element e (const version)
Definition mesh.h:458
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition mesh.h:183
void enable_resizing_of_halo_nodes()
Function to (re-)enable resizing of halo nodes – this returns things to the default behaviour.
Definition mesh.h:2048
std::map< unsigned, Vector< Node * > > Shared_node_pt
Map of vectors holding the pointers to the shared nodes. These are all the nodes that are on two "nei...
Definition mesh.h:116
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors.
Definition mesh.h:75
bool does_pointer_correspond_to_mesh_data(double *const &parameter_pt)
Does the double pointer correspond to any mesh data.
Definition mesh.cc:2471
virtual void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
Plot error when compared against a given time-depdendent exact solution. Also returns the norm of the...
Definition mesh.h:1359
void distribute(OomphCommunicator *comm_pt, const Vector< unsigned > &element_domain, Vector< GeneralisedElement * > &deleted_element_pt, const bool &report_stats=false)
Distribute the problem Add to vector of pointers to deleted elements.
Definition mesh.h:1653
void disable_resizing_of_halo_nodes()
Function to suppress resizing of halo nodes – optmisation but call it at your own risk!
Definition mesh.h:2040
unsigned ndof_types() const
Return number of dof types in mesh.
Definition mesh.cc:8764
void remove_boundary_node(const unsigned &b, Node *const &node_pt)
Remove a node from the boundary b.
Definition mesh.cc:221
bool is_mesh_distributed() const
Boolean to indicate if Mesh has been distributed.
Definition mesh.h:1596
void output_external_halo_elements(std::ostream &outfile, const unsigned &n_plot=5)
Output all external halo elements.
Definition mesh.h:2166
void setup_shared_node_scheme()
Setup shared node scheme.
Definition mesh.cc:2712
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:2385
GeneralisedElement *& external_halo_element_pt(const unsigned &p, const unsigned &e)
Access fct to the e-th external halo element in this Mesh whose non-halo counterpart is held on proce...
Definition mesh.h:2259
void max_and_min_element_size(double &max_size, double &min_size)
Determine max and min area for all FiniteElements in the mesh (non-FiniteElements are ignored)
Definition mesh.h:700
std::map< unsigned, Vector< GeneralisedElement * > > Root_haloed_element_pt
Map of vectors holding the pointers to the root haloed elements.
Definition mesh.h:103
void set_keep_all_elements_as_halos()
Call this function to keep all the elements as halo elements.
Definition mesh.h:1629
unsigned nroot_haloed_element(const unsigned &p)
Number of root haloed elements in this Mesh whose non-halo counterpart is held on processor p.
Definition mesh.h:1944
virtual unsigned try_to_add_haloed_node_pt(const unsigned &p, Node *&nod_pt)
Definition mesh.h:2533
Vector< Vector< FiniteElement * > > Boundary_element_pt
Vector of Vector of pointers to elements on the boundaries: Boundary_element_pt(b,...
Definition mesh.h:91
void add_halo_node_pt(const unsigned &p, Node *&nod_pt)
Add halo node whose non-halo counterpart is held on processor p to the storage scheme for halo nodes.
Definition mesh.h:1914
unsigned nexternal_haloed_element()
Total number of external haloed elements in this Mesh.
Definition mesh.h:2275
unsigned add_external_haloed_node_pt(const unsigned &p, Node *&nod_pt)
Add external haloed node whose halo (external) counterpart is held on processor p to the storage sche...
Definition mesh.cc:9516
unsigned nexternal_halo_node()
Total number of external halo nodes in this Mesh.
Definition mesh.h:2316
GeneralisedElement *& root_halo_element_pt(const unsigned &p, const unsigned &e)
Access fct to the e-th root halo element in this Mesh whose non-halo counterpart is held on processor...
Definition mesh.h:1870
unsigned nexternal_haloed_element(const unsigned &p)
Number of external haloed elements in this Mesh whose non-halo counterpart is held on processor p.
Definition mesh.h:2290
unsigned nodal_dimension() const
Return number of nodal dimension in mesh.
Definition mesh.cc:9055
void add_external_halo_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add external halo element whose non-halo counterpart is held on processor p to this Mesh.
Definition mesh.h:2267
virtual void compute_norm(double &norm)
Compute norm of solution by summing contributions of compute_norm(...) for all constituent elements i...
Definition mesh.h:1076
virtual void reset_boundary_element_info(Vector< unsigned > &ntmp_boundary_elements, Vector< Vector< unsigned > > &ntmp_boundary_elements_in_region, Vector< FiniteElement * > &deleted_elements)
Virtual function to perform the reset boundary elements info rutines.
Definition mesh.h:288
bool Lookup_for_elements_next_boundary_is_setup
Flag to indicate that the lookup schemes for elements that are adjacent to the boundaries has been se...
Definition mesh.h:87
void flush_element_and_node_storage()
Flush storage for elements and nodes by emptying the vectors that store the pointers to them....
Definition mesh.h:411
Node * boundary_node_pt(const unsigned &b, const unsigned &n) const
Return pointer to node n on boundary b.
Definition mesh.h:503
std::map< unsigned, Vector< GeneralisedElement * > > External_haloed_element_pt
Map of vectors holding the pointers to the external haloed elements.
Definition mesh.h:129
void add_shared_node_pt(const unsigned &p, Node *&nod_pt)
Add shared node whose counterpart is held on processor p to the storage scheme for shared nodes....
Definition mesh.h:2141
void set_boundary_coordinate_does_not_exist(const unsigned &i)
Set boundary coordinate on the i-th boundary to be non-existing.
Definition mesh.h:591
void flush_element_storage()
Flush storage for elements (only) by emptying the vectors that store the pointers to them....
Definition mesh.h:427
void output(const std::string &output_filename)
Output for all elements.
Definition mesh.h:983
virtual void setup_boundary_element_info(std::ostream &outfile)
Setup lookup schemes which establish whic elements are located next to mesh's boundaries....
Definition mesh.h:285
GeneralisedElement *& external_haloed_element_pt(const unsigned &p, const unsigned &e)
Access fct to the e-th external haloed element in this Mesh whose non-halo counterpart is held on pro...
Definition mesh.h:2304
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Definition mesh.h:477
void get_haloed_node_stats(double &av_number, unsigned &max_number, unsigned &min_number)
Get haloed node stats for this distributed mesh: Average/max/min number of haloed nodes over all proc...
Definition mesh.cc:4904
void(FiniteElement::* UnsteadyExactSolutionFctPt)(const double &time, const Vector< double > &x, Vector< double > &soln)
Typedef for function pointer to function that computes unsteady exact solution.
Definition mesh.h:232
void check_halo_schemes(DocInfo &doc_info, double &max_permitted_error_for_halo_check)
Check halo and shared schemes on the mesh.
Definition mesh.cc:6881
virtual void set_mesh_level_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Function that can be used to set any additional timestepper data stored at the Mesh (as opposed to no...
Definition mesh.cc:2402
Vector< unsigned > Boundary_coordinate_exists_stored_as_unsigned
Indicate whether the boundary coordinates have been set for the specified boundary....
Definition mesh.h:205
unsigned nhaloed_node(const unsigned &p)
Number of haloed nodes in this Mesh whose haloed counterpart is held on processor p.
Definition mesh.h:2009
void describe_local_dofs(std::ostream &out, const std::string &current_string) const
Function to describe the local dofs of the elements. The ostream specifies the output stream to which...
Definition mesh.cc:746
virtual void classify_halo_and_haloed_nodes(DocInfo &doc_info, const bool &report_stats)
Classify the halo and haloed nodes in the mesh. Virtual so it can be overloaded to perform additional...
Definition mesh.cc:3262
void add_root_haloed_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add root haloed element whose non-halo counterpart is held on processor p to the storage scheme for h...
Definition mesh.h:1985
void synchronise_shared_nodes(const bool &report_stats)
Synchronise shared node lookup schemes to cater for the the case where: (1) a certain node on the cur...
Definition mesh.cc:2890
void check_inverted_elements(bool &mesh_has_inverted_elements)
Check for inverted elements and report outcome in boolean variable. This visits all elements at their...
Definition mesh.h:750
int face_index_at_boundary(const unsigned &b, const unsigned &e) const
For the e-th finite element on boundary b, return int to indicate the face_index of the face adjacent...
Definition mesh.h:904
void output_external_halo_elements(const unsigned &p, std::ostream &outfile, const unsigned &n_plot=5)
Output all external halo elements with processor p.
Definition mesh.h:2180
Vector< Vector< int > > Face_index_at_boundary
For the e-th finite element on boundary b, this is the index of the face that lies along that boundar...
Definition mesh.h:95
unsigned nexternal_haloed_node(const unsigned &p)
Number of external haloed nodes in this Mesh whose halo (external) counterpart is held on processor p...
Definition mesh.h:2435
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Definition mesh.h:509
void copy_boundary_node_data_from_nodes()
Replace existing boundary node lookup schemes with new schemes created using the boundary data stored...
Definition mesh.h:532
void set_elemental_internal_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Set the timestepper associated with the internal data stored within elements in the meah.
Definition mesh.cc:2535
void doc_boundary_coordinates(const unsigned &b, std::ofstream &the_file)
Output boundary coordinates on boundary b – template argument specifies the bulk element type (needed...
Definition mesh.h:307
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
Definition mesh.h:886
bool Keep_all_elements_as_halos
bool to indicate whether to keep all elements in a mesh as halos or not
Definition mesh.h:141
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition mesh.h:440
std::map< unsigned, Vector< Node * > > External_haloed_node_pt
Map of vectors holding the pointers to the external haloed nodes.
Definition mesh.h:138
void output_external_haloed_elements(const unsigned &p, std::ostream &outfile, const unsigned &n_plot=5)
Output all external haloed elements with processor p.
Definition mesh.h:2212
void set_nodal_and_elemental_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Set the timestepper associated with all nodal and elemental data stored in the mesh.
Definition mesh.h:1040
virtual void setup_boundary_element_info()
Interface for function that is used to setup the boundary information (Empty virtual function – imple...
Definition mesh.h:279
FiniteElement * boundary_element_pt(const unsigned &b, const unsigned &e) const
Return pointer to e-th finite element on boundary b.
Definition mesh.h:848
std::map< unsigned, Vector< GeneralisedElement * > > Root_halo_element_pt
Map of vectors holding the pointers to the root halo elements.
Definition mesh.h:100
unsigned elemental_dimension() const
Return number of elemental dimension in mesh.
Definition mesh.cc:8917
void set_external_haloed_node_pt(const unsigned &p, const Vector< Node * > &external_haloed_node_pt)
Set vector of external haloed node in this Mesh whose halo external counterpart is held on processor ...
Definition mesh.h:2474
void check_inverted_elements(bool &mesh_has_inverted_elements, std::ofstream &inverted_element_file)
Check for inverted elements and report outcome in boolean variable. This visits all elements at their...
Definition mesh.cc:870
OomphCommunicator * Comm_pt
Pointer to communicator – set to NULL if mesh is not distributed.
Definition mesh.h:119
virtual void create_shared_boundaries(OomphCommunicator *comm_pt, const Vector< unsigned > &element_domain, const Vector< GeneralisedElement * > &backed_up_el_pt, const Vector< FiniteElement * > &backed_up_f_el_pt, std::map< Data *, std::set< unsigned > > &processors_associated_with_data, const bool &overrule_keep_as_halo_element_status)
Creates the shared boundaries, only used in unstructured meshes In this case with the "TriangleMesh" ...
Definition mesh.h:2498
virtual void compute_norm(Vector< double > &norm)
Compute norm of solution by summing contributions of compute_norm(...) for all constituent elements i...
Definition mesh.h:1107
void add_root_halo_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add root halo element whose non-halo counterpart is held on processor p to this Mesh.
Definition mesh.h:1879
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt)
Output a given Vector function at f(n_plot) points in each element.
Definition mesh.cc:2199
virtual void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Plot error when compared against a given exact solution. Also returns the norm of the error and that ...
Definition mesh.h:1148
virtual void scale_mesh(const double &factor)
Scale all nodal coordinates by given factor. Virtual so it can be overloaded in SolidMesh class where...
Definition mesh.h:377
void shift_time_values()
Shift time-dependent data along for next timestep: Deal with nodal Data/positions and the element's i...
Definition mesh.cc:2326
Vector< GeneralisedElement * > & element_pt()
Return reference to the Vector of elements.
Definition mesh.h:470
virtual void reorder_nodes(const bool &use_old_ordering=true)
Re-order nodes in the order in which they appear in elements – can be overloaded for more efficient r...
Definition mesh.cc:508
void prune_halo_elements_and_nodes(Vector< GeneralisedElement * > &deleted_element_pt, const bool &report_stats=false)
(Irreversibly) prune halo(ed) elements and nodes, usually after another round of refinement,...
Definition mesh.h:1675
unsigned nhalo_node(const unsigned &p)
Number of halo nodes in this Mesh whose non-halo counterpart is held on processor p.
Definition mesh.h:1901
void calculate_predictions()
Calculate predictions for all Data and positions associated with the mesh, usually used in adaptive t...
Definition mesh.cc:2366
void output_boundaries(const std::string &output_filename)
Output the nodes on the boundaries (into separate tecplot zones). Specify filename.
Definition mesh.h:1017
unsigned nboundary() const
Return number of boundaries.
Definition mesh.h:835
unsigned add_external_haloed_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add external haloed element whose non-halo counterpart is held on processor p to the storage scheme f...
Definition mesh.cc:9475
void describe_dofs(std::ostream &out, const std::string &current_string) const
Function to describe the dofs of the Mesh. The ostream specifies the output stream to which the descr...
Definition mesh.cc:711
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:1748
void disable_output_of_halo_elements()
Function to disable halo element output.
Definition mesh.h:2054
void output_fct_paraview(std::ofstream &file_out, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
Output in paraview format into specified file. Breaks up each element into sub-elements for plotting ...
Definition mesh.cc:1491
unsigned nroot_halo_element(const unsigned &p)
Number of root halo elements in this Mesh whose non-halo counterpart is held on processor p.
Definition mesh.h:1854
void remove_boundary_nodes()
Clear all pointers to boundary nodes.
Definition mesh.cc:204
bool Output_halo_elements
Bool for output of halo elements.
Definition mesh.h:2035
void build_face_mesh(const unsigned &b, Mesh *const &face_mesh_pt)
Constuct a Mesh of FACE_ELEMENTs along the b-th boundary of the mesh (which contains elements of type...
Definition mesh.h:661
unsigned long nnode() const
Return number of nodes in the mesh.
Definition mesh.h:604
virtual void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Plot error when compared against a given time-depdendent exact solution. Also returns the norm of the...
Definition mesh.h:1194
virtual void node_update(const bool &update_all_solid_nodes=false)
Update nodal positions in response to changes in the domain shape. Uses the FiniteElement::get_x(....
Definition mesh.cc:287
void get_efficiency_of_mesh_distribution(double &av_efficiency, double &max_efficiency, double &min_efficiency)
Get efficiency of mesh distribution: In an ideal distribution without halo overhead,...
Definition mesh.cc:6390
unsigned nroot_haloed_element()
Total number of root haloed elements in this Mesh.
Definition mesh.h:1929
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
Definition mesh.h:452
void output_external_haloed_elements(std::ostream &outfile, const unsigned &n_plot=5)
Output all external haloed elements.
Definition mesh.h:2198
GeneralisedElement *& root_haloed_element_pt(const unsigned &p, const unsigned &e)
Access fct to the e-th root haloed element in this Mesh whose non-halo counterpart is held on process...
Definition mesh.h:1974
void delete_all_external_storage()
Wipe the storage for all externally-based elements.
Definition mesh.cc:9190
unsigned nnon_halo_element()
Total number of non-halo elements in this mesh (Costly call computes result on the fly)
Definition mesh.h:1825
virtual void compute_error(FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
Returns the norm of the error and that of the exact solution. Version with vectors of norms and error...
Definition mesh.h:1533
void get_all_halo_data(std::map< unsigned, double * > &map_of_halo_data)
Get all the halo data stored in the mesh and add pointers to the data to the map, indexed by global e...
Definition mesh.cc:4749
Node *& external_haloed_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th external haloed node in this Mesh whose halo external counterpart is held on p...
Definition mesh.h:2449
unsigned nhalo_node()
Total number of halo nodes in this Mesh.
Definition mesh.h:1886
std::map< unsigned, Vector< Node * > > Halo_node_pt
Map of vectors holding the pointers to the halo nodes.
Definition mesh.h:106
Mesh()
Default constructor.
Definition mesh.h:240
void set_communicator_pt(OomphCommunicator *comm_pt)
Function to set communicator (mesh is assumed to be distributed if the communicator pointer is non-nu...
Definition mesh.h:1623
Vector< Node * > external_halo_node_pt(const unsigned &p)
Access fct to vector of external halo node in this Mesh whose non-halo external counterpart is held o...
Definition mesh.h:2392
unsigned check_for_repeated_nodes(const double &epsilon=1.0e-12)
Check for repeated nodes within a given spatial tolerance. Return (0/1) for (pass/fail).
Definition mesh.h:760
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this,...
Definition mesh.cc:2590
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition mesh.h:464
void output(std::ostream &outfile)
Output for all elements.
Definition mesh.cc:2027
Vector< GeneralisedElement * > root_halo_element_pt(const unsigned &p)
Vector of pointers to root halo elements in this Mesh whose non-halo counterpart is held on processor...
Definition mesh.h:1862
virtual void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
Plot error when compared against a given time-depdendent exact solution. Also returns the norm of the...
Definition mesh.h:1425
void add_element_pt(GeneralisedElement *const &element_pt)
Add a (pointer to) an element to the mesh.
Definition mesh.h:625
virtual unsigned try_to_add_root_haloed_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Definition mesh.h:2518
std::map< unsigned, Vector< Node * > > Haloed_node_pt
Map of vectors holding the pointers to the haloed nodes.
Definition mesh.h:109
void doc_shared_nodes()
Doc shared nodes.
Definition mesh.h:2080
void operator=(const Mesh &)=delete
Broken assignment operator.
void set_boundary_coordinate_exists(const unsigned &i)
Set boundary coordinate on the i-th boundary to be existing.
Definition mesh.h:584
void assign_initial_values_impulsive()
Assign initial values for an impulsive start.
Definition mesh.cc:2288
Node * haloed_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th haloed node in this Mesh whose halo counterpart is held on processor p.
Definition mesh.h:2022
bool Resize_halo_nodes_not_required
Set this to true to suppress resizing of halo nodes (at your own risk!)
Definition mesh.h:144
void flush_node_storage()
Flush storage for nodes (only) by emptying the vectors that store the pointers to them.
Definition mesh.h:434
void assign_local_eqn_numbers(const bool &store_local_dof_pt)
Assign the local equation numbers in all elements If the boolean argument is true then also store poi...
Definition mesh.cc:765
unsigned nexternal_halo_element(const unsigned &p)
Number of external halo elements in this Mesh whose non-halo counterpart is held on processor p.
Definition mesh.h:2245
Vector< Vector< Node * > > Boundary_node_pt
Vector of Vector of pointers to nodes on the boundaries: Boundary_node_pt(b,n). Note that this is pri...
Definition mesh.h:83
virtual ~Mesh()
Virtual Destructor to clean up all memory.
Definition mesh.cc:650
void add_haloed_node_pt(const unsigned &p, Node *&nod_pt)
Add haloed node whose halo counterpart is held on processor p to the storage scheme for haloed nodes.
Definition mesh.h:2029
void get_external_halo_node_pt(Vector< Node * > &external_halo_node_pt)
Get vector of pointers to all external halo nodes.
Definition mesh.h:2331
void enable_output_of_halo_elements()
Function to enable halo element output.
Definition mesh.h:2060
void add_node_pt(Node *const &node_pt)
Add a (pointer to a) node to the mesh.
Definition mesh.h:619
void add_external_halo_node_pt(const unsigned &p, Node *&nod_pt)
Add external halo node whose non-halo (external) counterpart is held on processor p to the storage sc...
Definition mesh.h:2376
void unset_keep_all_elements_as_halos()
Calll this function to unset the flag that keeps all elements in the mesh as halo elements.
Definition mesh.h:1636
virtual void read(std::ifstream &restart_file)
Read solution from restart file.
Definition mesh.cc:1130
void set_nodal_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Set the timestepper associated with the nodal data in the mesh.
Definition mesh.cc:2516
void doc_mesh_distribution(DocInfo &doc_info)
Doc the mesh distribution, to be processed with tecplot macros.
Definition mesh.cc:6470
unsigned self_test()
Self-test: Check elements and nodes. Return 0 for OK.
Definition mesh.cc:778
void get_shared_node_pt(const unsigned &p, Vector< Node * > &shared_node_pt)
Get vector of pointers to shared nodes with processor p. Required for faster search in Missing_master...
Definition mesh.h:2127
void get_halo_node_stats(double &av_number, unsigned &max_number, unsigned &min_number)
Get halo node stats for this distributed mesh: Average/max/min number of halo nodes over all processo...
Definition mesh.cc:4845
void set_consistent_pinned_values_for_continuation(ContinuationStorageScheme *const &continuation_stepper_pt)
Set consistent values for pinned data in continuation.
Definition mesh.cc:2436
Vector< Node * > prune_dead_nodes()
Prune nodes. Nodes that have been marked as obsolete are removed from the mesh (and its boundary-node...
Definition mesh.cc:966
void output(const std::string &output_filename, const unsigned &n_plot)
Output at f(n_plot) points in each element.
Definition mesh.h:992
std::set< int > external_halo_proc()
Return the set of processors that hold external halo nodes. This is required to avoid having to pass ...
Definition mesh.h:2483
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition mesh.h:186
virtual void compute_error(FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
Plot error when compared against a given time-dependent exact solution. Also returns the norm of the ...
Definition mesh.h:1287
Node * get_some_non_boundary_node() const
Find a node not on any boundary in mesh_pt (useful for pinning a single node in a purely Neumann prob...
Definition mesh.h:867
OomphCommunicator * communicator_pt() const
Read-only access fct to communicator (Null if mesh is not distributed, i.e. if we don't have mpi).
Definition mesh.h:1608
bool boundary_coordinate_exists(const unsigned &i) const
Indicate whether the i-th boundary has an intrinsic coordinate.
Definition mesh.h:571
void resize_halo_nodes()
Helper function that resizes halo nodes to the same size as their non-halo counterparts if required....
Definition mesh.cc:4426
unsigned nexternal_halo_node(const unsigned &p)
Number of external halo nodes in this Mesh whose non-halo (external) counterpart is held on processor...
Definition mesh.h:2362
std::map< unsigned, Vector< Node * > > External_halo_node_pt
Map of vectors holding the pointers to the external halo nodes.
Definition mesh.h:135
unsigned nhaloed_node()
Total number of haloed nodes in this Mesh.
Definition mesh.h:1993
unsigned nexternal_haloed_node()
Total number of external haloed nodes in this Mesh.
Definition mesh.h:2420
unsigned nshared_node(const unsigned &p)
Number of shared nodes in this Mesh who have a counterpart on processor p.
Definition mesh.h:2105
Node * halo_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th halo node in this Mesh whose non-halo counterpart is held on processor p.
Definition mesh.h:1922
static bool Suppress_warning_about_empty_mesh_level_time_stepper_function
Boolean used to control warning about empty mesh level timestepper function.
Definition mesh.h:237
unsigned long assign_global_eqn_numbers(Vector< double * > &Dof_pt)
Assign the global equation numbers in the Data stored at the nodes and also internal element Data....
Definition mesh.cc:677
virtual void compute_error(FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Plot error when compared against a given time-dependent exact solution. Also returns the norm of the ...
Definition mesh.h:1239
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 * > haloed_element_pt(const unsigned &p)
Return vector of haloed elements in this Mesh whose haloing counterpart is held on processor p.
Definition mesh.h:1787
Node * shared_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th shared node in this Mesh who has a counterpart on processor p.
Definition mesh.h:2118
void null_external_halo_node(const unsigned &p, Node *nod_pt)
Null out specified external halo node (used when deleting duplicates)
Definition mesh.cc:8569
Mesh(const Mesh &dummy)=delete
Broken copy constructor.
unsigned nshared_node()
Total number of shared nodes in this Mesh.
Definition mesh.h:2066
virtual void compute_error(FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Returns the norm of the error and that of the exact solution.
Definition mesh.h:1487
void remove_null_pointers_from_external_halo_node_storage()
Consolidate external halo node storage by removing nulled out pointes in external halo and haloed sch...
Definition mesh.cc:8589
unsigned long nelement() const
Return number of elements in the mesh.
Definition mesh.h:598
virtual void get_node_reordering(Vector< Node * > &reordering, const bool &use_old_ordering=true) const
Get a reordering of the nodes in the order in which they appear in elements – can be overloaded for m...
Definition mesh.cc:532
virtual void classify_halo_and_haloed_nodes(const bool &report_stats=false)
Classify the halo and haloed nodes in the mesh. Virtual so it can be overloaded to perform additional...
Definition mesh.h:1720
Vector< GeneralisedElement * > root_haloed_element_pt(const unsigned &p)
Vector of pointers to root haloed elements in this Mesh whose non-halo counterpart is held on process...
Definition mesh.h:1959
void merge_meshes(const Vector< Mesh * > &sub_mesh_pt)
Merge meshes. Note: This simply merges the meshes' elements and nodes (ignoring duplicates; no bounda...
Definition mesh.cc:65
void output_paraview(std::ofstream &file_out, const unsigned &nplot) const
Output in paraview format into specified file. Breaks up each element into sub-elements for plotting ...
Definition mesh.cc:1225
void output_boundaries(std::ostream &outfile)
Output the nodes on the boundaries (into separate tecplot zones)
Definition mesh.cc:1064
unsigned nexternal_halo_element()
Total number of external halo elements in this Mesh.
Definition mesh.h:2230
virtual void dump(std::ofstream &dump_file, const bool &use_old_ordering=true) const
Dump the data in the mesh into a file for restart.
Definition mesh.cc:1088
double total_size()
Determine the sum of all "sizes" of the FiniteElements in the mesh (non-FiniteElements are ignored)....
Definition mesh.h:716
void dump(const std::string &dump_file_name, const bool &use_old_ordering=true) const
Dump the data in the mesh into a file for restart.
Definition mesh.h:923
std::map< unsigned, Vector< GeneralisedElement * > > External_halo_element_pt
External halo(ed) elements are created as and when they are needed to act as source elements for the ...
Definition mesh.h:126
Mesh(const Vector< Mesh * > &sub_mesh_pt)
Constructor builds combined mesh from the meshes specified. Note: This simply merges the meshes' elem...
Definition mesh.h:261
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
Definition mesh.h:497
unsigned nroot_halo_element()
Total number of root halo elements in this Mesh.
Definition mesh.h:1838
Node * node_pt(const unsigned long &n) const
Return pointer to global node n (const version)
Definition mesh.h:446
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition nodes.h:906
virtual bool is_on_boundary() const
Test whether the Node lies on a boundary. The "bulk" Node cannot lie on a boundary,...
Definition nodes.h:1373
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition nodes.h:1054
void resize(const unsigned &n_value)
Resize the number of equations.
Definition nodes.cc:2167
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
An OomphLibError object which should be thrown when an run-time error is encountered....
////////////////////////////////////////////////////////////////// //////////////////////////////////...
Definition problem.h:154
RefineableElements are FiniteElements that may be subdivided into children to provide a better local ...
IC problem for an elastic body discretised on a given (sub)-mesh. We switch the elements' residuals a...
General SolidMesh class.
Definition mesh.h:2570
SolidNode * node_pt(const unsigned long &n)
Return a pointer to the n-th global SolidNode.
Definition mesh.h:2602
void operator=(const SolidMesh &)=delete
Broken assignment operator.
SolidMesh()
Default constructor.
Definition mesh.h:2573
void set_lagrangian_nodal_coordinates()
Make the current configuration the undeformed one by setting the nodal Lagrangian coordinates to thei...
Definition mesh.cc:9564
SolidNode * boundary_node_pt(const unsigned &b, const unsigned &n)
Return n-th SolidNodes on b-th boundary.
Definition mesh.h:2620
void scale_mesh(const double &factor)
Scale all nodal coordinates by given factor and re-assign the Lagrangian coordinates.
Definition mesh.h:2677
SolidNode * element_node_pt(const unsigned long &e, const unsigned &n)
Return the n-th local SolidNode in elemnet e. This is required to cast the nodes in a solid mesh to b...
Definition mesh.h:2639
static SolidICProblem Solid_IC_problem
Static problem that can be used to assign initial conditions on a given solid mesh (need to define th...
Definition mesh.h:2687
SolidMesh(const Vector< SolidMesh * > &sub_mesh_pt)
Constructor builds combined mesh from the meshes specified. Note: This simply merges the meshes' elem...
Definition mesh.h:2584
SolidMesh(const SolidMesh &dummy)=delete
Broken copy constructor.
A Class for nodes that deform elastically (i.e. position is an unknown in the problem)....
Definition nodes.h:1686
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
void output(std::ostream &outfile)
Output function: x,y,u or x,y,z,u.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
A slight extension to the standard template vector class so that we can include "graceful" array rang...
Definition Vector.h:58
void assert_geometric_element(const unsigned &dim, const unsigned &nnode_1d=0)
Helper function to assert that finite element of type ELEMENT can be cast to base class of type GEOM_...
Definition mesh.h:2829
bool node_global_position_comparison(Node *nd1_pt, Node *nd2_pt)
Function for ordering nodes. Return true if first node's position is "before" second nodes....
Definition mesh.h:2926
void write_pvd_footer(std::ofstream &pvd_file)
Write the pvd file footer.
Definition mesh.cc:9639
void write_pvd_header(std::ofstream &pvd_file)
Write the pvd file header.
Definition mesh.cc:9615
void write_pvd_information(std::ofstream &pvd_file, const std::string &output_filename, const double &time)
Add name of output file and associated continuous time to pvd file.
Definition mesh.cc:9624
std::string to_string(T object, unsigned float_precision=8)
Conversion function that should work for anything with operator<< defined (at least all basic types).
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...