MFEM  v4.5.1
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-2022, 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  fixing wrong boundary element orientations */
88  int RotationPUMItoMFEM(apf::Mesh2* apf_mesh,
89  apf::MeshEntity* tet,
90  int elemId);
91  /// Convert the parent coordinate from PUMI to MFEM
92  /** By default this functions assumes that there is always
93  change in the orientations of some of the elements. In case it
94  is known for sure that there is NO change in the orientation,
95  call the functions with last argument = false */
96  IntegrationRule ParentXisPUMItoMFEM(apf::Mesh2* apf_mesh,
97  apf::MeshEntity* tet,
98  int elemId,
99  apf::NewArray<apf::Vector3>& pumi_xi,
100  bool checkOrientation = true);
101  /// Convert the parent coordinate from MFEM to PUMI
102  /** This is the inverse of ParentXisPUMItoMFEM.
103  By default this functions assumes that there is always
104  change in the orientations of some of the elements. In case it
105  is known for sure that there is NO change in the orientation,
106  call the functions with last argument = false */
107  void ParentXisMFEMtoPUMI(apf::Mesh2* apf_mesh,
108  int elemId,
109  apf::MeshEntity* tet,
110  const IntegrationRule& mfem_xi,
111  apf::NewArray<apf::Vector3>& pumi_xi,
112  bool checkOrientation = true);
113  /// Transfer field from MFEM mesh to PUMI mesh [Mixed].
114  void FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
115  ParGridFunction* grid_vel,
116  ParGridFunction* grid_pr,
117  apf::Field* vel_field,
118  apf::Field* pr_field,
119  apf::Field* vel_mag_field);
120 
121  /// Transfer field from MFEM mesh to PUMI mesh [Scalar].
122  void FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
123  ParGridFunction* grid_pr,
124  apf::Field* pr_field,
125  apf::Field* pr_mag_field);
126 
127  /// Transfer field from MFEM mesh to PUMI mesh [Vector].
128  void VectorFieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
129  ParGridFunction* grid_vel,
130  apf::Field* vel_field,
131  apf::Field* vel_mag_field);
132 
133  /// Transfer Nedelec field from MFEM mesh to PUMI mesh [Vector].
134  void NedelecFieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
135  ParGridFunction* gf,
136  apf::Field* nedelec_field);
137 
138  /// Update the mesh after adaptation.
139  void UpdateMesh(const ParMesh* AdaptedpMesh);
140 
141  /// Transfer a field from PUMI to MFEM after mesh adapt [Scalar and Vector].
142  void FieldPUMItoMFEM(apf::Mesh2* apf_mesh,
143  apf::Field* field,
144  ParGridFunction* grid);
145 
146  virtual ~ParPumiMesh() {}
147 };
148 
149 
150 /// Class for PUMI grid functions
152 {
153 public:
154  /// Construct a GridFunction from a PUMI mesh.
155  GridFunctionPumi(Mesh* m, apf::Mesh2* PumiM, apf::Numbering* v_num_loc,
156  const int mesh_order);
157 
158  /// Destroy the grid function.
159  virtual ~GridFunctionPumi() { }
160 };
161 
162 } // namespace mfem
163 
164 #endif // MFEM_USE_MPI
165 #endif // MFEM_USE_PUMI
166 
167 #endif
void UpdateMesh(const ParMesh *AdaptedpMesh)
Update the mesh after adaptation.
Definition: pumi.cpp:956
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:151
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:1216
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:1116
virtual void Load(std::istream &input, int generate_edges=0, int refine=1, bool fix_orientation=true)
Definition: mesh.hpp:891
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:1151
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:1316
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:1417
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:1179
virtual ~ParPumiMesh()
Definition: pumi.hpp:146
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:443
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:1362
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:887
Class for parallel meshes.
Definition: pmesh.hpp:32
virtual ~GridFunctionPumi()
Destroy the grid function.
Definition: pumi.hpp:159