MFEM  v4.2.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
pumi.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_PUMI
13 #define MFEM_PUMI
14 
15 #include "../config/config.hpp"
16 
17 #ifdef MFEM_USE_PUMI
18 #ifdef MFEM_USE_MPI
19 
20 #include "../fem/fespace.hpp"
21 #include "../fem/gridfunc.hpp"
22 #include "../fem/pgridfunc.hpp"
23 #include "../fem/coefficient.hpp"
24 #include "../fem/bilininteg.hpp"
25 
26 #include <iostream>
27 #include <limits>
28 #include <ostream>
29 #include <string>
30 #include "mesh.hpp"
31 #include "pmesh.hpp"
32 
33 #include <apf.h>
34 #include <apfMesh2.h>
35 #include <apfShape.h>
36 #include <apfField.h>
37 #include <apfNumbering.h>
38 #include <apfDynamicVector.h>
39 #include <maMesh.h>
40 
41 namespace mfem
42 {
43 
44 /// Base class for PUMI meshes
45 class PumiMesh : public Mesh
46 {
47 protected:
48  void CountBoundaryEntity(apf::Mesh2* apf_mesh, const int BcDim, int &NumBC);
49 
50  // Readers for PUMI mesh formats, used in the Load() method.
51  void ReadSCORECMesh(apf::Mesh2* apf_mesh, apf::Numbering* v_num_loc,
52  const int curved);
53 
54 public:
55  /// Generate an MFEM mesh from a PUMI mesh.
56  PumiMesh(apf::Mesh2* apf_mesh, int generate_edges = 0, int refine = 1,
57  bool fix_orientation = true);
58 
59  using Mesh::Load;
60  /// Load a PUMI mesh (following the steps in the MFEM Load function).
61  void Load(apf::Mesh2* apf_mesh, int generate_edges = 0, int refine = 1,
62  bool fix_orientation = true);
63 
64  /// Destroys Mesh.
65  virtual ~PumiMesh() { }
66 };
67 
68 
69 /// Class for PUMI parallel meshes
70 class ParPumiMesh : public ParMesh
71 {
72 private:
73  // This has to persist during an adaptive simulation, and therefore
74  // needs to be updated each time the mesh changes.
75  apf::Numbering* v_num_loc;
76 
77 public:
78  /// Build a parallel MFEM mesh from a parallel PUMI mesh.
79  ParPumiMesh(MPI_Comm comm, apf::Mesh2* apf_mesh,
80  int refine = 1, bool fix_orientation = true);
81 
82 
83  /// Returns the PUMI-to-MFEM permutation (aka rotation, aka orientation)
84  /** This represents the change in tet-to-vertex connectivity between
85  the PUMI and MFEM meshes. E.g.,
86  PUMI_tet{v0,v1,v2,v3} ---> MFEM_tet{v1,v0,v3,v2}
87  * Note that change in the orientation can be caused by
88  a) fixing wrong boundary element orientations
89  b) a call to ReorientTetMesh() which is required for Nedelec */
90  int RotationPUMItoMFEM(apf::Mesh2* apf_mesh,
91  apf::MeshEntity* tet,
92  int elemId);
93  /// Convert the parent coordinate from PUMI to MFEM
94  /** By default this functions assumes that there is always
95  change in the orientations of some of the elements. In case it
96  is known for sure that there is NO change in the orientation,
97  call the functions with last argument = false */
98  IntegrationRule ParentXisPUMItoMFEM(apf::Mesh2* apf_mesh,
99  apf::MeshEntity* tet,
100  int elemId,
101  apf::NewArray<apf::Vector3>& pumi_xi,
102  bool checkOrientation = true);
103  /// Convert the parent coordinate from MFEM to PUMI
104  /** This is the inverse of ParentXisPUMItoMFEM.
105  By default this functions assumes that there is always
106  change in the orientations of some of the elements. In case it
107  is known for sure that there is NO change in the orientation,
108  call the functions with last argument = false */
109  void ParentXisMFEMtoPUMI(apf::Mesh2* apf_mesh,
110  int elemId,
111  apf::MeshEntity* tet,
112  const IntegrationRule& mfem_xi,
113  apf::NewArray<apf::Vector3>& pumi_xi,
114  bool checkOrientation = true);
115  /// Transfer field from MFEM mesh to PUMI mesh [Mixed].
116  void FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
117  ParGridFunction* grid_vel,
118  ParGridFunction* grid_pr,
119  apf::Field* vel_field,
120  apf::Field* pr_field,
121  apf::Field* vel_mag_field);
122 
123  /// Transfer field from MFEM mesh to PUMI mesh [Scalar].
124  void FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
125  ParGridFunction* grid_pr,
126  apf::Field* pr_field,
127  apf::Field* pr_mag_field);
128 
129  /// Transfer field from MFEM mesh to PUMI mesh [Vector].
130  void VectorFieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
131  ParGridFunction* grid_vel,
132  apf::Field* vel_field,
133  apf::Field* vel_mag_field);
134 
135  /// Transfer Nedelec field from MFEM mesh to PUMI mesh [Vector].
136  void NedelecFieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
137  ParGridFunction* gf,
138  apf::Field* nedelec_field);
139 
140  /// Update the mesh after adaptation.
141  void UpdateMesh(const ParMesh* AdaptedpMesh);
142 
143  /// Transfer a field from PUMI to MFEM after mesh adapt [Scalar and Vector].
144  void FieldPUMItoMFEM(apf::Mesh2* apf_mesh,
145  apf::Field* field,
146  ParGridFunction* grid);
147 
148  virtual ~ParPumiMesh() {}
149 };
150 
151 
152 /// Class for PUMI grid functions
154 {
155 public:
156  /// Construct a GridFunction from a PUMI mesh.
157  GridFunctionPumi(Mesh* m, apf::Mesh2* PumiM, apf::Numbering* v_num_loc,
158  const int mesh_order);
159 
160  /// Destroy the grid function.
161  virtual ~GridFunctionPumi() { }
162 };
163 
164 } // namespace mfem
165 
166 #endif // MFEM_USE_MPI
167 #endif // MFEM_USE_PUMI
168 
169 #endif
void UpdateMesh(const ParMesh *AdaptedpMesh)
Update the mesh after adaptation.
Definition: pumi.cpp:752
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:90
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:30
PumiMesh(apf::Mesh2 *apf_mesh, int generate_edges=0, int refine=1, bool fix_orientation=true)
Generate an MFEM mesh from a PUMI mesh.
Definition: pumi.cpp:58
Class for PUMI grid functions.
Definition: pumi.hpp:153
Base class for PUMI meshes.
Definition: pumi.hpp:45
void FieldMFEMtoPUMI(apf::Mesh2 *apf_mesh, ParGridFunction *grid_vel, ParGridFunction *grid_pr, apf::Field *vel_field, apf::Field *pr_field, apf::Field *vel_mag_field)
Transfer field from MFEM mesh to PUMI mesh [Mixed].
Definition: pumi.cpp:1005
Class for PUMI parallel meshes.
Definition: pumi.hpp:70
int RotationPUMItoMFEM(apf::Mesh2 *apf_mesh, apf::MeshEntity *tet, int elemId)
Returns the PUMI-to-MFEM permutation (aka rotation, aka orientation)
Definition: pumi.cpp:912
virtual void Load(std::istream &input, int generate_edges=0, int refine=1, bool fix_orientation=true)
Definition: mesh.hpp:711
IntegrationRule ParentXisPUMItoMFEM(apf::Mesh2 *apf_mesh, apf::MeshEntity *tet, int elemId, apf::NewArray< apf::Vector3 > &pumi_xi, bool checkOrientation=true)
Convert the parent coordinate from PUMI to MFEM.
Definition: pumi.cpp:946
void CountBoundaryEntity(apf::Mesh2 *apf_mesh, const int BcDim, int &NumBC)
Definition: pumi.cpp:66
void VectorFieldMFEMtoPUMI(apf::Mesh2 *apf_mesh, ParGridFunction *grid_vel, apf::Field *vel_field, apf::Field *vel_mag_field)
Transfer field from MFEM mesh to PUMI mesh [Vector].
Definition: pumi.cpp:1105
void FieldPUMItoMFEM(apf::Mesh2 *apf_mesh, apf::Field *field, ParGridFunction *grid)
Transfer a field from PUMI to MFEM after mesh adapt [Scalar and Vector].
Definition: pumi.cpp:1206
virtual ~PumiMesh()
Destroys Mesh.
Definition: pumi.hpp:65
void Load(apf::Mesh2 *apf_mesh, int generate_edges=0, int refine=1, bool fix_orientation=true)
Load a PUMI mesh (following the steps in the MFEM Load function).
Definition: pumi.cpp:89
void ParentXisMFEMtoPUMI(apf::Mesh2 *apf_mesh, int elemId, apf::MeshEntity *tet, const IntegrationRule &mfem_xi, apf::NewArray< apf::Vector3 > &pumi_xi, bool checkOrientation=true)
Convert the parent coordinate from MFEM to PUMI.
Definition: pumi.cpp:971
virtual ~ParPumiMesh()
Definition: pumi.hpp:148
ParPumiMesh(MPI_Comm comm, apf::Mesh2 *apf_mesh, int refine=1, bool fix_orientation=true)
Build a parallel MFEM mesh from a parallel PUMI mesh.
Definition: pumi.cpp:248
void NedelecFieldMFEMtoPUMI(apf::Mesh2 *apf_mesh, ParGridFunction *gf, apf::Field *nedelec_field)
Transfer Nedelec field from MFEM mesh to PUMI mesh [Vector].
Definition: pumi.cpp:1151
void ReadSCORECMesh(apf::Mesh2 *apf_mesh, apf::Numbering *v_num_loc, const int curved)
Definition: pumi.cpp:155
Class for parallel grid function.
Definition: pgridfunc.hpp:32
GridFunctionPumi(Mesh *m, apf::Mesh2 *PumiM, apf::Numbering *v_num_loc, const int mesh_order)
Construct a GridFunction from a PUMI mesh.
Definition: pumi.cpp:683
Class for parallel meshes.
Definition: pmesh.hpp:32
virtual ~GridFunctionPumi()
Destroy the grid function.
Definition: pumi.hpp:161