MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
ncnurbs.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, 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_NCNURBS
13#define MFEM_NCNURBS
14
15#include "nurbs.hpp"
16
17namespace mfem
18{
19
20/** @brief NCNURBSExtension extends NURBSExtension to support NC-patch NURBS
21 meshes. */
23{
24public:
25 /// Copy constructor: deep copy
27
28 NCNURBSExtension(std::istream &input, bool spacing=false);
29
30 void UniformRefinement(const Array<int> &rf) override;
31
32protected:
33 /** @brief Set the mesh and space offsets, and also count the global
34 @a NumOfVertices and the global @a NumOfDofs. */
35 void GenerateOffsets() override;
36
37 /// Return true if @a edge is a master NC-patch edge.
38 bool IsMasterEdge(int edge) const override
39 { return masterEdges.count(edge) > 0; }
40
41 /// Return true if @a face is a master NC-patch face.
42 bool IsMasterFace(int face) const override
43 { return masterFaces.count(face) > 0; }
44
45 /// Given a pair of vertices, return the corresponding edge.
46 int VertexPairToEdge(const std::pair<int, int> &vertices) const override
47 { return v2e.at(vertices); }
48
49 /** @brief Get the DOFs (dof = true) or vertices (dof = false) for
50 master edge @a me. */
51 void GetMasterEdgeDofs(bool dof, int me, Array<int> &dofs) const override;
52
53 /** @brief Get the DOFs (dof = true) or vertices (dof = false) for
54 master face @a mf. */
55 void GetMasterFaceDofs(bool dof, int mf, Array2D<int> &dofs) const override;
56
57 /// Load refinement factors for a list of knotvectors from file.
58 void LoadFactorsForKV(const std::string &filename);
59
60 /// Set consistent refinement factors on patch @a p.
61 int SetPatchFactors(int p);
62
63 /// Ensure consistent refinement factors on all knotvectors.
64 void PropagateFactorsForKV(int rf_default);
65
66 /// Refine with refinement factors loaded for some knotvectors specified in
67 /// the given file, with default refinement factor @a rf elsewhere. The flag
68 /// @a coarsened indicates whether each patch is a single element.
69 void RefineWithKVFactors(int rf, const std::string &kvf_filename,
70 bool coarsened) override;
71
72private:
73 /// Global mesh offsets, meshOffsets == meshVertexOffsets
74 Array<int> aux_e_meshOffsets, aux_f_meshOffsets;
75
76 /// Global space offsets, spaceOffsets == dofOffsets
77 Array<int> aux_e_spaceOffsets, aux_f_spaceOffsets;
78
79 /// Represents a nonconforming edge not in patchTopo->ncmesh.
80 struct AuxiliaryEdge
81 {
82 int parent; /// Signed parent edge index (sign encodes orientation)
83 int v[2]; /// Vertex indices
84 int ksi[2]; /// Knot-span indices of vertices in parent edge
85 };
86
87 /// Represents a nonconforming face not in patchTopo->ncmesh.
88 struct AuxiliaryFace
89 {
90 int parent; /// Parent face index
91 int ori; /// Orientation with respect to parent face
92 int v[4]; /// Vertex indices
93 int ksi0[2]; /// Lower knot-span indices in parent face
94 int ksi1[2]; /// Upper knot-span indices in parent face
95 };
96
97 /** @brief Represents a pair of child and parent edges for a nonconforming
98 patch topology. */
99 struct EdgePairInfo
100 {
101 int v; /// Vertex index
102 int ksi; /// Knot-span index of vertex
103 int child, parent; /// Child and parent edge indices
104 bool isSet; /// Whether this instance is set
105
106 EdgePairInfo() : isSet(false) { }
107
108 EdgePairInfo(int vertex, int knotIndex, int childEdge, int parentEdge)
109 : v(vertex), ksi(knotIndex), child(childEdge), parent(parentEdge),
110 isSet(true) { }
111
112 /// Set the data members.
113 void Set(int vertex, int knotIndex, int childEdge, int parentEdge)
114 {
115 v = vertex;
116 ksi = knotIndex;
117 child = childEdge;
118 parent = parentEdge;
119 isSet = true;
120 }
121
122 bool operator==(const EdgePairInfo& other) const
123 {
124 return v == other.v && ksi == other.ksi && child == other.child
125 && parent == other.parent;
126 }
127 };
128
129 /// Master edge data for a nonconforming patch topology.
130 struct MasterEdgeInfo
131 {
132 std::vector<int> slaves; /// Slave edge indices on the master edge
133 std::vector<int> vertices; /// Vertex indices on the master edge
134 std::vector<int> ks; /// Knot-span indices of vertices on the master edge
135
136 void Reverse()
137 {
138 std::reverse(slaves.begin(), slaves.end());
139 std::reverse(vertices.begin(), vertices.end());
140 std::reverse(ks.begin(), ks.end());
141 }
142 };
143
144 /// Master face data for a nonconforming patch topology.
145 struct MasterFaceInfo
146 {
147 std::vector<int> slaves; /// Slave face indices on the master face
148 std::vector<int> slaveCorners; /// Corner vertices of slave faces
149 std::array<int, 2> ne; /// Number of elements in each direction
150 std::array<int, 2> s0; /// Cartesian shift, see Reorder2D
151 bool rev; /// Whether dimensions are interchanged
152
153 MasterFaceInfo() : rev(false)
154 {
155 for (int i=0; i<2; ++i)
156 {
157 ne[i] = 0;
158 s0[i] = -1;
159 }
160 }
161
162 MasterFaceInfo(int ne1, int ne2) : rev(false)
163 {
164 ne[0] = ne1;
165 ne[1] = ne2;
166 for (int i=0; i<2; ++i) { s0[i] = -1; }
167 }
168 };
169
170 /// Slave face data for a nonconforming patch topology.
171 struct SlaveFaceInfo
172 {
173 int index; /// Face index
174 int ori; /// Orientation
175 int ksi[2]; /// Knot-span indices in parent face of v0
176 int ne[2]; /// Number of elements in each direction on child face
177 };
178
179 /** @brief Represents a pair of child and parent faces for a nonconforming
180 patch topology. */
181 struct FacePairInfo
182 {
183 int v0; /// Lower left corner vertex
184 int parent; /// Parent face index
185 SlaveFaceInfo info; /// Data for the child face
186 };
187
188 /// Auxiliary edges and faces for a nonconforming patch topology.
189 std::vector<AuxiliaryEdge> auxEdges;
190 std::vector<AuxiliaryFace> auxFaces;
191
192 /** @brief Maps from vertex pairs to indices in auxEdges, auxFaces. Vertex
193 pairs are sorted indices, with faces having 4 vertices represented by the
194 minimum index and the index of the diagonally opposite vertex. */
195 std::map<std::pair<int, int>, int> auxv2e, auxv2f;
196
197 /// Map from sorted vertex pairs to edge indices.
198 std::map<std::pair<int, int>, int> v2e;
199
200 /// Sets of master edges and face in patchTopo->ncmesh.
201 std::set<int> masterEdges, masterFaces;
202
203 /// Array form of @a masterEdges.
204 Array<int> masterEdgeIndex;
205
206 /** @brief Arrays of slave edges or faces, with possible repetitions, ordered
207 by position within their master entities. */
208 std::vector<int> slaveEdges;
209 std::vector<SlaveFaceInfo> slaveFaces;
210
211 /// Arrays of unique indices in @a slaveEdges, @a slaveFaces.
212 Array<int> slaveEdgesUnique, slaveFacesUnique;
213
214 /// Maps from slaveEdges/slaveFaces to slaveEdgesUnique/slaveEdgesUnique.
215 std::map<int,int> slaveEdgesToUnique, slaveFacesToUnique;
216
217 /// Maps from masterEdges/masterFaces to their indices in an ordered list.
218 std::map<int,int> masterEdgeToId, masterFaceToId;
219
220 /// Master edge and face data for a nonconforming patch topology.
221 std::vector<MasterEdgeInfo> masterEdgeInfo;
222 std::vector<MasterFaceInfo> masterFaceInfo;
223
224 /** @brief Get the DOF (dof = true) or vertex (dof = false) offset for the
225 edge with index @a edge plus @a increment. */
226 int GetEdgeOffset(bool dof, int edge, int increment) const;
227
228 /** @brief Get the DOF (dof = true) or vertex (dof = false) offset for the
229 face with index @a face plus @a increment. */
230 int GetFaceOffset(bool dof, int face, int increment) const;
231
232 /// Map from a parent entity vertex index pair to knotvectors on the entity.
233 std::map<std::pair<int, int>, std::array<int, 2>> parentToKV;
234
235 /// Update knot-span indices in @a auxEdges and @a auxFaces on refinement.
236 void UpdateAuxiliaryKnotSpans(const Array<int> &rf);
237
238 /// For the master edge with index @a mid, set offsets @a os for the number
239 /// of mesh edges in each subedge (slave or auxiliary edge).
240 void GetMasterEdgePieceOffsets(int mid, Array<int> &os);
241
242 /// Return the number of mesh edges in auxiliary edge @a aux_edge.
243 int AuxiliaryEdgeNE(int aux_edge);
244
245 /** @brief Find the permutation @a perm of slave face entities, with entity
246 perm[i] of the slave face being entity i in the master face ordering.
247
248 @param[in] sf Slave face index in @a patchTopo
249 @param[in] n1 Number of slave face edges, first master face direction.
250 @param[in] n2 Number of slave face edges, second master face direction.
251 @param[in] v0 Bottom-left face vertex with respect to the master face.
252 @param[in] e1 Local edge index, first direction of the slave face.
253 @param[in] e2 Local edge index, second direction of the slave face. */
254 void GetFaceOrdering(int sf, int n1, int n2, int v0, int e1, int e2,
255 Array<int> &perm) const;
256
257 /// Find additional slave and auxiliary faces after ProcessVertexToKnot3D.
258 void FindAdditionalFacesSA(
259 std::map<std::pair<int, int>, int> &v2f,
260 std::set<int> &addParentFaces,
261 std::vector<FacePairInfo> &facePairs);
262
263 /// Helper function for @a GenerateOffsets().
264 void ProcessFacePairs(int start, int midStart,
265 const std::vector<std::array<int, 2>> &parentSize,
266 std::vector<int> &parentVerts,
267 const std::vector<FacePairInfo> &facePairs);
268
269 /// Helper function for @a GenerateOffsets().
270 void ProcessVertexToKnot2D(const VertexToKnotSpan &v2k,
271 std::set<int> &reversedParents,
272 std::vector<EdgePairInfo> &edgePairs);
273
274 /// Helper function for @a GenerateOffsets().
275 void ProcessVertexToKnot3D(const VertexToKnotSpan &v2k,
276 const std::map<std::pair<int, int>, int> &v2f,
277 std::vector<std::array<int, 2>> &parentSize,
278 std::vector<EdgePairInfo> &edgePairs,
279 std::vector<FacePairInfo> &facePairs,
280 std::vector<int> &parentFaces,
281 std::vector<int> &parentVerts);
282
283 /// Helper function for @a GenerateOffsets().
284 void SetDofToPatch() override;
285
286 /// Helper functions for @a PropagateFactorsForKV().
287 void GetAuxFaceToPatchTable(Array2D<int> &auxface2patch);
288 void GetSlaveFaceToPatchTable(Array2D<int> &sface2patch);
289
290 /// Helper function for @a UniformRefinement().
291 void Refine(bool coarsened, const Array<int> *rf = nullptr);
292
293 /// Get the two endpoints of the auxiliary edge with index @a auxEdge.
294 void GetAuxEdgeVertices(int auxEdge, Array<int> &verts) const;
295
296 /// Get the four vertices of the auxiliary face with index @a auxFace.
297 void GetAuxFaceVertices(int auxFace, Array<int> &verts) const;
298
299 /// Get the four edges of the auxiliary face with index @a auxFace.
300 void GetAuxFaceEdges(int auxFace, Array<int> &edges) const;
301
302 /// Helper function for @a SetPatchFactors().
303 void SlaveEdgeToParent(int se, int parent, const Array<int> &os,
304 const std::vector<int> &parentVerts,
305 Array<int> &edges);
306
307 /// Helper function for @a FindAdditionalFacesSA().
308 void GetMasterEdgeEntities(int edge, Array<int> &edgeV, Array<int> &edgeE,
309 Array<int> &edgeVki);
310
311 /// Helper function for @a Refine().
312 void UpdateCoarseKVF();
313
314 /** @brief Read the control points for coarse patches.
315
316 This is useful for a mesh with a nonconforming patch topology, when
317 non-nested refinement is done. In such cases, knot insertion is done on
318 coarse structured patches with a single element. */
319 void ReadCoarsePatchCP(std::istream &input) override;
320
321 /// Print control points for coarse patches @a patchCP.
322 void PrintCoarsePatches(std::ostream &os) override;
323
324 std::vector<Array<int>> auxef; /// Auxiliary edge refinement factors
325};
326
327}
328
329#endif
Dynamic 2D array using row-major layout.
Definition array.hpp:430
NCNURBSExtension extends NURBSExtension to support NC-patch NURBS meshes.
Definition ncnurbs.hpp:23
void GenerateOffsets() override
Set the mesh and space offsets, and also count the global NumOfVertices and the global NumOfDofs.
Definition ncnurbs.cpp:3475
NCNURBSExtension(const NCNURBSExtension &orig)
Copy constructor: deep copy.
Definition ncnurbs.cpp:44
bool IsMasterFace(int face) const override
Return true if face is a master NC-patch face.
Definition ncnurbs.hpp:42
void GetMasterFaceDofs(bool dof, int mf, Array2D< int > &dofs) const override
Get the DOFs (dof = true) or vertices (dof = false) for master face mf.
Definition ncnurbs.cpp:925
bool IsMasterEdge(int edge) const override
Return true if edge is a master NC-patch edge.
Definition ncnurbs.hpp:38
void UniformRefinement(const Array< int > &rf) override
Definition ncnurbs.cpp:3338
void PropagateFactorsForKV(int rf_default)
Ensure consistent refinement factors on all knotvectors.
Definition ncnurbs.cpp:2617
int VertexPairToEdge(const std::pair< int, int > &vertices) const override
Given a pair of vertices, return the corresponding edge.
Definition ncnurbs.hpp:46
void RefineWithKVFactors(int rf, const std::string &kvf_filename, bool coarsened) override
Definition ncnurbs.cpp:2900
void LoadFactorsForKV(const std::string &filename)
Load refinement factors for a list of knotvectors from file.
Definition ncnurbs.cpp:2348
int SetPatchFactors(int p)
Set consistent refinement factors on patch p.
Definition ncnurbs.cpp:2486
void GetMasterEdgeDofs(bool dof, int me, Array< int > &dofs) const override
Get the DOFs (dof = true) or vertices (dof = false) for master edge me.
Definition ncnurbs.cpp:660
NURBSExtension generally contains multiple NURBSPatch objects spanning an entire Mesh....
Definition nurbs.hpp:474
real_t p(const Vector &x, real_t t)