added: option to return local node numbers in getBoundaryNodes

This commit is contained in:
Arne Morten Kvarving 2017-01-03 07:49:50 +01:00 committed by timovanopstal
parent a4fcd0d594
commit 38858395b0
17 changed files with 99 additions and 156 deletions

View File

@ -206,12 +206,12 @@ public:
//! in one element
virtual bool getElementCoordinates(Matrix& X, int iel) const = 0;
//! \brief Finds the global numbers of the nodes on a patch boundary.
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
//! \param[in] lIndex Local index of the boundary face/edge
//! \param glbNodes Array of global boundary node numbers
//! \param nodes Array of node numbers
//! \param basis Which basis to grab nodes for (0 for all)
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes,
int basis = 0) const = 0;
virtual void getBoundaryNodes(int lIndex, IntVec& nodes,
int basis = 0, bool local = false) const = 0;
//! \brief Finds the node that is closest to the given point.
virtual std::pair<size_t,double> findClosestNode(const Vec3&) const

View File

@ -584,17 +584,20 @@ bool ASMs1D::updateRotations (const Vector& displ, bool reInit)
}
void ASMs1D::getBoundaryNodes (int lIndex, IntVec& glbNodes, int) const
void ASMs1D::getBoundaryNodes (int lIndex, IntVec& nodes,
int, bool local) const
{
if (!curv) return; // silently ignore empty patches
size_t iel = lIndex == 1 ? 0 : nel-1;
if (MLGE[iel] > 0)
{
int node;
if (lIndex == 1)
glbNodes.push_back(MLGN[MNPC[iel].front()]);
node = MNPC[iel].front();
else if (lIndex == 2)
glbNodes.push_back(MLGN[MNPC[iel][curv->order()-1]]);
node = MNPC[iel][curv->order()-1];
nodes.push_back(local ? node+1 : MLGN[node]);
}
}

View File

@ -105,10 +105,12 @@ public:
//! \brief Updates the previous nodal rotations for this patch at convergence.
void updateRotations() { prevT = myT; }
//! \brief Finds the global number of the node on a patch end.
//! \brief Finds the global (or patch-local) node number on a patch end.
//! \param[in] lIndex Local index of the end point
//! \param glbNodes Array of global boundary node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int) const;
//! \param nodes Array of global boundary node numbers
//! \param local If \e true, return patch-local node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& nodes,
int, bool local) const;
//! \brief Finds the node that is closest to the given point.
//! \param[in] X Global coordinates of point to search for

View File

@ -1292,7 +1292,7 @@ bool ASMs2D::updateCoords (const Vector& displ)
}
void ASMs2D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
void ASMs2D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis, bool local) const
{
if (basis == 0)
basis = 1;
@ -1316,14 +1316,14 @@ void ASMs2D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
node += n1-1;
case 1: // Left edge (negative I-direction)
for (int i2 = 1; i2 <= n2; i2++, node += n1)
nodes.push_back(getNodeID(node));
nodes.push_back(local ? node : this->getNodeID(node));
break;
case 4: // Back edge (positive J-direction)
node += n1*(n2-1);
case 3: // Front edge (negative J-direction)
for (int i1 = 1; i1 <= n1; i1++, node++)
nodes.push_back(getNodeID(node));
nodes.push_back(local ? node : this->getNodeID(node));
break;
}

View File

@ -179,11 +179,13 @@ public:
//! \param[in] displ Incremental displacements to update the coordinates with
virtual bool updateCoords(const Vector& displ);
//! \brief Finds the global numbers of the nodes on a patch boundary.
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
//! \param[in] lIndex Local index of the boundary edge
//! \param glbNodes Array of global boundary node numbers
//! \param basis Which basis to grab nodes for
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis) const;
//! \param nodes Array of node numbers
//! \param basis Which basis to grab nodes for (0 for all)
//! \param local If \e true, return patch-local node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& nodes,
int basis, bool local) const;
//! \brief Returns the node index for a given corner.
virtual int getCorner(int I, int J, int basis = 1) const;

View File

@ -1014,11 +1014,12 @@ void ASMs2Dmx::generateThreadGroups (const Integrand& integrand, bool silence,
}
void ASMs2Dmx::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
void ASMs2Dmx::getBoundaryNodes (int lIndex, IntVec& nodes,
int basis, bool local) const
{
if (basis > 0)
this->ASMs2D::getBoundaryNodes(lIndex, nodes, basis);
this->ASMs2D::getBoundaryNodes(lIndex, nodes, basis, local);
else
for (size_t b = 1; b <= this->getNoBasis(); ++b)
this->ASMs2D::getBoundaryNodes(lIndex, nodes, b);
this->ASMs2D::getBoundaryNodes(lIndex, nodes, b, local);
}

View File

@ -208,11 +208,12 @@ public:
//! \param[in] basis Which basis to return size parameters for
virtual bool getSize(int& n1, int& n2, int basis = 0) const;
//! \brief Finds the global numbers of the nodes on a patch boundary.
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
//! \param[in] lIndex Local index of the boundary edge
//! \param glbNodes Array of global boundary node numbers
//! \param nodes Array of node numbers
//! \param basis Which basis to grab nodes for (0 for all)
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis) const;
virtual void getBoundaryNodes(int lIndex, IntVec& nodes,
int basis, bool local = false) const;
protected:
std::vector<std::shared_ptr<Go::SplineSurface>> m_basis; //!< Vector of bases

View File

@ -1542,7 +1542,8 @@ bool ASMs3D::updateCoords (const Vector& displ)
}
void ASMs3D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
void ASMs3D::getBoundaryNodes (int lIndex, IntVec& nodes,
int basis, bool local) const
{
if (basis == 0)
basis = 1;
@ -1562,7 +1563,7 @@ void ASMs3D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
case 1: // Left face (negative I-direction)
for (int i3 = 1; i3 <= n3; i3++)
for (int i2 = 1; i2 <= n2; i2++, node += n1)
nodes.push_back(getNodeID(node));
nodes.push_back(local ? node : this->getNodeID(node));
break;
case 4: // Back face (positive J-direction)
@ -1570,7 +1571,7 @@ void ASMs3D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
case 3: // Front face (negative J-direction)
for (int i3 = 1; i3 <= n3; i3++, node += n1*(n2-1))
for (int i1 = 1; i1 <= n1; i1++, node++)
nodes.push_back(getNodeID(node));
nodes.push_back(local ? node : this->getNodeID(node));
break;
case 6: // Top face (positive K-direction)
@ -1578,7 +1579,7 @@ void ASMs3D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
case 5: // Bottom face (negative K-direction)
for (int i2 = 1; i2 <= n2; i2++)
for (int i1 = 1; i1 <= n1; i1++, node++)
nodes.push_back(getNodeID(node));
nodes.push_back(local ? node : this->getNodeID(node));
break;
}

View File

@ -195,11 +195,13 @@ public:
//! \param[in] displ Incremental displacements to update the coordinates with
virtual bool updateCoords(const Vector& displ);
//! \brief Finds the global numbers of the nodes on a patch boundary.
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
//! \param[in] lIndex Local index of the boundary face
//! \param glbNodes Array of global boundary node numbers
//! \param nodes Array of node numbers
//! \param basis Which basis to grab nodes for (0 for all)
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis) const;
//! \param local If \e true, return patch-local node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis,
bool local) const;
//! \brief Returns the node index for a given corner.
virtual int getCorner(int I, int J, int K, int basis = 1) const;

View File

@ -1109,11 +1109,12 @@ double ASMs3Dmx::getParametricArea (int iel, int dir) const
}
void ASMs3Dmx::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
void ASMs3Dmx::getBoundaryNodes (int lIndex, IntVec& nodes,
int basis, bool local) const
{
if (basis > 0)
this->ASMs3D::getBoundaryNodes(lIndex, nodes, basis);
this->ASMs3D::getBoundaryNodes(lIndex, nodes, basis, local);
else
for (size_t b = 1; b <= this->getNoBasis(); ++b)
this->ASMs3D::getBoundaryNodes(lIndex, nodes, b);
this->ASMs3D::getBoundaryNodes(lIndex, nodes, b, local);
}

View File

@ -214,11 +214,13 @@ protected:
//! \param[in] dir Local face index of the boundary face
double getParametricArea(int iel, int dir) const;
//! \brief Finds the global numbers of the nodes on a patch boundary.
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
//! \param[in] lIndex Local index of the boundary edge
//! \param glbNodes Array of global boundary node numbers
//! \param nodes Array of global boundary node numbers
//! \param basis Which basis to grab nodes for (0 for all)
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis = 0) const;
//! \param local If \e true, return patch-local node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& nodes,
int basis, bool local) const;
private:
std::vector<std::shared_ptr<Go::SplineVolume>> m_basis; //!< Vector of bases

View File

@ -1812,7 +1812,8 @@ bool ASMu2D::evalSolution (Matrix& sField, const IntegrandBase& integrand,
}
void ASMu2D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
void ASMu2D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis,
bool local) const
{
if (basis == 0)
basis = 1;

View File

@ -91,10 +91,12 @@ public:
//! \param[in] displ Incremental displacements to update the coordinates with
virtual bool updateCoords(const Vector& displ);
//! \brief Finds the global numbers of the nodes on a patch boundary.
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
//! \param[in] lIndex Local index of the boundary edge
//! \param glbNodes Array of global boundary node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis) const;
//! \param nodes Array of node numbers
//! \param local If true return patch-local node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& nodes,
int basis, bool local = false) const;
//! \brief Returns the polynomial order in each parameter direction.
//! \param[out] p1 Order in first (u) direction

View File

@ -1966,7 +1966,7 @@ std::vector<int> ASMu3D::getFaceNodes (int face, int basis) const
}
void ASMu3D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis) const
void ASMu3D::getBoundaryNodes (int lIndex, IntVec& nodes, int basis, bool) const
{
if (basis == 0)
basis = 1;

View File

@ -87,10 +87,12 @@ public:
//! \brief Returns the node indices for a given face.
std::vector<int> getFaceNodes(int face, int basis = 1) const;
//! \brief Finds the global numbers of the nodes on a patch boundary.
//! \brief Finds the global (or patch-local) node numbers on a patch boundary.
//! \param[in] lIndex Local index of the boundary edge
//! \param glbNodes Array of global boundary node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& glbNodes, int basis) const;
//! \param nodes Array of global boundary node numbers
//! \param local If \e true return patch-local node numbers
virtual void getBoundaryNodes(int lIndex, IntVec& nodes,
int basis, bool local) const;
//! \brief Returns the node index for a given corner.
virtual int getCorner(int I, int J, int K, int basis = 1) const;

View File

@ -31,16 +31,6 @@ class TestASMu2D : public testing::Test,
};
static void getBoundaryNodes (const char* edgeName, std::vector<int>& nodes)
{
SIM2D sim(1);
sim.opt.discretization = ASM::LRSpline;
ASSERT_TRUE(sim.read("src/ASM/LR/Test/refdata/boundary_nodes.xinp"));
ASSERT_TRUE(sim.createFEMmodel());
sim.getBoundaryNodes(sim.getUniquePropertyCode(edgeName,0),nodes);
}
static ASMu2D* getPatch (SIMinput& sim)
{
sim.opt.discretization = ASM::LRSpline;
@ -50,46 +40,6 @@ static ASMu2D* getPatch (SIMinput& sim)
}
TEST(TestASMu2D, BoundaryNodesE1)
{
std::vector<int> vec;
getBoundaryNodes("Edge1",vec);
ASSERT_EQ(vec.size(), 4U);
for (int i = 0; i < 4; ++i)
ASSERT_EQ(vec[i], 4*i+1);
}
TEST(TestASMu2D, BoundaryNodesE2)
{
std::vector<int> vec;
getBoundaryNodes("Edge2",vec);
ASSERT_EQ(vec.size(), 4U);
for (int i = 0; i < 4; ++i)
ASSERT_EQ(vec[i], 2+4*i);
}
TEST(TestASMu2D, BoundaryNodesE3)
{
std::vector<int> vec;
getBoundaryNodes("Edge3",vec);
ASSERT_EQ(vec.size(), 4U);
for (int i = 0; i < 4; ++i)
ASSERT_EQ(vec[i], i+1);
}
TEST(TestASMu2D, BoundaryNodesE4)
{
std::vector<int> vec;
getBoundaryNodes("Edge4",vec);
ASSERT_EQ(vec.size(), 4U);
for (int i = 0; i < 4; ++i)
ASSERT_EQ(vec[i], 5+i);
}
TEST_P(TestASMu2D, ConstrainEdge)
{
SIM2D sim(1);
@ -97,7 +47,7 @@ TEST_P(TestASMu2D, ConstrainEdge)
ASSERT_TRUE(pch != nullptr);
pch->constrainEdge(GetParam().edgeIdx, false, 1, 1, 1);
std::vector<int> glbNodes;
pch->getBoundaryNodes(GetParam().edge, glbNodes, 1);
pch->getBoundaryNodes(GetParam().edge, glbNodes, 1, 1);
for (int& it : glbNodes)
ASSERT_TRUE(pch->findMPC(it, 1) != nullptr);
}
@ -110,7 +60,7 @@ TEST_P(TestASMu2D, ConstrainEdgeOpen)
ASSERT_TRUE(pch != nullptr);
pch->constrainEdge(GetParam().edgeIdx, true, 1, 1, 1);
std::vector<int> glbNodes;
pch->getBoundaryNodes(GetParam().edge, glbNodes, 1);
pch->getBoundaryNodes(GetParam().edge, glbNodes, 1, 1);
int crn = pch->getCorner(GetParam().c1[0], GetParam().c1[1], 1);
ASSERT_TRUE(pch->findMPC(crn, 1) == nullptr);
glbNodes.erase(std::find(glbNodes.begin(), glbNodes.end(), crn));

View File

@ -15,74 +15,47 @@
#include "gtest/gtest.h"
class TestASMu3D :
public testing::Test,
public testing::WithParamInterface<int>
{
};
static void getBoundaryNodes (const char* faceName, std::vector<int>& nodes)
TEST_P(TestASMu3D, BoundaryNodes)
{
SIM3D sim(1);
sim.opt.discretization = ASM::LRSpline;
ASSERT_TRUE(sim.read("src/ASM/LR/Test/refdata/boundary_nodes_3d.xinp"));
ASSERT_TRUE(sim.createFEMmodel());
sim.getBoundaryNodes(sim.getUniquePropertyCode(faceName,0),nodes);
}
sim.preprocess();
TEST(TestASMu3D, BoundaryNodesF1)
{
std::stringstream str;
str << "Face" << GetParam();
int bcode = sim.getUniquePropertyCode(str.str(),0);
std::vector<int> vec;
getBoundaryNodes("Face1",vec);
sim.getBoundaryNodes(bcode,vec);
ASSERT_EQ(vec.size(), 16U);
for (int i = 0; i < 16; ++i)
ASSERT_EQ(vec[i], 1+4*i);
auto it = vec.begin();
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
if (GetParam() == 1)
ASSERT_EQ(*it++, 1+4*(4*i+j));
else if (GetParam() == 2)
ASSERT_EQ(*it++, 2+4*(4*i+j));
else if (GetParam() == 3)
ASSERT_EQ(*it++, 16*i+j+1);
else if (GetParam() == 4)
ASSERT_EQ(*it++, 5+16*i+j);
else if (GetParam() == 5)
ASSERT_EQ(*it++, 4*i+j+1);
else if (GetParam() == 6)
ASSERT_EQ(*it++, 17+4*i+j);
}
}
}
TEST(TestASMu3D, BoundaryNodesF2)
{
std::vector<int> vec;
getBoundaryNodes("Face2",vec);
ASSERT_EQ(vec.size(), 16U);
for (int i = 0; i < 16; ++i)
ASSERT_EQ(vec[i], 2+4*i);
}
TEST(TestASMu3D, BoundaryNodesF3)
{
std::vector<int> vec;
getBoundaryNodes("Face3",vec);
ASSERT_EQ(vec.size(), 16U);
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
ASSERT_EQ(vec[4*i+j], 16*i+j+1);
}
TEST(TestASMu3D, BoundaryNodesF4)
{
std::vector<int> vec;
getBoundaryNodes("Face4",vec);
ASSERT_EQ(vec.size(), 16U);
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
ASSERT_EQ(vec[4*i+j], 5+16*i+j);
}
TEST(TestASMu3D, BoundaryNodesF5)
{
std::vector<int> vec;
getBoundaryNodes("Face5",vec);
ASSERT_EQ(vec.size(), 16U);
for (int i = 0; i < 16; ++i)
ASSERT_EQ(vec[i], i+1);
}
TEST(TestASMu3D, BoundaryNodesF6)
{
std::vector<int> vec;
getBoundaryNodes("Face6",vec);
ASSERT_EQ(vec.size(), 16U);
for (int i = 0; i < 16; ++i)
ASSERT_EQ(vec[i], 17+i);
}
const std::vector<int> tests = {1,2,3,4,5,6};
INSTANTIATE_TEST_CASE_P(TestASMu3D,
TestASMu3D,
testing::ValuesIn(tests));