From a3b635c371b8a94a1b9b65cfa0e6e6d1bd3a8de5 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 29 Aug 2016 13:43:08 +0200 Subject: [PATCH] changed: introduce virtual getCorner method in ASM[2|3]D and getEdge in ASM3D --- src/ASM/ASM2D.h | 3 ++ src/ASM/ASM3D.h | 6 +++ src/ASM/ASMs2D.C | 36 ++++++++++------- src/ASM/ASMs2D.h | 3 ++ src/ASM/ASMs3D.C | 49 ++++++++++++++++------- src/ASM/ASMs3D.h | 6 +++ src/ASM/LR/ASMu2D.h | 2 +- src/ASM/LR/ASMu3D.C | 95 ++++++++++++++++++++++++++------------------- src/ASM/LR/ASMu3D.h | 6 +++ 9 files changed, 138 insertions(+), 68 deletions(-) diff --git a/src/ASM/ASM2D.h b/src/ASM/ASM2D.h index edebe46d..aa31a51c 100644 --- a/src/ASM/ASM2D.h +++ b/src/ASM/ASM2D.h @@ -127,6 +127,9 @@ public: //! \param[in] nSegSpan Number of visualization segments over each knot-span virtual bool getGridParameters(std::vector& prm, int dir, int nSegSpan) const = 0; + + //! \brief Returns the node index for a given corner. + virtual int getCorner(int I, int J, int basis = 1) const = 0; }; #endif diff --git a/src/ASM/ASM3D.h b/src/ASM/ASM3D.h index f312d11c..e63a2c06 100644 --- a/src/ASM/ASM3D.h +++ b/src/ASM/ASM3D.h @@ -159,6 +159,12 @@ public: //! \param[in] nSegSpan Number of visualization segments over each knot-span virtual bool getGridParameters(std::vector& prm, int dir, int nSegSpan) const = 0; + + //! \brief Returns the node index for a given corner. + virtual int getCorner(int I, int J, int K, int basis = 1) const = 0; + + //! \brief Returns the node indices for a given edge. + virtual std::vector getEdge(int lEdge, bool open, int basis = 1) const = 0; }; #endif diff --git a/src/ASM/ASMs2D.C b/src/ASM/ASMs2D.C index 5bad0ac8..e165d8e9 100644 --- a/src/ASM/ASMs2D.C +++ b/src/ASM/ASMs2D.C @@ -1016,20 +1016,9 @@ size_t ASMs2D::constrainEdgeLocal (int dir, bool open, int dof, int code, void ASMs2D::constrainCorner (int I, int J, int dof, int code, char basis) { - int n1, n2, node = 1; - for (char i = 1; i <= basis; i++) - if (!this->getSize(n1,n2,i)) - return; - else if (i < basis) - node += n1*n2; - - if (swapV) // Account for swapped parameter direction - J = -J; - - if (I > 0) node += n1-1; - if (J > 0) node += n1*(n2-1); - - this->prescribe(node,dof,code); + int node = this->getCorner(I, J, basis); + if (node > -1) + this->prescribe(node,dof,code); } @@ -2745,3 +2734,22 @@ bool ASMs2D::evaluate (const RealFunc* func, RealArray& vec, return true; } + + +int ASMs2D::getCorner(int I, int J, int basis) const +{ + int n1, n2, node = 1; + for (char i = 1; i <= basis; i++) + if (!this->getSize(n1,n2,i)) + return -1; + else if (i < basis) + node += n1*n2; + + if (swapV) // Account for swapped parameter direction + J = -J; + + if (I > 0) node += n1-1; + if (J > 0) node += n1*(n2-1); + + return node; +} diff --git a/src/ASM/ASMs2D.h b/src/ASM/ASMs2D.h index 05aecc6c..bf0fd75f 100644 --- a/src/ASM/ASMs2D.h +++ b/src/ASM/ASMs2D.h @@ -185,6 +185,9 @@ public: //! \param basis Which basis to grab nodes for virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis) const; + //! \brief Returns the node index for a given corner. + virtual int getCorner(int I, int J, int basis = 1) const; + //! \brief Assigns new global node numbers for all nodes of the patch. //! \param nodes Object with global nodes numbers to assign to this patch //! \param[in] basis Which basis to assign node numbers for in mixed methods diff --git a/src/ASM/ASMs3D.C b/src/ASM/ASMs3D.C index d61869a2..58a0e0e2 100644 --- a/src/ASM/ASMs3D.C +++ b/src/ASM/ASMs3D.C @@ -1110,12 +1110,12 @@ size_t ASMs3D::constrainFaceLocal (int dir, bool open, int dof, int code, } -void ASMs3D::constrainEdge (int lEdge, bool open, int dof, - int code, char basis) +std::vector ASMs3D::getEdge(int lEdge, bool open, int basis) const { + std::vector result; int n1, n2, n3, n, inc = 1; int node = this->findStartNode(n1,n2,n3,basis); - if (node < 1) return; + if (node < 1) return result; if (swapW && lEdge <= 8) // Account for swapped parameter direction lEdge += (lEdge-1)%4 < 2 ? 2 : -2; @@ -1161,7 +1161,18 @@ void ASMs3D::constrainEdge (int lEdge, bool open, int dof, // Skip the first and last node if we are requesting an open boundary for (int i = 1; i <= n; i++, node += inc) if (!open || (i > 1 && i < n)) - this->prescribe(node,dof,code); + result.push_back(node); + + return result; +} + + +void ASMs3D::constrainEdge (int lEdge, bool open, int dof, + int code, char basis) +{ + std::vector nodes = this->getEdge(lEdge, open, basis); + for (const int& node : nodes) + this->prescribe(node,dof,code); } @@ -1242,16 +1253,9 @@ void ASMs3D::constrainLine (int fdir, int ldir, double xi, int dof, void ASMs3D::constrainCorner (int I, int J, int K, int dof, int code, char basis) { - int n1, n2, n3; - int node = this->findStartNode(n1,n2,n3,basis); - if (node < 1) return; - - if (swapW) // Account for swapped parameter direction - K = -K; - - if (I > 0) node += n1-1; - if (J > 0) node += n1*(n2-1); - if (K > 0) node += n1*n2*(n3-1); + int node = this->getCorner(I, J, K, basis); + if (node < 1) + return; this->prescribe(node,dof,code); } @@ -3193,3 +3197,20 @@ bool ASMs3D::evaluate (const RealFunc* func, RealArray& vec, return true; } + + +int ASMs3D::getCorner(int I, int J, int K, int basis) const +{ + int n1, n2, n3; + int node = this->findStartNode(n1,n2,n3,basis); + if (node < 1) return -1; + + if (swapW) // Account for swapped parameter direction + K = -K; + + if (I > 0) node += n1-1; + if (J > 0) node += n1*(n2-1); + if (K > 0) node += n1*n2*(n3-1); + + return node; +} diff --git a/src/ASM/ASMs3D.h b/src/ASM/ASMs3D.h index a5cd7e03..12d5d856 100644 --- a/src/ASM/ASMs3D.h +++ b/src/ASM/ASMs3D.h @@ -201,6 +201,12 @@ public: //! \param basis Which basis to grab nodes for (0 for all) virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis) const; + //! \brief Returns the node index for a given corner. + virtual int getCorner(int I, int J, int K, int basis = 1) const; + + //! \brief Returns the node indices for a given edge. + virtual std::vector getEdge(int lEdge, bool open, int basis = 1) const; + //! \brief Assigns new global node numbers for all nodes of the patch. //! \param nodes Object with global nodes numbers to assign to this patch //! \param[in] basis Which basis to assign node numbers for in mixed methods diff --git a/src/ASM/LR/ASMu2D.h b/src/ASM/LR/ASMu2D.h index 983a010f..dd98b263 100644 --- a/src/ASM/LR/ASMu2D.h +++ b/src/ASM/LR/ASMu2D.h @@ -235,7 +235,7 @@ public: const std::map* g2l = nullptr); //! \brief Returns the node index for a given corner. - int getCorner(int I, int J, int basis = 1) const; + virtual int getCorner(int I, int J, int basis = 1) const; //! \brief Returns the node indices for a given edge. std::vector getEdgeNodes(int edge, int basis = 1) const; diff --git a/src/ASM/LR/ASMu3D.C b/src/ASM/LR/ASMu3D.C index 625103cf..32e6e0be 100644 --- a/src/ASM/LR/ASMu3D.C +++ b/src/ASM/LR/ASMu3D.C @@ -487,48 +487,58 @@ size_t ASMu3D::constrainFaceLocal(int dir, bool open, int dof, int code, bool pr return 0; } + +std::vector ASMu3D::getEdge(int lEdge, bool open, int) const +{ + // lEdge = 1-4, running index is u (vmin,wmin), (vmax,wmin), (vmin,wmax), (vmax,wmax) + // lEdge = 5-8, running index is v (umin,wmin), (umax,wmin), (umin,wmax), (umax,wmax) + // lEdge = 9-12, running index is w + + int edge = LR::NONE; + if(lEdge == 1) + edge = LR::BOTTOM | LR::SOUTH; + else if(lEdge == 2) + edge = LR::BOTTOM | LR::NORTH; + else if(lEdge == 3) + edge = LR::TOP | LR::SOUTH; + else if(lEdge == 4) + edge = LR::TOP | LR::NORTH; + else if(lEdge == 5) + edge = LR::BOTTOM | LR::WEST; + else if(lEdge == 6) + edge = LR::BOTTOM | LR::EAST; + else if(lEdge == 7) + edge = LR::TOP | LR::WEST; + else if(lEdge == 8) + edge = LR::TOP | LR::EAST; + else if(lEdge == 9) + edge = LR::SOUTH | LR::WEST; + else if(lEdge == 10) + edge = LR::SOUTH | LR::EAST; + else if(lEdge == 11) + edge = LR::NORTH | LR::WEST; + else if(lEdge == 12) + edge = LR::NORTH | LR::EAST; + + // get all the boundary functions from the LRspline object + std::vector thisEdge; + lrspline->getEdgeFunctions(thisEdge, (LR::parameterEdge) edge, 1); + std::vector result; + for (LR::Basisfunction* b : thisEdge) + result.push_back(b->getId()+1); + + return result; +} + void ASMu3D::constrainEdge (int lEdge, bool open, int dof, int code, char) { - if(open) - std::cerr << "\nWARNING: ASMu3D::constrainEdge, open boundary conditions not supported yet. Treating it as closed" << std::endl; + if(open) + std::cerr << "\nWARNING: ASMu3D::constrainEdge, open boundary conditions not supported yet. Treating it as closed" << std::endl; - // lEdge = 1-4, running index is u (vmin,wmin), (vmax,wmin), (vmin,wmax), (vmax,wmax) - // lEdge = 5-8, running index is v (umin,wmin), (umax,wmin), (umin,wmax), (umax,wmax) - // lEdge = 9-12, running index is w - - int edge = LR::NONE; - if(lEdge == 1) - edge = LR::BOTTOM | LR::SOUTH; - else if(lEdge == 2) - edge = LR::BOTTOM | LR::NORTH; - else if(lEdge == 3) - edge = LR::TOP | LR::SOUTH; - else if(lEdge == 4) - edge = LR::TOP | LR::NORTH; - else if(lEdge == 5) - edge = LR::BOTTOM | LR::WEST; - else if(lEdge == 6) - edge = LR::BOTTOM | LR::EAST; - else if(lEdge == 7) - edge = LR::TOP | LR::WEST; - else if(lEdge == 8) - edge = LR::TOP | LR::EAST; - else if(lEdge == 9) - edge = LR::SOUTH | LR::WEST; - else if(lEdge == 10) - edge = LR::SOUTH | LR::EAST; - else if(lEdge == 11) - edge = LR::NORTH | LR::WEST; - else if(lEdge == 12) - edge = LR::NORTH | LR::EAST; - - // get all the boundary functions from the LRspline object - std::vector thisEdge; - lrspline->getEdgeFunctions(thisEdge, (LR::parameterEdge) edge, 1); - - // enforce the boundary conditions - for(LR::Basisfunction* b : thisEdge) - this->prescribe(b->getId()+1,dof,code); + // enforce the boundary conditions + std::vector nodes = this->getEdge(lEdge, open, 1); + for (const int& node : nodes) + this->prescribe(node,dof,code); } @@ -1972,3 +1982,10 @@ bool ASMu3D::getOrder (int& p1, int& p2, int& p3) const return true; } + + +int ASMu3D::getCorner(int I, int J, int K, int basis) const +{ + std::cerr << "ASMu3D::getCorner not implemented properly yet" << std::endl; + exit(776654); +} diff --git a/src/ASM/LR/ASMu3D.h b/src/ASM/LR/ASMu3D.h index 5c24b6ac..4b84fa1d 100644 --- a/src/ASM/LR/ASMu3D.h +++ b/src/ASM/LR/ASMu3D.h @@ -92,6 +92,12 @@ public: //! \param glbNodes Array of global boundary node numbers virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis) const; + //! \brief Returns the node index for a given corner. + virtual int getCorner(int I, int J, int K, int basis = 1) const; + + //! \brief Returns the node indices for a given edge. + virtual std::vector getEdge(int lEdge, bool open, int basis = 1) const; + //! \brief Returns the polynomial order in each parameter direction. //! \param[out] p1 Order in first (u) direction //! \param[out] p2 Order in second (v) direction