Line data Source code
1 : // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 : // SPDX-License-Identifier: Apache-2.0
3 :
4 : #ifndef PALACE_FEM_MESH_HPP
5 : #define PALACE_FEM_MESH_HPP
6 :
7 : #include <memory>
8 : #include <unordered_map>
9 : #include <vector>
10 : #include <mfem.hpp>
11 : #include "fem/libceed/ceed.hpp"
12 :
13 : namespace palace
14 : {
15 :
16 : namespace ceed
17 : {
18 :
19 : //
20 : // Data structure for geometry information stored at quadrature points.
21 : //
22 54674 : struct CeedGeomFactorData
23 : {
24 : // Dimension of this element topology and space dimension of the underlying mesh.
25 : int dim, space_dim;
26 :
27 : // Domain or boundary indices from the mesh used to construct Ceed objects with these
28 : // geometry factors.
29 : std::vector<int> indices;
30 :
31 : // Mesh geometry factor data: {attr, w * |J|, adj(J)^T / |J|}. Jacobian matrix is
32 : // space_dim x dim, stored column-major by component.
33 : CeedVector geom_data;
34 :
35 : // Element restriction for the geometry factor quadrature data.
36 : CeedElemRestriction geom_data_restr;
37 : };
38 :
39 : } // namespace ceed
40 :
41 : //
42 : // Wrapper for MFEM's ParMesh class, with extensions for Palace.
43 : //
44 : class Mesh
45 : {
46 : private:
47 : // Underlying MFEM object (can also point to a derived class of mfem::ParMesh, such as
48 : // mfem::ParSubMesh).
49 : std::unique_ptr<mfem::ParMesh> mesh;
50 :
51 : // Attribute mapping for (global, MFEM, 1-based) domain and boundary attributes to those
52 : // for libCEED (local to this process, contiguous, also 1-based). For boundaries, the
53 : // inner map is a mapping from neighboring MFEM domain attribute to the resulting local
54 : // boundary attribute (to discern boundary elements of a given attribute which border more
55 : // than one domain). Interior boundaries use as neighbor the element with the smaller
56 : // domain attribute in order to be consistent when the interior boundary element normals
57 : // are not aligned.
58 : std::unordered_map<int, int> loc_attr;
59 : std::unordered_map<int, std::unordered_map<int, int>> loc_bdr_attr;
60 :
61 : // Mesh data structures for assembling libCEED operators on a (mixed) mesh:
62 : // - Mesh element indices for threads and element geometry types.
63 : // - Attributes for domain and boundary elements. The attributes are not the same as the
64 : // MFEM mesh element attributes, they correspond to the local, contiguous (1-based)
65 : // attributes above.
66 : // - Geometry factor quadrature point data (w |J| and adj(J)^T / |J|) for domain and
67 : // boundary elements.
68 : mutable ceed::CeedObjectMap<ceed::CeedGeomFactorData> geom_data;
69 :
70 : public:
71 : template <typename... T>
72 7 : Mesh(T &&...args) : Mesh(std::make_unique<mfem::ParMesh>(std::forward<T>(args)...))
73 : {
74 7 : }
75 : template <typename T>
76 11627 : Mesh(std::unique_ptr<T> &&mesh) : mesh(std::move(mesh))
77 : {
78 11627 : this->mesh->EnsureNodes();
79 11627 : Update();
80 11627 : }
81 11627 : ~Mesh() { ResetCeedObjects(); }
82 :
83 : const auto &Get() const { return *mesh; }
84 : auto &Get() { return *mesh; }
85 :
86 : operator const mfem::ParMesh &() const { return Get(); }
87 : operator mfem::ParMesh &() { return Get(); }
88 :
89 : operator const std::unique_ptr<mfem::ParMesh> &() const { return mesh; }
90 0 : operator std::unique_ptr<mfem::ParMesh> &() { return mesh; }
91 :
92 : auto Dimension() const { return Get().Dimension(); }
93 : auto SpaceDimension() const { return Get().SpaceDimension(); }
94 : auto GetNE() const { return Get().GetNE(); }
95 : auto GetNBE() const { return Get().GetNBE(); }
96 :
97 : const auto &GetCeedAttributes() const { return loc_attr; }
98 : const auto &GetCeedBdrAttributes() const { return loc_bdr_attr; }
99 :
100 : // Convert a list of global attributes to the corresponding process-local libCEED ones.
101 : template <typename T>
102 47924 : auto GetCeedAttributes(const T &attr_list) const
103 : {
104 : // Skip any entries in the input global attribute list which are not local to this
105 : // process.
106 : mfem::Array<int> loc_attr_list;
107 95848 : for (auto attr : attr_list)
108 : {
109 47924 : if (loc_attr.find(attr) != loc_attr.end())
110 : {
111 47108 : loc_attr_list.Append(loc_attr.at(attr));
112 : }
113 : }
114 47924 : return loc_attr_list;
115 : }
116 :
117 : // Convert a list of global boundary attributes to the corresponding process-local libCEED
118 : // ones.
119 : template <typename T>
120 49572 : auto GetCeedBdrAttributes(const T &attr_list) const
121 : {
122 : // Skip any entries in the input global boundary attribute list which are not local
123 : // to this process.
124 : mfem::Array<int> loc_attr_list;
125 99144 : for (auto attr : attr_list)
126 : {
127 49572 : if (loc_bdr_attr.find(attr) != loc_bdr_attr.end())
128 : {
129 : const auto &bdr_attr_map = loc_bdr_attr.at(attr);
130 100368 : for (auto it = bdr_attr_map.begin(); it != bdr_attr_map.end(); ++it)
131 : {
132 63444 : loc_attr_list.Append(it->second);
133 : }
134 : }
135 : }
136 49572 : return loc_attr_list;
137 : }
138 :
139 47924 : auto GetCeedAttributes(const int attr) const
140 : {
141 95848 : return GetCeedAttributes(std::vector<int>{attr});
142 : }
143 :
144 49572 : auto GetCeedBdrAttributes(const int attr) const
145 : {
146 99144 : return GetCeedBdrAttributes(std::vector<int>{attr});
147 : }
148 :
149 : auto MaxCeedAttribute() const { return GetCeedAttributes().size(); }
150 : auto MaxCeedBdrAttribute() const
151 : {
152 : std::size_t bdr_attr_max = 0;
153 40596 : for (const auto &[attr, bdr_attr_map] : GetCeedBdrAttributes())
154 : {
155 36924 : bdr_attr_max += bdr_attr_map.size();
156 : }
157 : return bdr_attr_max;
158 : }
159 :
160 : const ceed::GeometryObjectMap<ceed::CeedGeomFactorData> &
161 : GetCeedGeomFactorData(Ceed ceed) const;
162 :
163 : void ResetCeedObjects();
164 :
165 : void Update();
166 :
167 : MPI_Comm GetComm() const { return mesh->GetComm(); }
168 : };
169 :
170 : } // namespace palace
171 :
172 : #endif // PALACE_FEM_MESH_HPP
|