MFEM  v4.3.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-2021, 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 
40 namespace mfem
41 {
42 
43 /// Base class for PUMI meshes
44 class PumiMesh : public Mesh
45 {
46 protected:
47  void CountBoundaryEntity(apf::Mesh2* apf_mesh, const int BcDim, int &NumBC);
48 
49  // Readers for PUMI mesh formats, used in the Load() method.
50  void ReadSCORECMesh(apf::Mesh2* apf_mesh, apf::Numbering* v_num_loc,
51  const int curved);
52 
53 public:
54  /// Generate an MFEM mesh from a PUMI mesh.
55  PumiMesh(apf::Mesh2* apf_mesh, int generate_edges = 0, int refine = 1,
56  bool fix_orientation = true);
57 
58  using Mesh::Load;
59  /// Load a PUMI mesh (following the steps in the MFEM Load function).
60  void Load(apf::Mesh2* apf_mesh, int generate_edges = 0, int refine = 1,
61  bool fix_orientation = true);
62 
63  /// Destroys Mesh.
64  virtual ~PumiMesh() { }
65 };
66 
67 
68 /// Class for PUMI parallel meshes
69 class ParPumiMesh : public ParMesh
70 {
71 private:
72  // This has to persist during an adaptive simulation, and therefore
73  // needs to be updated each time the mesh changes.
74  apf::Numbering* v_num_loc;
75 
76 public:
77  /// Build a parallel MFEM mesh from a parallel PUMI mesh.
78  ParPumiMesh(MPI_Comm comm, apf::Mesh2* apf_mesh,
79  int refine = 1, bool fix_orientation = true);
80 
81 
82  /// Returns the PUMI-to-MFEM permutation (aka rotation, aka orientation)
83  /** This represents the change in tet-to-vertex connectivity between
84  the PUMI and MFEM meshes. E.g.,
85  PUMI_tet{v0,v1,v2,v3} ---> MFEM_tet{v1,v0,v3,v2}
86  * Note that change in the orientation can be caused by
87  a) fixing wrong boundary element orientations
88  b) a call to ReorientTetMesh() which is required for Nedelec */
89  int RotationPUMItoMFEM(apf::Mesh2* apf_mesh,
90  apf::MeshEntity* tet,
91  int elemId);
92  /// Convert the parent coordinate from PUMI to MFEM
93  /** By default this functions assumes that there is always
94  change in the orientations of some of the elements. In case it
95  is known for sure that there is NO change in the orientation,
96  call the functions with last argument = false */
97  IntegrationRule ParentXisPUMItoMFEM(apf::Mesh2* apf_mesh,
98  apf::MeshEntity* tet,
99  int elemId,
100  apf::NewArray<apf::Vector3>& pumi_xi,
101  bool checkOrientation = true);
102  /// Convert the parent coordinate from MFEM to PUMI
103  /** This is the inverse of ParentXisPUMItoMFEM.
104  By default this functions assumes that there is always
105  change in the orientations of some of the elements. In case it
106  is known for sure that there is NO change in the orientation,
107  call the functions with last argument = false */
108  void ParentXisMFEMtoPUMI(apf::Mesh2* apf_mesh,
109  int elemId,
110  apf::MeshEntity* tet,
111  const IntegrationRule& mfem_xi,
112  apf::NewArray<apf::Vector3>& pumi_xi,
113  bool checkOrientation = true);
114  /// Transfer field from MFEM mesh to PUMI mesh [Mixed].
115  void FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
116  ParGridFunction* grid_vel,
117  ParGridFunction* grid_pr,
118  apf::Field* vel_field,
119  apf::Field* pr_field,
120  apf::Field* vel_mag_field);
121 
122  /// Transfer field from MFEM mesh to PUMI mesh [Scalar].
123  void FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
124  ParGridFunction* grid_pr,
125  apf::Field* pr_field,
126  apf::Field* pr_mag_field);
127 
128  /// Transfer field from MFEM mesh to PUMI mesh [Vector].
129  void VectorFieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
130  ParGridFunction* grid_vel,
131  apf::Field* vel_field,
132  apf::Field* vel_mag_field);
133 
134  /// Transfer Nedelec field from MFEM mesh to PUMI mesh [Vector].
135  void NedelecFieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
136  ParGridFunction* gf,
137  apf::Field* nedelec_field);
138 
139  /// Update the mesh after adaptation.
140  void UpdateMesh(const ParMesh* AdaptedpMesh);
141 
142  /// Transfer a field from PUMI to MFEM after mesh adapt [Scalar and Vector].
143  void FieldPUMItoMFEM(apf::Mesh2* apf_mesh,
144  apf::Field* field,
145  ParGridFunction* grid);
146 
147  virtual ~ParPumiMesh() {}
148 };
149 
150 
151 /// Class for PUMI grid functions
153 {
154 public:
155  /// Construct a GridFunction from a PUMI mesh.
156  GridFunctionPumi(Mesh* m, apf::Mesh2* PumiM, apf::Numbering* v_num_loc,
157  const int mesh_order);
158 
159  /// Destroy the grid function.
160  virtual ~GridFunctionPumi() { }
161 };
162 
163 } // namespace mfem
164 
165 #endif // MFEM_USE_MPI
166 #endif // MFEM_USE_PUMI
167 
168 #endif
void UpdateMesh(const ParMesh *AdaptedpMesh)
Update the mesh after adaptation.
Definition: pumi.cpp:939
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:245
Class for PUMI grid functions.
Definition: pumi.hpp:152
Base class for PUMI meshes.
Definition: pumi.hpp:44
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:1199
Class for PUMI parallel meshes.
Definition: pumi.hpp:69
int RotationPUMItoMFEM(apf::Mesh2 *apf_mesh, apf::MeshEntity *tet, int elemId)
Returns the PUMI-to-MFEM permutation (aka rotation, aka orientation)
Definition: pumi.cpp:1099
virtual void Load(std::istream &input, int generate_edges=0, int refine=1, bool fix_orientation=true)
Definition: mesh.hpp:820
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:1134
void CountBoundaryEntity(apf::Mesh2 *apf_mesh, const int BcDim, int &NumBC)
Definition: pumi.cpp:253
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:1299
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:1400
virtual ~PumiMesh()
Destroys Mesh.
Definition: pumi.hpp:64
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:276
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:1162
virtual ~ParPumiMesh()
Definition: pumi.hpp:147
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:435
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:1345
void ReadSCORECMesh(apf::Mesh2 *apf_mesh, apf::Numbering *v_num_loc, const int curved)
Definition: pumi.cpp:342
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:870
Class for parallel meshes.
Definition: pmesh.hpp:32
virtual ~GridFunctionPumi()
Destroy the grid function.
Definition: pumi.hpp:160