MFEM  v3.3
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
mesh.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #ifndef MFEM_MESH
13 #define MFEM_MESH
14 
15 #include "../config/config.hpp"
16 #include "../general/stable3d.hpp"
17 #include "triangle.hpp"
18 #include "tetrahedron.hpp"
19 #include "vertex.hpp"
20 #include "ncmesh.hpp"
21 #include "../fem/eltrans.hpp"
22 #include "../fem/coefficient.hpp"
23 #include "../general/gzstream.hpp"
24 #include <iostream>
25 #include <fstream>
26 
27 namespace mfem
28 {
29 
30 // Data type mesh
31 
32 class KnotVector;
33 class NURBSExtension;
34 class FiniteElementSpace;
35 class GridFunction;
36 struct Refinement;
37 
38 #ifdef MFEM_USE_MPI
39 class ParMesh;
40 class ParNCMesh;
41 #endif
42 
43 
44 class Mesh
45 {
46 #ifdef MFEM_USE_MPI
47  friend class ParMesh;
48  friend class ParNCMesh;
49 #endif
50  friend class NURBSExtension;
51 
52 protected:
53  int Dim;
54  int spaceDim;
55 
58 
59  int BaseGeom, BaseBdrGeom; // element base geometries, -1 if not all the same
60 
61  int meshgen; // see MeshGenerator()
62 
63  // Counter for Mesh transformations: refinement, derefinement, rebalancing.
64  // Used for checking during Update operations on objects depending on the
65  // Mesh, such as FiniteElementSpace, GridFunction, etc.
66  long sequence;
67 
69  // Vertices are only at the corners of elements, where you would expect them
70  // in the lowest-order mesh.
74 
75  struct FaceInfo
76  {
77  // Inf = 64 * LocalFaceIndex + FaceOrientation
79  int NCFace; /* -1 if this is a regular conforming/boundary face;
80  index into 'nc_faces_info' if >= 0. */
81  };
82  // NOTE: in NC meshes, master faces have Elem2No == -1. Slave faces on the
83  // other hand have Elem2No and Elem2Inf set to the master face's element and
84  // its local face number.
85 
86  struct NCFaceInfo
87  {
88  bool Slave; // true if this is a slave face, false if master face
89  int MasterFace; // if Slave, this is the index of the master face
90  const DenseMatrix* PointMatrix; // if Slave, position within master face
91  // (NOTE: PointMatrix points to a matrix owned by NCMesh.)
92 
93  NCFaceInfo(bool slave, int master, const DenseMatrix* pm)
94  : Slave(slave), MasterFace(master), PointMatrix(pm) {}
95  };
96 
99 
104  Table *bel_to_edge; // for 3D
106  mutable Table *face_edge;
107  mutable Table *edge_vertex;
108 
112 
113  // refinement embeddings for forward compatibility with NCMesh
115 
116  // Nodes are only active for higher order meshes, and share locations with
117  // the vertices, plus all the higher- order control points within the
118  // element and along the edges and on the faces.
121 
122  static const int vtk_quadratic_tet[10];
123  static const int vtk_quadratic_hex[27];
124 
125 #ifdef MFEM_USE_MEMALLOC
126  friend class Tetrahedron;
128 #endif
129 
130 public:
136 
138 
139  /// A list of all unique element attributes used by the Mesh.
141  /// A list of all unique boundary attributes used by the Mesh.
143 
144  NURBSExtension *NURBSext; ///< Optional NURBS mesh extension.
145  NCMesh *ncmesh; ///< Optional non-conforming mesh extension.
146 
147 protected:
149 
150  void Init();
151  void InitTables();
152  void SetEmpty(); // Init all data members with empty values
153  void DestroyTables();
155  void DestroyPointers(); // Delete data specifically allocated by class Mesh.
156  void Destroy(); // Delete all owned data.
157 
158  Element *ReadElementWithoutAttr(std::istream &);
159  static void PrintElementWithoutAttr(const Element *, std::ostream &);
160 
161  Element *ReadElement(std::istream &);
162  static void PrintElement(const Element *, std::ostream &);
163 
164  // Readers for different mesh formats, used in the Load() method.
165  // The implementations of these methods are in mesh_readers.cpp.
166  void ReadMFEMMesh(std::istream &input, bool mfem_v11, int &curved);
167  void ReadLineMesh(std::istream &input);
168  void ReadNetgen2DMesh(std::istream &input, int &curved);
169  void ReadNetgen3DMesh(std::istream &input);
170  void ReadTrueGridMesh(std::istream &input);
171  void ReadVTKMesh(std::istream &input, int &curved, int &read_gf);
172  void ReadNURBSMesh(std::istream &input, int &curved, int &read_gf);
173  void ReadInlineMesh(std::istream &input, int generate_edges = 0);
174  void ReadGmshMesh(std::istream &input);
175  /* Note NetCDF (optional library) is used for reading cubit files */
176 #ifdef MFEM_USE_NETCDF
177  void ReadCubit(const char *filename, int &curved, int &read_gf);
178 #endif
179 
180  /// Determine the mesh generator bitmask #meshgen, see MeshGenerator().
181  void SetMeshGen();
182 
183  /// Return the length of the segment from node i to node j.
184  double GetLength(int i, int j) const;
185 
186  /** Compute the Jacobian of the transformation from the perfect
187  reference element at the center of the element. */
188  void GetElementJacobian(int i, DenseMatrix &J);
189 
190  void MarkForRefinement();
192  void GetEdgeOrdering(DSTable &v_to_v, Array<int> &order);
193  virtual void MarkTetMeshForRefinement(DSTable &v_to_v);
194 
195  void PrepareNodeReorder(DSTable **old_v_to_v, Table **old_elem_vert);
196  void DoNodeReorder(DSTable *old_v_to_v, Table *old_elem_vert);
197 
199  STable3D *GetElementToFaceTable(int ret_ftbl = 0);
200 
201  /** Red refinement. Element with index i is refined. The default
202  red refinement for now is Uniform. */
203  void RedRefinement(int i, const DSTable &v_to_v,
204  int *edge1, int *edge2, int *middle)
205  { UniformRefinement(i, v_to_v, edge1, edge2, middle); }
206 
207  /** Green refinement. Element with index i is refined. The default
208  refinement for now is Bisection. */
209  void GreenRefinement(int i, const DSTable &v_to_v,
210  int *edge1, int *edge2, int *middle)
211  { Bisection(i, v_to_v, edge1, edge2, middle); }
212 
213  /** Bisection. Element with index i is bisected. */
214  void Bisection(int i, const DSTable &, int *, int *, int *);
215 
216  /** Bisection. Boundary element with index i is bisected. */
217  void Bisection(int i, const DSTable &, int *);
218 
219  /** Uniform Refinement. Element with index i is refined uniformly. */
220  void UniformRefinement(int i, const DSTable &, int *, int *, int *);
221 
222  /** Averages the vertices with given indexes and saves the result in
223  vertices[result]. */
224  void AverageVertices (int * indexes, int n, int result);
225 
227  int FindCoarseElement(int i);
228 
229  /// Update the nodes of a curved mesh after refinement
230  void UpdateNodes();
231 
232  /// Refine quadrilateral mesh.
233  virtual void QuadUniformRefinement();
234 
235  /// Refine hexahedral mesh.
236  virtual void HexUniformRefinement();
237 
238  /// Refine NURBS mesh.
239  virtual void NURBSUniformRefinement();
240 
241  /// This function is not public anymore. Use GeneralRefinement instead.
242  virtual void LocalRefinement(const Array<int> &marked_el, int type = 3);
243 
244  /// This function is not public anymore. Use GeneralRefinement instead.
245  virtual void NonconformingRefinement(const Array<Refinement> &refinements,
246  int nc_limit = 0);
247 
248  /// NC version of GeneralDerefinement.
249  virtual bool NonconformingDerefinement(Array<double> &elem_error,
250  double threshold, int nc_limit = 0,
251  int op = 1);
252 
253  /// Derefine elements once a list of derefinements is known.
254  void DerefineMesh(const Array<int> &derefinements);
255 
256  /// Read NURBS patch/macro-element mesh
257  void LoadPatchTopo(std::istream &input, Array<int> &edge_to_knot);
258 
259  void UpdateNURBS();
260 
261  void PrintTopo(std::ostream &out, const Array<int> &e_to_k) const;
262 
263  /// Used in GetFaceElementTransformations (...)
266  int i);
268  int i);
269  /// Used in GetFaceElementTransformations (...)
271  int i);
272  /// Used in GetFaceElementTransformations (...)
274  int i);
275  /// Used in GetFaceElementTransformations (...)
276  void GetLocalFaceTransformation(int face_type, int elem_type,
278  int inf);
279  /** Used in GetFaceElementTransformations to account for the fact that a
280  slave face occupies only a portion of its master face. */
282  const FaceInfo &fi);
283  bool IsSlaveFace(const FaceInfo &fi) const;
284 
285  /// Returns the orientation of "test" relative to "base"
286  static int GetTriOrientation (const int * base, const int * test);
287  /// Returns the orientation of "test" relative to "base"
288  static int GetQuadOrientation (const int * base, const int * test);
289 
290  static void GetElementArrayEdgeTable(const Array<Element*> &elem_array,
291  const DSTable &v_to_v,
292  Table &el_to_edge);
293 
294  /** Return vertex to vertex table. The connections stored in the table
295  are from smaller to bigger vertex index, i.e. if i<j and (i, j) is
296  in the table, then (j, i) is not stored. */
297  void GetVertexToVertexTable(DSTable &) const;
298 
299  /** Return element to edge table and the indices for the boundary edges.
300  The entries in the table are ordered according to the order of the
301  nodes in the elements. For example, if T is the element to edge table
302  T(i, 0) gives the index of edge in element i that connects vertex 0
303  to vertex 1, etc. Returns the number of the edges. */
305 
306  /// Used in GenerateFaces()
307  void AddPointFaceElement(int lf, int gf, int el);
308 
309  void AddSegmentFaceElement (int lf, int gf, int el, int v0, int v1);
310 
311  void AddTriangleFaceElement (int lf, int gf, int el,
312  int v0, int v1, int v2);
313 
314  void AddQuadFaceElement (int lf, int gf, int el,
315  int v0, int v1, int v2, int v3);
316  /** For a serial Mesh, return true if the face is interior. For a parallel
317  ParMesh return true if the face is interior or shared. In parallel, this
318  method only works if the face neighbor data is exchanged. */
319  bool FaceIsTrueInterior(int FaceNo) const
320  {
321  return FaceIsInterior(FaceNo) || (faces_info[FaceNo].Elem2Inf >= 0);
322  }
323 
324  // shift cyclically 3 integers left-to-right
325  inline static void ShiftL2R(int &, int &, int &);
326  // shift cyclically 3 integers so that the smallest is first
327  inline static void Rotate3(int &, int &, int &);
328 
329  void FreeElement(Element *E);
330 
331  void GenerateFaces();
332  void GenerateNCFaceInfo();
333 
334  /// Begin construction of a mesh
335  void InitMesh(int _Dim, int _spaceDim, int NVert, int NElem, int NBdrElem);
336 
337  void InitBaseGeom();
338 
339  // Used in the methods FinalizeXXXMesh() and FinalizeTopology()
340  void FinalizeCheck();
341 
342  void Loader(std::istream &input, int generate_edges = 0,
343  std::string parse_tag = "");
344 
345  // If NURBS mesh, write NURBS format. If NCMesh, write mfem v1.1 format.
346  // If section_delimiter is empty, write mfem v1.0 format. Otherwise, write
347  // mfem v1.2 format with the given section_delimiter at the end.
348  void Printer(std::ostream &out = std::cout,
349  std::string section_delimiter = "") const;
350 
351  /** Creates mesh for the parallelepiped [0,sx]x[0,sy]x[0,sz], divided into
352  nx*ny*nz hexahedrals if type=HEXAHEDRON or into 6*nx*ny*nz tetrahedrons
353  if type=TETRAHEDRON. If generate_edges = 0 (default) edges are not
354  generated, if 1 edges are generated. */
355  void Make3D(int nx, int ny, int nz, Element::Type type, int generate_edges,
356  double sx, double sy, double sz);
357 
358  /** Creates mesh for the rectangle [0,sx]x[0,sy], divided into nx*ny
359  quadrilaterals if type = QUADRILATERAL or into 2*nx*ny triangles if
360  type = TRIANGLE. If generate_edges = 0 (default) edges are not generated,
361  if 1 edges are generated. */
362  void Make2D(int nx, int ny, Element::Type type, int generate_edges,
363  double sx, double sy);
364 
365  /// Creates a 1D mesh for the interval [0,sx] divided into n equal intervals.
366  void Make1D(int n, double sx = 1.0);
367 
368  /// Initialize vertices/elements/boundary/tables from a nonconforming mesh.
369  void InitFromNCMesh(const NCMesh &ncmesh);
370 
371  /// Create from a nonconforming mesh.
372  Mesh(const NCMesh &ncmesh);
373 
374  /// Swaps internal data with another mesh. By default, non-geometry members
375  /// like 'ncmesh' and 'NURBSExt' are only swapped when 'non_geometry' is set.
376  void Swap(Mesh& other, bool non_geometry = false);
377 
378  // used in GetElementData() and GetBdrElementData()
379  void GetElementData(const Array<Element*> &elem_array, int geom,
380  Array<int> &elem_vtx, Array<int> &attr) const;
381 
382 public:
383 
384  Mesh() { SetEmpty(); }
385 
386  /** Copy constructor. Performs a deep copy of (almost) all data, so that the
387  source mesh can be modified (e.g. deleted, refined) without affecting the
388  new mesh. If 'copy_nodes' is false, use a shallow (pointer) copy for the
389  nodes, if present. */
390  explicit Mesh(const Mesh &mesh, bool copy_nodes = true);
391 
392  /// Construct a Mesh from the given primary data.
393  /** The array @a vertices is used as external data, i.e. the Mesh does not
394  copy the data and will not delete the pointer.
395 
396  The data from the other arrays is copied into the internal Mesh data
397  structures.
398 
399  This method calls the method FinalizeTopology(). The method Finalize()
400  may be called after this constructor and after optionally setting the
401  Mesh nodes. */
402  Mesh(double *vertices, int num_vertices,
403  int *element_indices, Geometry::Type element_type,
404  int *element_attributes, int num_elements,
405  int *boundary_indices, Geometry::Type boundary_type,
406  int *boundary_attributes, int num_boundary_elements,
407  int dimension, int space_dimension= -1);
408 
409  /** @anchor mfem_Mesh_init_ctor
410  @brief _Init_ constructor: begin the construction of a Mesh object. */
411  Mesh(int _Dim, int NVert, int NElem, int NBdrElem = 0, int _spaceDim = -1)
412  {
413  if (_spaceDim == -1)
414  {
415  _spaceDim = _Dim;
416  }
417  InitMesh(_Dim, _spaceDim, NVert, NElem, NBdrElem);
418  }
419 
420  /** @name Methods for Mesh construction.
421 
422  These methods are intended to be used with the @ref mfem_Mesh_init_ctor
423  "init constructor". */
424  ///@{
425 
426  Element *NewElement(int geom);
427 
428  void AddVertex(const double *);
429  void AddTri(const int *vi, int attr = 1);
430  void AddTriangle(const int *vi, int attr = 1);
431  void AddQuad(const int *vi, int attr = 1);
432  void AddTet(const int *vi, int attr = 1);
433  void AddHex(const int *vi, int attr = 1);
434  void AddHexAsTets(const int *vi, int attr = 1);
435  // 'elem' should be allocated using the NewElement method
436  void AddElement(Element *elem) { elements[NumOfElements++] = elem; }
437  void AddBdrElement(Element *elem) { boundary[NumOfBdrElements++] = elem; }
438  void AddBdrSegment(const int *vi, int attr = 1);
439  void AddBdrTriangle(const int *vi, int attr = 1);
440  void AddBdrQuad(const int *vi, int attr = 1);
441  void AddBdrQuadAsTriangles(const int *vi, int attr = 1);
442 
444  /// Finalize the construction of a triangular Mesh.
445  void FinalizeTriMesh(int generate_edges = 0, int refine = 0,
446  bool fix_orientation = true);
447  /// Finalize the construction of a quadrilateral Mesh.
448  void FinalizeQuadMesh(int generate_edges = 0, int refine = 0,
449  bool fix_orientation = true);
450  /// Finalize the construction of a tetrahedral Mesh.
451  void FinalizeTetMesh(int generate_edges = 0, int refine = 0,
452  bool fix_orientation = true);
453  /// Finalize the construction of a hexahedral Mesh.
454  void FinalizeHexMesh(int generate_edges = 0, int refine = 0,
455  bool fix_orientation = true);
456 
457  ///@}
458 
459  /** @brief Finalize the construction of the secondary topology (connectivity)
460  data of a Mesh. */
461  /** This method does not require any actual coordinate data (either vertex
462  coordinates for linear meshes or node coordinates for meshes with nodes)
463  to be available. However, the data generated by this method is generally
464  required by the FiniteElementSpace class.
465 
466  After calling this method, setting the Mesh vertices or nodes, it may be
467  appropriate to call the method Finalize(). */
468  void FinalizeTopology();
469 
470  /// Finalize the construction of a general Mesh.
471  /** This method will:
472  - check and optionally fix the orientation of regular elements
473  - check and fix the orientation of boundary elements
474  - assume that #vertices are defined, if #Nodes == NULL
475  - assume that #Nodes are defined, if #Nodes != NULL.
476  @param[in] refine If true, prepare the Mesh for conforming refinement of
477  triangular or tetrahedral meshes.
478  @param[in] fix_orientation
479  If true, fix the orientation of inverted mesh elements
480  by permuting their vertices.
481 
482  Before calling this method, call FinalizeTopology() and ensure that the
483  Mesh vertices or nodes are set. */
484  void Finalize(bool refine = false, bool fix_orientation = false);
485 
486  void SetAttributes();
487 
488 #ifdef MFEM_USE_GECKO
489  /** This is our integration with the Gecko library. This will call the
490  Gecko library to find an element ordering that will increase memory
491  coherency by putting elements that are in physical proximity closer in
492  memory. */
493  void GetGeckoElementReordering(Array<int> &ordering);
494 #endif
495 
496  /** Rebuilds the mesh with a different order of elements. The ordering
497  vector maps the old element number to the new element number. This also
498  reorders the vertices and nodes edges and faces along with the elements. */
499  void ReorderElements(const Array<int> &ordering, bool reorder_vertices = true);
500 
501  /** Creates mesh for the parallelepiped [0,sx]x[0,sy]x[0,sz], divided into
502  nx*ny*nz hexahedrals if type=HEXAHEDRON or into 6*nx*ny*nz tetrahedrons
503  if type=TETRAHEDRON. If generate_edges = 0 (default) edges are not
504  generated, if 1 edges are generated. */
505  Mesh(int nx, int ny, int nz, Element::Type type, int generate_edges = 0,
506  double sx = 1.0, double sy = 1.0, double sz = 1.0)
507  {
508  Make3D(nx, ny, nz, type, generate_edges, sx, sy, sz);
509  }
510 
511  /** Creates mesh for the rectangle [0,sx]x[0,sy], divided into nx*ny
512  quadrilaterals if type = QUADRILATERAL or into 2*nx*ny triangles if
513  type = TRIANGLE. If generate_edges = 0 (default) edges are not generated,
514  if 1 edges are generated. */
515  Mesh(int nx, int ny, Element::Type type, int generate_edges = 0,
516  double sx = 1.0, double sy = 1.0)
517  {
518  Make2D(nx, ny, type, generate_edges, sx, sy);
519  }
520 
521  /** Creates 1D mesh , divided into n equal intervals. */
522  explicit Mesh(int n, double sx = 1.0)
523  {
524  Make1D(n, sx);
525  }
526 
527  /** Creates mesh by reading a file in MFEM, netgen, or VTK format. If
528  generate_edges = 0 (default) edges are not generated, if 1 edges are
529  generated. */
530  Mesh(const char *filename, int generate_edges = 0, int refine = 1,
531  bool fix_orientation = true);
532 
533  /** Creates mesh by reading data stream in MFEM, netgen, or VTK format. If
534  generate_edges = 0 (default) edges are not generated, if 1 edges are
535  generated. */
536  Mesh(std::istream &input, int generate_edges = 0, int refine = 1,
537  bool fix_orientation = true);
538 
539  /// Create a disjoint mesh from the given mesh array
540  Mesh(Mesh *mesh_array[], int num_pieces);
541 
542  /// Create a uniformly refined (by any factor) version of @a orig_mesh.
543  /** @param[in] orig_mesh The starting coarse mesh.
544  @param[in] ref_factor The refinement factor, an integer > 1.
545  @param[in] ref_type Specify the positions of the new vertices. The
546  options are BasisType::ClosedUniform or
547  BasisType::GaussLobatto.
548 
549  The refinement data which can be accessed with GetRefinementTransforms()
550  is set to reflect the performed refinements.
551 
552  @note The constructed Mesh is linear, i.e. it does not have nodes. */
553  Mesh(Mesh *orig_mesh, int ref_factor, int ref_type);
554 
555  /** This is similar to the mesh constructor with the same arguments, but here
556  the current mesh is destroyed and another one created based on the data
557  stream again given in MFEM, netgen, or VTK format. If generate_edges = 0
558  (default) edges are not generated, if 1 edges are generated. */
559  /// \see mfem::igzstream() for on-the-fly decompression of compressed ascii
560  /// inputs.
561  virtual void Load(std::istream &input, int generate_edges = 0,
562  int refine = 1, bool fix_orientation = true)
563  {
564  Loader(input, generate_edges);
565  Finalize(refine, fix_orientation);
566  }
567 
568  /// Clear the contents of the Mesh.
569  void Clear() { Destroy(); SetEmpty(); }
570 
571  /** @brief Get the mesh generator/type.
572 
573  @return A bitmask:
574  - bit 0 - simplices are present in the mesh (triangles, tets),
575  - bit 1 - tensor product elements are present in the mesh (quads, hexes).
576  */
577  inline int MeshGenerator() { return meshgen; }
578 
579  /** @brief Returns number of vertices. Vertices are only at the corners of
580  elements, where you would expect them in the lowest-order mesh. */
581  inline int GetNV() const { return NumOfVertices; }
582 
583  /// Returns number of elements.
584  inline int GetNE() const { return NumOfElements; }
585 
586  /// Returns number of boundary elements.
587  inline int GetNBE() const { return NumOfBdrElements; }
588 
589  /// Return the number of edges.
590  inline int GetNEdges() const { return NumOfEdges; }
591 
592  /// Return the number of faces in a 3D mesh.
593  inline int GetNFaces() const { return NumOfFaces; }
594 
595  /// Return the number of faces (3D), edges (2D) or vertices (1D).
596  int GetNumFaces() const;
597 
598  /// Utility function: sum integers from all processors (Allreduce).
599  virtual long ReduceInt(int value) const { return value; }
600 
601  /// Return the total (global) number of elements.
602  long GetGlobalNE() const { return ReduceInt(NumOfElements); }
603 
604  /// Equals 1 + num_holes - num_loops
605  inline int EulerNumber() const
607  /// Equals 1 - num_holes
608  inline int EulerNumber2D() const
609  { return NumOfVertices - NumOfEdges + NumOfElements; }
610 
611  int Dimension() const { return Dim; }
612  int SpaceDimension() const { return spaceDim; }
613 
614  /// @brief Return pointer to vertex i's coordinates.
615  /// @warning For high-order meshes (when #Nodes != NULL) vertices may not be
616  /// updated and should not be used!
617  const double *GetVertex(int i) const { return vertices[i](); }
618 
619  /// @brief Return pointer to vertex i's coordinates.
620  /// @warning For high-order meshes (when Nodes != NULL) vertices may not
621  /// being updated and should not be used!
622  double *GetVertex(int i) { return vertices[i](); }
623 
624  void GetElementData(int geom, Array<int> &elem_vtx, Array<int> &attr) const
625  { GetElementData(elements, geom, elem_vtx, attr); }
626 
627  void GetBdrElementData(int geom, Array<int> &bdr_elem_vtx,
628  Array<int> &bdr_attr) const
629  { GetElementData(boundary, geom, bdr_elem_vtx, bdr_attr); }
630 
631  /** @brief Set the internal Vertex array to point to the given @a vertices
632  array without assuming ownership of the pointer. */
633  /** If @a zerocopy is `true`, the vertices must be given as an array of 3
634  doubles per vertex. If @a zerocopy is `false` then the current Vertex
635  data is first copied to the @a vertices array. */
636  void ChangeVertexDataOwnership(double *vertices, int len_vertices,
637  bool zerocopy = false);
638 
639  const Element* const *GetElementsArray() const
640  { return elements.GetData(); }
641 
642  const Element *GetElement(int i) const { return elements[i]; }
643 
644  Element *GetElement(int i) { return elements[i]; }
645 
646  const Element *GetBdrElement(int i) const { return boundary[i]; }
647 
648  Element *GetBdrElement(int i) { return boundary[i]; }
649 
650  const Element *GetFace(int i) const { return faces[i]; }
651 
652  int GetFaceBaseGeometry(int i) const;
653 
654  int GetElementBaseGeometry(int i = 0) const
655  { return i < GetNE() ? elements[i]->GetGeometryType() : BaseGeom; }
656 
657  int GetBdrElementBaseGeometry(int i = 0) const
658  { return i < GetNBE() ? boundary[i]->GetGeometryType() : BaseBdrGeom; }
659 
660  /// Returns the indices of the dofs of element i.
661  void GetElementVertices(int i, Array<int> &dofs) const
662  { elements[i]->GetVertices(dofs); }
663 
664  /// Returns the indices of the dofs of boundary element i.
665  void GetBdrElementVertices(int i, Array<int> &dofs) const
666  { boundary[i]->GetVertices(dofs); }
667 
668  /// Return the indices and the orientations of all edges of element i.
669  void GetElementEdges(int i, Array<int> &edges, Array<int> &cor) const;
670 
671  /// Return the indices and the orientations of all edges of bdr element i.
672  void GetBdrElementEdges(int i, Array<int> &edges, Array<int> &cor) const;
673 
674  /** Return the indices and the orientations of all edges of face i.
675  Works for both 2D (face=edge) and 3D faces. */
676  void GetFaceEdges(int i, Array<int> &, Array<int> &) const;
677 
678  /// Returns the indices of the vertices of face i.
679  void GetFaceVertices(int i, Array<int> &vert) const
680  {
681  if (Dim == 1)
682  {
683  vert.SetSize(1); vert[0] = i;
684  }
685  else
686  {
687  faces[i]->GetVertices(vert);
688  }
689  }
690 
691  /// Returns the indices of the vertices of edge i.
692  void GetEdgeVertices(int i, Array<int> &vert) const;
693 
694  /// Returns the face-to-edge Table (3D)
695  Table *GetFaceEdgeTable() const;
696 
697  /// Returns the edge-to-vertex Table (3D)
698  Table *GetEdgeVertexTable() const;
699 
700  /// Return the indices and the orientations of all faces of element i.
701  void GetElementFaces(int i, Array<int> &, Array<int> &) const;
702 
703  /// Return the index and the orientation of the face of bdr element i. (3D)
704  void GetBdrElementFace(int i, int *, int *) const;
705 
706  /** Return the vertex index of boundary element i. (1D)
707  Return the edge index of boundary element i. (2D)
708  Return the face index of boundary element i. (3D) */
709  int GetBdrElementEdgeIndex(int i) const;
710 
711  /** @brief For the given boundary element, bdr_el, return its adjacent
712  element and its info, i.e. 64*local_bdr_index+bdr_orientation. */
713  void GetBdrElementAdjacentElement(int bdr_el, int &el, int &info) const;
714 
715  /// Returns the type of element i.
716  int GetElementType(int i) const;
717 
718  /// Returns the type of boundary element i.
719  int GetBdrElementType(int i) const;
720 
721  /* Return point matrix of element i of dimension Dim X #dofs, where for
722  every degree of freedom we give its coordinates in space of dimension
723  Dim. */
724  void GetPointMatrix(int i, DenseMatrix &pointmat) const;
725 
726  /* Return point matrix of boundary element i of dimension Dim X #dofs,
727  where for every degree of freedom we give its coordinates in space
728  of dimension Dim. */
729  void GetBdrPointMatrix(int i, DenseMatrix &pointmat) const;
730 
732 
733  /** Builds the transformation defining the i-th element in the user-defined
734  variable. */
736 
737  /// Returns the transformation defining the i-th element
739 
740  /** Return the transformation defining the i-th element assuming
741  the position of the vertices/nodes are given by 'nodes'. */
742  void GetElementTransformation(int i, const Vector &nodes,
744 
745  /// Returns the transformation defining the i-th boundary element
748 
749  /** Returns the transformation defining the given face element.
750  The transformation is stored in a user-defined variable. */
752 
753  /// Returns the transformation defining the given face element
755 
756  /** Returns the transformation defining the given edge element.
757  The transformation is stored in a user-defined variable. */
759 
760  /// Returns the transformation defining the given face element
762 
763  /// Returns (a pointer to a structure containing) the following data:
764  ///
765  /// 1) Elem1No - the index of the first element that contains this face this
766  /// is the element that has the same outward unit normal vector as the
767  /// face;
768  ///
769  /// 2) Elem2No - the index of the second element that contains this face this
770  /// element has outward unit normal vector as the face multiplied with -1;
771  ///
772  /// 3) Elem1, Elem2 - pointers to the ElementTransformation's of the first
773  /// and the second element respectively;
774  ///
775  /// 4) Face - pointer to the ElementTransformation of the face;
776  ///
777  /// 5) Loc1, Loc2 - IntegrationPointTransformation's mapping the face
778  /// coordinate system to the element coordinate system (both in their
779  /// reference elements). Used to transform IntegrationPoints from face to
780  /// element. More formally, let:
781  /// TL1, TL2 be the transformations represented by Loc1, Loc2,
782  /// TE1, TE2 - the transformations represented by Elem1, Elem2,
783  /// TF - the transformation represented by Face, then
784  /// TF(x) = TE1(TL1(x)) = TE2(TL2(x)) for all x in the reference face.
785  ///
786  /// 6) FaceGeom - the base geometry for the face.
787  ///
788  /// The mask specifies which fields in the structure to return:
789  /// mask & 1 - Elem1, mask & 2 - Elem2
790  /// mask & 4 - Loc1, mask & 8 - Loc2, mask & 16 - Face.
792  int mask = 31);
793 
795  {
796  if (faces_info[FaceNo].Elem2No < 0) { return NULL; }
797  return GetFaceElementTransformations (FaceNo);
798  }
799 
801 
802  /// Return true if the given face is interior
803  bool FaceIsInterior(int FaceNo) const
804  {
805  return (faces_info[FaceNo].Elem2No >= 0);
806  }
807  void GetFaceElements (int Face, int *Elem1, int *Elem2);
808  void GetFaceInfos (int Face, int *Inf1, int *Inf2);
809 
810  int GetFaceGeometryType(int Face) const;
811  int GetFaceElementType(int Face) const;
812 
813  /// Check the orientation of the elements
814  /** @return The number of elements with wrong orientation. */
815  int CheckElementOrientation(bool fix_it = true);
816  /// Check the orientation of the boundary elements
817  /** @return The number of boundary elements with wrong orientation. */
818  int CheckBdrElementOrientation(bool fix_it = true);
819 
820  /// Return the attribute of element i.
821  int GetAttribute(int i) const { return elements[i]->GetAttribute();}
822 
823  /// Return the attribute of boundary element i.
824  int GetBdrAttribute(int i) const { return boundary[i]->GetAttribute(); }
825 
826  const Table &ElementToElementTable();
827 
828  const Table &ElementToFaceTable() const;
829 
830  const Table &ElementToEdgeTable() const;
831 
832  /// The returned Table must be destroyed by the caller
834 
835  /** Return the "face"-element Table. Here "face" refers to face (3D),
836  edge (2D), or vertex (1D).
837  The returned Table must be destroyed by the caller. */
838  Table *GetFaceToElementTable() const;
839 
840  /** This method modifies a tetrahedral mesh so that Nedelec spaces of order
841  greater than 1 can be defined on the mesh. Specifically, we
842  1) rotate all tets in the mesh so that the vertices {v0, v1, v2, v3}
843  satisfy: v0 < v1 < min(v2, v3).
844  2) rotate all boundary triangles so that the vertices {v0, v1, v2}
845  satisfy: v0 < min(v1, v2).
846 
847  @note Refinement does not work after a call to this method! */
848  virtual void ReorientTetMesh();
849 
850  int *CartesianPartitioning(int nxyz[]);
851  int *GeneratePartitioning(int nparts, int part_method = 1);
852  void CheckPartitioning(int *partitioning);
853 
854  void CheckDisplacements(const Vector &displacements, double &tmax);
855 
856  // Vertices are only at the corners of elements, where you would expect them
857  // in the lowest-order mesh.
858  void MoveVertices(const Vector &displacements);
859  void GetVertices(Vector &vert_coord) const;
860  void SetVertices(const Vector &vert_coord);
861 
862  // Nodes are only active for higher order meshes, and share locations with
863  // the vertices, plus all the higher- order control points within the element
864  // and along the edges and on the faces.
865  void GetNode(int i, double *coord);
866  void SetNode(int i, const double *coord);
867 
868  // Node operations for curved mesh.
869  // They call the corresponding '...Vertices' method if the
870  // mesh is not curved (i.e. Nodes == NULL).
871  void MoveNodes(const Vector &displacements);
872  void GetNodes(Vector &node_coord) const;
873  void SetNodes(const Vector &node_coord);
874 
875  /// Return a pointer to the internal node GridFunction (may be NULL).
876  GridFunction *GetNodes() { return Nodes; }
877  const GridFunction *GetNodes() const { return Nodes; }
878  /// Return the mesh nodes ownership flag.
879  bool OwnsNodes() const { return own_nodes; }
880  /// Set the mesh nodes ownership flag.
881  void SetNodesOwner(bool nodes_owner) { own_nodes = nodes_owner; }
882  /// Replace the internal node GridFunction with the given GridFunction.
883  void NewNodes(GridFunction &nodes, bool make_owner = false);
884  /** Swap the internal node GridFunction pointer and ownership flag members
885  with the given ones. */
886  void SwapNodes(GridFunction *&nodes, int &own_nodes_);
887 
888  /// Return the mesh nodes/vertices projected on the given GridFunction.
889  void GetNodes(GridFunction &nodes) const;
890  /** Replace the internal node GridFunction with a new GridFunction defined
891  on the given FiniteElementSpace. The new node coordinates are projected
892  (derived) from the current nodes/vertices. */
894  /** Replace the internal node GridFunction with the given GridFunction. The
895  given GridFunction is updated with node coordinates projected (derived)
896  from the current nodes/vertices. */
897  void SetNodalGridFunction(GridFunction *nodes, bool make_owner = false);
898  /** Return the FiniteElementSpace on which the current mesh nodes are
899  defined or NULL if the mesh does not have nodes. */
900  const FiniteElementSpace *GetNodalFESpace() const;
901 
902  /** Set the curvature of the mesh nodes using the given polynomial degree,
903  'order', and optionally: discontinuous or continuous FE space, 'discont',
904  new space dimension, 'space_dim' (if != -1), and 'ordering'. */
905  void SetCurvature(int order, bool discont = false, int space_dim = -1,
906  int ordering = 1);
907 
908  /** Refine all mesh elements. */
909  void UniformRefinement();
910 
911  /** Refine selected mesh elements. Refinement type can be specified for each
912  element. The function can do conforming refinement of triangles and
913  tetrahedra and non-conforming refinement (i.e., with hanging-nodes) of
914  triangles, quadrilaterals and hexahedrons. If 'nonconforming' = -1,
915  suitable refinement method is selected automatically (namely, conforming
916  refinement for triangles). Use nonconforming = 0/1 to force the method.
917  For nonconforming refinements, nc_limit optionally specifies the maximum
918  level of hanging nodes (unlimited by default). */
919  void GeneralRefinement(const Array<Refinement> &refinements,
920  int nonconforming = -1, int nc_limit = 0);
921 
922  /** Simplified version of GeneralRefinement taking a simple list of elements
923  to refine, without refinement types. */
924  void GeneralRefinement(const Array<int> &el_to_refine,
925  int nonconforming = -1, int nc_limit = 0);
926 
927  /// Refine each element with given probability. Uses GeneralRefinement.
928  void RandomRefinement(double prob, bool aniso = false,
929  int nonconforming = -1, int nc_limit = 0);
930 
931  /// Refine elements sharing the specified vertex. Uses GeneralRefinement.
932  void RefineAtVertex(const Vertex& vert,
933  double eps = 0.0, int nonconforming = -1);
934 
935  /** Refine element i if elem_error[i] > threshold, for all i.
936  Returns true if at least one element was refined, false otherwise. */
937  bool RefineByError(const Array<double> &elem_error, double threshold,
938  int nonconforming = -1, int nc_limit = 0);
939 
940  /** Refine element i if elem_error(i) > threshold, for all i.
941  Returns true if at least one element was refined, false otherwise. */
942  bool RefineByError(const Vector &elem_error, double threshold,
943  int nonconforming = -1, int nc_limit = 0);
944 
945  /** Derefine the mesh based on an error measure associated with each
946  element. A derefinement is performed if the sum of errors of its fine
947  elements is smaller than 'threshold'. If 'nc_limit' > 0, derefinements
948  that would increase the maximum level of hanging nodes of the mesh are
949  skipped. Returns true if the mesh changed, false otherwise. */
950  bool DerefineByError(Array<double> &elem_error, double threshold,
951  int nc_limit = 0, int op = 1);
952 
953  /// Same as DerefineByError for an error vector.
954  bool DerefineByError(const Vector &elem_error, double threshold,
955  int nc_limit = 0, int op = 1);
956 
957  ///@{ @name NURBS mesh refinement methods
959  void DegreeElevate(int t);
960  ///@}
961 
962  /** Make sure that a quad/hex mesh is considered to be non-conforming (i.e.,
963  has an associated NCMesh object). Triangles meshes can be both conforming
964  (default) or non-conforming. */
965  void EnsureNCMesh(bool triangles_nonconforming = false);
966 
967  bool Conforming() const { return ncmesh == NULL; }
968  bool Nonconforming() const { return ncmesh != NULL; }
969 
970  /** Return fine element transformations following a mesh refinement.
971  Space uses this to construct a global interpolation matrix. */
973 
974  /// Return type of last modification of the mesh.
976 
977  /** Return update counter. The counter starts at zero and is incremented
978  each time refinement, derefinement, or rebalancing method is called.
979  It is used for checking proper sequence of Space:: and GridFunction::
980  Update() calls. */
981  long GetSequence() const { return sequence; }
982 
983  /// Print the mesh to the given stream using Netgen/Truegrid format.
984  virtual void PrintXG(std::ostream &out = std::cout) const;
985 
986  /// Print the mesh to the given stream using the default MFEM mesh format.
987  /// \see mfem::ogzstream() for on-the-fly compression of ascii outputs
988  virtual void Print(std::ostream &out = std::cout) const { Printer(out); }
989 
990  /// Print the mesh in VTK format (linear and quadratic meshes only).
991  /// \see mfem::ogzstream() for on-the-fly compression of ascii outputs
992  void PrintVTK(std::ostream &out);
993 
994  /** Print the mesh in VTK format. The parameter ref > 0 specifies an element
995  subdivision number (useful for high order fields and curved meshes).
996  If the optional field_data is set, we also add a FIELD section in the
997  beginning of the file with additional dataset information. */
998  /// \see mfem::ogzstream() for on-the-fly compression of ascii outputs
999  void PrintVTK(std::ostream &out, int ref, int field_data=0);
1000 
1001  void GetElementColoring(Array<int> &colors, int el0 = 0);
1002 
1003  /** Prints the mesh with bdr elements given by the boundary of
1004  the subdomains, so that the boundary of subdomain i has bdr
1005  attribute i+1. */
1006  /// \see mfem::ogzstream() for on-the-fly compression of ascii outputs
1007  void PrintWithPartitioning (int *partitioning,
1008  std::ostream &out, int elem_attr = 0) const;
1009 
1010  void PrintElementsWithPartitioning (int *partitioning,
1011  std::ostream &out,
1012  int interior_faces = 0);
1013 
1014  /// Print set of disjoint surfaces:
1015  /*!
1016  * If Aface_face(i,j) != 0, print face j as a boundary
1017  * element with attribute i+1.
1018  */
1019  void PrintSurfaces(const Table &Aface_face, std::ostream &out) const;
1020 
1021  void ScaleSubdomains (double sf);
1022  void ScaleElements (double sf);
1023 
1024  void Transform(void (*f)(const Vector&, Vector&));
1025  void Transform(VectorCoefficient &deformation);
1026 
1027  /// Remove unused vertices and rebuild mesh connectivity.
1028  void RemoveUnusedVertices();
1029 
1030  /** Remove boundary elements that lie in the interior of the mesh, i.e. that
1031  have two adjacent faces in 3D, or edges in 2D. */
1032  void RemoveInternalBoundaries();
1033 
1034  /** Get the size of the i-th element relative to the perfect
1035  reference element. */
1036  double GetElementSize(int i, int type = 0);
1037 
1038  double GetElementSize(int i, const Vector &dir);
1039 
1040  double GetElementVolume(int i);
1041 
1042  /// Returns the minimum and maximum corners of the mesh bounding box. For
1043  /// high-order meshes, the geometry is refined first "ref" times.
1044  void GetBoundingBox(Vector &min, Vector &max, int ref = 2);
1045 
1046  void PrintCharacteristics(Vector *Vh = NULL, Vector *Vk = NULL,
1047  std::ostream &out = std::cout);
1048 
1049  virtual void PrintInfo(std::ostream &out = std::cout)
1050  {
1051  PrintCharacteristics(NULL, NULL, out);
1052  }
1053 
1054  void MesquiteSmooth(const int mesquite_option = 0);
1055 
1056  /// Destroys Mesh.
1057  virtual ~Mesh() { DestroyPointers(); }
1058 };
1059 
1060 /** Overload operator<< for std::ostream and Mesh; valid also for the derived
1061  class ParMesh */
1062 std::ostream &operator<<(std::ostream &out, const Mesh &mesh);
1063 
1064 
1065 /// Class used to extrude the nodes of a mesh
1067 {
1068 private:
1069  int n, layer;
1070  double p[2], s;
1071  Vector tip;
1072 public:
1073  NodeExtrudeCoefficient(const int dim, const int _n, const double _s);
1074  void SetLayer(const int l) { layer = l; }
1076  virtual void Eval(Vector &V, ElementTransformation &T,
1077  const IntegrationPoint &ip);
1079 };
1080 
1081 
1082 /// Extrude a 1D mesh
1083 Mesh *Extrude1D(Mesh *mesh, const int ny, const double sy,
1084  const bool closed = false);
1085 
1086 
1087 /// Input file stream that remembers the input file name (useful for example
1088 /// when reading NetCDF meshes) and supports optional gzstream decompression.
1090 {
1091 public:
1092  const char *filename;
1093  named_ifgzstream(const char *mesh_name) :
1094  mfem::ifgzstream(mesh_name), filename(mesh_name) {}
1095 };
1096 
1097 
1098 // inline functions
1099 inline void Mesh::ShiftL2R(int &a, int &b, int &c)
1100 {
1101  int t = a;
1102  a = c; c = b; b = t;
1103 }
1104 
1105 inline void Mesh::Rotate3(int &a, int &b, int &c)
1106 {
1107  if (a < b)
1108  {
1109  if (a > c)
1110  {
1111  ShiftL2R(a, b, c);
1112  }
1113  }
1114  else
1115  {
1116  if (b < c)
1117  {
1118  ShiftL2R(c, b, a);
1119  }
1120  else
1121  {
1122  ShiftL2R(a, b, c);
1123  }
1124  }
1125 }
1126 
1127 }
1128 
1129 #endif
Abstract class for Finite Elements.
Definition: fe.hpp:46
void AddHex(const int *vi, int attr=1)
Definition: mesh.cpp:949
void Loader(std::istream &input, int generate_edges=0, std::string parse_tag="")
Definition: mesh.cpp:2543
std::ostream & operator<<(std::ostream &out, const Mesh &mesh)
Definition: mesh.cpp:8491
void GetFaceEdges(int i, Array< int > &, Array< int > &) const
Definition: mesh.cpp:3675
void PrintSurfaces(const Table &Aface_face, std::ostream &out) const
Print set of disjoint surfaces:
Definition: mesh.cpp:8023
void GetPointMatrix(int i, DenseMatrix &pointmat) const
Definition: mesh.cpp:3962
static const int vtk_quadratic_hex[27]
Definition: mesh.hpp:123
int * CartesianPartitioning(int nxyz[])
Definition: mesh.cpp:4541
virtual void PrintInfo(std::ostream &out=std::cout)
Definition: mesh.hpp:1049
const DenseMatrix * PointMatrix
Definition: mesh.hpp:90
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
Definition: mesh.hpp:824
const double * GetVertex(int i) const
Return pointer to vertex i&#39;s coordinates.
Definition: mesh.hpp:617
void ScaleElements(double sf)
Definition: mesh.cpp:8158
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:27
Table * GetEdgeVertexTable() const
Returns the edge-to-vertex Table (3D)
Definition: mesh.cpp:3742
void GetBdrElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of bdr element i.
Definition: mesh.cpp:3643
void FreeElement(Element *E)
Definition: mesh.cpp:8472
void DerefineMesh(const Array< int > &derefinements)
Derefine elements once a list of derefinements is known.
Definition: mesh.cpp:6018
void GetFaceInfos(int Face, int *Inf1, int *Inf2)
Definition: mesh.cpp:719
int CheckElementOrientation(bool fix_it=true)
Check the orientation of the elements.
Definition: mesh.cpp:3312
void SetVertices(const Vector &vert_coord)
Definition: mesh.cpp:5308
static const int vtk_quadratic_tet[10]
Definition: mesh.hpp:122
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
Definition: mesh.cpp:3705
bool FaceIsTrueInterior(int FaceNo) const
Definition: mesh.hpp:319
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)
Definition: mesh.cpp:8504
long GetGlobalNE() const
Return the total (global) number of elements.
Definition: mesh.hpp:602
void AddHexAsTets(const int *vi, int attr=1)
Definition: mesh.cpp:954
void GetFaceElements(int Face, int *Elem1, int *Elem2)
Definition: mesh.cpp:713
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
Array< Element * > boundary
Definition: mesh.hpp:72
Geometry::Constants< Geometry::SQUARE > quad_t
Definition: mesh.hpp:133
int * GeneratePartitioning(int nparts, int part_method=1)
Definition: mesh.cpp:4586
CoarseFineTransformations CoarseFineTr
Definition: mesh.hpp:114
int own_nodes
Definition: mesh.hpp:120
bool Conforming() const
Definition: mesh.hpp:967
void MoveVertices(const Vector &displacements)
Definition: mesh.cpp:5288
int GetNBE() const
Returns number of boundary elements.
Definition: mesh.hpp:587
IsoparametricTransformation Transformation
Definition: mesh.hpp:109
void GetLocalPtToSegTransformation(IsoparametricTransformation &, int)
Used in GetFaceElementTransformations (...)
Definition: mesh.cpp:475
void PrintWithPartitioning(int *partitioning, std::ostream &out, int elem_attr=0) const
Definition: mesh.cpp:7538
int GetFaceGeometryType(int Face) const
Definition: mesh.cpp:725
const Geometry::Type geom
void NewNodes(GridFunction &nodes, bool make_owner=false)
Replace the internal node GridFunction with the given GridFunction.
Definition: mesh.cpp:5392
int NumOfEdges
Definition: mesh.hpp:57
void SwapNodes(GridFunction *&nodes, int &own_nodes_)
Definition: mesh.cpp:5406
void GetElementFaces(int i, Array< int > &, Array< int > &) const
Return the indices and the orientations of all faces of element i.
Definition: mesh.cpp:3837
void GetLocalFaceTransformation(int face_type, int elem_type, IsoparametricTransformation &Transf, int inf)
Used in GetFaceElementTransformations (...)
Definition: mesh.cpp:571
void AddBdrElement(Element *elem)
Definition: mesh.hpp:437
int BaseGeom
Definition: mesh.hpp:59
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Definition: mesh.cpp:88
void ReadNetgen2DMesh(std::istream &input, int &curved)
void DegreeElevate(int t)
Definition: mesh.cpp:3038
int EulerNumber2D() const
Equals 1 - num_holes.
Definition: mesh.hpp:608
void AddTri(const int *vi, int attr=1)
Definition: mesh.cpp:921
void DeleteTables()
Definition: mesh.hpp:154
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
Definition: mesh.hpp:679
Data type dense matrix using column-major storage.
Definition: densemat.hpp:22
GridFunction * Nodes
Definition: mesh.hpp:119
int NumOfElements
Definition: mesh.hpp:56
Mesh * Extrude1D(Mesh *mesh, const int ny, const double sy, const bool closed)
Extrude a 1D mesh.
Definition: mesh.cpp:8522
void Transform(void(*f)(const Vector &, Vector &))
Definition: mesh.cpp:8228
void FinalizeCheck()
Definition: mesh.cpp:1041
int GetBdrElementEdgeIndex(int i) const
Definition: mesh.cpp:3920
int GetNE() const
Returns number of elements.
Definition: mesh.hpp:584
const Element * GetFace(int i) const
Definition: mesh.hpp:650
Element * GetElement(int i)
Definition: mesh.hpp:644
void GenerateBoundaryElements()
Definition: mesh.cpp:1003
void GetElementVertices(int i, Array< int > &dofs) const
Returns the indices of the dofs of element i.
Definition: mesh.hpp:661
Data type for vertex.
Definition: vertex.hpp:21
void SetMeshGen()
Determine the mesh generator bitmask meshgen, see MeshGenerator().
Definition: mesh.cpp:2524
static int GetQuadOrientation(const int *base, const int *test)
Returns the orientation of &quot;test&quot; relative to &quot;base&quot;.
Definition: mesh.cpp:3471
void GetVertices(Vector &vert_coord) const
Definition: mesh.cpp:5297
void ReadNetgen3DMesh(std::istream &input)
int BaseBdrGeom
Definition: mesh.hpp:59
void AddBdrSegment(const int *vi, int attr=1)
Definition: mesh.cpp:973
int GetFaceElementType(int Face) const
Definition: mesh.cpp:730
FaceElementTransformations * GetInteriorFaceTransformations(int FaceNo)
Definition: mesh.hpp:794
void RemoveInternalBoundaries()
Definition: mesh.cpp:8384
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
Definition: mesh.cpp:604
void SetEmpty()
Definition: mesh.cpp:758
Array< Element * > faces
Definition: mesh.hpp:73
virtual long ReduceInt(int value) const
Utility function: sum integers from all processors (Allreduce).
Definition: mesh.hpp:599
void FinalizeHexMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
Finalize the construction of a hexahedral Mesh.
Definition: mesh.cpp:1696
void GetVertexToVertexTable(DSTable &) const
Definition: mesh.cpp:4031
void RedRefinement(int i, const DSTable &v_to_v, int *edge1, int *edge2, int *middle)
Definition: mesh.hpp:203
Operation last_operation
Definition: mesh.hpp:148
void MarkTriMeshForRefinement()
Definition: mesh.cpp:1328
void ReadCubit(const char *filename, int &curved, int &read_gf)
void InitRefinementTransforms()
Definition: mesh.cpp:6774
IsoparametricTransformation FaceTransformation
Definition: mesh.hpp:110
Array< NCFaceInfo > nc_faces_info
Definition: mesh.hpp:98
Element * ReadElement(std::istream &)
Definition: mesh.cpp:2506
void KnotInsert(Array< KnotVector * > &kv)
Definition: mesh.cpp:3006
A parallel extension of the NCMesh class.
Definition: pncmesh.hpp:65
Element * NewElement(int geom)
Definition: mesh.cpp:2457
FaceElementTransformations FaceElemTr
Definition: mesh.hpp:111
Table * el_to_face
Definition: mesh.hpp:101
void GetEdgeTransformation(int i, IsoparametricTransformation *EdTr)
Definition: mesh.cpp:413
const GridFunction * GetNodes() const
Definition: mesh.hpp:877
void MarkForRefinement()
Definition: mesh.cpp:1311
ElementTransformation * GetBdrElementTransformation(int i)
Returns the transformation defining the i-th boundary element.
Definition: mesh.cpp:311
void AddVertex(const double *)
Definition: mesh.cpp:910
Mesh(int _Dim, int NVert, int NElem, int NBdrElem=0, int _spaceDim=-1)
Init constructor: begin the construction of a Mesh object.
Definition: mesh.hpp:411
void PrintTopo(std::ostream &out, const Array< int > &e_to_k) const
Definition: mesh.cpp:7100
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Definition: mesh.cpp:3297
Geometry::Constants< Geometry::SEGMENT > seg_t
Definition: mesh.hpp:131
void AddElement(Element *elem)
Definition: mesh.hpp:436
void GetElementJacobian(int i, DenseMatrix &J)
Definition: mesh.cpp:36
void MesquiteSmooth(const int mesquite_option=0)
Definition: mesquite.cpp:1144
long GetSequence() const
Definition: mesh.hpp:981
bool Nonconforming() const
Definition: mesh.hpp:968
Mesh(int nx, int ny, Element::Type type, int generate_edges=0, double sx=1.0, double sy=1.0)
Definition: mesh.hpp:515
void MoveNodes(const Vector &displacements)
Definition: mesh.cpp:5356
void GetEdgeOrdering(DSTable &v_to_v, Array< int > &order)
Definition: mesh.cpp:1343
void GetElementData(int geom, Array< int > &elem_vtx, Array< int > &attr) const
Definition: mesh.hpp:624
int dim
Definition: ex3.cpp:47
NCFaceInfo(bool slave, int master, const DenseMatrix *pm)
Definition: mesh.hpp:93
void FinalizeTriMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
Finalize the construction of a triangular Mesh.
Definition: mesh.cpp:1054
void UpdateNURBS()
Definition: mesh.cpp:3060
Symmetric 3D Table.
Definition: stable3d.hpp:28
void FinalizeTetMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
Finalize the construction of a tetrahedral Mesh.
Definition: mesh.cpp:1652
void AddBdrQuadAsTriangles(const int *vi, int attr=1)
Definition: mesh.cpp:988
void AddSegmentFaceElement(int lf, int gf, int el, int v0, int v1)
Definition: mesh.cpp:4166
void SetAttributes()
Definition: mesh.cpp:839
int FindCoarseElement(int i)
Definition: mesh.cpp:6786
void GetFaceTransformation(int i, IsoparametricTransformation *FTr)
Definition: mesh.cpp:345
void GetLocalSegToTriTransformation(IsoparametricTransformation &loc, int i)
Definition: mesh.cpp:489
void AddQuadFaceElement(int lf, int gf, int el, int v0, int v1, int v2, int v3)
Definition: mesh.cpp:4217
static FiniteElement * GetTransformationFEforElementType(int)
Definition: mesh.cpp:222
void LoadPatchTopo(std::istream &input, Array< int > &edge_to_knot)
Read NURBS patch/macro-element mesh.
Definition: mesh.cpp:3123
STable3D * GetElementToFaceTable(int ret_ftbl=0)
Definition: mesh.cpp:4389
void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
Definition: mesh.cpp:3278
static void Rotate3(int &, int &, int &)
Definition: mesh.hpp:1105
void Make2D(int nx, int ny, Element::Type type, int generate_edges, double sx, double sy)
Definition: mesh.cpp:2055
int MeshGenerator()
Get the mesh generator/type.
Definition: mesh.hpp:577
const char * filename
Definition: mesh.hpp:1092
Type
Constants for the classes derived from Element.
Definition: element.hpp:37
void GetBdrPointMatrix(int i, DenseMatrix &pointmat) const
Definition: mesh.cpp:3978
void InitTables()
Definition: mesh.cpp:752
void CheckDisplacements(const Vector &displacements, double &tmax)
Definition: mesh.cpp:5211
void ReadInlineMesh(std::istream &input, int generate_edges=0)
Geometry::Constants< Geometry::TETRAHEDRON > tet_t
Definition: mesh.hpp:134
void ReadLineMesh(std::istream &input)
virtual void Load(std::istream &input, int generate_edges=0, int refine=1, bool fix_orientation=true)
Definition: mesh.hpp:561
void SetNodesOwner(bool nodes_owner)
Set the mesh nodes ownership flag.
Definition: mesh.hpp:881
void SetLayer(const int l)
Definition: mesh.hpp:1074
int GetElementToEdgeTable(Table &, Array< int > &)
Definition: mesh.cpp:4056
void GetBdrElementAdjacentElement(int bdr_el, int &el, int &info) const
For the given boundary element, bdr_el, return its adjacent element and its info, i...
Definition: mesh.cpp:3932
void RandomRefinement(double prob, bool aniso=false, int nonconforming=-1, int nc_limit=0)
Refine each element with given probability. Uses GeneralRefinement.
Definition: mesh.cpp:6367
int GetElementType(int i) const
Returns the type of element i.
Definition: mesh.cpp:3952
const Element * GetElement(int i) const
Definition: mesh.hpp:642
Mesh(int n, double sx=1.0)
Definition: mesh.hpp:522
void GetLocalQuadToHexTransformation(IsoparametricTransformation &loc, int i)
Used in GetFaceElementTransformations (...)
Definition: mesh.cpp:550
IsoparametricTransformation Transformation2
Definition: mesh.hpp:109
void Init()
Definition: mesh.cpp:735
void SetNodalFESpace(FiniteElementSpace *nfes)
Definition: mesh.cpp:3261
Element * GetBdrElement(int i)
Definition: mesh.hpp:648
A class for non-conforming AMR on higher-order hexahedral, quadrilateral or triangular meshes...
Definition: ncmesh.hpp:80
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
Definition: mesh.cpp:687
int Dimension() const
Definition: mesh.hpp:611
virtual void ReorientTetMesh()
Definition: mesh.cpp:4462
int NumOfBdrElements
Definition: mesh.hpp:56
Table * el_to_edge
Definition: mesh.hpp:100
void InitBaseGeom()
Definition: mesh.cpp:887
static void ShiftL2R(int &, int &, int &)
Definition: mesh.hpp:1099
virtual void LocalRefinement(const Array< int > &marked_el, int type=3)
This function is not public anymore. Use GeneralRefinement instead.
Definition: mesh.cpp:5713
int GetBdrElementType(int i) const
Returns the type of boundary element i.
Definition: mesh.cpp:3957
void GetGeckoElementReordering(Array< int > &ordering)
Definition: mesh.cpp:1119
Data type tetrahedron element.
Definition: tetrahedron.hpp:22
virtual void MarkTetMeshForRefinement(DSTable &v_to_v)
Definition: mesh.cpp:1368
void Destroy()
Definition: mesh.cpp:811
double GetElementSize(int i, int type=0)
Definition: mesh.cpp:44
int CheckBdrElementOrientation(bool fix_it=true)
Check the orientation of the boundary elements.
Definition: mesh.cpp:3519
int SpaceDimension() const
Definition: mesh.hpp:612
void GetBdrElementFace(int i, int *, int *) const
Return the index and the orientation of the face of bdr element i. (3D)
Definition: mesh.cpp:3875
void CheckPartitioning(int *partitioning)
Definition: mesh.cpp:4893
void PrintElementsWithPartitioning(int *partitioning, std::ostream &out, int interior_faces=0)
Definition: mesh.cpp:7649
bool FaceIsInterior(int FaceNo) const
Return true if the given face is interior.
Definition: mesh.hpp:803
void ReadMFEMMesh(std::istream &input, bool mfem_v11, int &curved)
void AddPointFaceElement(int lf, int gf, int el)
Used in GenerateFaces()
Definition: mesh.cpp:4149
void Make1D(int n, double sx=1.0)
Creates a 1D mesh for the interval [0,sx] divided into n equal intervals.
Definition: mesh.cpp:2215
const Element *const * GetElementsArray() const
Definition: mesh.hpp:639
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition: mesh.hpp:142
void FinalizeTopology()
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
Definition: mesh.cpp:1729
virtual void NonconformingRefinement(const Array< Refinement > &refinements, int nc_limit=0)
This function is not public anymore. Use GeneralRefinement instead.
Definition: mesh.cpp:5970
void PrintVTK(std::ostream &out)
Definition: mesh.cpp:7142
virtual ~Mesh()
Destroys Mesh.
Definition: mesh.hpp:1057
Table * el_to_el
Definition: mesh.hpp:102
Geometry::Constants< Geometry::CUBE > hex_t
Definition: mesh.hpp:135
void RemoveUnusedVertices()
Remove unused vertices and rebuild mesh connectivity.
Definition: mesh.cpp:8277
void ApplyLocalSlaveTransformation(IsoparametricTransformation &transf, const FaceInfo &fi)
Definition: mesh.cpp:674
static void PrintElement(const Element *, std::ostream &)
Definition: mesh.cpp:2518
virtual void NURBSUniformRefinement()
Refine NURBS mesh.
Definition: mesh.cpp:3025
static void GetElementArrayEdgeTable(const Array< Element * > &elem_array, const DSTable &v_to_v, Table &el_to_edge)
Definition: mesh.cpp:4009
void PrintCharacteristics(Vector *Vh=NULL, Vector *Vk=NULL, std::ostream &out=std::cout)
Definition: mesh.cpp:151
GridFunction * GetNodes()
Return a pointer to the internal node GridFunction (may be NULL).
Definition: mesh.hpp:876
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:349
void PrepareNodeReorder(DSTable **old_v_to_v, Table **old_elem_vert)
Definition: mesh.cpp:1391
bool IsSlaveFace(const FaceInfo &fi) const
Definition: mesh.cpp:669
void AddQuad(const int *vi, int attr=1)
Definition: mesh.cpp:931
void ReadGmshMesh(std::istream &input)
Array< Vertex > vertices
Definition: mesh.hpp:71
virtual void QuadUniformRefinement()
Refine quadrilateral mesh.
Definition: mesh.cpp:5446
virtual void HexUniformRefinement()
Refine hexahedral mesh.
Definition: mesh.cpp:5548
void Printer(std::ostream &out=std::cout, std::string section_delimiter="") const
Definition: mesh.cpp:7018
void RefineAtVertex(const Vertex &vert, double eps=0.0, int nonconforming=-1)
Refine elements sharing the specified vertex. Uses GeneralRefinement.
Definition: mesh.cpp:6386
void Swap(Mesh &other, bool non_geometry=false)
Definition: mesh.cpp:6176
Array< Element * > elements
Definition: mesh.hpp:68
const Table & ElementToElementTable()
Definition: mesh.cpp:4095
double GetLength(int i, int j) const
Return the length of the segment from node i to node j.
Definition: mesh.cpp:3994
int meshgen
Definition: mesh.hpp:61
const CoarseFineTransformations & GetRefinementTransforms()
Definition: mesh.cpp:6796
bool RefineByError(const Array< double > &elem_error, double threshold, int nonconforming=-1, int nc_limit=0)
Definition: mesh.cpp:6412
Table * bel_to_edge
Definition: mesh.hpp:104
Operation GetLastOperation() const
Return type of last modification of the mesh.
Definition: mesh.hpp:975
int GetElementBaseGeometry(int i=0) const
Definition: mesh.hpp:654
void AddBdrTriangle(const int *vi, int attr=1)
Definition: mesh.cpp:978
Table * GetFaceToElementTable() const
Definition: mesh.cpp:3803
void GetLocalTriToTetTransformation(IsoparametricTransformation &loc, int i)
Used in GetFaceElementTransformations (...)
Definition: mesh.cpp:527
int EulerNumber() const
Equals 1 + num_holes - num_loops.
Definition: mesh.hpp:605
NURBSExtension * NURBSext
Optional NURBS mesh extension.
Definition: mesh.hpp:144
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
Definition: mesh.hpp:581
void AddBdrQuad(const int *vi, int attr=1)
Definition: mesh.cpp:983
Array< int > be_to_edge
Definition: mesh.hpp:103
const Table & ElementToFaceTable() const
Definition: mesh.cpp:4131
Class for integration point with weight.
Definition: intrules.hpp:25
void UniformRefinement()
Definition: mesh.cpp:6246
Element * ReadElementWithoutAttr(std::istream &)
Definition: mesh.cpp:2477
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
Definition: mesh.cpp:3621
void AddTriangle(const int *vi, int attr=1)
Definition: mesh.cpp:926
bool OwnsNodes() const
Return the mesh nodes ownership flag.
Definition: mesh.hpp:879
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
Definition: mesh.cpp:238
void GetLocalSegToQuadTransformation(IsoparametricTransformation &loc, int i)
Definition: mesh.cpp:508
const FiniteElementSpace * GetNodalFESpace() const
Definition: mesh.cpp:3273
Table * face_edge
Definition: mesh.hpp:106
void FinalizeQuadMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
Finalize the construction of a quadrilateral Mesh.
Definition: mesh.cpp:1086
void GetBdrElementData(int geom, Array< int > &bdr_elem_vtx, Array< int > &bdr_attr) const
Definition: mesh.hpp:627
void Finalize(bool refine=false, bool fix_orientation=false)
Finalize the construction of a general Mesh.
Definition: mesh.cpp:1807
bool DerefineByError(Array< double > &elem_error, double threshold, int nc_limit=0, int op=1)
Definition: mesh.cpp:6089
NodeExtrudeCoefficient(const int dim, const int _n, const double _s)
Definition: mesh.cpp:8498
void ReorderElements(const Array< int > &ordering, bool reorder_vertices=true)
Definition: mesh.cpp:1164
Table * edge_vertex
Definition: mesh.hpp:107
void ReadVTKMesh(std::istream &input, int &curved, int &read_gf)
void GetBdrElementVertices(int i, Array< int > &dofs) const
Returns the indices of the dofs of boundary element i.
Definition: mesh.hpp:665
long sequence
Definition: mesh.hpp:66
virtual ~NodeExtrudeCoefficient()
Definition: mesh.hpp:1078
void DestroyPointers()
Definition: mesh.cpp:785
Array< FaceInfo > faces_info
Definition: mesh.hpp:97
STable3D * GetFacesTable()
Definition: mesh.cpp:4354
void Make3D(int nx, int ny, int nz, Element::Type type, int generate_edges, double sx, double sy, double sz)
Definition: mesh.cpp:1867
void EnsureNCMesh(bool triangles_nonconforming=false)
Definition: mesh.cpp:6350
NCMesh * ncmesh
Optional non-conforming mesh extension.
Definition: mesh.hpp:145
static void PrintElementWithoutAttr(const Element *, std::ostream &)
Definition: mesh.cpp:2494
virtual bool NonconformingDerefinement(Array< double > &elem_error, double threshold, int nc_limit=0, int op=1)
NC version of GeneralDerefinement.
Definition: mesh.cpp:6044
int Dim
Definition: mesh.hpp:53
void Clear()
Clear the contents of the Mesh.
Definition: mesh.hpp:569
int GetNEdges() const
Return the number of edges.
Definition: mesh.hpp:590
Geometry::Constants< Geometry::TRIANGLE > tri_t
Definition: mesh.hpp:132
double * GetVertex(int i)
Return pointer to vertex i&#39;s coordinates.
Definition: mesh.hpp:622
int GetNFaces() const
Return the number of faces in a 3D mesh.
Definition: mesh.hpp:593
Vector data type.
Definition: vector.hpp:36
void ReadTrueGridMesh(std::istream &input)
int GetFaceBaseGeometry(int i) const
Definition: mesh.cpp:3898
void AverageVertices(int *indexes, int n, int result)
Definition: mesh.cpp:5416
Mesh(int nx, int ny, int nz, Element::Type type, int generate_edges=0, double sx=1.0, double sy=1.0, double sz=1.0)
Definition: mesh.hpp:505
static int GetTriOrientation(const int *base, const int *test)
Returns the orientation of &quot;test&quot; relative to &quot;base&quot;.
Definition: mesh.cpp:3423
void SetNode(int i, const double *coord)
Definition: mesh.cpp:5336
void GetNode(int i, double *coord)
Definition: mesh.cpp:5317
void DestroyTables()
Definition: mesh.cpp:770
void GenerateFaces()
Definition: mesh.cpp:4238
void GetElementColoring(Array< int > &colors, int el0=0)
Definition: mesh.cpp:7463
void ChangeVertexDataOwnership(double *vertices, int len_vertices, bool zerocopy=false)
Set the internal Vertex array to point to the given vertices array without assuming ownership of the ...
Definition: mesh.cpp:2392
int spaceDim
Definition: mesh.hpp:54
IsoparametricTransformation EdgeTransformation
Definition: mesh.hpp:110
Defines the coarse-fine transformations of all fine elements.
Definition: ncmesh.hpp:51
void AddTet(const int *vi, int attr=1)
Definition: mesh.cpp:936
MemAlloc< Tetrahedron, 1024 > TetMemory
Definition: mesh.hpp:127
Table * GetFaceEdgeTable() const
Returns the face-to-edge Table (3D)
Definition: mesh.cpp:3714
void DoNodeReorder(DSTable *old_v_to_v, Table *old_elem_vert)
Definition: mesh.cpp:1433
void SetNodes(const Vector &node_coord)
Definition: mesh.cpp:5380
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
Definition: mesh.cpp:3267
named_ifgzstream(const char *mesh_name)
Definition: mesh.hpp:1093
void ReadNURBSMesh(std::istream &input, int &curved, int &read_gf)
int NumOfVertices
Definition: mesh.hpp:56
void ScaleSubdomains(double sf)
Definition: mesh.cpp:8088
Array< int > be_to_face
Definition: mesh.hpp:105
virtual void PrintXG(std::ostream &out=std::cout) const
Print the mesh to the given stream using Netgen/Truegrid format.
Definition: mesh.cpp:6854
void InitFromNCMesh(const NCMesh &ncmesh)
Initialize vertices/elements/boundary/tables from a nonconforming mesh.
Definition: mesh.cpp:6118
void Bisection(int i, const DSTable &, int *, int *, int *)
Definition: mesh.cpp:6441
void GeneralRefinement(const Array< Refinement > &refinements, int nonconforming=-1, int nc_limit=0)
Definition: mesh.cpp:6285
Class for parallel meshes.
Definition: pmesh.hpp:28
Abstract data type element.
Definition: element.hpp:27
int GetAttribute(int i) const
Return the attribute of element i.
Definition: mesh.hpp:821
void AddTriangleFaceElement(int lf, int gf, int el, int v0, int v1, int v2)
Definition: mesh.cpp:4196
const Table & ElementToEdgeTable() const
Definition: mesh.cpp:4140
void GenerateNCFaceInfo()
Definition: mesh.cpp:4307
int GetBdrElementBaseGeometry(int i=0) const
Definition: mesh.hpp:657
double GetElementVolume(int i)
Definition: mesh.cpp:71
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Definition: mesh.hpp:140
void InitMesh(int _Dim, int _spaceDim, int NVert, int NElem, int NBdrElem)
Begin construction of a mesh.
Definition: mesh.cpp:870
Table * GetVertexToElementTable()
The returned Table must be destroyed by the caller.
Definition: mesh.cpp:3768
const Element * GetBdrElement(int i) const
Definition: mesh.hpp:646
void GetElementData(const Array< Element * > &elem_array, int geom, Array< int > &elem_vtx, Array< int > &attr) const
Definition: mesh.cpp:6218
void UpdateNodes()
Update the nodes of a curved mesh after refinement.
Definition: mesh.cpp:5437
void GreenRefinement(int i, const DSTable &v_to_v, int *edge1, int *edge2, int *middle)
Definition: mesh.hpp:209
virtual void Print(std::ostream &out=std::cout) const
Definition: mesh.hpp:988
Class used to extrude the nodes of a mesh.
Definition: mesh.hpp:1066
int NumOfFaces
Definition: mesh.hpp:57