MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
nurbs.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, 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_NURBS
13#define MFEM_NURBS
14
15#include "../config/config.hpp"
16#include "../general/table.hpp"
17#include "../linalg/vector.hpp"
18#include "element.hpp"
19#include "mesh.hpp"
20#include "spacing.hpp"
21#ifdef MFEM_USE_MPI
23#endif
24#include <iostream>
25
26namespace mfem
27{
28
29class GridFunction;
30
31/** @brief A vector of knots in one dimension, with B-spline basis functions of
32 a prescribed order.
33
34 @note Order is defined in the sense of "The NURBS book" - 2nd ed - Piegl and
35 Tiller, cf. section 2.2.
36*/
38{
39protected:
40 static const int MaxOrder;
41
42 /// Stores the values of all knots.
44
45 /// Order of the B-spline basis functions.
46 int Order;
47
48 /// Number of control points.
50
51 /// Number of elements, defined by distinct knots.
53
54 // Stores the demko points
55 mutable Vector demko;
56
57 /// Compute all the Demko points
58 void ComputeDemko() const;
59
60#ifdef MFEM_USE_LAPACK
61 // Data for reusing banded matrix factorization in FindInterpolant().
62 mutable DenseMatrix fact_AB; /// Banded matrix factorization
63 mutable Array<int> fact_ipiv; /// Row pivot indices
64#else
65 mutable DenseMatrix A_coll_inv; /// Collocation matrix inverse
66#endif
67
68
69public:
70 /// Create an empty KnotVector.
71 KnotVector() = default;
72
73 /** @brief Create a KnotVector by reading data from stream @a input. Two
74 integers are read, for order and number of control points. */
75 KnotVector(std::istream &input);
76
77 /** @brief Create a KnotVector with order @a order.
78 When @a NCP is not provided the number of control points is set to
79 @a order + 1, and the first @a order + 1 knots are set to 0 and last
80 @a order + 1 knots are set to 1.
81 When @a NCP is given number of control points is @a NCP and
82 the knots are initialized to -1) */
83 KnotVector(int order, int NCP = -1);
84
85 /** @brief Create a KnotVector with order @a order and knots @a knot.
86 If @a k has the correct number of repeated knots at the begin and end,
87 then this constructor will copy the knots as provided.
88 Otherwise, the knot vector will be extended by repeating the end knots
89 (order + 1) times. Internal knots will retain the multiplicity as given
90 in the input. */
91 KnotVector(int order, const Vector &k);
92
93 /** @brief Create a KnotVector by passing in a degree, a Vector of interval
94 lengths of length n, and a list of continuity of length n + 1.
95 The intervals refer to spans between unique knot values (not counting
96 zero-size intervals at repeated knots), and the continuity values should
97 be >= -1 (discontinuous) and <= order-1 (maximally-smooth for the given
98 polynomial degree). Periodicity is not supported.*/
99 KnotVector(int order, const Vector& intervals,
100 const Array<int>& continuity);
101
102 /// Copy constructor.
103 KnotVector(const KnotVector &kv) { (*this) = kv; }
104
105 KnotVector &operator=(const KnotVector &kv);
106
107 /// Return the number of elements, defined by distinct knots.
108 int GetNE() const { return NumOfElements; }
109
110 /// Return the number of control points.
111 int GetNCP() const { return NumOfControlPoints; }
112
113 /// Return the order.
114 int GetOrder() const { return Order; }
115
116 /// Return the number of knots, including multiplicities.
117 int Size() const { return knot.Size(); }
118
119 /// Count the number of elements.
120 void GetElements();
121
122 /** @brief Return whether the knot index Order plus @a i is the beginning of
123 an element. */
124 bool isElement(int i) const { return (knot(Order+i) != knot(Order+i+1)); }
125
126 /** @brief Return the number of control points minus the order. This is not
127 the number of knot spans, but it gives the number of knots to be checked
128 with @a isElement for non-empty knot spans (elements). */
129 int GetNKS() const { return NumOfControlPoints - Order; }
130
131 /// Return whether knot location @a u is in a given span @a ni.
132 bool inSpan(real_t u, int ni) const
133 {
134 if ((u < knot(ni)) || (u > knot(ni+1))) { return false; }
135 return true;
136 }
137
138 /// Return the index of the knot span containing parameter @a u.
139 int GetSpan(real_t u) const;
140
141 /** @brief Return the reference coordinate in [0,1] for parameter @a u
142 in the element beginning at knot @a ni. */
143 real_t GetRefPoint(real_t u, int ni) const
144 { return (u-knot(ni))/(knot(ni+1)-knot(ni)); };
145
146 /** @brief Return the knot location for element reference coordinate @a xi
147 in [0,1], for the element beginning at knot @a ni. */
148 real_t GetKnotLocation(real_t xi, int ni) const
149 { return (xi*knot(ni+1) + (1. - xi)*knot(ni)); }
150
151 /** @brief Return the parameter for element reference coordinate @a xi
152 in [0,1], for the element beginning at knot @a ni. */
153 MFEM_DEPRECATED real_t getKnotLocation(real_t xi, int ni) const
154 { return (xi*knot(ni+1) + (1. - xi)*knot(ni)); } // Use GetKnotLocation instead
155
156 /// Return the index of the knot span containing parameter @a u.
157 MFEM_DEPRECATED int findKnotSpan(real_t u) const; // Use GetSpan instead
158
159 /** Gives the @a i average knot location. Average is taken over @a Order
160 number of knots.*/
161 real_t GetGreville(int i) const;
162
163 void GetGreville(Vector &xi) const;
164
165 /** Gives the knot location where the @a i shape function is maximum.
166 Reverts to the Greville point if knot is repeated @a Order +1 times.
167 For background see:
168
169 Olivier Botella and Karim Shariff.
170 "B-spline methods in fluid dynamics."
171 International Journal of Computational Fluid Dynamics 17.2 (2003): 133-149.
172
173 Points are found using Newton iteration, with the Greville point as the
174 starting value. */
175 real_t GetBotella(int i) const;
176
177 void GetBotella(Vector &xi) const;
178
179 /** Gives the knot location of the @a i extremum of the Chebyshev spline.
180 For background see:
181
182 Stephen Demko
183 "On the existence of interpolating projections onto spline spaces."
184 Journal of approximation theory 43.2 (1985): 151-156.
185
186 Points are found using Remez iteration:
187 - Find interpolant, given by a, through given points, given by Demko
188 - Find extrema of this polynomial and update Demko points
189 - Repeat until converged
190 - Use the Greville point as starting point */
191 real_t GetDemko(int i) const;
192
193 void GetDemko(Vector &xi) const;
194
195 // The following functions evaluate shape functions, which are B-spline basis
196 // functions.
197
198 /** @brief Calculate the nonvanishing shape function values in @a shape for
199 the element corresponding to knot index @a i and element reference
200 coordinate @a xi. */
201 void CalcShape (Vector &shape, int i, real_t xi) const;
202
203 /** @brief Calculate derivatives of the nonvanishing shape function values in
204 @a grad for the element corresponding to knot index @a i and element
205 reference coordinate @a xi. */
206 void CalcDShape (Vector &grad, int i, real_t xi) const;
207
208 /** @brief Calculate n-th derivatives (order @a n) of the nonvanishing shape
209 function values in @a grad for the element corresponding to knot index
210 @a i and element reference coordinate @a xi. */
211 void CalcDnShape(Vector &gradn, int n, int i, real_t xi) const;
212
213 /// Calculate second-order shape function derivatives, using CalcDnShape.
214 void CalcD2Shape(Vector &grad2, int i, real_t xi) const
215 { CalcDnShape(grad2, 2, i, xi); }
216
217 /** @brief Gives the locations of the maxima of the KnotVector in reference
218 space. The function gives the knot span @a ks, the coordinate in the
219 knot span @a xi, and the coordinate of the maximum in parameter space
220 @a u.
221 The main purpose of this function is its use in FindInterpolant.
222 Use GetBotella instead for each shape function separately, perhaps in
223 conjunction with GetSpan and GetRefPoint.*/
224 MFEM_DEPRECATED void FindMaxima(Array<int> &ks, Vector &xi, Vector &u) const;
225
226 /** @brief Global curve interpolation through the points @a x (overwritten).
227 @a x is an array with the length of the spatial dimension containing
228 vectors with spatial coordinates. The control points of the interpolated
229 curve are returned in @a x in the same form.
230 Use GetInterpolant instead. For the knot location one can use either
231 GetBotella, GetDemko or GetGreville. FindInterpolant uses the Botella
232 points, however, the Demko points might be more appropriate. */
233 MFEM_DEPRECATED void FindInterpolant(Array<Vector*> &x, bool reuse_inverse);
234
235 /** @brief Global curve interpolation through the points @a x (overwritten)
236 at the knot location @a u. The control points of the
237 interpolated curve are returned in @a x in the same form.
238 For the knot location one can use for instance GetBotella, GetDemko or
239 GetGreville. The Demko points might be most appropriate.*/
240 void GetInterpolant(Array<Vector*> &x, const Vector &u,
241 bool reuse_inverse = false) const;
242
243 /// Different interface to same routine
244 void GetInterpolant(const Vector &x, const Vector &u,
245 Vector &a, bool reuse_inverse = false) const;
246
247 /** Set @a diff, comprised of knots in @a kv not contained in this KnotVector.
248 @a kv must be of the same order as this KnotVector. The current
249 implementation is not well defined, and the function may have undefined
250 behavior, as @a diff may have unset entries at the end. */
251 void Difference(const KnotVector &kv, Vector &diff) const;
252
253 /// Uniformly refine by factor @a rf, by inserting knots in each span.
254 void UniformRefinement(Vector &new_knots, int rf) const;
255
256 /// Refine with refinement factor @a rf.
257 void Refinement(Vector &new_knots, int rf) const;
258
259 /** Returns the coarsening factor needed for non-nested nonuniform spacing
260 functions, to result in a single element from which refinement can be
261 done. The return value is 1 if uniform or nested spacing is used. */
262 int GetCoarseningFactor() const;
263
264 /** For a given coarsening factor @a cf, find the fine knots between the
265 coarse knots. */
266 Vector GetFineKnots(const int cf) const;
267
268 /** @brief Return a new KnotVector with elevated degree by repeating the
269 endpoints of the KnotVector. */
270 /// @note The returned object should be deleted by the caller.
271 KnotVector *DegreeElevate(int t) const;
272
273 /// Reverse the knots.
274 void Flip();
275
276 /** @brief Print the order, number of control points, and knots.
277
278 The output is formatted for writing a mesh to file. This function is
279 called by NURBSPatch::Print. */
280 void Print(std::ostream &os) const;
281
282 /** @brief Prints the non-zero shape functions and their first and second
283 derivatives associated with the KnotVector per element. Use GetElements()
284 to count the elements before using this function. @a samples is the
285 number of samples of the shape functions per element.*/
286 void PrintFunctions(std::ostream &os, int samples=11) const;
287
288 /** Prints the function with basis function coefficient @a a, and its first
289 and second derivatives associated with the KnotVector per element.
290 Use GetElements() to count the elements before using this function.
291 @a samples is the number of samples of the shape functions per element.*/
292 void PrintFunction(std::ostream &os, const Vector &a, int samples=11) const;
293
294 /** Prints the @a i-th function and its first and second
295 derivatives associated with the KnotVector per element. Use GetElements()
296 to count the elements before using this function. @a samples is the
297 number of samples of the shape functions per element.*/
298 void PrintFunction(std::ostream &os, int i, int samples=11) const;
299
300 /// Destroys KnotVector
302
303 /// Access function to knot @a i.
304 real_t &operator[](int i) { return knot(i); }
305
306 /// Const access function to knot @a i.
307 const real_t &operator[](int i) const { return knot(i); }
308
309 /// Coarsen to a single element.
311
312 /// Function to define the distribution of knots for any number of knot spans.
313 std::shared_ptr<SpacingFunction> spacing;
314
315 /** @brief Flag to indicate whether the KnotVector has been coarsened, which
316 means it is ready for non-nested refinement. */
317 bool coarse;
318};
319
320
321/** @brief A NURBS patch can be 1D, 2D, or 3D, and is defined as a tensor
322 product of KnotVectors. */
324{
325protected:
326
327 /// B-NET dimensions
328 int ni, nj, nk;
329
330 /// Physical dimension plus 1
331 int Dim;
332
333 /// Data with the layout (Dim x ni x nj x nk)
335
336 /// KnotVectors in each direction
338
339 // Special B-NET access functions
340 // - SetLoopDirection(int dir) flattens the multi-dimensional B-NET in the
341 // requested direction. It effectively creates a 1D net in homogeneous
342 // coordinates.
343 // - The slice(int, int) operator is the access function in that flattened
344 // structure. The first int gives the slice and the second int the element
345 // in that slice.
346 // - Both routines are used in 'KnotInsert', `KnotRemove`, 'DegreeElevate',
347 // and 'UniformRefinement'.
348 // - In older implementations, slice(int, int) was implemented as
349 // operator()(int, int).
350 int nd; // Number of control points in flattened structure
351 int ls; // Number of variables per control point in flattened structure
352 int sd; // Stride for data access
353
354 /** @brief Flattens the B-NET in direction @a dir, producing a 1D net.
355 Returns the number of variables per knot in flattened structure. */
356 int SetLoopDirection(int dir);
357
358 /** @brief Access function for the effectively 1D flattened net, where @a i
359 is a knot index, and @a j is an index of a variable per knot. */
360 inline real_t &slice(int i, int j);
361 inline const real_t &slice(int i, int j) const;
362
363 /** @brief Construct a new patch, copying the KnotVectors of @a parent
364 except in direction @a dir, which gets a new KnotVector of order
365 @a Order with @a NCP control points (knots initialized to -1). The
366 control point data is allocated but not initialized. */
367 NURBSPatch(NURBSPatch *parent, int dir, int Order, int NCP);
368
369 /// Deletes own data, takes data from @a np, and deletes np.
370 void swap(NURBSPatch *np);
371
372 /// Sets dimensions and allocates data, based on KnotVectors.
373 /// @a dim is the physical dimension plus 1.
374 void init(int dim);
375
376public:
377 /// Copy constructor
378 NURBSPatch(const NURBSPatch &orig);
379
380 /// Constructor using data read from stream @a input.
381 NURBSPatch(std::istream &input);
382
383 /// Constructor for a 2D patch. @a dim is the physical dimension plus 1.
384 NURBSPatch(const KnotVector *kv0, const KnotVector *kv1, int dim);
385
386 /// Constructor for a 3D patch.
387 NURBSPatch(const KnotVector *kv0, const KnotVector *kv1,
388 const KnotVector *kv2, int dim);
389
390 /** Create a bivariate NURBS patch with given control points. See n-variate
391 overload for additional notes. */
392 NURBSPatch(const KnotVector *kv0, const KnotVector *kv1, int dim_,
393 const real_t* control_points);
394 /** Create a trivariate NURBS patch with given control points. See n-variate
395 overload for additional notes. */
396 NURBSPatch(const KnotVector *kv0, const KnotVector *kv1,
397 const KnotVector *kv2, int dim_, const real_t* control_points);
398 /** Create an n-variate NURBS patch with given control points of dimension
399 dim_, where n is the length of the array of knot vectors and dim_
400 includes the weight. The array of control point coordinates stores each
401 point's coordinates contiguously, and points are ordered in a standard
402 ijk grid ordering. */
404 const real_t* control_points);
405
406 /// Constructor for a patch of dimension equal to the size of @a kv.
408
409 /// Copy assignment not supported.
410 NURBSPatch& operator=(const NURBSPatch&) = delete;
411
412 /// Deletes data and KnotVectors.
413 ~NURBSPatch();
414
415 /** @brief Writes KnotVectors and data to the stream @a os.
416
417 The output is formatted for writing a mesh to file. This function is
418 called by NURBSExtension::Print. */
419 void Print(std::ostream &os) const;
420
421 /// Increase the order in direction @a dir by @a t >= 0.
422 void DegreeElevate(int dir, int t);
423
424 /// Increase the order in all directions by @a t >= 0.
425 void DegreeElevate(int t);
426
427 /** @brief Insert any new knots from @a knot in direction @a dir. If the
428 order of @a knot is higher than the current order in direction
429 @a dir, then the order is elevated in that direction to match. */
430 void KnotInsert(int dir, const KnotVector &knot);
431
432 /** @brief Insert knots from @a knot in direction @a dir. If a knot already
433 exists, then it is still added, increasing its multiplicity. */
434 void KnotInsert(int dir, const Vector &knot);
435
436 /// Call KnotInsert for each direction with the corresponding @a knot entry.
437 void KnotInsert(Array<Vector *> &knot);
438 /// Insert knots from @a knot determined by @a Difference, in each direction.
440
441 /** @brief Remove knot with value @a knot from direction @a dir.
442
443 The optional input parameter @a ntimes specifies the number of times the
444 knot should be removed, default 1. The knot is removed only if the new
445 curve (in direction @a dir) deviates from the old curve by less than
446 @a tol.
447
448 @returns The number of times the knot was successfully removed. */
449 int KnotRemove(int dir, real_t knot, int ntimes=1, real_t tol = 1.0e-12);
450
451 /// Remove all knots in @a knot once.
452 void KnotRemove(int dir, Vector const& knot, real_t tol = 1.0e-12);
453 /// Remove all knots in @a knot once, for each direction.
454 void KnotRemove(Array<Vector *> &knot, real_t tol = 1.0e-12);
455
456 /** @brief Refine with optional refinement factor @a rf. Uniform means
457 refinement is done everywhere by the same factor, although nonuniform
458 spacing functions may be used.
459
460 @param[in] rf Optional refinement factor. If scalar, the factor is used
461 for all dimensions. If an array, factors can be specified
462 for each dimension.
463 @param[in] multiplicity Optional multiplicity for new knots inserted. */
464 void UniformRefinement(int rf = 2, int multiplicity = 1);
465 void UniformRefinement(const Array<int> &rf, int multiplicity = 1);
466
467 /// Flag @a coarsened indicates whether the patch is a single element.
468 void UniformRefinement(const std::vector<Array<int>> &rf,
469 bool coarsened = false, int multiplicity = 1);
470
471 /** @brief Coarsen with optional coarsening factor @a cf which divides the
472 number of elements in each dimension. Nonuniform spacing functions may be
473 used in each direction.
474
475 @param[in] cf Optional coarsening factor. If scalar, the factor is used
476 for all dimensions. If an array, factors can be specified
477 for each dimension.
478 @param[in] tol NURBS geometry deviation tolerance, cf. Algorithm A5.8 of
479 "The NURBS Book", 2nd ed, Piegl and Tiller. */
480 void Coarsen(int cf = 2, real_t tol = 1.0e-12);
481 void Coarsen(const Array<int> &cf, real_t tol = 1.0e-12);
482
483 /// Calls KnotVector::GetCoarseningFactor for each direction.
484 void GetCoarseningFactors(Array<int> &f) const;
485
486 /// Marks the KnotVector in each dimension as coarse.
487 void SetKnotVectorsCoarse(bool c);
488
489 /// Coarsen to a single element.
490 void FullyCoarsen(const Array2D<double> &cp, int ncp1D);
491
492 /// Update piecewise spacing function partitions to match refined @a pkv.
494
495 /// Return the number of components stored in the NURBSPatch
496 int GetNC() const { return Dim; }
497
498 /// Return the number of KnotVectors, which is the patch dimension.
499 int GetNKV() const { return kv.Size(); }
500
501 /// Return a pointer to the KnotVector in direction @a dir.
502 /// @note The returned object should NOT be deleted by the caller.
503 KnotVector *GetKV(int dir) { return kv[dir]; }
504
505 // Standard B-NET access functions
506
507 /// 1D access function. @a i is a B-NET index, and @a l is a variable index.
508 inline real_t &operator()(int i, int l);
509 inline const real_t &operator()(int i, int l) const;
510
511 /** @brief 2D access function. @a i, @a j are B-NET indices, and @a l is a
512 variable index. */
513 inline real_t &operator()(int i, int j, int l);
514 inline const real_t &operator()(int i, int j, int l) const;
515
516 /** @brief 3D access function. @a i, @a j, @a k are B-NET indices, and @a l
517 is a variable index. */
518 inline real_t &operator()(int i, int j, int k, int l);
519 inline const real_t &operator()(int i, int j, int k, int l) const;
520
521 /// Compute the 2D rotation matrix @a T for angle @a angle.
522 static void Get2DRotationMatrix(real_t angle, DenseMatrix &T);
523
524 /** @brief Compute the 3D rotation matrix @a T for angle @a angle around
525 axis @a n (a 3D vector, not necessarily normalized) and scalar factor
526 @a r. */
527 static void Get3DRotationMatrix(real_t n[], real_t angle, real_t r,
528 DenseMatrix &T);
529
530 /// Reverse data and knots in direction @a dir.
531 void FlipDirection(int dir);
532
533 /// Swap data and KnotVectors in directions @a dir1 and @a dir2.
534 /** @note Direction pairs (0,2) and (2,0) are not supported, resulting in an
535 error being thrown. */
536 void SwapDirections(int dir1, int dir2);
537
538 /// Rotate the NURBSPatch in 2D or 3D..
539 /** A rotation of a 2D NURBS-patch requires an angle only. Rotating
540 a 3D NURBS-patch requires a normal as well.*/
541 void Rotate(real_t angle, real_t normal[] = NULL);
542
543 /// Rotate the NURBSPatch, 2D case.
544 void Rotate2D(real_t angle);
545
546 /// Rotate the NURBSPatch, 3D case.
547 void Rotate3D(real_t normal[], real_t angle);
548
549 /** Elevate KnotVectors in all directions to degree @a degree if given,
550 otherwise to the maximum current degree among all directions. */
551 int MakeUniformDegree(int degree = -1);
552
553 /** @brief Given two patches @a p1 and @a p2 of the same dimensions, create
554 and return a new patch by merging their knots and data. */
555 /// @note The returned object should be deleted by the caller.
557
558 /// Create and return a new patch by revolving @a patch in 3D.
559 /// @note The returned object should be deleted by the caller.
560 friend NURBSPatch *Revolve3D(NURBSPatch &patch, real_t n[], real_t ang,
561 int times);
562};
563
564
565#ifdef MFEM_USE_MPI
566class ParNURBSExtension;
567#endif
568
569class NURBSPatchMap;
570
571/** @brief NURBSExtension generally contains multiple NURBSPatch objects
572 spanning an entire Mesh. It also defines and manages DOFs in NURBS finite
573 element spaces. */
575{
576#ifdef MFEM_USE_MPI
577 friend class ParNURBSExtension;
578#endif
579 friend class NURBSPatchMap;
580
581protected:
582
583 /// Flag for indicating what type of NURBS fespace this extension is used for.
584 enum class Mode
585 {
586 H_1, ///> Extension for a standard scalar-valued space
587 H_DIV, ///> Extension for a divergence conforming vector-valued space
588 H_CURL, ///> Extension for a curl conforming vector-valued space
589 };
591
592 /// Order of KnotVectors, see GetOrder() for description.
594
595 /// Orders of all KnotVectors
597
598 /// Number of unique (not comprehensive) KnotVectors
600
601 /// Global entity counts
603
604 /// Local entity counts
607
608 Array<int> activeVert; // activeVert[glob_vert] = loc_vert or -1
611 Array<int> activeDof; // activeDof[glob_dof] = loc_dof + 1 or 0
612
613 /// Patch topology mesh
615
616 /// Whether this object owns patchTopo
618
619 /// Map from patchTopo edge indices to unique KnotVector indices
621
622 /// Set of unique KnotVectors
624
625 /// Comprehensive set of all KnotVectors, one for every edge.
627
628 /// Weights for each control point or DOF
630
631 /** @brief Periodic BC info:
632 - dof 2 dof map
633 - master and slave boundary indices */
637
638 /// Global mesh offsets, meshOffsets == meshVertexOffsets
643
644 /// Global space offsets, spaceOffsets == dofOffsets
649
650 /// Table of DOFs for each element (el_dof) or boundary element (bel_dof).
652
653 /// Map from element indices to patch indices
655 /// Map from boundary element indices to patch indices
657
658 /// Map from element indices to IJK knot span indices
659 Array2D<int> el_to_IJK; // IJK are "knot-span" indices!
660 Array2D<int> bel_to_IJK; // they are NOT element indices!
661
662 /// For each patch p, @a patch_to_el[p] lists all elements in the patch.
663 std::vector<Array<int>> patch_to_el;
664 /// For each patch p, @a patch_to_bel[p] lists all boundary elements in the patch.
665 std::vector<Array<int>> patch_to_bel;
666
667 /// Array of all patches in the mesh.
669
670 /// Return the unsigned index of the KnotVector for edge @a edge.
671 inline int KnotInd(int edge) const;
672 /// Return the sign (orientation) of the KnotVector for edge @a edge.
673 inline int KnotSign(int edge) const;
674
675 bool nonconformingPT = false; /// Whether patchTopo is a nonconforming mesh.
676
677 int num_structured_patches = 0; /// Number of structured patches
678
679 Array3D<double> patchCP; /// Control points for coarse structured patches
680
681 std::vector<Array<int>> kvf, kvf_coarse; /// Knotvector refinement factors
682
683 Array<int> ref_factors; /// Refinement factors in each dimension.
684
685 static constexpr int unsetFactor = 0; /// Unset refinement factor value
686
687 Array<int> dof2patch; /// DOF to owning patch map in @a SetSolutionVector()
688
689 /// Access function for the KnotVector associated with edge @a edge.
690 /// @note The returned object should NOT be deleted by the caller.
691 inline KnotVector *KnotVec(int edge);
692 /// Const access function for the KnotVector associated with edge @a edge.
693 /// @note The returned object should NOT be deleted by the caller.
694 inline const KnotVector *KnotVec(int edge) const;
695 /** @brief Const access function for the KnotVector associated with edge
696 @a edge. The output orientation @a okv is set to @a oedge with sign flipped
697 if the KnotVector index associated with edge @a edge is negative. */
698 inline const KnotVector *KnotVec(int edge, int oedge, int *okv) const;
699
700 /// Throw an error if any boundary patch has invalid KnotVector orientation.
701 MFEM_DEPRECATED void CheckBdrPatches();
702
703 /// Return the patch-topology edge indices that define the KnotVectors for
704 /// patch @a p in each parametric direction.
705 void GetPatchDirectionEdges(int p, Array<int> &edges);
706
707 /** @brief Return the directions in @a kvdir of the KnotVectors in patch @a p
708 based on the patch edge orientations. Each entry of @a kvdir is -1 if the
709 KnotVector direction is flipped, +1 otherwise. */
710 void CheckKVDirection(int p, Array <int> &kvdir);
711
712 /** @brief Create the comprehensive set of KnotVectors, one per patch and
713 parametric direction, accounting for the edge orientations. */
715
716 /** @brief Update the unique set of KnotVectors from the comprehensive set
717 of KnotVectors. */
718 void UpdateUniqueKV();
719
720 /** @brief Check if the comprehensive array of KnotVectors agrees with the
721 unique set of KnotVectors, on each patch. Return false if there is a
722 difference, true otherwise. */
723 bool ConsistentKVSets();
724
725 /// Return KnotVectors in @a kv in each dimension for patch @a p.
727 /// Return KnotVectors in @a kv in each dimension for boundary patch @a bp.
729
730 /// Set overall order @a mOrder based on KnotVector orders.
731 void SetOrderFromOrders();
732
733 /// Set orders from KnotVector orders.
735
736 // Periodic BC helper functions
737
738 /// Set DOF map sizes to 0.
739 void InitDofMap();
740
741 /// Set DOF maps for periodic BC.
742 void ConnectBoundaries();
743 void ConnectBoundaries1D(int bnd0, int bnd1);
744 void ConnectBoundaries2D(int bnd0, int bnd1);
745 void ConnectBoundaries3D(int bnd0, int bnd1);
746
747 /** @brief Set the mesh and space offsets, and also count the global
748 @a NumOfVertices and the global @a NumOfDofs. */
749 virtual void GenerateOffsets();
750
751 /// Count the global @a NumOfElements.
752 void CountElements();
753 /// Count the global @a NumOfBdrElements.
754 void CountBdrElements();
755
756 /// Generate the active mesh elements and return them in @a elements.
757 void Get1DElementTopo(Array<Element *> &elements) const;
758 void Get2DElementTopo(Array<Element *> &elements) const;
759 void Get3DElementTopo(Array<Element *> &elements) const;
760
761 /// Generate the active mesh boundary elements and return them in @a boundary.
762 void Get1DBdrElementTopo(Array<Element *> &boundary) const;
763 void Get2DBdrElementTopo(Array<Element *> &boundary) const;
764 void Get3DBdrElementTopo(Array<Element *> &boundary) const;
765
766 // FE space generation functions
767
768 /** @brief Based on activeElem, count NumOfActiveDofs and generate el_dof,
769 el_to_patch, el_to_IJK, activeDof map (global-to-local). */
771
772 /** @brief Generate elem_to_global-dof table for the active elements, and
773 define el_to_patch, el_to_IJK, activeDof (as bool). */
777
778 /// Call after GenerateElementDofTable to set boundary element DOF table.
780
781 /** @brief Generate the table of global DOFs for active boundary elements,
782 and define bel_to_patch, bel_to_IJK. */
786
787 // FE --> Patch translation functions
788
789 /// Set the B-NET on each patch using values from @a coords.
790 void GetPatchNets (const Vector &coords, int vdim);
791 void Get1DPatchNets(const Vector &coords, int vdim);
792 void Get2DPatchNets(const Vector &coords, int vdim);
793 void Get3DPatchNets(const Vector &coords, int vdim);
794
795 // Patch --> FE translation functions
796
797 /** @brief Return in @a coords the coordinates from each patch. Side effects:
798 delete the patches and update the weights from the patches. */
799 void SetSolutionVector (Vector &coords, int vdim);
800 void Set1DSolutionVector(Vector &coords, int vdim);
801 void Set2DSolutionVector(Vector &coords, int vdim);
802 void Set3DSolutionVector(Vector &coords, int vdim);
803
804 /// Determine activeVert, NumOfActiveVertices from the activeElem array.
806
807 /// Determine activeBdrElem, NumOfActiveBdrElems.
809
810 /** @brief Set the weights in this object to values from active elements in
811 @a num_pieces meshes in @a mesh_array. */
812 void MergeWeights(Mesh *mesh_array[], int num_pieces);
813
814 /// Set @a patch_to_el.
815 void SetPatchToElements();
816 /// Set @a patch_to_bel.
818
819 /// Load data from file (used by constructor).
820 void Load(std::istream &input, bool spacing);
821
822 /// Return true if @a edge is a master NC-patch edge.
823 virtual bool IsMasterEdge(int edge) const { return false; }
824
825 /// Return true if @a face is a master NC-patch face.
826 virtual bool IsMasterFace(int face) const { return false; }
827
828 /// Given a pair of vertices, return the corresponding edge.
829 virtual int VertexPairToEdge(const std::pair<int, int> &vertices) const;
830
831 /** @brief Get the DOFs (dof = true) or vertices (dof = false) for
832 master edge @a me. */
833 virtual void GetMasterEdgeDofs(bool dof, int me, Array<int> &dofs) const;
834
835 /** @brief Get the DOFs (dof = true) or vertices (dof = false) for
836 master face @a mf. */
837 virtual void GetMasterFaceDofs(bool dof, int mf, Array2D<int> &dofs) const;
838
839 /// Helper function for @a GenerateOffsets().
840 void GetPatchOffsets(int &meshCounter, int &spaceCounter);
841
842 /// Return NURBSPatch object; returned object should NOT be deleted.
843 const NURBSPatch* GetPatch(int patch) const { return patches[patch]; }
844
845 /// To be used by ParNURBSExtension constructor(s)
846 NURBSExtension() : el_dof(nullptr), bel_dof(nullptr) { }
847
848private:
849 /// Get the degrees of freedom for the vertex @a vertex in @a dofs.
850 void GetVertexDofs(int vertex, Array<int> &dofs) const;
851
852 /// Get the degrees of freedom for the edge @a edge in @a dofs.
853 void GetEdgeDofs(int edge, Array<int> &dofs) const;
854
855 // TODO: does this still need to be virtual?
856 /// Helper function for @a GenerateOffsets().
857 virtual void SetDofToPatch() { };
858
859public:
860 /// Copy constructor: deep copy
861 NURBSExtension(const NURBSExtension &orig);
862 /// Read-in a NURBSExtension from a stream @a input.
863 NURBSExtension(std::istream &input, bool spacing=false);
864 /** @brief Create a NURBSExtension with elevated order by repeating the
865 endpoints of the KnotVectors and using uniform weights of 1. */
866 /** @note If a KnotVector in @a parent already has order greater than or
867 equal to @a newOrder, it will be used unmodified. */
868 NURBSExtension(NURBSExtension *parent, int newOrder);
869 /** @brief Create a NURBSExtension with elevated KnotVector orders (by
870 repeating the endpoints of the KnotVectors and using uniform weights of
871 1) as given by the array @a newOrders. */
872 /** @a note If a KnotVector in @a parent already has order greater than or
873 equal to the corresponding entry in @a newOrder, it will be used
874 unmodified. */
875 NURBSExtension(NURBSExtension *parent, const Array<int> &newOrders,
877 /// Construct a NURBSExtension by merging a partitioned NURBS mesh.
878
879 NURBSExtension(Mesh *mesh_array[], int num_pieces);
880
881 NURBSExtension(const Mesh *patch_topology,
882 const Array<const NURBSPatch*> &patches_);
883
884 /// Copy assignment not supported.
886
887 /// Generate connections between boundaries, such as periodic BCs.
889 const Array<int> &GetMaster() const { return master; };
891 const Array<int> &GetSlave() const { return slave; };
892 Array<int> &GetSlave() { return slave; };
893
894 /** @brief Set the DOFs of @a merged to values from active elements in
895 @a num_pieces of Gridfunctions @a gf_array. */
896 void MergeGridFunctions(GridFunction *gf_array[], int num_pieces,
897 GridFunction &merged);
898
899 /// Returns false if any patch has an inconsistent edge_to_ukv mapping.
900 bool CheckPatches();
901
902 /// Destroy a NURBSExtension.
903 virtual ~NURBSExtension();
904
905 // Print functions
906
907 /** @brief Writes all patch data to the stream @a os.
908
909 The optional input argument @a comments is a string of comments to be
910 printed after the first line (containing version number) of a mesh file.
911 The output is formatted for writing a mesh to file. This function is
912 called by Mesh::Printer. */
913 void Print(std::ostream &os, const std::string &comments = "") const;
914
915 /// Print various mesh characteristics to the stream @a os.
916 void PrintCharacteristics(std::ostream &os) const;
917
918 /** @brief Call @a KnotVector::PrintFunctions for all KnotVectors, using a
919 separate, newly created ofstream with filename "basename_i.dat" for
920 KnotVector i. */
921 void PrintFunctions(const char *basename, int samples=11) const;
922
923 // Meta data functions
924
925 /// Return the dimension of the reference space (not physical space).
926 int Dimension() const { return patchTopo->Dimension(); }
927
928 /** @brief Return the physical dimension of the NURBS geometry
929
930 The physical dimension is inferred from the first patch,
931 i.e. number of coordinates per control point minus one (for the weight).
932 This method requires patch data to be present, i.e. HavePatches() == true */
933 int GetPatchSpaceDimension() const;
934
935 /// Return the number of patches.
936 int GetNP() const { return patchTopo->GetNE(); }
937
938 /// Return the number of boundary patches.
939 int GetNBP() const { return patchTopo->GetNBE(); }
940
941 /// Read-only access to the orders of all KnotVectors.
942 const Array<int> &GetOrders() const { return mOrders; }
943
944 /** @brief If all KnotVector orders are identical, return that number.
945 Otherwise, return NURBSFECollection::VariableOrder. */
946 int GetOrder() const { return mOrder; }
947
948 /// Return the number of KnotVectors.
949 int GetNKV() const { return NumOfKnotVectors; }
950
951 /// Return the global number of vertices.
952 int GetGNV() const { return NumOfVertices; }
953 /// Return the local number of active vertices.
954 int GetNV() const { return NumOfActiveVertices; }
955 /// Return the global number of elements.
956 int GetGNE() const { return NumOfElements; }
957 /// Return the number of active elements.
958 int GetNE() const { return NumOfActiveElems; }
959 /// Return the global number of boundary elements.
960 int GetGNBE() const { return NumOfBdrElements; }
961 /// Return the number of active boundary elements.
962 int GetNBE() const { return NumOfActiveBdrElems; }
963
964 /// Return the total number of DOFs.
965 int GetNTotalDof() const { return NumOfDofs; }
966 /// Return the number of active DOFs.
967 int GetNDof() const { return NumOfActiveDofs; }
968
969 /// Return the local DOF number for a given global DOF number @a glob.
970 int GetActiveDof(int glob) const { return activeDof[glob]; };
971
972 /// Return the dof index whilst accounting for periodic boundaries.
973 int DofMap(int dof) const
974 {
975 return (d_to_d.Size() > 0) ? d_to_d[dof] : dof;
976 };
977
978 /// Return KnotVectors in @a kv in each dimension for patch @a p.
980
981 /// Return KnotVectors in @a kv in each dimension for boundary patch @a bp.
983
984 /// KnotVector read-only access function.
985 const KnotVector *GetKnotVector(int i) const { return knotVectors[i]; }
986
987 // Mesh generation functions
988
989 /// Generate the active mesh elements and return them in @a elements.
990 void GetElementTopo (Array<Element *> &elements) const;
991 /// Generate the active mesh boundary elements and return them in @a boundary.
992 void GetBdrElementTopo(Array<Element *> &boundary) const;
993
994 /// Return true if at least 1 patch is defined, false otherwise.
995 bool HavePatches() const { return (patches.Size() != 0); }
996
997 /// Access function for the element DOF table @a el_dof.
998 /// @note The returned object should NOT be deleted by the caller.
1000
1001 /// Access function for the boundary element DOF table @a bel_dof.
1002 /// @note The returned object should NOT be deleted by the caller.
1004
1005 /// Get the local to global vertex index map @a lvert_vert.
1006 void GetVertexLocalToGlobal(Array<int> &lvert_vert);
1007 /// Get the local to global element index map @a lelem_elem.
1008 void GetElementLocalToGlobal(Array<int> &lelem_elem);
1009
1010 /** @brief Set the attribute for patch @a i, which is set to all elements in
1011 the patch. */
1012 void SetPatchAttribute(int i, int attr) { patchTopo->SetAttribute(i, attr); }
1013
1014 /** @brief Get the attribute for patch @a i, which is set to all elements in
1015 the patch. */
1016 int GetPatchAttribute(int i) const { return patchTopo->GetAttribute(i); }
1017
1018 /** @brief Set the attribute for patch boundary element @a i to @a attr, which
1019 is set to all boundary elements in the patch. */
1020 void SetPatchBdrAttribute(int i, int attr)
1021 { patchTopo->SetBdrAttribute(i, attr); }
1022
1023 /** @brief Get the attribute for boundary patch element @a i, which is set to
1024 all boundary elements in the patch. */
1025 int GetPatchBdrAttribute(int i) const
1026 { return patchTopo->GetBdrAttribute(i); }
1027
1028 /// Return the number of knotvector elements for edge @a edge.
1029 inline int KnotVecNE(int edge) const;
1030
1031 // Load functions
1032
1033 /// Load element @a i into @a FE.
1034 void LoadFE(int i, const FiniteElement *FE) const;
1035 /// Load boundary element @a i into @a BE.
1036 void LoadBE(int i, const FiniteElement *BE) const;
1037
1038 /// Access function to the vector of weights @a weights.
1039 const Vector &GetWeights() const { return weights; }
1041
1042 // Translation functions between FE coordinates and IJK patch format.
1043
1044 /// Define patches in IKJ (B-net) format, using FE coordinates in @a Nodes.
1045 void ConvertToPatches(const Vector &Nodes);
1046 /// Set KnotVectors from @a patches and construct mesh and space data.
1047 void SetKnotsFromPatches();
1048 /** @brief Set FE coordinates in @a Nodes, using data from @a patches,
1049 with physical vector dimension @a vdim, and erase @a patches. */
1050 void SetCoordsFromPatches(Vector &Nodes, int vdim);
1051
1052 /** @brief Read a GridFunction @a sol from stream @a input, written
1053 patch-by-patch, e.g. with PrintSolution(). */
1054 void LoadSolution(std::istream &input, GridFunction &sol) const;
1055 /// Write a GridFunction @a sol patch-by-patch to stream @a os.
1056 void PrintSolution(const GridFunction &sol, std::ostream &os) const;
1057
1058 // Refinement methods
1059
1060 /** @brief Call @a DegreeElevate for all KnotVectors of all patches. For each
1061 KnotVector, the new degree is
1062 max(old_degree, min(old_degree + rel_degree, degree)). */
1063 void DegreeElevate(int rel_degree, int degree = 16);
1064
1065 /** @brief Refine with optional refinement factor @a rf. Uniform means
1066 refinement is done everywhere by the same factor, although nonuniform
1067 spacing functions may be used. */
1068 void UniformRefinement(int rf = 2);
1069 virtual void UniformRefinement(const Array<int> &rf);
1070
1071 /// Refine with refinement factors loaded for some knotvectors specified in
1072 /// the given file, with default refinement factor @a rf elsewhere. The flag
1073 /// @a coarsened indicates whether each patch is a single element.
1074 virtual void RefineWithKVFactors(int rf, const std::string &kvf_filename,
1075 bool coarsened);
1076
1077 /// Coarsen with optional coarsening factor @a cf.
1078 void Coarsen(int cf = 2, real_t tol = 1.0e-12);
1079 void Coarsen(Array<int> const& cf, real_t tol = 1.0e-12);
1080
1081 /** @brief Insert knots from @a kv into all KnotVectors in all patches. The
1082 size of @a kv should be the same as @a knotVectors. */
1084 void KnotInsert(Array<Vector *> &kv);
1085
1086 /** Returns the NURBSExtension to be used for @a component of
1087 an H(div) conforming NURBS space. Caller gets ownership of
1088 the returned object, and is responsible for deletion.*/
1089 NURBSExtension* GetDivExtension(int component);
1090
1091 /** Returns the NURBSExtension to be used for @a component of
1092 an H(curl) conforming NURBS space. Caller gets ownership of
1093 the returned object, and is responsible for deletion.*/
1094 NURBSExtension* GetCurlExtension(int component);
1095
1096 void KnotRemove(Array<Vector *> &kv, real_t tol = 1.0e-12);
1097
1098 /** Calls GetCoarseningFactors for each patch and finds the minimum factor
1099 for each direction that ensures refinement will work in the case of
1100 non-nested spacing functions. */
1101 void GetCoarseningFactors(Array<int> &f) const;
1102
1103 /// Returns the index of the patch containing element @a elem.
1104 int GetElementPatch(int elem) const { return el_to_patch[elem]; }
1105
1106 /** @brief Return Cartesian indices (i,j) in 2D or (i,j,k) in 3D of element
1107 @a elem, in the knot-span tensor product ordering for its patch. */
1108 void GetElementIJK(int elem, Array<int> & ijk);
1109
1110 /** @brief Return the degrees of freedom in @a dofs on patch @a patch, in
1111 Cartesian order. */
1112 void GetPatchDofs(const int patch, Array<int> &dofs);
1113
1114 /// Returns a deep copy of the patch topology mesh
1115 Mesh GetPatchTopology() const { return Mesh(*patchTopo); }
1116
1117 /** Returns a deep copy of all instantiated patches. To ensure that patches
1118 are instantiated, use Mesh::GetNURBSPatches() instead. Caller gets
1119 ownership of the returned object, and is responsible for deletion.*/
1121
1122 /// Return the array of indices of all elements in patch @a patch.
1123 const Array<int>& GetPatchElements(int patch);
1124 /// Return the array of indices of all boundary elements in patch @a patch.
1125 const Array<int>& GetPatchBdrElements(int patch);
1126
1127 /// Return true if the patch topology mesh is nonconforming.
1128 bool NonconformingPatches() const { return nonconformingPT; }
1129
1130 /// Return a pointer to the NCMesh of a nonconforming patch topology mesh.
1131 NCMesh *GetNCMesh() const { return patchTopo->ncmesh; }
1132
1133 /// Read the control points for coarse patches.
1134 virtual void ReadCoarsePatchCP(std::istream &input);
1135
1136 /** @brief Fully coarsen all structured patches, for non-nested refinement of
1137 a mesh with a nonconforming patch topology. */
1138 void FullyCoarsen();
1139
1140 /// Print control points for coarse patches.
1141 virtual void PrintCoarsePatches(std::ostream &os);
1142};
1143
1144
1145#ifdef MFEM_USE_MPI
1146/** @brief Parallel version of NURBSExtension. */
1148{
1149private:
1150 /// Partitioning of the global elements by MPI rank
1151 mfem::Array<int> partitioning;
1152
1153 /// Construct and return a table of DOFs for each global element.
1154 Table *GetGlobalElementDofTable();
1155 Table *Get1DGlobalElementDofTable();
1156 Table *Get2DGlobalElementDofTable();
1157 Table *Get3DGlobalElementDofTable();
1158
1159 /** @brief Set active global elements and boundary elements based on MPI
1160 ranks in @a partition and the array @a active_bel. */
1161 void SetActive(const int *partitioning_, const Array<bool> &active_bel);
1162
1163 /// Set up GroupTopology @a gtopo for MPI communication.
1164 void BuildGroups(const int *partitioning_, const Table &elem_dof);
1165
1166public:
1168
1170
1171 /// Copy constructor
1173
1174 /** @brief Constructor for an MPI communicator @a comm, a global
1175 NURBSExtension @a parent, a partitioning @a partitioning_ of the global
1176 elements by MPI rank, and a marker @a active_bel of active global
1177 boundary elements on this rank. The partitioning is deep-copied and will
1178 not be deleted by this object. */
1179 ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent,
1180 const int *partitioning_,
1181 const Array<bool> &active_bel);
1182
1183 /** @brief Create a parallel version of @a parent with partitioning as in
1184 @a par_parent; the @a parent object is destroyed.
1185 The @a parent can be either a local NURBSExtension or a global one. */
1187 const ParNURBSExtension *par_parent);
1188};
1189#endif
1190
1191
1192/** @brief Mapping for mesh vertices and NURBS space DOFs on a patch.
1193
1194 This class has two modes, for vertices or DOFs, depending on whether
1195 @a SetPatchVertexMap or @a SetPatchDofMap is called.
1196 */
1198{
1199private:
1200 /// This object must be associated with exactly one NURBSExtension.
1201 const NURBSExtension *Ext;
1202
1203 /// Vertex mode: Number of elements in each direction, minus 1.
1204 /// DOF mode: Number of control points in each direction, minus 2.
1205 int I, J, K;
1206
1207 /// Vertex/DOF offset for this patch, among all patches.
1208 int pOffset;
1209 /// Orientation for this boundary patch (0 in the patch case).
1210 int opatch;
1211
1212 /// Patch topology entities for this patch or boundary patch.
1213 Array<int> verts, edges, faces, oedge, oface;
1214 Array<bool> edgeMaster, faceMaster;
1215 Array<int> edgeMasterOffset, faceMasterOffset;
1216 Array<int> masterDofs;
1217
1218 inline static int F(const int n, const int N)
1219 { return (n < 0) ? 0 : ((n >= N) ? 2 : 1); }
1220
1221 inline static int Or1D(const int n, const int N, const int Or)
1222 { return (Or > 0) ? n : (N - 1 - n); }
1223
1224 inline static int Or2D(const int n1, const int n2,
1225 const int N1, const int N2, const int Or);
1226
1227 inline int EC(const int e, const int n, const int N, const int s=1) const
1228 {
1229 return !edgeMaster[e] ? edges[e] + Or1D(n, N, s*oedge[e]) :
1230 GetMasterEdgeDof(e, Or1D(n, N, s*oedge[e]));
1231 }
1232
1233 inline int FC(const int f, const int m, const int n,
1234 const int M, const int N) const
1235 {
1236 return !faceMaster[f] ? faces[f] + Or2D(m, n, M, N, oface[f]) :
1237 GetMasterFaceDof(f, Or2D(m, n, M, N, oface[f]));
1238 }
1239
1240 inline int FCP(const int f, const int m, const int n,
1241 const int M, const int N) const
1242 {
1243 return (faceMaster.Size() == 0 || !faceMaster[f]) ?
1244 pOffset + Or2D(m, n, M, N, opatch) :
1245 GetMasterFaceDof(f, Or2D(m, n, M, N, opatch));
1246 }
1247
1248 // The following 2 functions also set verts, edges, faces, orientations etc.
1249
1250 /// Get the KnotVectors for patch @a p in @a kv.
1251 void GetPatchKnotVectors (int p, const KnotVector *kv[]);
1252 /** @brief Get the KnotVectors for boundary patch @a bp in @a kv, with
1253 orientations output in @a okv. */
1254 void GetBdrPatchKnotVectors(int bp, const KnotVector *kv[], int *okv);
1255
1256 void SetMasterEdges(bool dof, const KnotVector *kv[] = nullptr);
1257 void SetMasterFaces(bool dof);
1258 int GetMasterEdgeDof(const int e, const int i) const;
1259 int GetMasterFaceDof(const int f, const int i) const;
1260
1261public:
1262 /// Constructor for an object associated with NURBSExtension @a ext.
1263 NURBSPatchMap(const NURBSExtension *ext) { Ext = ext; }
1264
1265 /// Vertex mode: Return the number of elements in the first direction.
1266 /// DOF mode: Return the number of control points - 1 in the first direction.
1267 inline int nx() const { return I + 1; }
1268
1269 /// Vertex mode: Return the number of elements in the second direction (2D or 3D).
1270 /// DOF mode: Return the number of control points - 1 in the second direction (2D or 3D).
1271 inline int ny() const { return J + 1; }
1272
1273 /// Vertex mode: Return the number of elements in the third direction (3D).
1274 /// DOF mode: Return the number of control points - 1 in the third direction (3D).
1275 inline int nz() const { return K + 1; }
1276
1277 /// Set mesh vertex map for patch @a p with KnotVectors @a kv.
1278 void SetPatchVertexMap(int p, const KnotVector *kv[]);
1279 /// Set NURBS space DOF map for patch @a p with KnotVectors @a kv.
1280 void SetPatchDofMap (int p, const KnotVector *kv[]);
1281
1282 /// Set mesh vertex map for boundary patch @a bp with KnotVectors @a kv.
1283 void SetBdrPatchVertexMap(int bp, const KnotVector *kv[], int *okv);
1284 /// Set NURBS space DOF map for boundary patch @a bp with KnotVectors @a kv.
1285 void SetBdrPatchDofMap (int bp, const KnotVector *kv[], int *okv);
1286
1287 /// For 1D, return the vertex or DOF at index @a i.
1288 inline int operator()(const int i) const;
1289 inline int operator[](const int i) const { return (*this)(i); }
1290
1291 /// For 2D, return the vertex or DOF at indices @a i, @a j.
1292 inline int operator()(const int i, const int j) const;
1293
1294 /// For 3D, return the vertex or DOF at indices @a i, @a j, @a k.
1295 inline int operator()(const int i, const int j, const int k) const;
1296};
1297
1298
1299// Inline function implementations
1300
1301inline real_t &NURBSPatch::slice(int i, int j)
1302{
1303#ifdef MFEM_DEBUG
1304 if (data == 0 || i < 0 || i >= nd || j < 0 || j > ls)
1305 {
1306 mfem_error("NURBSPatch::slice()");
1307 }
1308#endif
1309 return data[j%sd + sd*(i + (j/sd)*nd)];
1310}
1311
1312inline const real_t &NURBSPatch::slice(int i, int j) const
1313{
1314#ifdef MFEM_DEBUG
1315 if (data == 0 || i < 0 || i >= nd || j < 0 || j > ls)
1316 {
1317 mfem_error("NURBSPatch::slice()");
1318 }
1319#endif
1320 return data[j%sd + sd*(i + (j/sd)*nd)];
1321}
1322
1323
1324inline real_t &NURBSPatch::operator()(int i, int l)
1325{
1326#ifdef MFEM_DEBUG
1327 if (data == 0 || i < 0 || i >= ni || nj > 0 || nk > 0 ||
1328 l < 0 || l >= Dim)
1329 {
1330 mfem_error("NURBSPatch::operator() 1D");
1331 }
1332#endif
1333
1334 return data[i*Dim+l];
1335}
1336
1337inline const real_t &NURBSPatch::operator()(int i, int l) const
1338{
1339#ifdef MFEM_DEBUG
1340 if (data == 0 || i < 0 || i >= ni || nj > 0 || nk > 0 ||
1341 l < 0 || l >= Dim)
1342 {
1343 mfem_error("NURBSPatch::operator() const 1D");
1344 }
1345#endif
1346
1347 return data[i*Dim+l];
1348}
1349
1350inline real_t &NURBSPatch::operator()(int i, int j, int l)
1351{
1352#ifdef MFEM_DEBUG
1353 if (data == 0 || i < 0 || i >= ni || j < 0 || j >= nj || nk > 0 ||
1354 l < 0 || l >= Dim)
1355 {
1356 mfem_error("NURBSPatch::operator() 2D");
1357 }
1358#endif
1359
1360 return data[(i+j*ni)*Dim+l];
1361}
1362
1363inline const real_t &NURBSPatch::operator()(int i, int j, int l) const
1364{
1365#ifdef MFEM_DEBUG
1366 if (data == 0 || i < 0 || i >= ni || j < 0 || j >= nj || nk > 0 ||
1367 l < 0 || l >= Dim)
1368 {
1369 mfem_error("NURBSPatch::operator() const 2D");
1370 }
1371#endif
1372
1373 return data[(i+j*ni)*Dim+l];
1374}
1375
1376inline real_t &NURBSPatch::operator()(int i, int j, int k, int l)
1377{
1378#ifdef MFEM_DEBUG
1379 if (data == 0 || i < 0 || i >= ni || j < 0 || j >= nj || k < 0 ||
1380 k >= nk || l < 0 || l >= Dim)
1381 {
1382 mfem_error("NURBSPatch::operator() 3D");
1383 }
1384#endif
1385
1386 return data[(i+(j+k*nj)*ni)*Dim+l];
1387}
1388
1389inline const real_t &NURBSPatch::operator()(int i, int j, int k, int l) const
1390{
1391#ifdef MFEM_DEBUG
1392 if (data == 0 || i < 0 || i >= ni || j < 0 || j >= nj || k < 0 ||
1393 k >= nk || l < 0 || l >= Dim)
1394 {
1395 mfem_error("NURBSPatch::operator() const 3D");
1396 }
1397#endif
1398
1399 return data[(i+(j+k*nj)*ni)*Dim+l];
1400}
1401
1402inline int NURBSExtension::KnotInd(int edge) const
1403{
1404 return UnsignIndex(edge_to_ukv[edge]);
1405}
1406
1407inline int NURBSExtension::KnotSign(int edge) const
1408{
1409 return edge_to_ukv[edge] >= 0 ? 1 : -1;
1410}
1411
1413{
1414 return knotVectors[KnotInd(edge)];
1415}
1416
1417inline const KnotVector *NURBSExtension::KnotVec(int edge) const
1418{
1419 return knotVectors[KnotInd(edge)];
1420}
1421
1422inline const KnotVector *NURBSExtension::KnotVec(int edge, int oedge, int *okv)
1423const
1424{
1425 int kv = edge_to_ukv[edge];
1426 if (kv >= 0)
1427 {
1428 *okv = oedge;
1429 return knotVectors[kv];
1430 }
1431 else
1432 {
1433 *okv = -oedge;
1434 return knotVectors[FlipIndexSign(kv)];
1435 }
1436}
1437
1438inline int NURBSExtension::KnotVecNE(int edge) const
1439{
1440 return knotVectors[KnotInd(edge)]->GetNE();
1441}
1442
1443// static method
1444inline int NURBSPatchMap::Or2D(const int n1, const int n2,
1445 const int N1, const int N2, const int Or)
1446{
1447 switch (Or)
1448 {
1449 case 0: return n1 + n2*N1;
1450 case 1: return n2 + n1*N2;
1451 case 2: return n2 + (N1 - 1 - n1)*N2;
1452 case 3: return (N1 - 1 - n1) + n2*N1;
1453 case 4: return (N1 - 1 - n1) + (N2 - 1 - n2)*N1;
1454 case 5: return (N2 - 1 - n2) + (N1 - 1 - n1)*N2;
1455 case 6: return (N2 - 1 - n2) + n1*N2;
1456 case 7: return n1 + (N2 - 1 - n2)*N1;
1457 }
1458#ifdef MFEM_DEBUG
1459 mfem_error("NURBSPatchMap::Or2D");
1460#endif
1461 return -1;
1462}
1463
1464inline int NURBSPatchMap::operator()(const int i) const
1465{
1466 const int i1 = i - 1;
1467 switch (F(i1, I))
1468 {
1469 case 0: return verts[0];
1470 case 1: return edgeMaster.Size() > 0 && edgeMaster[0] ?
1471 GetMasterEdgeDof(0, Or1D(i1, I, opatch)) :
1472 pOffset + Or1D(i1, I, opatch);
1473 case 2: return verts[1];
1474 }
1475#ifdef MFEM_DEBUG
1476 mfem_error("NURBSPatchMap::operator() const 1D");
1477#endif
1478 return -1;
1479}
1480
1481inline int NURBSPatchMap::operator()(const int i, const int j) const
1482{
1483 const int i1 = i - 1, j1 = j - 1;
1484 switch (3*F(j1, J) + F(i1, I))
1485 {
1486 case 0: return verts[0];
1487 case 1: return EC(0, i1, I);
1488 case 2: return verts[1];
1489 case 3: return EC(3, j1, J, -1);
1490 case 4: return FCP(0, i1, j1, I, J);
1491 case 5: return EC(1, j1, J);
1492 case 6: return verts[3];
1493 case 7: return EC(2, i1, I, -1);
1494 case 8: return verts[2];
1495 }
1496#ifdef MFEM_DEBUG
1497 mfem_error("NURBSPatchMap::operator() const 2D");
1498#endif
1499 return -1;
1500}
1501
1502inline int NURBSPatchMap::operator()(const int i, const int j, const int k)
1503const
1504{
1505 const int i1 = i - 1, j1 = j - 1, k1 = k - 1;
1506 switch (3*(3*F(k1, K) + F(j1, J)) + F(i1, I))
1507 {
1508 case 0: return verts[0];
1509 case 1: return EC(0, i1, I);
1510 case 2: return verts[1];
1511 case 3: return EC(3, j1, J);
1512 case 4: return FC(0, i1, J - 1 - j1, I, J);
1513 case 5: return EC(1, j1, J);
1514 case 6: return verts[3];
1515 case 7: return EC(2, i1, I);
1516 case 8: return verts[2];
1517 case 9: return EC(8, k1, K);
1518 case 10: return FC(1, i1, k1, I, K);
1519 case 11: return EC(9, k1, K);
1520 case 12: return FC(4, J - 1 - j1, k1, J, K);
1521 case 13: return pOffset + I*(J*k1 + j1) + i1;
1522 case 14: return FC(2, j1, k1, J, K);
1523 case 15: return EC(11, k1, K);
1524 case 16: return FC(3, I - 1 - i1, k1, I, K);
1525 case 17: return EC(10, k1, K);
1526 case 18: return verts[4];
1527 case 19: return EC(4, i1, I);
1528 case 20: return verts[5];
1529 case 21: return EC(7, j1, J);
1530 case 22: return FC(5, i1, j1, I, J);
1531 case 23: return EC(5, j1, J);
1532 case 24: return verts[7];
1533 case 25: return EC(6, i1, I);
1534 case 26: return verts[6];
1535 }
1536#ifdef MFEM_DEBUG
1537 mfem_error("NURBSPatchMap::operator() const 3D");
1538#endif
1539 return -1;
1540}
1541
1542}
1543
1544#endif
Dynamic 2D array using row-major layout.
Definition array.hpp:459
int Size() const
Return the logical size of the array.
Definition array.hpp:192
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
Abstract class for all finite elements.
Definition fe_base.hpp:294
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:53
A vector of knots in one dimension, with B-spline basis functions of a prescribed order.
Definition nurbs.hpp:38
~KnotVector()
Destroys KnotVector.
Definition nurbs.hpp:301
std::shared_ptr< SpacingFunction > spacing
Function to define the distribution of knots for any number of knot spans.
Definition nurbs.hpp:313
MFEM_DEPRECATED void FindMaxima(Array< int > &ks, Vector &xi, Vector &u) const
Gives the locations of the maxima of the KnotVector in reference space. The function gives the knot s...
Definition nurbs.cpp:914
MFEM_DEPRECATED int findKnotSpan(real_t u) const
Return the index of the knot span containing parameter u.
Definition nurbs.cpp:1190
void GetInterpolant(Array< Vector * > &x, const Vector &u, bool reuse_inverse=false) const
Global curve interpolation through the points x (overwritten) at the knot location u....
Definition nurbs.cpp:1092
void PrintFunctions(std::ostream &os, int samples=11) const
Prints the non-zero shape functions and their first and second derivatives associated with the KnotVe...
Definition nurbs.cpp:638
real_t GetRefPoint(real_t u, int ni) const
Return the reference coordinate in [0,1] for parameter u in the element beginning at knot ni.
Definition nurbs.hpp:143
void PrintFunction(std::ostream &os, const Vector &a, int samples=11) const
Definition nurbs.cpp:669
int NumOfElements
Number of elements, defined by distinct knots.
Definition nurbs.hpp:52
void CalcDnShape(Vector &gradn, int n, int i, real_t xi) const
Calculate n-th derivatives (order n) of the nonvanishing shape function values in grad for the elemen...
Definition nurbs.cpp:813
int Order
Order of the B-spline basis functions.
Definition nurbs.hpp:46
bool inSpan(real_t u, int ni) const
Return whether knot location u is in a given span ni.
Definition nurbs.hpp:132
KnotVector & operator=(const KnotVector &kv)
Definition nurbs.cpp:163
bool isElement(int i) const
Return whether the knot index Order plus i is the beginning of an element.
Definition nurbs.hpp:124
Array< int > fact_ipiv
Banded matrix factorization.
Definition nurbs.hpp:63
real_t GetBotella(int i) const
Definition nurbs.cpp:230
real_t GetDemko(int i) const
Definition nurbs.cpp:281
MFEM_DEPRECATED void FindInterpolant(Array< Vector * > &x, bool reuse_inverse)
Global curve interpolation through the points x (overwritten). x is an array with the length of the s...
Definition nurbs.cpp:975
void CalcShape(Vector &shape, int i, real_t xi) const
Calculate the nonvanishing shape function values in shape for the element corresponding to knot index...
Definition nurbs.cpp:728
void UniformRefinement(Vector &new_knots, int rf) const
Uniformly refine by factor rf, by inserting knots in each span.
Definition nurbs.cpp:432
const real_t & operator[](int i) const
Const access function to knot i.
Definition nurbs.hpp:307
real_t GetKnotLocation(real_t xi, int ni) const
Return the knot location for element reference coordinate xi in [0,1], for the element beginning at k...
Definition nurbs.hpp:148
MFEM_DEPRECATED real_t getKnotLocation(real_t xi, int ni) const
Return the parameter for element reference coordinate xi in [0,1], for the element beginning at knot ...
Definition nurbs.hpp:153
Vector knot
Stores the values of all knots.
Definition nurbs.hpp:43
KnotVector()=default
Collocation matrix inverse.
int GetNKS() const
Return the number of control points minus the order. This is not the number of knot spans,...
Definition nurbs.hpp:129
KnotVector * FullyCoarsen()
Coarsen to a single element.
Definition nurbs.cpp:1254
void GetElements()
Count the number of elements.
Definition nurbs.cpp:605
void ComputeDemko() const
Compute all the Demko points.
Definition nurbs.cpp:299
real_t GetGreville(int i) const
Definition nurbs.cpp:213
KnotVector * DegreeElevate(int t) const
Return a new KnotVector with elevated degree by repeating the endpoints of the KnotVector.
Definition nurbs.cpp:403
DenseMatrix fact_AB
Definition nurbs.hpp:62
static const int MaxOrder
Definition nurbs.hpp:40
void CalcD2Shape(Vector &grad2, int i, real_t xi) const
Calculate second-order shape function derivatives, using CalcDnShape.
Definition nurbs.hpp:214
int GetOrder() const
Return the order.
Definition nurbs.hpp:114
int GetNCP() const
Return the number of control points.
Definition nurbs.hpp:111
int NumOfControlPoints
Number of control points.
Definition nurbs.hpp:49
void CalcDShape(Vector &grad, int i, real_t xi) const
Calculate derivatives of the nonvanishing shape function values in grad for the element corresponding...
Definition nurbs.cpp:755
int Size() const
Return the number of knots, including multiplicities.
Definition nurbs.hpp:117
bool coarse
Flag to indicate whether the KnotVector has been coarsened, which means it is ready for non-nested re...
Definition nurbs.hpp:317
void Flip()
Reverse the knots.
Definition nurbs.cpp:617
DenseMatrix A_coll_inv
Row pivot indices.
Definition nurbs.hpp:65
void Difference(const KnotVector &kv, Vector &diff) const
Definition nurbs.cpp:1219
int GetSpan(real_t u) const
Return the index of the knot span containing parameter u.
Definition nurbs.cpp:175
int GetCoarseningFactor() const
Definition nurbs.cpp:453
Vector GetFineKnots(const int cf) const
Definition nurbs.cpp:472
real_t & operator[](int i)
Access function to knot i.
Definition nurbs.hpp:304
int GetNE() const
Return the number of elements, defined by distinct knots.
Definition nurbs.hpp:108
KnotVector(const KnotVector &kv)
Copy constructor.
Definition nurbs.hpp:103
void Refinement(Vector &new_knots, int rf) const
Refine with refinement factor rf.
Definition nurbs.cpp:540
void Print(std::ostream &os) const
Print the order, number of control points, and knots.
Definition nurbs.cpp:632
Mesh data type.
Definition mesh.hpp:67
int GetAttribute(int i) const
Return the attribute of element i.
Definition mesh.hpp:1497
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
Definition mesh.hpp:1503
void SetAttribute(int i, int attr)
Set the attribute of element i.
Definition mesh.cpp:8433
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1390
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1314
int GetNBE() const
Returns number of boundary elements.
Definition mesh.hpp:1393
NCMesh * ncmesh
Optional nonconforming mesh extension.
Definition mesh.hpp:318
void SetBdrAttribute(int i, int attr)
Set the attribute of boundary element i.
Definition mesh.hpp:1506
A class for non-conforming AMR. The class is not used directly by the user, rather it is an extension...
Definition ncmesh.hpp:190
NURBSExtension generally contains multiple NURBSPatch objects spanning an entire Mesh....
Definition nurbs.hpp:575
void Get2DPatchNets(const Vector &coords, int vdim)
Definition nurbs.cpp:5498
void SetSolutionVector(Vector &coords, int vdim)
Return in coords the coordinates from each patch. Side effects: delete the patches and update the wei...
Definition nurbs.cpp:5555
int GetNP() const
Return the number of patches.
Definition nurbs.hpp:936
int GetNBE() const
Return the number of active boundary elements.
Definition nurbs.hpp:962
Mode
Flag for indicating what type of NURBS fespace this extension is used for.
Definition nurbs.hpp:585
@ H_CURL
‍Extension for a divergence conforming vector-valued space
@ H_DIV
‍Extension for a standard scalar-valued space
std::vector< Array< int > > kvf_coarse
Definition nurbs.hpp:681
void InitDofMap()
Set DOF map sizes to 0.
Definition nurbs.cpp:3346
Mesh * patchTopo
Patch topology mesh.
Definition nurbs.hpp:614
void GetPatches(Array< NURBSPatch * > &patches)
Definition nurbs.cpp:5670
Array< int > ref_factors
Knotvector refinement factors.
Definition nurbs.hpp:683
void GetCoarseningFactors(Array< int > &f) const
Definition nurbs.cpp:5291
void Generate3DElementDofTable()
Definition nurbs.cpp:4639
void SetPatchAttribute(int i, int attr)
Set the attribute for patch i, which is set to all elements in the patch.
Definition nurbs.hpp:1012
Vector & GetWeights()
Definition nurbs.hpp:1040
const Array< int > & GetPatchElements(int patch)
Return the array of indices of all elements in patch patch.
Definition nurbs.cpp:5710
std::vector< Array< int > > patch_to_bel
For each patch p, patch_to_bel[p] lists all boundary elements in the patch.
Definition nurbs.hpp:665
void UniformRefinement(int rf=2)
Refine with optional refinement factor rf. Uniform means refinement is done everywhere by the same fa...
Definition nurbs.cpp:5223
Array< int > p_meshOffsets
Definition nurbs.hpp:642
int GetGNE() const
Return the global number of elements.
Definition nurbs.hpp:956
virtual int VertexPairToEdge(const std::pair< int, int > &vertices) const
Given a pair of vertices, return the corresponding edge.
Definition nurbs.cpp:5784
Array< int > mOrders
Orders of all KnotVectors.
Definition nurbs.hpp:596
void Print(std::ostream &os, const std::string &comments="") const
Writes all patch data to the stream os.
Definition nurbs.cpp:3196
virtual void ReadCoarsePatchCP(std::istream &input)
Read the control points for coarse patches.
Definition nurbs.cpp:5768
int num_structured_patches
Whether patchTopo is a nonconforming mesh.
Definition nurbs.hpp:677
Table * el_dof
Table of DOFs for each element (el_dof) or boundary element (bel_dof).
Definition nurbs.hpp:651
void SetPatchBdrAttribute(int i, int attr)
Set the attribute for patch boundary element i to attr, which is set to all boundary elements in the ...
Definition nurbs.hpp:1020
void PrintSolution(const GridFunction &sol, std::ostream &os) const
Write a GridFunction sol patch-by-patch to stream os.
Definition nurbs.cpp:5130
int GetPatchSpaceDimension() const
Return the physical dimension of the NURBS geometry.
Definition nurbs.cpp:5680
friend class ParNURBSExtension
Definition nurbs.hpp:577
virtual void GenerateOffsets()
Set the mesh and space offsets, and also count the global NumOfVertices and the global NumOfDofs.
Definition nurbs.cpp:4127
int DofMap(int dof) const
Return the dof index whilst accounting for periodic boundaries.
Definition nurbs.hpp:973
Array< bool > activeBdrElem
Definition nurbs.hpp:610
int GetNBP() const
Return the number of boundary patches.
Definition nurbs.hpp:939
bool own_topo
Whether this object owns patchTopo.
Definition nurbs.hpp:617
void SetOrderFromOrders()
Set overall order mOrder based on KnotVector orders.
Definition nurbs.cpp:4103
Array3D< double > patchCP
Number of structured patches.
Definition nurbs.hpp:679
void GetElementIJK(int elem, Array< int > &ijk)
Return Cartesian indices (i,j) in 2D or (i,j,k) in 3D of element elem, in the knot-span tensor produc...
Definition nurbs.cpp:5664
void MergeGridFunctions(GridFunction *gf_array[], int num_pieces, GridFunction &merged)
Set the DOFs of merged to values from active elements in num_pieces of Gridfunctions gf_array.
Definition nurbs.cpp:3677
const Vector & GetWeights() const
Access function to the vector of weights weights.
Definition nurbs.hpp:1039
void Set2DSolutionVector(Vector &coords, int vdim)
Definition nurbs.cpp:5597
void Set3DSolutionVector(Vector &coords, int vdim)
Definition nurbs.cpp:5629
void GenerateActiveVertices()
Determine activeVert, NumOfActiveVertices from the activeElem array.
Definition nurbs.cpp:3557
Array< int > el_to_patch
Map from element indices to patch indices.
Definition nurbs.hpp:654
void Coarsen(int cf=2, real_t tol=1.0e-12)
Coarsen with optional coarsening factor cf.
Definition nurbs.cpp:5284
static constexpr int unsetFactor
Refinement factors in each dimension.
Definition nurbs.hpp:685
int GetPatchAttribute(int i) const
Get the attribute for patch i, which is set to all elements in the patch.
Definition nurbs.hpp:1016
void SetCoordsFromPatches(Vector &Nodes, int vdim)
Set FE coordinates in Nodes, using data from patches, with physical vector dimension vdim,...
Definition nurbs.cpp:5044
Array< int > activeDof
Definition nurbs.hpp:611
const Array< int > & GetSlave() const
Definition nurbs.hpp:891
Array< int > slave
Definition nurbs.hpp:636
void Get2DBdrElementTopo(Array< Element * > &boundary) const
Definition nurbs.cpp:4437
void GetElementTopo(Array< Element * > &elements) const
Generate the active mesh elements and return them in elements.
Definition nurbs.cpp:4267
const Array< int > & GetPatchBdrElements(int patch)
Return the array of indices of all boundary elements in patch patch.
Definition nurbs.cpp:5717
void Get1DElementTopo(Array< Element * > &elements) const
Generate the active mesh elements and return them in elements.
Definition nurbs.cpp:4285
bool CheckPatches()
Returns false if any patch has an inconsistent edge_to_ukv mapping.
Definition nurbs.cpp:3702
int KnotInd(int edge) const
Return the unsigned index of the KnotVector for edge edge.
Definition nurbs.hpp:1402
int GetNKV() const
Return the number of KnotVectors.
Definition nurbs.hpp:949
void GetVertexLocalToGlobal(Array< int > &lvert_vert)
Get the local to global vertex index map lvert_vert.
Definition nurbs.cpp:4961
void CountBdrElements()
Count the global NumOfBdrElements.
Definition nurbs.cpp:4247
void LoadBE(int i, const FiniteElement *BE) const
Load boundary element i into BE.
Definition nurbs.cpp:5002
void Get2DElementTopo(Array< Element * > &elements) const
Definition nurbs.cpp:4315
Table * GetElementDofTable()
Definition nurbs.hpp:999
void GenerateElementDofTable()
Based on activeElem, count NumOfActiveDofs and generate el_dof, el_to_patch, el_to_IJK,...
Definition nurbs.cpp:4506
void Generate3DBdrElementDofTable()
Definition nurbs.cpp:4880
int GetGNV() const
Return the global number of vertices.
Definition nurbs.hpp:952
KnotVector * KnotVec(int edge)
DOF to owning patch map in SetSolutionVector()
Definition nurbs.hpp:1412
bool HavePatches() const
Return true if at least 1 patch is defined, false otherwise.
Definition nurbs.hpp:995
NCMesh * GetNCMesh() const
Return a pointer to the NCMesh of a nonconforming patch topology mesh.
Definition nurbs.hpp:1131
std::vector< Array< int > > patch_to_el
For each patch p, patch_to_el[p] lists all elements in the patch.
Definition nurbs.hpp:663
Array< int > v_meshOffsets
Global mesh offsets, meshOffsets == meshVertexOffsets.
Definition nurbs.hpp:639
NURBSExtension & operator=(const NURBSExtension &)=delete
Copy assignment not supported.
int NumOfActiveVertices
Local entity counts.
Definition nurbs.hpp:605
void CheckKVDirection(int p, Array< int > &kvdir)
Return the directions in kvdir of the KnotVectors in patch p based on the patch edge orientations....
Definition nurbs.cpp:3811
void GetBdrElementTopo(Array< Element * > &boundary) const
Generate the active mesh boundary elements and return them in boundary.
Definition nurbs.cpp:4396
void SetOrdersFromKnotVectors()
Set orders from KnotVector orders.
Definition nurbs.cpp:4117
Array< KnotVector * > knotVectorsCompr
Comprehensive set of all KnotVectors, one for every edge.
Definition nurbs.hpp:626
Array2D< int > el_to_IJK
Map from element indices to IJK knot span indices.
Definition nurbs.hpp:659
void Get1DPatchNets(const Vector &coords, int vdim)
Definition nurbs.cpp:5474
void GenerateBdrElementDofTable()
Call after GenerateElementDofTable to set boundary element DOF table.
Definition nurbs.cpp:4754
Array< int > & GetMaster()
Definition nurbs.hpp:890
virtual void GetMasterEdgeDofs(bool dof, int me, Array< int > &dofs) const
Get the DOFs (dof = true) or vertices (dof = false) for master edge me.
Definition nurbs.cpp:5790
Array< int > f_spaceOffsets
Definition nurbs.hpp:647
void MergeWeights(Mesh *mesh_array[], int num_pieces)
Set the weights in this object to values from active elements in num_pieces meshes in mesh_array.
Definition nurbs.cpp:3652
int NumOfVertices
Global entity counts.
Definition nurbs.hpp:602
void Generate2DBdrElementDofTable()
Definition nurbs.cpp:4817
void GetBdrPatchKnotVectors(int bp, Array< KnotVector * > &kv)
Return KnotVectors in kv in each dimension for boundary patch bp.
Definition nurbs.cpp:4062
Array< int > master
Definition nurbs.hpp:635
bool NonconformingPatches() const
Return true if the patch topology mesh is nonconforming.
Definition nurbs.hpp:1128
void ConnectBoundaries2D(int bnd0, int bnd1)
Definition nurbs.cpp:3440
virtual void RefineWithKVFactors(int rf, const std::string &kvf_filename, bool coarsened)
Definition nurbs.cpp:5801
Array2D< int > bel_to_IJK
Definition nurbs.hpp:660
Array< NURBSPatch * > patches
Array of all patches in the mesh.
Definition nurbs.hpp:668
virtual bool IsMasterEdge(int edge) const
Return true if edge is a master NC-patch edge.
Definition nurbs.hpp:823
void GetPatchOffsets(int &meshCounter, int &spaceCounter)
Helper function for GenerateOffsets().
Definition nurbs.cpp:4187
int GetNTotalDof() const
Return the total number of DOFs.
Definition nurbs.hpp:965
void SetPatchToElements()
Set patch_to_el.
Definition nurbs.cpp:5688
int GetElementPatch(int elem) const
Returns the index of the patch containing element elem.
Definition nurbs.hpp:1104
Array< int > & GetSlave()
Definition nurbs.hpp:892
void GetPatchNets(const Vector &coords, int vdim)
Set the B-NET on each patch using values from coords.
Definition nurbs.cpp:5458
void ConnectBoundaries3D(int bnd0, int bnd1)
Definition nurbs.cpp:3486
const Array< int > & GetMaster() const
Definition nurbs.hpp:889
void CountElements()
Count the global NumOfElements.
Definition nurbs.cpp:4227
bool ConsistentKVSets()
Check if the comprehensive array of KnotVectors agrees with the unique set of KnotVectors,...
Definition nurbs.cpp:3969
void Load(std::istream &input, bool spacing)
Load data from file (used by constructor).
Definition nurbs.cpp:2748
void KnotRemove(Array< Vector * > &kv, real_t tol=1.0e-12)
Definition nurbs.cpp:5412
void LoadFE(int i, const FiniteElement *FE) const
Load element i into FE.
Definition nurbs.cpp:4981
void GetElementLocalToGlobal(Array< int > &lelem_elem)
Get the local to global element index map lelem_elem.
Definition nurbs.cpp:4971
virtual void PrintCoarsePatches(std::ostream &os)
Print control points for coarse patches.
Definition nurbs.cpp:5773
void GenerateActiveBdrElems()
Determine activeBdrElem, NumOfActiveBdrElems.
Definition nurbs.cpp:3630
Array< bool > activeElem
Definition nurbs.hpp:609
Array< int > d_to_d
Periodic BC info:
Definition nurbs.hpp:634
int NumOfKnotVectors
Number of unique (not comprehensive) KnotVectors.
Definition nurbs.hpp:599
Vector weights
Weights for each control point or DOF.
Definition nurbs.hpp:629
void CreateComprehensiveKV()
Create the comprehensive set of KnotVectors, one per patch and parametric direction,...
Definition nurbs.cpp:3887
void GetPatchDofs(const int patch, Array< int > &dofs)
Return the degrees of freedom in dofs on patch patch, in Cartesian order.
Definition nurbs.cpp:4705
void GetPatchDirectionEdges(int p, Array< int > &edges)
Definition nurbs.cpp:3789
Array< int > bel_to_patch
Map from boundary element indices to patch indices.
Definition nurbs.hpp:656
void FullyCoarsen()
Fully coarsen all structured patches, for non-nested refinement of a mesh with a nonconforming patch ...
Definition nurbs.cpp:5251
void GetPatchKnotVectors(int p, Array< KnotVector * > &kv)
Return KnotVectors in kv in each dimension for patch p.
Definition nurbs.cpp:4017
Array< int > edge_to_ukv
Map from patchTopo edge indices to unique KnotVector indices.
Definition nurbs.hpp:620
Table * GetBdrElementDofTable()
Definition nurbs.hpp:1003
void PrintFunctions(const char *basename, int samples=11) const
Call KnotVector::PrintFunctions for all KnotVectors, using a separate, newly created ofstream with fi...
Definition nurbs.cpp:3333
std::vector< Array< int > > kvf
Control points for coarse structured patches.
Definition nurbs.hpp:681
void Generate2DElementDofTable()
Definition nurbs.cpp:4585
void Set1DSolutionVector(Vector &coords, int vdim)
Definition nurbs.cpp:5571
int KnotVecNE(int edge) const
Return the number of knotvector elements for edge edge.
Definition nurbs.hpp:1438
void PrintCharacteristics(std::ostream &os) const
Print various mesh characteristics to the stream os.
Definition nurbs.cpp:3303
int GetNDof() const
Return the number of active DOFs.
Definition nurbs.hpp:967
virtual void GetMasterFaceDofs(bool dof, int mf, Array2D< int > &dofs) const
Get the DOFs (dof = true) or vertices (dof = false) for master face mf.
Definition nurbs.cpp:5795
void KnotInsert(Array< KnotVector * > &kv)
Insert knots from kv into all KnotVectors in all patches. The size of kv should be the same as knotVe...
Definition nurbs.cpp:5328
virtual bool IsMasterFace(int face) const
Return true if face is a master NC-patch face.
Definition nurbs.hpp:826
int GetOrder() const
If all KnotVector orders are identical, return that number. Otherwise, return NURBSFECollection::Vari...
Definition nurbs.hpp:946
NURBSExtension * GetCurlExtension(int component)
Definition nurbs.cpp:5199
Array< int > e_meshOffsets
Definition nurbs.hpp:640
const Array< int > & GetOrders() const
Read-only access to the orders of all KnotVectors.
Definition nurbs.hpp:942
int GetActiveDof(int glob) const
Return the local DOF number for a given global DOF number glob.
Definition nurbs.hpp:970
int GetGNBE() const
Return the global number of boundary elements.
Definition nurbs.hpp:960
Array< int > activeVert
Definition nurbs.hpp:608
int KnotSign(int edge) const
Return the sign (orientation) of the KnotVector for edge edge.
Definition nurbs.hpp:1407
Array< int > dof2patch
Unset refinement factor value.
Definition nurbs.hpp:687
void ConnectBoundaries1D(int bnd0, int bnd1)
Definition nurbs.cpp:3426
int GetNV() const
Return the local number of active vertices.
Definition nurbs.hpp:954
void ConvertToPatches(const Vector &Nodes)
Define patches in IKJ (B-net) format, using FE coordinates in Nodes.
Definition nurbs.cpp:5025
void Generate1DBdrElementDofTable()
Generate the table of global DOFs for active boundary elements, and define bel_to_patch,...
Definition nurbs.cpp:4787
void Get3DPatchNets(const Vector &coords, int vdim)
Definition nurbs.cpp:5525
int Dimension() const
Return the dimension of the reference space (not physical space).
Definition nurbs.hpp:926
Array< int > f_meshOffsets
Definition nurbs.hpp:641
NURBSExtension * GetDivExtension(int component)
Definition nurbs.cpp:5184
void UpdateUniqueKV()
Update the unique set of KnotVectors from the comprehensive set of KnotVectors.
Definition nurbs.cpp:3912
void Get3DBdrElementTopo(Array< Element * > &boundary) const
Definition nurbs.cpp:4468
int mOrder
Order of KnotVectors, see GetOrder() for description.
Definition nurbs.hpp:593
Mesh GetPatchTopology() const
Returns a deep copy of the patch topology mesh.
Definition nurbs.hpp:1115
void SetKnotsFromPatches()
Set KnotVectors from patches and construct mesh and space data.
Definition nurbs.cpp:5052
Array< KnotVector * > knotVectors
Set of unique KnotVectors.
Definition nurbs.hpp:623
Array< int > p_spaceOffsets
Definition nurbs.hpp:648
void Generate1DElementDofTable()
Generate elem_to_global-dof table for the active elements, and define el_to_patch,...
Definition nurbs.cpp:4542
void SetPatchToBdrElements()
Set patch_to_bel.
Definition nurbs.cpp:5699
Array< int > v_spaceOffsets
Global space offsets, spaceOffsets == dofOffsets.
Definition nurbs.hpp:645
int GetNE() const
Return the number of active elements.
Definition nurbs.hpp:958
int GetPatchBdrAttribute(int i) const
Get the attribute for boundary patch element i, which is set to all boundary elements in the patch.
Definition nurbs.hpp:1025
void DegreeElevate(int rel_degree, int degree=16)
Call DegreeElevate for all KnotVectors of all patches. For each KnotVector, the new degree is max(old...
Definition nurbs.cpp:5168
const KnotVector * GetKnotVector(int i) const
KnotVector read-only access function.
Definition nurbs.hpp:985
void LoadSolution(std::istream &input, GridFunction &sol) const
Read a GridFunction sol from stream input, written patch-by-patch, e.g. with PrintSolution().
Definition nurbs.cpp:5093
void ConnectBoundaries()
Set DOF maps for periodic BC.
Definition nurbs.cpp:3360
MFEM_DEPRECATED void CheckBdrPatches()
Throw an error if any boundary patch has invalid KnotVector orientation.
Definition nurbs.cpp:3761
const NURBSPatch * GetPatch(int patch) const
Return NURBSPatch object; returned object should NOT be deleted.
Definition nurbs.hpp:843
NURBSExtension()
To be used by ParNURBSExtension constructor(s)
Definition nurbs.hpp:846
void Get1DBdrElementTopo(Array< Element * > &boundary) const
Generate the active mesh boundary elements and return them in boundary.
Definition nurbs.cpp:4414
virtual ~NURBSExtension()
Destroy a NURBSExtension.
Definition nurbs.cpp:3170
Array< int > e_spaceOffsets
Definition nurbs.hpp:646
void Get3DElementTopo(Array< Element * > &elements) const
Definition nurbs.cpp:4351
Mapping for mesh vertices and NURBS space DOFs on a patch.
Definition nurbs.hpp:1198
NURBSPatchMap(const NURBSExtension *ext)
Constructor for an object associated with NURBSExtension ext.
Definition nurbs.hpp:1263
int nx() const
Definition nurbs.hpp:1267
void SetPatchDofMap(int p, const KnotVector *kv[])
Set NURBS space DOF map for patch p with KnotVectors kv.
Definition nurbs.cpp:6322
int nz() const
Definition nurbs.hpp:1275
int operator[](const int i) const
Definition nurbs.hpp:1289
void SetBdrPatchDofMap(int bp, const KnotVector *kv[], int *okv)
Set NURBS space DOF map for boundary patch bp with KnotVectors kv.
Definition nurbs.cpp:6407
void SetBdrPatchVertexMap(int bp, const KnotVector *kv[], int *okv)
Set mesh vertex map for boundary patch bp with KnotVectors kv.
Definition nurbs.cpp:6371
int ny() const
Definition nurbs.hpp:1271
void SetPatchVertexMap(int p, const KnotVector *kv[])
Set mesh vertex map for patch p with KnotVectors kv.
Definition nurbs.cpp:6289
int operator()(const int i) const
For 1D, return the vertex or DOF at index i.
Definition nurbs.hpp:1464
A NURBS patch can be 1D, 2D, or 3D, and is defined as a tensor product of KnotVectors.
Definition nurbs.hpp:324
int ni
B-NET dimensions.
Definition nurbs.hpp:328
int MakeUniformDegree(int degree=-1)
Definition nurbs.cpp:2497
int GetNKV() const
Return the number of KnotVectors, which is the patch dimension.
Definition nurbs.hpp:499
friend NURBSPatch * Revolve3D(NURBSPatch &patch, real_t n[], real_t ang, int times)
Definition nurbs.cpp:2567
real_t & operator()(int i, int l)
1D access function. i is a B-NET index, and l is a variable index.
Definition nurbs.hpp:1324
void UpdateSpacingPartitions(const Array< KnotVector * > &pkv)
Update piecewise spacing function partitions to match refined pkv.
Definition nurbs.cpp:1632
void GetCoarseningFactors(Array< int > &f) const
Calls KnotVector::GetCoarseningFactor for each direction.
Definition nurbs.cpp:1696
void Coarsen(int cf=2, real_t tol=1.0e-12)
Coarsen with optional coarsening factor cf which divides the number of elements in each dimension....
Definition nurbs.cpp:1689
int KnotRemove(int dir, real_t knot, int ntimes=1, real_t tol=1.0e-12)
Remove knot with value knot from direction dir.
Definition nurbs.cpp:1875
void Rotate2D(real_t angle)
Rotate the NURBSPatch, 2D case.
Definition nurbs.cpp:2404
NURBSPatch & operator=(const NURBSPatch &)=delete
Copy assignment not supported.
int Dim
Physical dimension plus 1.
Definition nurbs.hpp:331
void Rotate3D(real_t normal[], real_t angle)
Rotate the NURBSPatch, 3D case.
Definition nurbs.cpp:2471
void KnotInsert(int dir, const KnotVector &knot)
Insert any new knots from knot in direction dir. If the order of knot is higher than the current orde...
Definition nurbs.cpp:1714
void FullyCoarsen(const Array2D< double > &cp, int ncp1D)
Coarsen to a single element.
Definition nurbs.cpp:2632
real_t & slice(int i, int j)
Access function for the effectively 1D flattened net, where i is a knot index, and j is an index of a...
Definition nurbs.hpp:1301
static void Get3DRotationMatrix(real_t n[], real_t angle, real_t r, DenseMatrix &T)
Compute the 3D rotation matrix T for angle angle around axis n (a 3D vector, not necessarily normaliz...
Definition nurbs.cpp:2430
void SwapDirections(int dir1, int dir2)
Swap data and KnotVectors in directions dir1 and dir2.
Definition nurbs.cpp:2350
static void Get2DRotationMatrix(real_t angle, DenseMatrix &T)
Compute the 2D rotation matrix T for angle angle.
Definition nurbs.cpp:2392
~NURBSPatch()
Deletes data and KnotVectors.
Definition nurbs.cpp:1471
void init(int dim)
Definition nurbs.cpp:1274
int SetLoopDirection(int dir)
Flattens the B-NET in direction dir, producing a 1D net. Returns the number of variables per knot in ...
Definition nurbs.cpp:1508
KnotVector * GetKV(int dir)
Definition nurbs.hpp:503
int GetNC() const
Return the number of components stored in the NURBSPatch.
Definition nurbs.hpp:496
void Print(std::ostream &os) const
Writes KnotVectors and data to the stream os.
Definition nurbs.cpp:1484
friend NURBSPatch * Interpolate(NURBSPatch &p1, NURBSPatch &p2)
Given two patches p1 and p2 of the same dimensions, create and return a new patch by merging their kn...
Definition nurbs.cpp:2520
Array< KnotVector * > kv
KnotVectors in each direction.
Definition nurbs.hpp:337
void UniformRefinement(int rf=2, int multiplicity=1)
Refine with optional refinement factor rf. Uniform means refinement is done everywhere by the same fa...
Definition nurbs.cpp:1625
void FlipDirection(int dir)
Reverse data and knots in direction dir.
Definition nurbs.cpp:2338
void swap(NURBSPatch *np)
Deletes own data, takes data from np, and deletes np.
Definition nurbs.cpp:1445
NURBSPatch(NURBSPatch *parent, int dir, int Order, int NCP)
Construct a new patch, copying the KnotVectors of parent except in direction dir, which gets a new Kn...
Definition nurbs.cpp:1430
void SetKnotVectorsCoarse(bool c)
Marks the KnotVector in each dimension as coarse.
Definition nurbs.cpp:2627
void Rotate(real_t angle, real_t normal[]=NULL)
Rotate the NURBSPatch in 2D or 3D..
Definition nurbs.cpp:2375
void DegreeElevate(int dir, int t)
Increase the order in direction dir by t >= 0.
Definition nurbs.cpp:2082
real_t * data
Data with the layout (Dim x ni x nj x nk)
Definition nurbs.hpp:334
Parallel version of NURBSExtension.
Definition nurbs.hpp:1148
GroupTopology gtopo
Definition nurbs.hpp:1167
Array< int > ldof_group
Definition nurbs.hpp:1169
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
Definition table.hpp:43
Vector data type.
Definition vector.hpp:82
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
int dim
Definition ex24.cpp:53
real_t a
Definition lissajous.cpp:41
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
void mfem_error(const char *msg)
Definition error.cpp:154
MFEM_HOST_DEVICE int FlipIndexSign(int i)
Signed indices i -> -1 - i are used as a convention to encode orientation.
Definition globals.hpp:117
MFEM_HOST_DEVICE int UnsignIndex(int i)
Definition globals.hpp:118
float real_t
Definition config.hpp:46
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
real_t p(const Vector &x, real_t t)
real_t sol(const Vector &x)