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