MFEM v4.8.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#include <set>
26
27namespace mfem
28{
29
30class GridFunction;
31
32
33/** @brief A vector of knots in one dimension, with B-spline basis functions of
34 a prescribed order.
35
36 @note Order is defined in the sense of "The NURBS book" - 2nd ed - Piegl and
37 Tiller, cf. section 2.2.
38*/
40{
41protected:
42 static const int MaxOrder;
43
44 /// Stores the values of all knots.
46
47 /// Order of the B-spline basis functions.
48 int Order;
49
50 /// Number of control points.
52
53 /// Number of elements, defined by distinct knots.
55
56public:
57 /// Create an empty KnotVector.
59
60 /** @brief Create a KnotVector by reading data from stream @a input. Two
61 integers are read, for order and number of control points. */
62 KnotVector(std::istream &input);
63
64 /** @brief Create a KnotVector with undefined knots (initialized to -1) of
65 order @a order and number of control points @a NCP. */
66 KnotVector(int order, int NCP);
67
68 /** @brief Create a KnotVector by passing in a degree, a Vector of interval
69 lengths of length n, and a list of continuity of length n + 1.
70
71 The intervals refer to spans between unique knot values (not counting
72 zero-size intervals at repeated knots), and the continuity values should
73 be >= -1 (discontinuous) and <= order-1 (maximally-smooth for the given
74 polynomial degree). Periodicity is not supported.
75 */
76 KnotVector(int order, const Vector& intervals,
77 const Array<int>& continuity );
78
79 /// Copy constructor.
80 KnotVector(const KnotVector &kv) { (*this) = kv; }
81
83
84 /// Return the number of elements, defined by distinct knots.
85 int GetNE() const { return NumOfElements; }
86
87 /// Return the number of control points.
88 int GetNCP() const { return NumOfControlPoints; }
89
90 /// Return the order.
91 int GetOrder() const { return Order; }
92
93 /// Return the number of knots, including multiplicities.
94 int Size() const { return knot.Size(); }
95
96 /// Count the number of elements.
97 void GetElements();
98
99 /** @brief Return whether the knot index Order plus @a i is the beginning of
100 an element. */
101 bool isElement(int i) const { return (knot(Order+i) != knot(Order+i+1)); }
102
103 /** @brief Return the number of control points minus the order. This is not
104 the number of knot spans, but it gives the number of knots to be checked
105 with @a isElement for non-empty knot spans (elements). */
106 int GetNKS() const { return NumOfControlPoints - Order; }
107
108 /** @brief Return the parameter for element reference coordinate @a xi
109 in [0,1], for the element beginning at knot @a ni. */
110 real_t getKnotLocation(real_t xi, int ni) const
111 { return (xi*knot(ni+1) + (1. - xi)*knot(ni)); }
112
113 /// Return the index of the knot span containing parameter @a u.
114 int findKnotSpan(real_t u) const;
115
116 // The following functions evaluate shape functions, which are B-spline basis
117 // functions.
118
119 /** @brief Calculate the nonvanishing shape function values in @a shape for
120 the element corresponding to knot index @a i and element reference
121 coordinate @a xi. */
122 void CalcShape (Vector &shape, int i, real_t xi) const;
123
124 /** @brief Calculate derivatives of the nonvanishing shape function values in
125 @a grad for the element corresponding to knot index @a i and element
126 reference coordinate @a xi. */
127 void CalcDShape (Vector &grad, int i, real_t xi) const;
128
129 /** @brief Calculate n-th derivatives (order @a n) of the nonvanishing shape
130 function values in @a grad for the element corresponding to knot index
131 @a i and element reference coordinate @a xi. */
132 void CalcDnShape(Vector &gradn, int n, int i, real_t xi) const;
133
134 /// Calculate second-order shape function derivatives, using CalcDnShape.
135 void CalcD2Shape(Vector &grad2, int i, real_t xi) const
136 { CalcDnShape(grad2, 2, i, xi); }
137
138 /** @brief Gives the locations of the maxima of the KnotVector in reference
139 space. The function gives the knot span @a ks, the coordinate in the
140 knot span @a xi, and the coordinate of the maximum in parameter space
141 @a u. */
142 void FindMaxima(Array<int> &ks, Vector &xi, Vector &u) const;
143
144 /** @brief Global curve interpolation through the points @a x (overwritten).
145 @a x is an array with the length of the spatial dimension containing
146 vectors with spatial coordinates. The control points of the interpolated
147 curve are returned in @a x in the same form. */
149
150 /** Set @a diff, comprised of knots in @a kv not contained in this KnotVector.
151 @a kv must be of the same order as this KnotVector. The current
152 implementation is not well defined, and the function may have undefined
153 behavior, as @a diff may have unset entries at the end. */
154 void Difference(const KnotVector &kv, Vector &diff) const;
155
156 /// Uniformly refine by factor @a rf, by inserting knots in each span.
157 void UniformRefinement(Vector &newknots, int rf) const;
158
159 /// Refine with refinement factor @a rf.
160 void Refinement(Vector &newknots, int rf) const;
161
162 /** Returns the coarsening factor needed for non-nested nonuniform spacing
163 functions, to result in a single element from which refinement can be
164 done. The return value is 1 if uniform or nested spacing is used. */
165 int GetCoarseningFactor() const;
166
167 /** For a given coarsening factor @a cf, find the fine knots between the
168 coarse knots. */
169 Vector GetFineKnots(const int cf) const;
170
171 /** @brief Return a new KnotVector with elevated degree by repeating the
172 endpoints of the KnotVector. */
173 /// @note The returned object should be deleted by the caller.
174 KnotVector *DegreeElevate(int t) const;
175
176 /// Reverse the knots.
177 void Flip();
178
179 /** @brief Print the order, number of control points, and knots.
180
181 The output is formatted for writing a mesh to file. This function is
182 called by NURBSPatch::Print. */
183 void Print(std::ostream &os) const;
184
185 /** @brief Prints the non-zero shape functions and their first and second
186 derivatives associated with the KnotVector per element. Use GetElements()
187 to count the elements before using this function. @a samples is the
188 number of samples of the shape functions per element.*/
189 void PrintFunctions(std::ostream &os, int samples=11) const;
190
191 /// Destroys KnotVector
193
194 /// Access function to knot @a i.
195 real_t &operator[](int i) { return knot(i); }
196
197 /// Const access function to knot @a i.
198 const real_t &operator[](int i) const { return knot(i); }
199
200 /// Function to define the distribution of knots for any number of knot spans.
201 std::shared_ptr<SpacingFunction> spacing;
202
203 /** Flag to indicate whether the KnotVector has been coarsened, which means
204 it is ready for non-nested refinement. */
205 bool coarse;
206};
207
208
209/** @brief A NURBS patch can be 1D, 2D, or 3D, and is defined as a tensor
210 product of KnotVectors. */
212{
213protected:
214
215 /// B-NET dimensions
216 int ni, nj, nk;
217
218 /// Physical dimension plus 1
219 int Dim;
220
221 /// Data with the layout (Dim x ni x nj x nk)
223
224 /// KnotVectors in each direction
226
227 // Special B-NET access functions
228 // - SetLoopDirection(int dir) flattens the multi-dimensional B-NET in the
229 // requested direction. It effectively creates a 1D net in homogeneous
230 // coordinates.
231 // - The slice(int, int) operator is the access function in that flattened
232 // structure. The first int gives the slice and the second int the element
233 // in that slice.
234 // - Both routines are used in 'KnotInsert', `KnotRemove`, 'DegreeElevate',
235 // and 'UniformRefinement'.
236 // - In older implementations, slice(int, int) was implemented as
237 // operator()(int, int).
238 int nd; // Number of control points in flattened structure
239 int ls; // Number of variables per control point in flattened structure
240 int sd; // Stride for data access
241
242 /** @brief Flattens the B-NET in direction @a dir, producing a 1D net.
243 Returns the number of variables per knot in flattened structure. */
244 int SetLoopDirection(int dir);
245
246
247 /** @brief Access function for the effectively 1D flattened net, where @a i
248 is a knot index, and @a j is an index of a variable per knot. */
249 inline real_t &slice(int i, int j);
250 inline const real_t &slice(int i, int j) const;
251
252 /// Copy constructor
253 NURBSPatch(NURBSPatch *parent, int dir, int Order, int NCP);
254
255 /// Deletes own data, takes data from @a np, and deletes np.
256 void swap(NURBSPatch *np);
257
258 /// Sets dimensions and allocates data, based on KnotVectors.
259 /// @a dim is the physical dimension plus 1.
260 void init(int dim);
261
262public:
263 /// Copy constructor
264 NURBSPatch(const NURBSPatch &orig);
265
266 /// Constructor using data read from stream @a input.
267 NURBSPatch(std::istream &input);
268
269 /// Constructor for a 2D patch. @a dim is the physical dimension plus 1.
270 NURBSPatch(const KnotVector *kv0, const KnotVector *kv1, int dim);
271
272 /// Constructor for a 3D patch.
273 NURBSPatch(const KnotVector *kv0, const KnotVector *kv1,
274 const KnotVector *kv2, int dim);
275
276 /** Create a bivariate NURBS patch with given control points. See n-variate
277 overload for additional notes. */
278 NURBSPatch(const KnotVector *kv0, const KnotVector *kv1, int dim_,
279 const real_t* control_points);
280 /** Create a trivariate NURBS patch with given control points. See n-variate
281 overload for additional notes. */
282 NURBSPatch(const KnotVector *kv0, const KnotVector *kv1,
283 const KnotVector *kv2, int dim_, const real_t* control_points);
284 /** Create an n-variate NURBS patch with given control points of dimension
285 dim_, where n is the length of the array of knot vectors and dim_
286 includes the weight. The array of control point coordinates stores each
287 point's coordinates contiguously, and points are ordered in a standard
288 ijk grid ordering. */
290 const real_t* control_points);
291
292 /// Constructor for a patch of dimension equal to the size of @a kv.
294
295 /// Copy assignment not supported.
296 NURBSPatch& operator=(const NURBSPatch&) = delete;
297
298 /// Deletes data and KnotVectors.
299 ~NURBSPatch();
300
301 /** @brief Writes KnotVectors and data to the stream @a os.
302
303 The output is formatted for writing a mesh to file. This function is
304 called by NURBSExtension::Print. */
305 void Print(std::ostream &os) const;
306
307 /// Increase the order in direction @a dir by @a t >= 0.
308 void DegreeElevate(int dir, int t);
309
310 /** @brief Insert any new knots from @a knot in direction @a dir. If the
311 order of @a knot is higher than the current order in direction
312 @a dir, then the order is elevated in that direction to match. */
313 void KnotInsert(int dir, const KnotVector &knot);
314
315 /** @brief Insert knots from @a knot in direction @a dir. If a knot already
316 exists, then it is still added, increasing its multiplicity. */
317 void KnotInsert(int dir, const Vector &knot);
318
319 /// Call KnotInsert for each direction with the corresponding @a knot entry.
320 void KnotInsert(Array<Vector *> &knot);
321 /// Insert knots from @a knot determined by @a Difference, in each direction.
323
324 /** @brief Remove knot with value @a knot from direction @a dir.
325
326 The optional input parameter @a ntimes specifies the number of times the
327 knot should be removed, default 1. The knot is removed only if the new
328 curve (in direction @a dir) deviates from the old curve by less than
329 @a tol.
330
331 @returns The number of times the knot was successfully removed. */
332 int KnotRemove(int dir, real_t knot, int ntimes=1, real_t tol = 1.0e-12);
333
334 /// Remove all knots in @a knot once.
335 void KnotRemove(int dir, Vector const& knot, real_t tol = 1.0e-12);
336 /// Remove all knots in @a knot once, for each direction.
337 void KnotRemove(Array<Vector *> &knot, real_t tol = 1.0e-12);
338
339 void DegreeElevate(int t);
340
341 /** @brief Refine with optional refinement factor @a rf. Uniform means
342 refinement is done everywhere by the same factor, although nonuniform
343 spacing functions may be used.
344
345 @param[in] rf Optional refinement factor. If scalar, the factor is used
346 for all dimensions. If an array, factors can be specified
347 for each dimension. */
348 void UniformRefinement(int rf = 2);
349 void UniformRefinement(Array<int> const& rf);
350
351 /** @brief Coarsen with optional coarsening factor @a cf which divides the
352 number of elements in each dimension. Nonuniform spacing functions may be
353 used in each direction.
354
355 @param[in] cf Optional coarsening factor. If scalar, the factor is used
356 for all dimensions. If an array, factors can be specified
357 for each dimension.
358 @param[in] tol NURBS geometry deviation tolerance, cf. Algorithm A5.8 of
359 "The NURBS Book", 2nd ed, Piegl and Tiller. */
360 void Coarsen(int cf = 2, real_t tol = 1.0e-12);
361 void Coarsen(Array<int> const& cf, real_t tol = 1.0e-12);
362
363 /// Calls KnotVector::GetCoarseningFactor for each direction.
364 void GetCoarseningFactors(Array<int> & f) const;
365
366 /// Marks the KnotVector in each dimension as coarse.
367 void SetKnotVectorsCoarse(bool c);
368
369 /// Return the number of components stored in the NURBSPatch
370 int GetNC() const { return Dim; }
371
372 /// Return the number of KnotVectors, which is the patch dimension.
373 int GetNKV() const { return kv.Size(); }
374
375 /// Return a pointer to the KnotVector in direction @a dir.
376 /// @note The returned object should NOT be deleted by the caller.
377 KnotVector *GetKV(int dir) { return kv[dir]; }
378
379 // Standard B-NET access functions
380
381 /// 1D access function. @a i is a B-NET index, and @a l is a variable index.
382 inline real_t &operator()(int i, int l);
383 inline const real_t &operator()(int i, int l) const;
384
385 /** @brief 2D access function. @a i, @a j are B-NET indices, and @a l is a
386 variable index. */
387 inline real_t &operator()(int i, int j, int l);
388 inline const real_t &operator()(int i, int j, int l) const;
389
390 /** @brief 3D access function. @a i, @a j, @a k are B-NET indices, and @a l
391 is a variable index. */
392 inline real_t &operator()(int i, int j, int k, int l);
393 inline const real_t &operator()(int i, int j, int k, int l) const;
394
395 /// Compute the 2D rotation matrix @a T for angle @a angle.
396 static void Get2DRotationMatrix(real_t angle, DenseMatrix &T);
397
398 /** @brief Compute the 3D rotation matrix @a T for angle @a angle around
399 axis @a n (a 3D vector, not necessarily normalized) and scalar factor
400 @a r. */
401 static void Get3DRotationMatrix(real_t n[], real_t angle, real_t r,
402 DenseMatrix &T);
403
404 /// Reverse data and knots in direction @a dir.
405 void FlipDirection(int dir);
406
407 /// Swap data and KnotVectors in directions @a dir1 and @a dir2.
408 /** @note Direction pairs (0,2) and (2,0) are not supported, resulting in an
409 error being thrown. */
410 void SwapDirections(int dir1, int dir2);
411
412 /// Rotate the NURBSPatch in 2D or 3D..
413 /** A rotation of a 2D NURBS-patch requires an angle only. Rotating
414 a 3D NURBS-patch requires a normal as well.*/
415 void Rotate(real_t angle, real_t normal[]= NULL);
416
417 /// Rotate the NURBSPatch, 2D case.
418 void Rotate2D(real_t angle);
419
420 /// Rotate the NURBSPatch, 3D case.
421 void Rotate3D(real_t normal[], real_t angle);
422
423 /** Elevate KnotVectors in all directions to degree @a degree if given,
424 otherwise to the maximum current degree among all directions. */
425 int MakeUniformDegree(int degree = -1);
426
427 /** @brief Given two patches @a p1 and @a p2 of the same dimensions, create
428 and return a new patch by merging their knots and data. */
429 /// @note The returned object should be deleted by the caller.
431
432 /// Create and return a new patch by revolving @a patch in 3D.
433 /// @note The returned object should be deleted by the caller.
434 friend NURBSPatch *Revolve3D(NURBSPatch &patch, real_t n[], real_t ang,
435 int times);
436};
437
438
439#ifdef MFEM_USE_MPI
440class ParNURBSExtension;
441#endif
442
443class NURBSPatchMap;
444
445/** @brief NURBSExtension generally contains multiple NURBSPatch objects
446 spanning an entire Mesh. It also defines and manages DOFs in NURBS finite
447 element spaces. */
449{
450#ifdef MFEM_USE_MPI
451 friend class ParNURBSExtension;
452#endif
453 friend class NURBSPatchMap;
454
455protected:
456
457 /// Flag for indicating what type of NURBS fespace this extension is used for.
458 enum class Mode
459 {
460 H_1, ///> Extension for a standard scalar-valued space
461 H_DIV, ///> Extension for a divergence conforming vector-valued space
462 H_CURL, ///> Extension for a curl conforming vector-valued space
463 };
465
466 /// Order of KnotVectors, see GetOrder() for description.
468
469 /// Orders of all KnotVectors
471
472 /// Number of KnotVectors
474
475 /// Global entity counts
477
478 /// Local entity counts
481
482 Array<int> activeVert; // activeVert[glob_vert] = loc_vert or -1
485 Array<int> activeDof; // activeDof[glob_dof] = loc_dof + 1 or 0
486
487 /// Patch topology mesh
489
490 /// Whether this object owns patchTopo
492
493 /// Map from edge indices to KnotVector indices
495
496 /// Set of unique KnotVectors
498
499 /// Comprehensive set of all KnotVectors, one for every edge.
501
502 /// Weights for each control point or DOF
504
505 /** @brief Periodic BC info:
506 - dof 2 dof map
507 - master and slave boundary indices */
511
512 /// Global mesh offsets, meshOffsets == meshVertexOffsets
517
518 /// Global space offsets, spaceOffsets == dofOffsets
523
524 /// Table of DOFs for each element (el_dof) or boundary element (bel_dof).
526
527 /// Map from element indices to patch indices
529 /// Map from boundary element indices to patch indices
531
532 /// Map from element indices to IJK knot span indices
533 Array2D<int> el_to_IJK; // IJK are "knot-span" indices!
534 Array2D<int> bel_to_IJK; // they are NOT element indices!
535
536 /// For each patch p, @a patch_to_el[p] lists all elements in the patch.
537 std::vector<Array<int>> patch_to_el;
538 /// For each patch p, @a patch_to_bel[p] lists all boundary elements in the patch.
539 std::vector<Array<int>> patch_to_bel;
540
541 /// Array of all patches in the mesh.
543
544 /// Return the unsigned index of the KnotVector for edge @a edge.
545 inline int KnotInd(int edge) const;
546
547 /// Access function for the KnotVector associated with edge @a edge.
548 /// @note The returned object should NOT be deleted by the caller.
549 inline KnotVector *KnotVec(int edge);
550 /// Const access function for the KnotVector associated with edge @a edge.
551 /// @note The returned object should NOT be deleted by the caller.
552 inline const KnotVector *KnotVec(int edge) const;
553 /* brief Const access function for the KnotVector associated with edge
554 @a edge. The output orientation @a okv is set to @a oedge with sign flipped
555 if the KnotVector index associated with edge @a edge is negative. */
556 inline const KnotVector *KnotVec(int edge, int oedge, int *okv) const;
557
558 /// Throw an error if any patch has an inconsistent edge-to-knot mapping.
559 void CheckPatches();
560
561 /// Throw an error if any boundary patch has invalid KnotVector orientation.
562 void CheckBdrPatches();
563
564 /** @brief Return the directions in @a kvdir of the KnotVectors in patch @a p
565 based on the patch edge orientations. Each entry of @a kvdir is -1 if the
566 KnotVector direction is flipped, +1 otherwise. */
567 void CheckKVDirection(int p, Array <int> &kvdir);
568
569 /** @brief Create the comprehensive set of KnotVectors. In 1D, this set is
570 identical to the unique set of KnotVectors. */
572
573 /** Update the unique set of KnotVectors. In 1D, this set is identical to
574 the comprehensive set of KnotVectors. */
575 void UpdateUniqueKV();
576
577 /** @brief Check if the comprehensive array of KnotVectors agrees with the
578 unique set of KnotVectors, on each patch. Return false if there is a
579 difference, true otherwise. This function throws an error in 1D. */
580 bool ConsistentKVSets();
581
582 /// Return KnotVectors in @a kv in each dimension for patch @a p.
584 /// Return KnotVectors in @a kv in each dimension for boundary patch @a bp.
586
587 /// Set overall order @a mOrder based on KnotVector orders.
588 void SetOrderFromOrders();
589
590 /// Set orders from KnotVector orders.
592
593 // Periodic BC helper functions
594
595 /// Set DOF map sizes to 0.
596 void InitDofMap();
597
598 /// Set DOF maps for periodic BC.
599 void ConnectBoundaries();
600 void ConnectBoundaries1D(int bnd0, int bnd1);
601 void ConnectBoundaries2D(int bnd0, int bnd1);
602 void ConnectBoundaries3D(int bnd0, int bnd1);
603
604 /** @brief Set the mesh and space offsets, and also count the global
605 @a NumOfVertices and the global @a NumOfDofs. */
606 void GenerateOffsets();
607
608 /// Count the global @a NumOfElements.
609 void CountElements();
610 /// Count the global @a NumOfBdrElements.
611 void CountBdrElements();
612
613 /// Generate the active mesh elements and return them in @a elements.
614 void Get1DElementTopo(Array<Element *> &elements) const;
615 void Get2DElementTopo(Array<Element *> &elements) const;
616 void Get3DElementTopo(Array<Element *> &elements) const;
617
618 /// Generate the active mesh boundary elements and return them in @a boundary.
619 void Get1DBdrElementTopo(Array<Element *> &boundary) const;
620 void Get2DBdrElementTopo(Array<Element *> &boundary) const;
621 void Get3DBdrElementTopo(Array<Element *> &boundary) const;
622
623 // FE space generation functions
624
625 /** @brief Based on activeElem, count NumOfActiveDofs and generate el_dof,
626 el_to_patch, el_to_IJK, activeDof map (global-to-local). */
628
629 /** @brief Generate elem_to_global-dof table for the active elements, and
630 define el_to_patch, el_to_IJK, activeDof (as bool). */
634
635 /// Call after GenerateElementDofTable to set boundary element DOF table.
637
638 /** @brief Generate the table of global DOFs for active boundary elements,
639 and define bel_to_patch, bel_to_IJK. */
643
644 // FE --> Patch translation functions
645
646 /// Set the B-NET on each patch using values from @a coords.
647 void GetPatchNets (const Vector &coords, int vdim);
648 void Get1DPatchNets(const Vector &coords, int vdim);
649 void Get2DPatchNets(const Vector &coords, int vdim);
650 void Get3DPatchNets(const Vector &coords, int vdim);
651
652 // Patch --> FE translation functions
653
654 /** @brief Return in @a coords the coordinates from each patch. Side effects:
655 delete the patches and update the weights from the patches. */
656 void SetSolutionVector (Vector &coords, int vdim);
657 void Set1DSolutionVector(Vector &coords, int vdim);
658 void Set2DSolutionVector(Vector &coords, int vdim);
659 void Set3DSolutionVector(Vector &coords, int vdim);
660
661 /// Determine activeVert, NumOfActiveVertices from the activeElem array.
663
664 /// Determine activeBdrElem, NumOfActiveBdrElems.
666
667 /** @brief Set the weights in this object to values from active elements in
668 @a num_pieces meshes in @a mesh_array. */
669 void MergeWeights(Mesh *mesh_array[], int num_pieces);
670
671 /// Set @a patch_to_el.
672 void SetPatchToElements();
673 /// Set @a patch_to_bel.
675
676 /// To be used by ParNURBSExtension constructor(s)
677 NURBSExtension() : el_dof(nullptr), bel_dof(nullptr) { }
678
679public:
680 /// Copy constructor: deep copy
681 NURBSExtension(const NURBSExtension &orig);
682 /// Read-in a NURBSExtension from a stream @a input..
683 NURBSExtension(std::istream &input, bool spacing=false);
684 /** @brief Create a NURBSExtension with elevated order by repeating the
685 endpoints of the KnotVectors and using uniform weights of 1. */
686 /** @note If a KnotVector in @a parent already has order greater than or
687 equal to @a newOrder, it will be used unmodified. */
688 NURBSExtension(NURBSExtension *parent, int newOrder);
689 /** @brief Create a NURBSExtension with elevated KnotVector orders (by
690 repeating the endpoints of the KnotVectors and using uniform weights of
691 1) as given by the array @a newOrders. */
692 /** @a note If a KnotVector in @a parent already has order greater than or
693 equal to the corresponding entry in @a newOrder, it will be used
694 unmodified. */
695 NURBSExtension(NURBSExtension *parent, const Array<int> &newOrders,
697 /// Construct a NURBSExtension by merging a partitioned NURBS mesh.
698
699 NURBSExtension(Mesh *mesh_array[], int num_pieces);
700
701 NURBSExtension(const Mesh *patch_topology, const Array<const NURBSPatch*> p);
702
703 /// Copy assignment not supported.
705
706 /// Generate connections between boundaries, such as periodic BCs.
708 const Array<int> &GetMaster() const { return master; };
710 const Array<int> &GetSlave() const { return slave; };
711 Array<int> &GetSlave() { return slave; };
712
713 /** @brief Set the DOFs of @a merged to values from active elements in
714 @a num_pieces of Gridfunctions @a gf_array. */
715 void MergeGridFunctions(GridFunction *gf_array[], int num_pieces,
716 GridFunction &merged);
717
718 /// Destroy a NURBSExtension.
719 virtual ~NURBSExtension();
720
721 // Print functions
722
723 /** @brief Writes all patch data to the stream @a os.
724
725 The optional input argument @a comments is a string of comments to be
726 printed after the first line (containing version number) of a mesh file.
727 The output is formatted for writing a mesh to file. This function is
728 called by Mesh::Printer. */
729 void Print(std::ostream &os, const std::string &comments = "") const;
730
731 /// Print various mesh characteristics to the stream @a os.
732 void PrintCharacteristics(std::ostream &os) const;
733
734 /** @brief Call @a KnotVector::PrintFunctions for all KnotVectors, using a
735 separate, newly created ofstream with filename "basename_i.dat" for
736 KnotVector i. */
737 void PrintFunctions(const char *basename, int samples=11) const;
738
739 // Meta data functions
740
741 /// Return the dimension of the reference space (not physical space).
742 int Dimension() const { return patchTopo->Dimension(); }
743
744 /// Return the number of patches.
745 int GetNP() const { return patchTopo->GetNE(); }
746
747 /// Return the number of boundary patches.
748 int GetNBP() const { return patchTopo->GetNBE(); }
749
750 /// Read-only access to the orders of all KnotVectors.
751 const Array<int> &GetOrders() const { return mOrders; }
752
753 /** @brief If all KnotVector orders are identical, return that number.
754 Otherwise, return NURBSFECollection::VariableOrder. */
755 int GetOrder() const { return mOrder; }
756
757 /// Return the number of KnotVectors.
758 int GetNKV() const { return NumOfKnotVectors; }
759
760 /// Return the global number of vertices.
761 int GetGNV() const { return NumOfVertices; }
762 /// Return the local number of active vertices.
763 int GetNV() const { return NumOfActiveVertices; }
764 /// Return the global number of elements.
765 int GetGNE() const { return NumOfElements; }
766 /// Return the number of active elements.
767 int GetNE() const { return NumOfActiveElems; }
768 /// Return the global number of boundary elements.
769 int GetGNBE() const { return NumOfBdrElements; }
770 /// Return the number of active boundary elements.
771 int GetNBE() const { return NumOfActiveBdrElems; }
772
773 /// Return the total number of DOFs.
774 int GetNTotalDof() const { return NumOfDofs; }
775 /// Return the number of active DOFs.
776 int GetNDof() const { return NumOfActiveDofs; }
777
778 /// Return the local DOF number for a given global DOF number @a glob.
779 int GetActiveDof(int glob) const { return activeDof[glob]; };
780
781 /// Return the dof index whilst accounting for periodic boundaries.
782 int DofMap(int dof) const
783 {
784 return (d_to_d.Size() > 0) ? d_to_d[dof] : dof;
785 };
786
787 /// Return KnotVectors in @a kv in each dimension for patch @a p.
789
790 /// Return KnotVectors in @a kv in each dimension for boundary patch @a bp.
792
793 /// KnotVector read-only access function.
794 const KnotVector *GetKnotVector(int i) const { return knotVectors[i]; }
795
796 // Mesh generation functions
797
798 /// Generate the active mesh elements and return them in @a elements.
799 void GetElementTopo (Array<Element *> &elements) const;
800 /// Generate the active mesh boundary elements and return them in @a boundary.
801 void GetBdrElementTopo(Array<Element *> &boundary) const;
802
803 /// Return true if at least 1 patch is defined, false otherwise.
804 bool HavePatches() const { return (patches.Size() != 0); }
805
806 /// Access function for the element DOF table @a el_dof.
807 /// @note The returned object should NOT be deleted by the caller.
809
810 /// Access function for the boundary element DOF table @a bel_dof.
811 /// @note The returned object should NOT be deleted by the caller.
813
814 /// Get the local to global vertex index map @a lvert_vert.
815 void GetVertexLocalToGlobal(Array<int> &lvert_vert);
816 /// Get the local to global element index map @a lelem_elem.
817 void GetElementLocalToGlobal(Array<int> &lelem_elem);
818
819 /** @brief Set the attribute for patch @a i, which is set to all elements in
820 the patch. */
821 void SetPatchAttribute(int i, int attr) { patchTopo->SetAttribute(i, attr); }
822
823 /** @brief Get the attribute for patch @a i, which is set to all elements in
824 the patch. */
825 int GetPatchAttribute(int i) const { return patchTopo->GetAttribute(i); }
826
827 /** @brief Set the attribute for patch boundary element @a i to @a attr, which
828 is set to all boundary elements in the patch. */
829 void SetPatchBdrAttribute(int i, int attr)
830 { patchTopo->SetBdrAttribute(i, attr); }
831
832 /** @brief Get the attribute for boundary patch element @a i, which is set to
833 all boundary elements in the patch. */
834 int GetPatchBdrAttribute(int i) const
835 { return patchTopo->GetBdrAttribute(i); }
836
837 // Load functions
838
839 /// Load element @a i into @a FE.
840 void LoadFE(int i, const FiniteElement *FE) const;
841 /// Load boundary element @a i into @a BE.
842 void LoadBE(int i, const FiniteElement *BE) const;
843
844 /// Access function to the vector of weights @a weights.
845 const Vector &GetWeights() const { return weights; }
846 Vector &GetWeights() { return weights; }
847
848 // Translation functions between FE coordinates and IJK patch format.
849
850 /// Define patches in IKJ (B-net) format, using FE coordinates in @a Nodes.
851 void ConvertToPatches(const Vector &Nodes);
852 /// Set KnotVectors from @a patches and construct mesh and space data.
853 void SetKnotsFromPatches();
854 /** @brief Set FE coordinates in @a Nodes, using data from @a patches, and
855 erase @a patches. */
856 void SetCoordsFromPatches(Vector &Nodes);
857
858 /** @brief Read a GridFunction @a sol from stream @a input, written
859 patch-by-patch, e.g. with PrintSolution(). */
860 void LoadSolution(std::istream &input, GridFunction &sol) const;
861 /// Write a GridFunction @a sol patch-by-patch to stream @a os.
862 void PrintSolution(const GridFunction &sol, std::ostream &os) const;
863
864 // Refinement methods
865
866 /** @brief Call @a DegreeElevate for all KnotVectors of all patches. For each
867 KnotVector, the new degree is
868 max(old_degree, min(old_degree + rel_degree, degree)). */
869 void DegreeElevate(int rel_degree, int degree = 16);
870
871 /** @brief Refine with optional refinement factor @a rf. Uniform means
872 refinement is done everywhere by the same factor, although nonuniform
873 spacing functions may be used.
874 */
875 void UniformRefinement(int rf = 2);
876 void UniformRefinement(Array<int> const& rf);
877 void Coarsen(int cf = 2, real_t tol = 1.0e-12);
878 void Coarsen(Array<int> const& cf, real_t tol = 1.0e-12);
879
880 /** @brief Insert knots from @a kv into all KnotVectors in all patches. The
881 size of @a kv should be the same as @a knotVectors. */
883 void KnotInsert(Array<Vector *> &kv);
884
885 /** Returns the NURBSExtension to be used for @a component of
886 an H(div) conforming NURBS space. Caller gets ownership of
887 the returned object, and is responsible for deletion.*/
888 NURBSExtension* GetDivExtension(int component);
889
890 /** Returns the NURBSExtension to be used for @a component of
891 an H(curl) conforming NURBS space. Caller gets ownership of
892 the returned object, and is responsible for deletion.*/
893 NURBSExtension* GetCurlExtension(int component);
894
895 void KnotRemove(Array<Vector *> &kv, real_t tol = 1.0e-12);
896
897 /** Calls GetCoarseningFactors for each patch and finds the minimum factor
898 for each direction that ensures refinement will work in the case of
899 non-nested spacing functions. */
900 void GetCoarseningFactors(Array<int> & f) const;
901
902
903 /// Returns the index of the patch containing element @a elem.
904 int GetElementPatch(int elem) const { return el_to_patch[elem]; }
905
906 /** @brief Return Cartesian indices (i,j) in 2D or (i,j,k) in 3D of element
907 @a elem, in the knot-span tensor product ordering for its patch. */
908 void GetElementIJK(int elem, Array<int> & ijk);
909
910 /** @brief Return the degrees of freedom in @a dofs on patch @a patch, in
911 Cartesian order. */
912 void GetPatchDofs(const int patch, Array<int> &dofs);
913
914 /// Return the array of indices of all elements in patch @a patch.
915 const Array<int>& GetPatchElements(int patch);
916 /// Return the array of indices of all boundary elements in patch @a patch.
917 const Array<int>& GetPatchBdrElements(int patch);
918};
919
920
921#ifdef MFEM_USE_MPI
922/** @brief Parallel version of NURBSExtension. */
924{
925private:
926 /// Partitioning of the global elements by MPI rank
927 mfem::Array<int> partitioning;
928
929 /// Construct and return a table of DOFs for each global element.
930 Table *GetGlobalElementDofTable();
931 Table *Get1DGlobalElementDofTable();
932 Table *Get2DGlobalElementDofTable();
933 Table *Get3DGlobalElementDofTable();
934
935 /** @brief Set active global elements and boundary elements based on MPI
936 ranks in @a partition and the array @a active_bel. */
937 void SetActive(const int *partitioning_, const Array<bool> &active_bel);
938
939 /// Set up GroupTopology @a gtopo for MPI communication.
940 void BuildGroups(const int *partitioning_, const Table &elem_dof);
941
942public:
944
946
947 /// Copy constructor
949
950 /** @brief Constructor for an MPI communicator @a comm, a global
951 NURBSExtension @a parent, a partitioning @a partitioning_ of the global
952 elements by MPI rank, and a marker @a active_bel of active global
953 boundary elements on this rank. The partitioning is deep-copied and will
954 not be deleted by this object. */
955 ParNURBSExtension(MPI_Comm comm, NURBSExtension *parent,
956 const int *partitioning_,
957 const Array<bool> &active_bel);
958
959 /** @brief Create a parallel version of @a parent with partitioning as in
960 @a par_parent; the @a parent object is destroyed.
961 The @a parent can be either a local NURBSExtension or a global one. */
963 const ParNURBSExtension *par_parent);
964};
965#endif
966
967
968/** @brief Mapping for mesh vertices and NURBS space DOFs. */
970{
971private:
972 /// This object must be associated with exactly one NURBSExtension.
973 const NURBSExtension *Ext;
974
975 /// Number of elements in each direction, minus 1.
976 int I, J, K;
977
978 /// Vertex of DOF offset for this patch, among all patches.
979 int pOffset;
980 /// Orientation for this boundary patch (0 in the patch case).
981 int opatch;
982
983 /// Patch topology entities for this patch or boundary patch.
984 Array<int> verts, edges, faces, oedge, oface;
985
986 inline static int F(const int n, const int N)
987 { return (n < 0) ? 0 : ((n >= N) ? 2 : 1); }
988
989 inline static int Or1D(const int n, const int N, const int Or)
990 { return (Or > 0) ? n : (N - 1 - n); }
991
992 inline static int Or2D(const int n1, const int n2,
993 const int N1, const int N2, const int Or);
994
995 // The following 2 functions also set verts, edges, faces, orientations etc.
996
997 /// Get the KnotVectors for patch @a p in @a kv.
998 void GetPatchKnotVectors (int p, const KnotVector *kv[]);
999 /** @brief Get the KnotVectors for boundary patch @a bp in @a kv, with
1000 orientations output in @a okv. */
1001 void GetBdrPatchKnotVectors(int bp, const KnotVector *kv[], int *okv);
1002
1003public:
1004 /// Constructor for an object associated with NURBSExtension @a ext.
1005 NURBSPatchMap(const NURBSExtension *ext) { Ext = ext; }
1006
1007 /// Return the number of elements in the first direction.
1008 inline int nx() const { return I + 1; }
1009 /// Return the number of elements in the second direction (2D or 3D).
1010 inline int ny() const { return J + 1; }
1011 /// Return the number of elements in the third direction (3D).
1012 inline int nz() const { return K + 1; }
1013
1014 /// Set mesh vertex map for patch @a p with KnotVectors @a kv.
1015 void SetPatchVertexMap(int p, const KnotVector *kv[]);
1016 /// Set NURBS space DOF map for patch @a p with KnotVectors @a kv.
1017 void SetPatchDofMap (int p, const KnotVector *kv[]);
1018
1019 /// Set mesh vertex map for boundary patch @a bp with KnotVectors @a kv.
1020 void SetBdrPatchVertexMap(int bp, const KnotVector *kv[], int *okv);
1021 /// Set NURBS space DOF map for boundary patch @a bp with KnotVectors @a kv.
1022 void SetBdrPatchDofMap (int bp, const KnotVector *kv[], int *okv);
1023
1024 /// For 1D, return the vertex or DOF at index @a i.
1025 inline int operator()(const int i) const;
1026 inline int operator[](const int i) const { return (*this)(i); }
1027
1028 /// For 2D, return the vertex or DOF at indices @a i, @a j.
1029 inline int operator()(const int i, const int j) const;
1030
1031 /// For 3D, return the vertex or DOF at indices @a i, @a j, @a k.
1032 inline int operator()(const int i, const int j, const int k) const;
1033};
1034
1035
1036// Inline function implementations
1037
1038inline real_t &NURBSPatch::slice(int i, int j)
1039{
1040#ifdef MFEM_DEBUG
1041 if (data == 0 || i < 0 || i >= nd || j < 0 || j > ls)
1042 {
1043 mfem_error("NURBSPatch::slice()");
1044 }
1045#endif
1046 return data[j%sd + sd*(i + (j/sd)*nd)];
1047}
1048
1049inline const real_t &NURBSPatch::slice(int i, int j) const
1050{
1051#ifdef MFEM_DEBUG
1052 if (data == 0 || i < 0 || i >= nd || j < 0 || j > ls)
1053 {
1054 mfem_error("NURBSPatch::slice()");
1055 }
1056#endif
1057 return data[j%sd + sd*(i + (j/sd)*nd)];
1058}
1059
1060
1061inline real_t &NURBSPatch::operator()(int i, int l)
1062{
1063#ifdef MFEM_DEBUG
1064 if (data == 0 || i < 0 || i >= ni || nj > 0 || nk > 0 ||
1065 l < 0 || l >= Dim)
1066 {
1067 mfem_error("NURBSPatch::operator() 1D");
1068 }
1069#endif
1070
1071 return data[i*Dim+l];
1072}
1073
1074inline const real_t &NURBSPatch::operator()(int i, int l) const
1075{
1076#ifdef MFEM_DEBUG
1077 if (data == 0 || i < 0 || i >= ni || nj > 0 || nk > 0 ||
1078 l < 0 || l >= Dim)
1079 {
1080 mfem_error("NURBSPatch::operator() const 1D");
1081 }
1082#endif
1083
1084 return data[i*Dim+l];
1085}
1086
1087inline real_t &NURBSPatch::operator()(int i, int j, int l)
1088{
1089#ifdef MFEM_DEBUG
1090 if (data == 0 || i < 0 || i >= ni || j < 0 || j >= nj || nk > 0 ||
1091 l < 0 || l >= Dim)
1092 {
1093 mfem_error("NURBSPatch::operator() 2D");
1094 }
1095#endif
1096
1097 return data[(i+j*ni)*Dim+l];
1098}
1099
1100inline const real_t &NURBSPatch::operator()(int i, int j, int l) const
1101{
1102#ifdef MFEM_DEBUG
1103 if (data == 0 || i < 0 || i >= ni || j < 0 || j >= nj || nk > 0 ||
1104 l < 0 || l >= Dim)
1105 {
1106 mfem_error("NURBSPatch::operator() const 2D");
1107 }
1108#endif
1109
1110 return data[(i+j*ni)*Dim+l];
1111}
1112
1113inline real_t &NURBSPatch::operator()(int i, int j, int k, int l)
1114{
1115#ifdef MFEM_DEBUG
1116 if (data == 0 || i < 0 || i >= ni || j < 0 || j >= nj || k < 0 ||
1117 k >= nk || l < 0 || l >= Dim)
1118 {
1119 mfem_error("NURBSPatch::operator() 3D");
1120 }
1121#endif
1122
1123 return data[(i+(j+k*nj)*ni)*Dim+l];
1124}
1125
1126inline const real_t &NURBSPatch::operator()(int i, int j, int k, int l) const
1127{
1128#ifdef MFEM_DEBUG
1129 if (data == 0 || i < 0 || i >= ni || j < 0 || j >= nj || k < 0 ||
1130 k >= nk || l < 0 || l >= Dim)
1131 {
1132 mfem_error("NURBSPatch::operator() const 3D");
1133 }
1134#endif
1135
1136 return data[(i+(j+k*nj)*ni)*Dim+l];
1137}
1138
1139inline int NURBSExtension::KnotInd(int edge) const
1140{
1141 int kv = edge_to_knot[edge];
1142 return (kv >= 0) ? kv : (-1-kv);
1143}
1144
1146{
1147 return knotVectors[KnotInd(edge)];
1148}
1149
1150inline const KnotVector *NURBSExtension::KnotVec(int edge) const
1151{
1152 return knotVectors[KnotInd(edge)];
1153}
1154
1155inline const KnotVector *NURBSExtension::KnotVec(int edge, int oedge, int *okv)
1156const
1157{
1158 int kv = edge_to_knot[edge];
1159 if (kv >= 0)
1160 {
1161 *okv = oedge;
1162 return knotVectors[kv];
1163 }
1164 else
1165 {
1166 *okv = -oedge;
1167 return knotVectors[-1-kv];
1168 }
1169}
1170
1171
1172// static method
1173inline int NURBSPatchMap::Or2D(const int n1, const int n2,
1174 const int N1, const int N2, const int Or)
1175{
1176 // Needs testing
1177 switch (Or)
1178 {
1179 case 0: return n1 + n2*N1;
1180 case 1: return n2 + n1*N2;
1181 case 2: return n2 + (N1 - 1 - n1)*N2;
1182 case 3: return (N1 - 1 - n1) + n2*N1;
1183 case 4: return (N1 - 1 - n1) + (N2 - 1 - n2)*N1;
1184 case 5: return (N2 - 1 - n2) + (N1 - 1 - n1)*N2;
1185 case 6: return (N2 - 1 - n2) + n1*N2;
1186 case 7: return n1 + (N2 - 1 - n2)*N1;
1187 }
1188#ifdef MFEM_DEBUG
1189 mfem_error("NURBSPatchMap::Or2D");
1190#endif
1191 return -1;
1192}
1193
1194inline int NURBSPatchMap::operator()(const int i) const
1195{
1196 const int i1 = i - 1;
1197 switch (F(i1, I))
1198 {
1199 case 0: return verts[0];
1200 case 1: return pOffset + Or1D(i1, I, opatch);
1201 case 2: return verts[1];
1202 }
1203#ifdef MFEM_DEBUG
1204 mfem_error("NURBSPatchMap::operator() const 1D");
1205#endif
1206 return -1;
1207}
1208
1209inline int NURBSPatchMap::operator()(const int i, const int j) const
1210{
1211 const int i1 = i - 1, j1 = j - 1;
1212 switch (3*F(j1, J) + F(i1, I))
1213 {
1214 case 0: return verts[0];
1215 case 1: return edges[0] + Or1D(i1, I, oedge[0]);
1216 case 2: return verts[1];
1217 case 3: return edges[3] + Or1D(j1, J, -oedge[3]);
1218 case 4: return pOffset + Or2D(i1, j1, I, J, opatch);
1219 case 5: return edges[1] + Or1D(j1, J, oedge[1]);
1220 case 6: return verts[3];
1221 case 7: return edges[2] + Or1D(i1, I, -oedge[2]);
1222 case 8: return verts[2];
1223 }
1224#ifdef MFEM_DEBUG
1225 mfem_error("NURBSPatchMap::operator() const 2D");
1226#endif
1227 return -1;
1228}
1229
1230inline int NURBSPatchMap::operator()(const int i, const int j, const int k)
1231const
1232{
1233 // Needs testing
1234 const int i1 = i - 1, j1 = j - 1, k1 = k - 1;
1235 switch (3*(3*F(k1, K) + F(j1, J)) + F(i1, I))
1236 {
1237 case 0: return verts[0];
1238 case 1: return edges[0] + Or1D(i1, I, oedge[0]);
1239 case 2: return verts[1];
1240 case 3: return edges[3] + Or1D(j1, J, oedge[3]);
1241 case 4: return faces[0] + Or2D(i1, J - 1 - j1, I, J, oface[0]);
1242 case 5: return edges[1] + Or1D(j1, J, oedge[1]);
1243 case 6: return verts[3];
1244 case 7: return edges[2] + Or1D(i1, I, oedge[2]);
1245 case 8: return verts[2];
1246 case 9: return edges[8] + Or1D(k1, K, oedge[8]);
1247 case 10: return faces[1] + Or2D(i1, k1, I, K, oface[1]);
1248 case 11: return edges[9] + Or1D(k1, K, oedge[9]);
1249 case 12: return faces[4] + Or2D(J - 1 - j1, k1, J, K, oface[4]);
1250 case 13: return pOffset + I*(J*k1 + j1) + i1;
1251 case 14: return faces[2] + Or2D(j1, k1, J, K, oface[2]);
1252 case 15: return edges[11] + Or1D(k1, K, oedge[11]);
1253 case 16: return faces[3] + Or2D(I - 1 - i1, k1, I, K, oface[3]);
1254 case 17: return edges[10] + Or1D(k1, K, oedge[10]);
1255 case 18: return verts[4];
1256 case 19: return edges[4] + Or1D(i1, I, oedge[4]);
1257 case 20: return verts[5];
1258 case 21: return edges[7] + Or1D(j1, J, oedge[7]);
1259 case 22: return faces[5] + Or2D(i1, j1, I, J, oface[5]);
1260 case 23: return edges[5] + Or1D(j1, J, oedge[5]);
1261 case 24: return verts[7];
1262 case 25: return edges[6] + Or1D(i1, I, oedge[6]);
1263 case 26: return verts[6];
1264 }
1265#ifdef MFEM_DEBUG
1266 mfem_error("NURBSPatchMap::operator() const 3D");
1267#endif
1268 return -1;
1269}
1270
1271}
1272
1273#endif
Dynamic 2D array using row-major layout.
Definition array.hpp:392
int Size() const
Return the logical size of the array.
Definition array.hpp:147
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
Abstract class for all finite elements.
Definition fe_base.hpp:244
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
A vector of knots in one dimension, with B-spline basis functions of a prescribed order.
Definition nurbs.hpp:40
~KnotVector()
Destroys KnotVector.
Definition nurbs.hpp:192
std::shared_ptr< SpacingFunction > spacing
Function to define the distribution of knots for any number of knot spans.
Definition nurbs.hpp:201
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:523
int findKnotSpan(real_t u) const
Return the index of the knot span containing parameter u.
Definition nurbs.cpp:617
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:300
int NumOfElements
Number of elements, defined by distinct knots.
Definition nurbs.hpp:54
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:422
int Order
Order of the B-spline basis functions.
Definition nurbs.hpp:48
KnotVector & operator=(const KnotVector &kv)
Definition nurbs.cpp:91
void UniformRefinement(Vector &newknots, int rf) const
Uniformly refine by factor rf, by inserting knots in each span.
Definition nurbs.cpp:132
bool isElement(int i) const
Return whether the knot index Order plus i is the beginning of an element.
Definition nurbs.hpp:101
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:337
void FindInterpolant(Array< Vector * > &x)
Global curve interpolation through the points x (overwritten). x is an array with the length of the s...
Definition nurbs.cpp:584
const real_t & operator[](int i) const
Const access function to knot i.
Definition nurbs.hpp:198
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:110
Vector knot
Stores the values of all knots.
Definition nurbs.hpp:45
int GetNKS() const
Return the number of control points minus the order. This is not the number of knot spans,...
Definition nurbs.hpp:106
void GetElements()
Count the number of elements.
Definition nurbs.cpp:269
KnotVector * DegreeElevate(int t) const
Return a new KnotVector with elevated degree by repeating the endpoints of the KnotVector.
Definition nurbs.cpp:103
void Refinement(Vector &newknots, int rf) const
Refine with refinement factor rf.
Definition nurbs.cpp:209
KnotVector()
Create an empty KnotVector.
Definition nurbs.hpp:58
static const int MaxOrder
Definition nurbs.hpp:42
void CalcD2Shape(Vector &grad2, int i, real_t xi) const
Calculate second-order shape function derivatives, using CalcDnShape.
Definition nurbs.hpp:135
int GetOrder() const
Return the order.
Definition nurbs.hpp:91
int GetNCP() const
Return the number of control points.
Definition nurbs.hpp:88
int NumOfControlPoints
Number of control points.
Definition nurbs.hpp:51
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:364
int Size() const
Return the number of knots, including multiplicities.
Definition nurbs.hpp:94
void Flip()
Reverse the knots.
Definition nurbs.cpp:281
void Difference(const KnotVector &kv, Vector &diff) const
Definition nurbs.cpp:646
int GetCoarseningFactor() const
Definition nurbs.cpp:153
Vector GetFineKnots(const int cf) const
Definition nurbs.cpp:172
real_t & operator[](int i)
Access function to knot i.
Definition nurbs.hpp:195
int GetNE() const
Return the number of elements, defined by distinct knots.
Definition nurbs.hpp:85
KnotVector(const KnotVector &kv)
Copy constructor.
Definition nurbs.hpp:80
void Print(std::ostream &os) const
Print the order, number of control points, and knots.
Definition nurbs.cpp:294
Mesh data type.
Definition mesh.hpp:64
int GetAttribute(int i) const
Return the attribute of element i.
Definition mesh.hpp:1389
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
Definition mesh.hpp:1395
void SetAttribute(int i, int attr)
Set the attribute of element i.
Definition mesh.cpp:7629
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1282
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1216
int GetNBE() const
Returns number of boundary elements.
Definition mesh.hpp:1285
void SetBdrAttribute(int i, int attr)
Set the attribute of boundary element i.
Definition mesh.hpp:1398
NURBSExtension generally contains multiple NURBSPatch objects spanning an entire Mesh....
Definition nurbs.hpp:449
void Get2DPatchNets(const Vector &coords, int vdim)
Definition nurbs.cpp:4716
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:4773
int GetNP() const
Return the number of patches.
Definition nurbs.hpp:745
int GetNBE() const
Return the number of active boundary elements.
Definition nurbs.hpp:771
Mode
Flag for indicating what type of NURBS fespace this extension is used for.
Definition nurbs.hpp:459
@ H_CURL
‍Extension for a divergence conforming vector-valued space
@ H_DIV
‍Extension for a standard scalar-valued space
void InitDofMap()
Set DOF map sizes to 0.
Definition nurbs.cpp:2570
Mesh * patchTopo
Patch topology mesh.
Definition nurbs.hpp:488
void GetCoarseningFactors(Array< int > &f) const
Definition nurbs.cpp:4476
void Generate3DElementDofTable()
Definition nurbs.cpp:3869
void SetPatchAttribute(int i, int attr)
Set the attribute for patch i, which is set to all elements in the patch.
Definition nurbs.hpp:821
Vector & GetWeights()
Definition nurbs.hpp:846
const Array< int > & GetPatchElements(int patch)
Return the array of indices of all elements in patch patch.
Definition nurbs.cpp:4903
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:539
void UniformRefinement(int rf=2)
Refine with optional refinement factor rf. Uniform means refinement is done everywhere by the same fa...
Definition nurbs.cpp:4447
Array< int > p_meshOffsets
Definition nurbs.hpp:516
int GetGNE() const
Return the global number of elements.
Definition nurbs.hpp:765
Array< int > mOrders
Orders of all KnotVectors.
Definition nurbs.hpp:470
void Print(std::ostream &os, const std::string &comments="") const
Writes all patch data to the stream os.
Definition nurbs.cpp:2472
Table * el_dof
Table of DOFs for each element (el_dof) or boundary element (bel_dof).
Definition nurbs.hpp:525
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:829
void PrintSolution(const GridFunction &sol, std::ostream &os) const
Write a GridFunction sol patch-by-patch to stream os.
Definition nurbs.cpp:4353
friend class ParNURBSExtension
Definition nurbs.hpp:451
void GenerateOffsets()
Set the mesh and space offsets, and also count the global NumOfVertices and the global NumOfDofs.
Definition nurbs.cpp:3365
int DofMap(int dof) const
Return the dof index whilst accounting for periodic boundaries.
Definition nurbs.hpp:782
Array< bool > activeBdrElem
Definition nurbs.hpp:484
int GetNBP() const
Return the number of boundary patches.
Definition nurbs.hpp:748
bool own_topo
Whether this object owns patchTopo.
Definition nurbs.hpp:491
void SetCoordsFromPatches(Vector &Nodes)
Set FE coordinates in Nodes, using data from patches, and erase patches.
Definition nurbs.cpp:4267
void SetOrderFromOrders()
Set overall order mOrder based on KnotVector orders.
Definition nurbs.cpp:3341
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:4875
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:2901
const Vector & GetWeights() const
Access function to the vector of weights weights.
Definition nurbs.hpp:845
void Set2DSolutionVector(Vector &coords, int vdim)
Definition nurbs.cpp:4816
void Set3DSolutionVector(Vector &coords, int vdim)
Definition nurbs.cpp:4844
void GenerateActiveVertices()
Determine activeVert, NumOfActiveVertices from the activeElem array.
Definition nurbs.cpp:2781
Array< int > el_to_patch
Map from element indices to patch indices.
Definition nurbs.hpp:528
void Coarsen(int cf=2, real_t tol=1.0e-12)
Definition nurbs.cpp:4469
int GetPatchAttribute(int i) const
Get the attribute for patch i, which is set to all elements in the patch.
Definition nurbs.hpp:825
Array< int > activeDof
Definition nurbs.hpp:485
const Array< int > & GetSlave() const
Definition nurbs.hpp:710
Array< int > slave
Definition nurbs.hpp:510
void Get2DBdrElementTopo(Array< Element * > &boundary) const
Definition nurbs.cpp:3667
void GetElementTopo(Array< Element * > &elements) const
Generate the active mesh elements and return them in elements.
Definition nurbs.cpp:3497
const Array< int > & GetPatchBdrElements(int patch)
Return the array of indices of all boundary elements in patch patch.
Definition nurbs.cpp:4910
void Get1DElementTopo(Array< Element * > &elements) const
Generate the active mesh elements and return them in elements.
Definition nurbs.cpp:3515
int KnotInd(int edge) const
Return the unsigned index of the KnotVector for edge edge.
Definition nurbs.hpp:1139
int GetNKV() const
Return the number of KnotVectors.
Definition nurbs.hpp:758
void GetVertexLocalToGlobal(Array< int > &lvert_vert)
Get the local to global vertex index map lvert_vert.
Definition nurbs.cpp:4192
void CountBdrElements()
Count the global NumOfBdrElements.
Definition nurbs.cpp:3477
void LoadBE(int i, const FiniteElement *BE) const
Load boundary element i into BE.
Definition nurbs.cpp:4233
void Get2DElementTopo(Array< Element * > &elements) const
Definition nurbs.cpp:3545
Table * GetElementDofTable()
Definition nurbs.hpp:808
void GenerateElementDofTable()
Based on activeElem, count NumOfActiveDofs and generate el_dof, el_to_patch, el_to_IJK,...
Definition nurbs.cpp:3736
void Generate3DBdrElementDofTable()
Definition nurbs.cpp:4111
int GetGNV() const
Return the global number of vertices.
Definition nurbs.hpp:761
KnotVector * KnotVec(int edge)
Definition nurbs.hpp:1145
bool HavePatches() const
Return true if at least 1 patch is defined, false otherwise.
Definition nurbs.hpp:804
std::vector< Array< int > > patch_to_el
For each patch p, patch_to_el[p] lists all elements in the patch.
Definition nurbs.hpp:537
Array< int > v_meshOffsets
Global mesh offsets, meshOffsets == meshVertexOffsets.
Definition nurbs.hpp:513
NURBSExtension & operator=(const NURBSExtension &)=delete
Copy assignment not supported.
int NumOfActiveVertices
Local entity counts.
Definition nurbs.hpp:479
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:2991
void GetBdrElementTopo(Array< Element * > &boundary) const
Generate the active mesh boundary elements and return them in boundary.
Definition nurbs.cpp:3626
void SetOrdersFromKnotVectors()
Set orders from KnotVector orders.
Definition nurbs.cpp:3355
Array< KnotVector * > knotVectorsCompr
Comprehensive set of all KnotVectors, one for every edge.
Definition nurbs.hpp:500
Array2D< int > el_to_IJK
Map from element indices to IJK knot span indices.
Definition nurbs.hpp:533
void Get1DPatchNets(const Vector &coords, int vdim)
Definition nurbs.cpp:4691
void GenerateBdrElementDofTable()
Call after GenerateElementDofTable to set boundary element DOF table.
Definition nurbs.cpp:3984
Array< int > & GetMaster()
Definition nurbs.hpp:709
Array< int > f_spaceOffsets
Definition nurbs.hpp:521
void CheckPatches()
Throw an error if any patch has an inconsistent edge-to-knot mapping.
Definition nurbs.cpp:2926
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:2876
int NumOfVertices
Global entity counts.
Definition nurbs.hpp:476
void Generate2DBdrElementDofTable()
Definition nurbs.cpp:4048
void GetBdrPatchKnotVectors(int bp, Array< KnotVector * > &kv)
Return KnotVectors in kv in each dimension for boundary patch bp.
Definition nurbs.cpp:3300
Array< int > master
Definition nurbs.hpp:509
void ConnectBoundaries2D(int bnd0, int bnd1)
Definition nurbs.cpp:2664
Array2D< int > bel_to_IJK
Definition nurbs.hpp:534
Array< NURBSPatch * > patches
Array of all patches in the mesh.
Definition nurbs.hpp:542
int GetNTotalDof() const
Return the total number of DOFs.
Definition nurbs.hpp:774
void SetPatchToElements()
Set patch_to_el.
Definition nurbs.cpp:4881
int GetElementPatch(int elem) const
Returns the index of the patch containing element elem.
Definition nurbs.hpp:904
Array< int > & GetSlave()
Definition nurbs.hpp:711
void GetPatchNets(const Vector &coords, int vdim)
Set the B-NET on each patch using values from coords.
Definition nurbs.cpp:4675
void ConnectBoundaries3D(int bnd0, int bnd1)
Definition nurbs.cpp:2710
Array< int > edge_to_knot
Map from edge indices to KnotVector indices.
Definition nurbs.hpp:494
const Array< int > & GetMaster() const
Definition nurbs.hpp:708
void CountElements()
Count the global NumOfElements.
Definition nurbs.cpp:3457
bool ConsistentKVSets()
Check if the comprehensive array of KnotVectors agrees with the unique set of KnotVectors,...
Definition nurbs.cpp:3186
void KnotRemove(Array< Vector * > &kv, real_t tol=1.0e-12)
Definition nurbs.cpp:4615
void LoadFE(int i, const FiniteElement *FE) const
Load element i into FE.
Definition nurbs.cpp:4212
void GetElementLocalToGlobal(Array< int > &lelem_elem)
Get the local to global element index map lelem_elem.
Definition nurbs.cpp:4202
void GenerateActiveBdrElems()
Determine activeBdrElem, NumOfActiveBdrElems.
Definition nurbs.cpp:2854
Array< bool > activeElem
Definition nurbs.hpp:483
Array< int > d_to_d
Periodic BC info:
Definition nurbs.hpp:508
int NumOfKnotVectors
Number of KnotVectors.
Definition nurbs.hpp:473
Vector weights
Weights for each control point or DOF.
Definition nurbs.hpp:503
void CreateComprehensiveKV()
Create the comprehensive set of KnotVectors. In 1D, this set is identical to the unique set of KnotVe...
Definition nurbs.cpp:3058
void GetPatchDofs(const int patch, Array< int > &dofs)
Return the degrees of freedom in dofs on patch patch, in Cartesian order.
Definition nurbs.cpp:3935
Array< int > bel_to_patch
Map from boundary element indices to patch indices.
Definition nurbs.hpp:530
void GetPatchKnotVectors(int p, Array< KnotVector * > &kv)
Return KnotVectors in kv in each dimension for patch p.
Definition nurbs.cpp:3253
Table * GetBdrElementDofTable()
Definition nurbs.hpp:812
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:2557
void Generate2DElementDofTable()
Definition nurbs.cpp:3815
void Set1DSolutionVector(Vector &coords, int vdim)
Definition nurbs.cpp:4789
void PrintCharacteristics(std::ostream &os) const
Print various mesh characteristics to the stream os.
Definition nurbs.cpp:2527
int GetNDof() const
Return the number of active DOFs.
Definition nurbs.hpp:776
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:4503
int GetOrder() const
If all KnotVector orders are identical, return that number. Otherwise, return NURBSFECollection::Vari...
Definition nurbs.hpp:755
NURBSExtension * GetCurlExtension(int component)
Definition nurbs.cpp:4422
Array< int > e_meshOffsets
Definition nurbs.hpp:514
const Array< int > & GetOrders() const
Read-only access to the orders of all KnotVectors.
Definition nurbs.hpp:751
int GetActiveDof(int glob) const
Return the local DOF number for a given global DOF number glob.
Definition nurbs.hpp:779
int GetGNBE() const
Return the global number of boundary elements.
Definition nurbs.hpp:769
Array< int > activeVert
Definition nurbs.hpp:482
void ConnectBoundaries1D(int bnd0, int bnd1)
Definition nurbs.cpp:2650
int GetNV() const
Return the local number of active vertices.
Definition nurbs.hpp:763
void ConvertToPatches(const Vector &Nodes)
Define patches in IKJ (B-net) format, using FE coordinates in Nodes.
Definition nurbs.cpp:4256
void Generate1DBdrElementDofTable()
Generate the table of global DOFs for active boundary elements, and define bel_to_patch,...
Definition nurbs.cpp:4018
void Get3DPatchNets(const Vector &coords, int vdim)
Definition nurbs.cpp:4743
int Dimension() const
Return the dimension of the reference space (not physical space).
Definition nurbs.hpp:742
Array< int > f_meshOffsets
Definition nurbs.hpp:515
NURBSExtension * GetDivExtension(int component)
Definition nurbs.cpp:4407
void Get3DBdrElementTopo(Array< Element * > &boundary) const
Definition nurbs.cpp:3698
int mOrder
Order of KnotVectors, see GetOrder() for description.
Definition nurbs.hpp:467
void SetKnotsFromPatches()
Set KnotVectors from patches and construct mesh and space data.
Definition nurbs.cpp:4275
Array< KnotVector * > knotVectors
Set of unique KnotVectors.
Definition nurbs.hpp:497
Array< int > p_spaceOffsets
Definition nurbs.hpp:522
void Generate1DElementDofTable()
Generate elem_to_global-dof table for the active elements, and define el_to_patch,...
Definition nurbs.cpp:3772
void SetPatchToBdrElements()
Set patch_to_bel.
Definition nurbs.cpp:4892
Array< int > v_spaceOffsets
Global space offsets, spaceOffsets == dofOffsets.
Definition nurbs.hpp:519
int GetNE() const
Return the number of active elements.
Definition nurbs.hpp:767
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:834
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:4391
const KnotVector * GetKnotVector(int i) const
KnotVector read-only access function.
Definition nurbs.hpp:794
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:4316
void ConnectBoundaries()
Set DOF maps for periodic BC.
Definition nurbs.cpp:2584
void CheckBdrPatches()
Throw an error if any boundary patch has invalid KnotVector orientation.
Definition nurbs.cpp:2963
NURBSExtension()
To be used by ParNURBSExtension constructor(s)
Definition nurbs.hpp:677
void Get1DBdrElementTopo(Array< Element * > &boundary) const
Generate the active mesh boundary elements and return them in boundary.
Definition nurbs.cpp:3644
virtual ~NURBSExtension()
Destroy a NURBSExtension.
Definition nurbs.cpp:2446
Array< int > e_spaceOffsets
Definition nurbs.hpp:520
void Get3DElementTopo(Array< Element * > &elements) const
Definition nurbs.cpp:3581
Mapping for mesh vertices and NURBS space DOFs.
Definition nurbs.hpp:970
NURBSPatchMap(const NURBSExtension *ext)
Constructor for an object associated with NURBSExtension ext.
Definition nurbs.hpp:1005
int nx() const
Return the number of elements in the first direction.
Definition nurbs.hpp:1008
void SetPatchDofMap(int p, const KnotVector *kv[])
Set NURBS space DOF map for patch p with KnotVectors kv.
Definition nurbs.cpp:5430
int nz() const
Return the number of elements in the third direction (3D).
Definition nurbs.hpp:1012
int operator[](const int i) const
Definition nurbs.hpp:1026
void SetBdrPatchDofMap(int bp, const KnotVector *kv[], int *okv)
Set NURBS space DOF map for boundary patch bp with KnotVectors kv.
Definition nurbs.cpp:5494
void SetBdrPatchVertexMap(int bp, const KnotVector *kv[], int *okv)
Set mesh vertex map for boundary patch bp with KnotVectors kv.
Definition nurbs.cpp:5461
int ny() const
Return the number of elements in the second direction (2D or 3D).
Definition nurbs.hpp:1010
void SetPatchVertexMap(int p, const KnotVector *kv[])
Set mesh vertex map for patch p with KnotVectors kv.
Definition nurbs.cpp:5398
int operator()(const int i) const
For 1D, return the vertex or DOF at index i.
Definition nurbs.hpp:1194
A NURBS patch can be 1D, 2D, or 3D, and is defined as a tensor product of KnotVectors.
Definition nurbs.hpp:212
int ni
B-NET dimensions.
Definition nurbs.hpp:216
void UniformRefinement(int rf=2)
Refine with optional refinement factor rf. Uniform means refinement is done everywhere by the same fa...
Definition nurbs.cpp:995
int MakeUniformDegree(int degree=-1)
Definition nurbs.cpp:1832
int GetNKV() const
Return the number of KnotVectors, which is the patch dimension.
Definition nurbs.hpp:373
friend NURBSPatch * Revolve3D(NURBSPatch &patch, real_t n[], real_t ang, int times)
Definition nurbs.cpp:1902
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:1061
void GetCoarseningFactors(Array< int > &f) const
Calls KnotVector::GetCoarseningFactor for each direction.
Definition nurbs.cpp:1031
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:1024
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:1210
void Rotate2D(real_t angle)
Rotate the NURBSPatch, 2D case.
Definition nurbs.cpp:1739
NURBSPatch & operator=(const NURBSPatch &)=delete
Copy assignment not supported.
int Dim
Physical dimension plus 1.
Definition nurbs.hpp:219
void Rotate3D(real_t normal[], real_t angle)
Rotate the NURBSPatch, 3D case.
Definition nurbs.cpp:1806
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:1049
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:1038
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:1765
void SwapDirections(int dir1, int dir2)
Swap data and KnotVectors in directions dir1 and dir2.
Definition nurbs.cpp:1685
static void Get2DRotationMatrix(real_t angle, DenseMatrix &T)
Compute the 2D rotation matrix T for angle angle.
Definition nurbs.cpp:1727
~NURBSPatch()
Deletes data and KnotVectors.
Definition nurbs.cpp:870
void init(int dim)
Definition nurbs.cpp:681
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:907
KnotVector * GetKV(int dir)
Definition nurbs.hpp:377
int GetNC() const
Return the number of components stored in the NURBSPatch.
Definition nurbs.hpp:370
void Print(std::ostream &os) const
Writes KnotVectors and data to the stream os.
Definition nurbs.cpp:883
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:1855
Array< KnotVector * > kv
KnotVectors in each direction.
Definition nurbs.hpp:225
void FlipDirection(int dir)
Reverse data and knots in direction dir.
Definition nurbs.cpp:1673
void swap(NURBSPatch *np)
Deletes own data, takes data from np, and deletes np.
Definition nurbs.cpp:844
NURBSPatch(NURBSPatch *parent, int dir, int Order, int NCP)
Copy constructor.
Definition nurbs.cpp:829
void SetKnotVectorsCoarse(bool c)
Marks the KnotVector in each dimension as coarse.
Definition nurbs.cpp:1962
void Rotate(real_t angle, real_t normal[]=NULL)
Rotate the NURBSPatch in 2D or 3D..
Definition nurbs.cpp:1710
void DegreeElevate(int dir, int t)
Increase the order in direction dir by t >= 0.
Definition nurbs.cpp:1417
real_t * data
Data with the layout (Dim x ni x nj x nk)
Definition nurbs.hpp:222
Parallel version of NURBSExtension.
Definition nurbs.hpp:924
GroupTopology gtopo
Definition nurbs.hpp:943
Array< int > ldof_group
Definition nurbs.hpp:945
Vector data type.
Definition vector.hpp:82
int Size() const
Returns the size of the vector.
Definition vector.hpp:226
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:43
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)