62 {
return (xi*
knot(ni+1) + (1. - xi)*
knot(ni)); }
106 void Print(std::ostream &os)
const;
172 void Print(std::ostream &os)
const;
271class ParNURBSExtension;
340 inline int KnotInd(
int edge)
const;
476 void Print(std::ostream &os,
const std::string &comments =
"")
const;
612 Table *GetGlobalElementDofTable();
613 Table *Get1DGlobalElementDofTable();
614 Table *Get2DGlobalElementDofTable();
615 Table *Get3DGlobalElementDofTable();
617 void SetActive(
const int *partitioning,
const Array<bool> &active_bel);
618 void BuildGroups(
const int *partitioning,
const Table &elem_dof);
646 int I, J, K, pOffset, opatch;
649 inline static int F(
const int n,
const int N)
650 {
return (n < 0) ? 0 : ((n >= N) ? 2 : 1); }
652 inline static int Or1D(
const int n,
const int N,
const int Or)
653 {
return (Or > 0) ? n : (N - 1 - n); }
655 inline static int Or2D(
const int n1,
const int n2,
656 const int N1,
const int N2,
const int Or);
659 void GetPatchKnotVectors (
int p,
const KnotVector *kv[]);
660 void GetBdrPatchKnotVectors(
int p,
const KnotVector *kv[],
int *okv);
665 int nx() {
return I + 1; }
666 int ny() {
return J + 1; }
667 int nz() {
return K + 1; }
676 inline int operator[](
const int i)
const {
return (*
this)(i); }
678 inline int operator()(
const int i,
const int j)
const;
680 inline int operator()(
const int i,
const int j,
const int k)
const;
689 if (
data == 0 || i < 0 || i >=
nd || j < 0 || j >
ls)
700 if (
data == 0 || i < 0 || i >=
nd || j < 0 || j >
ls)
712 if (
data == 0 || i < 0 || i >=
ni ||
nj > 0 ||
nk > 0 ||
725 if (
data == 0 || i < 0 || i >=
ni ||
nj > 0 ||
nk > 0 ||
728 mfem_error(
"NURBSPatch::operator() const 1D");
738 if (
data == 0 || i < 0 || i >=
ni || j < 0 || j >=
nj ||
nk > 0 ||
751 if (
data == 0 || i < 0 || i >=
ni || j < 0 || j >=
nj ||
nk > 0 ||
754 mfem_error(
"NURBSPatch::operator() const 2D");
764 if (
data == 0 || i < 0 || i >=
ni || j < 0 || j >=
nj || k < 0 ||
765 k >=
nk || l < 0 || l >=
Dim)
777 if (
data == 0 || i < 0 || i >=
ni || j < 0 || j >=
nj || k < 0 ||
778 k >=
nk || l < 0 || l >=
Dim)
780 mfem_error(
"NURBSPatch::operator() const 3D");
791 return (kv >= 0) ? kv : (-1-kv);
822inline int NURBSPatchMap::Or2D(
const int n1,
const int n2,
823 const int N1,
const int N2,
const int Or)
828 case 0:
return n1 + n2*N1;
829 case 1:
return n2 + n1*N2;
830 case 2:
return n2 + (N1 - 1 - n1)*N2;
831 case 3:
return (N1 - 1 - n1) + n2*N1;
832 case 4:
return (N1 - 1 - n1) + (N2 - 1 - n2)*N1;
833 case 5:
return (N2 - 1 - n2) + (N1 - 1 - n1)*N2;
834 case 6:
return (N2 - 1 - n2) + n1*N2;
835 case 7:
return n1 + (N2 - 1 - n2)*N1;
845 const int i1 = i - 1;
848 case 0:
return verts[0];
849 case 1:
return pOffset + Or1D(i1, I, opatch);
850 case 2:
return verts[1];
853 mfem_error(
"NURBSPatchMap::operator() const 1D");
860 const int i1 = i - 1, j1 = j - 1;
861 switch (3*F(j1, J) + F(i1, I))
863 case 0:
return verts[0];
864 case 1:
return edges[0] + Or1D(i1, I, oedge[0]);
865 case 2:
return verts[1];
866 case 3:
return edges[3] + Or1D(j1, J, -oedge[3]);
867 case 4:
return pOffset + Or2D(i1, j1, I, J, opatch);
868 case 5:
return edges[1] + Or1D(j1, J, oedge[1]);
869 case 6:
return verts[3];
870 case 7:
return edges[2] + Or1D(i1, I, -oedge[2]);
871 case 8:
return verts[2];
874 mfem_error(
"NURBSPatchMap::operator() const 2D");
883 const int i1 = i - 1, j1 = j - 1, k1 = k - 1;
884 switch (3*(3*F(k1, K) + F(j1, J)) + F(i1, I))
886 case 0:
return verts[0];
887 case 1:
return edges[0] + Or1D(i1, I, oedge[0]);
888 case 2:
return verts[1];
889 case 3:
return edges[3] + Or1D(j1, J, oedge[3]);
890 case 4:
return faces[0] + Or2D(i1, J - 1 - j1, I, J, oface[0]);
891 case 5:
return edges[1] + Or1D(j1, J, oedge[1]);
892 case 6:
return verts[3];
893 case 7:
return edges[2] + Or1D(i1, I, oedge[2]);
894 case 8:
return verts[2];
895 case 9:
return edges[8] + Or1D(k1, K, oedge[8]);
896 case 10:
return faces[1] + Or2D(i1, k1, I, K, oface[1]);
897 case 11:
return edges[9] + Or1D(k1, K, oedge[9]);
898 case 12:
return faces[4] + Or2D(J - 1 - j1, k1, J, K, oface[4]);
899 case 13:
return pOffset + I*(J*k1 + j1) + i1;
900 case 14:
return faces[2] + Or2D(j1, k1, J, K, oface[2]);
901 case 15:
return edges[11] + Or1D(k1, K, oedge[11]);
902 case 16:
return faces[3] + Or2D(I - 1 - i1, k1, I, K, oface[3]);
903 case 17:
return edges[10] + Or1D(k1, K, oedge[10]);
904 case 18:
return verts[4];
905 case 19:
return edges[4] + Or1D(i1, I, oedge[4]);
906 case 20:
return verts[5];
907 case 21:
return edges[7] + Or1D(j1, J, oedge[7]);
908 case 22:
return faces[5] + Or2D(i1, j1, I, J, oface[5]);
909 case 23:
return edges[5] + Or1D(j1, J, oedge[5]);
910 case 24:
return verts[7];
911 case 25:
return edges[6] + Or1D(i1, I, oedge[6]);
912 case 26:
return verts[6];
915 mfem_error(
"NURBSPatchMap::operator() const 3D");
Dynamic 2D array using row-major layout.
int Size() const
Return the logical size of the array.
Data type dense matrix using column-major storage.
Abstract class for all finite elements.
Class for grid function - Vector with associated FE space.
~KnotVector()
Destroys KnotVector.
std::shared_ptr< SpacingFunction > spacing
Function to define the distribution of knots for any number of knot spans.
void FindMaxima(Array< int > &ks, Vector &xi, Vector &u) const
int findKnotSpan(real_t u) const
void PrintFunctions(std::ostream &os, int samples=11) const
void CalcDnShape(Vector &gradn, int n, int i, real_t xi) const
KnotVector & operator=(const KnotVector &kv)
void UniformRefinement(Vector &newknots, int rf) const
Refine uniformly with refinement factor rf.
bool isElement(int i) const
void CalcShape(Vector &shape, int i, real_t xi) const
void FindInterpolant(Array< Vector * > &x)
const real_t & operator[](int i) const
real_t getKnotLocation(real_t xi, int ni) const
void GetElements()
Count the number of elements.
KnotVector * DegreeElevate(int t) const
void Refinement(Vector &newknots, int rf) const
Refine with refinement factor rf.
KnotVector()
Create KnotVector.
static const int MaxOrder
void CalcD2Shape(Vector &grad2, int i, real_t xi) const
void CalcDShape(Vector &grad, int i, real_t xi) const
void Difference(const KnotVector &kv, Vector &diff) const
Finds the knots in the larger of this and kv, not contained in the other.
int GetCoarseningFactor() const
Vector GetFineKnots(const int cf) const
real_t & operator[](int i)
KnotVector(const KnotVector &kv)
void Print(std::ostream &os) const
int GetAttribute(int i) const
Return the attribute of element i.
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
void SetAttribute(int i, int attr)
Set the attribute of element i.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
int GetNBE() const
Returns number of boundary elements.
void SetBdrAttribute(int i, int attr)
Set the attribute of boundary element i.
void GetCoarseningFactors(Array< int > &f) const
void Generate3DElementDofTable()
void SetPatchAttribute(int i, int attr)
Array< NURBSPatch * > patches
const Array< int > & GetPatchElements(int patch)
void Set2DSolutionVector(Vector &Nodes, int vdim)
std::vector< Array< int > > patch_to_bel
void UniformRefinement(int rf=2)
Refine with optional refinement factor rf. Uniform means refinement is done everywhere by the same fa...
Array< int > p_meshOffsets
void Print(std::ostream &os, const std::string &comments="") const
void SetSolutionVector(Vector &Nodes, int vdim)
void SetPatchBdrAttribute(int i, int attr)
void PrintSolution(const GridFunction &sol, std::ostream &os) const
friend class ParNURBSExtension
int DofMap(int dof) const
Returns the dof index whilst accounting for periodic boundaries.
void PrintFunctions(const char *filename, int samples=11) const
void Set3DSolutionVector(Vector &Nodes, int vdim)
Array< bool > activeBdrElem
void SetCoordsFromPatches(Vector &Nodes)
void SetOrderFromOrders()
void GetElementIJK(int elem, Array< int > &ijk)
void MergeGridFunctions(GridFunction *gf_array[], int num_pieces, GridFunction &merged)
const Vector & GetWeights() const
void GenerateActiveVertices()
void Coarsen(int cf=2, real_t tol=1.0e-12)
int GetPatchAttribute(int i) const
const Array< int > & GetSlave() const
void Get2DBdrElementTopo(Array< Element * > &boundary) const
void GetElementTopo(Array< Element * > &elements) const
const Array< int > & GetPatchBdrElements(int patch)
void Get1DElementTopo(Array< Element * > &elements) const
int KnotInd(int edge) const
void GetVertexLocalToGlobal(Array< int > &lvert_vert)
void LoadBE(int i, const FiniteElement *BE) const
void Get2DElementTopo(Array< Element * > &elements) const
Table * GetElementDofTable()
void GenerateElementDofTable()
void Generate3DBdrElementDofTable()
void Get3DPatchNets(const Vector &Nodes, int vdim)
KnotVector * KnotVec(int edge)
std::vector< Array< int > > patch_to_el
void Get2DPatchNets(const Vector &Nodes, int vdim)
Array< int > v_meshOffsets
void GetPatchNets(const Vector &Nodes, int vdim)
NURBSExtension & operator=(const NURBSExtension &)=delete
Copy assignment not supported.
void CheckKVDirection(int p, Array< int > &kvdir)
void GetBdrElementTopo(Array< Element * > &boundary) const
void SetOrdersFromKnotVectors()
Array< KnotVector * > knotVectorsCompr
void GenerateBdrElementDofTable()
Array< int > & GetMaster()
Array< int > f_spaceOffsets
void MergeWeights(Mesh *mesh_array[], int num_pieces)
void Generate2DBdrElementDofTable()
void Set1DSolutionVector(Vector &Nodes, int vdim)
void ConnectBoundaries2D(int bnd0, int bnd1)
Array2D< int > bel_to_IJK
void SetPatchToElements()
int GetElementPatch(int elem) const
Returns the index of the patch containing element elem.
Array< int > & GetSlave()
void ConnectBoundaries3D(int bnd0, int bnd1)
Array< int > edge_to_knot
const Array< int > & GetMaster() const
void KnotRemove(Array< Vector * > &kv, real_t tol=1.0e-12)
void LoadFE(int i, const FiniteElement *FE) const
void GetElementLocalToGlobal(Array< int > &lelem_elem)
void GenerateActiveBdrElems()
void CreateComprehensiveKV()
void GetPatchDofs(const int patch, Array< int > &dofs)
Array< int > bel_to_patch
void GetPatchKnotVectors(int p, Array< KnotVector * > &kv)
Table * GetBdrElementDofTable()
void Generate2DElementDofTable()
void PrintCharacteristics(std::ostream &os) const
void KnotInsert(Array< KnotVector * > &kv)
int GetOrder() const
If all orders are identical, return that number. Otherwise, return NURBSFECollection::VariableOrder.
Array< int > e_meshOffsets
void GetBdrPatchKnotVectors(int p, Array< KnotVector * > &kv)
const Array< int > & GetOrders() const
Read-only access to the orders of all knot vectors.
int GetActiveDof(int glob) const
Returns the local dof number.
void ConnectBoundaries1D(int bnd0, int bnd1)
void Get1DPatchNets(const Vector &Nodes, int vdim)
void ConvertToPatches(const Vector &Nodes)
void Generate1DBdrElementDofTable()
Array< int > f_meshOffsets
void Get3DBdrElementTopo(Array< Element * > &boundary) const
void SetKnotsFromPatches()
Array< KnotVector * > knotVectors
Array< int > p_spaceOffsets
void Generate1DElementDofTable()
void SetPatchToBdrElements()
Array< int > v_spaceOffsets
int GetPatchBdrAttribute(int i) const
void DegreeElevate(int rel_degree, int degree=16)
const KnotVector * GetKnotVector(int i) const
void LoadSolution(std::istream &input, GridFunction &sol) const
void Get1DBdrElementTopo(Array< Element * > &boundary) const
virtual ~NURBSExtension()
Destroy a NURBSExtension.
Array< int > e_spaceOffsets
void Get3DElementTopo(Array< Element * > &elements) const
void SetBdrPatchDofMap(int p, const KnotVector *kv[], int *okv)
NURBSPatchMap(const NURBSExtension *ext)
void SetPatchDofMap(int p, const KnotVector *kv[])
void SetBdrPatchVertexMap(int p, const KnotVector *kv[], int *okv)
int operator[](const int i) const
void SetPatchVertexMap(int p, const KnotVector *kv[])
int operator()(const int i) const
void UniformRefinement(int rf=2)
Refine with optional refinement factor rf. Uniform means refinement is done everywhere by the same fa...
int MakeUniformDegree(int degree=-1)
friend NURBSPatch * Revolve3D(NURBSPatch &patch, real_t n[], real_t ang, int times)
void GetCoarseningFactors(Array< int > &f) const
Calls KnotVector::GetCoarseningFactor for each direction.
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....
int KnotRemove(int dir, real_t knot, int ntimes=1, real_t tol=1.0e-12)
Remove knot with value knot from direction dir.
void Rotate2D(real_t angle)
NURBSPatch & operator=(const NURBSPatch &)=delete
void Rotate3D(real_t normal[], real_t angle)
void KnotInsert(int dir, const KnotVector &knot)
Insert knots from knot determined by Difference, in direction dir.
real_t & slice(int i, int j)
static void Get3DRotationMatrix(real_t n[], real_t angle, real_t r, DenseMatrix &T)
void SwapDirections(int dir1, int dir2)
real_t & operator()(int i, int j)
static void Get2DRotationMatrix(real_t angle, DenseMatrix &T)
KnotVector * GetKV(int i)
int SetLoopDirection(int dir)
void Print(std::ostream &os) const
friend NURBSPatch * Interpolate(NURBSPatch &p1, NURBSPatch &p2)
void FlipDirection(int dir)
void swap(NURBSPatch *np)
NURBSPatch(NURBSPatch *parent, int dir, int Order, int NCP)
void SetKnotVectorsCoarse(bool c)
Marks the KnotVector in each dimension as coarse.
void Rotate(real_t angle, real_t normal[]=NULL)
Rotate the NURBSPatch.
void DegreeElevate(int dir, int t)
virtual ~ParNURBSExtension()
int Size() const
Returns the size of the vector.
real_t u(const Vector &xvec)
void mfem_error(const char *msg)
std::function< real_t(const Vector &)> f(real_t mass_coeff)
real_t p(const Vector &x, real_t t)