fixed: open edge constraints in ASMu2D
the assumption of the corners being the first / last node in the list was wrong.
This commit is contained in:
parent
6476c3380e
commit
c0b02fba77
@ -616,14 +616,33 @@ std::vector<int> ASMu2D::getEdgeNodes (int edge, int basis) const
|
|||||||
void ASMu2D::constrainEdge (int dir, bool open, int dof, int code, char basis)
|
void ASMu2D::constrainEdge (int dir, bool open, int dof, int code, char basis)
|
||||||
{
|
{
|
||||||
LR::parameterEdge edge;
|
LR::parameterEdge edge;
|
||||||
|
int c1, c2;
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case -2: edge = LR::SOUTH; break;
|
case -2:
|
||||||
case -1: edge = LR::WEST; break;
|
edge = LR::SOUTH;
|
||||||
case 1: edge = LR::EAST; break;
|
c1 = this->getCorner(-1, -1, basis);
|
||||||
case 2: edge = LR::NORTH; break;
|
c2 = this->getCorner( 1, -1, basis);
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
edge = LR::WEST;
|
||||||
|
c1 = this->getCorner(-1, -1, basis);
|
||||||
|
c2 = this->getCorner(-1, 1, basis);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
edge = LR::EAST;
|
||||||
|
c1 = this->getCorner( 1, -1, basis);
|
||||||
|
c2 = this->getCorner( 1, 1, basis);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
edge = LR::NORTH;
|
||||||
|
c1 = this->getCorner(-1, 1, basis);
|
||||||
|
c2 = this->getCorner( 1, 1, basis);
|
||||||
|
break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
std::vector<int> nodes = this->getEdgeNodes(edge,basis);
|
std::vector<int> nodes = this->getEdgeNodes(edge,basis);
|
||||||
|
nodes.erase(std::find(nodes.begin(), nodes.end(), c1));
|
||||||
|
nodes.erase(std::find(nodes.begin(), nodes.end(), c2));
|
||||||
|
|
||||||
int bcode = code;
|
int bcode = code;
|
||||||
if (code > 0) {
|
if (code > 0) {
|
||||||
@ -634,18 +653,15 @@ void ASMu2D::constrainEdge (int dir, bool open, int dof, int code, char basis)
|
|||||||
bcode = -code;
|
bcode = -code;
|
||||||
|
|
||||||
// Skip the first and last function if we are requesting an open boundary.
|
// Skip the first and last function if we are requesting an open boundary.
|
||||||
// I here assume the edgeFunctions are ordered such that the physical
|
|
||||||
// end points are represented by the first and last edgeFunction.
|
|
||||||
if (!open)
|
if (!open)
|
||||||
this->prescribe(nodes.front(),dof,bcode);
|
this->prescribe(c1,dof,bcode);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nodes.size(); i++)
|
||||||
for (size_t i = 1; i < nodes.size()-1; i++)
|
|
||||||
if (this->prescribe(nodes[i],dof,-code) == 0 && code > 0)
|
if (this->prescribe(nodes[i],dof,-code) == 0 && code > 0)
|
||||||
dirich.back().nodes.push_back(std::make_pair(i,nodes[i]));
|
dirich.back().nodes.push_back(std::make_pair(i,nodes[i]));
|
||||||
|
|
||||||
if (!open)
|
if (!open)
|
||||||
this->prescribe(nodes.back(),dof,bcode);
|
this->prescribe(c2,dof,bcode);
|
||||||
|
|
||||||
if (code > 0)
|
if (code > 0)
|
||||||
if (dirich.back().nodes.empty())
|
if (dirich.back().nodes.empty())
|
||||||
|
@ -16,6 +16,21 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct EdgeTest {
|
||||||
|
int edge;
|
||||||
|
int edgeIdx;
|
||||||
|
std::array<int,2> c1;
|
||||||
|
std::array<int,2> c2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TestASMu2D : public testing::Test,
|
||||||
|
public testing::WithParamInterface<EdgeTest>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
TEST(TestASMu2D, BoundaryNodesE1)
|
TEST(TestASMu2D, BoundaryNodesE1)
|
||||||
{
|
{
|
||||||
SIM2D sim(1);
|
SIM2D sim(1);
|
||||||
@ -78,3 +93,49 @@ TEST(TestASMu2D, BoundaryNodesE4)
|
|||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
ASSERT_EQ(vec[i], 5+i);
|
ASSERT_EQ(vec[i], 5+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_P(TestASMu2D, ConstrainEdge)
|
||||||
|
{
|
||||||
|
SIM2D sim(1);
|
||||||
|
sim.opt.discretization = ASM::LRSpline;
|
||||||
|
ASSERT_TRUE(sim.read("src/ASM/LR/Test/refdata/boundary_nodes.xinp"));
|
||||||
|
ASMu2D* pch = static_cast<ASMu2D*>(sim.getPatch(1));
|
||||||
|
pch->constrainEdge(GetParam().edgeIdx, false, 1, 1, 1);
|
||||||
|
std::vector<int> glbNodes;
|
||||||
|
pch->getBoundaryNodes(GetParam().edge, glbNodes, 1);
|
||||||
|
for (auto& it : glbNodes)
|
||||||
|
ASSERT_TRUE(pch->findMPC(it, 1) != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_P(TestASMu2D, ConstrainEdgeOpen)
|
||||||
|
{
|
||||||
|
SIM2D sim(1);
|
||||||
|
sim.opt.discretization = ASM::LRSpline;
|
||||||
|
ASSERT_TRUE(sim.read("src/ASM/LR/Test/refdata/boundary_nodes.xinp"));
|
||||||
|
ASMu2D* pch = static_cast<ASMu2D*>(sim.getPatch(1));
|
||||||
|
pch->constrainEdge(GetParam().edgeIdx, true, 1, 1, 1);
|
||||||
|
std::vector<int> glbNodes;
|
||||||
|
pch->getBoundaryNodes(GetParam().edge, glbNodes, 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));
|
||||||
|
crn = pch->getCorner(GetParam().c2[0], GetParam().c2[1], 1);
|
||||||
|
ASSERT_TRUE(pch->findMPC(crn, 1) == nullptr);
|
||||||
|
glbNodes.erase(std::find(glbNodes.begin(), glbNodes.end(), crn));
|
||||||
|
for (auto& it : glbNodes)
|
||||||
|
ASSERT_TRUE(pch->findMPC(it, 1) != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const std::vector<EdgeTest> edgeTestData =
|
||||||
|
{{1, -1, {-1, -1}, {-1 , 1}},
|
||||||
|
{2, 1, { 1, -1}, { 1 , 1}},
|
||||||
|
{3, -2, {-1, -1}, { 1, -1}},
|
||||||
|
{4, 2, {-1, 1}, { 1, 1}}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(TestASMu2D, TestASMu2D,
|
||||||
|
testing::ValuesIn(edgeTestData));
|
||||||
|
Loading…
Reference in New Issue
Block a user