Skip to content
Snippets Groups Projects
Commit ce730867 authored by Elias Pipping's avatar Elias Pipping
Browse files

Tests: Use proper obstacles for ::ProjectedBlockGSStep

parent 89723e23
Branches
No related tags found
No related merge requests found
Pipeline #
...@@ -46,7 +46,7 @@ struct GSTestSuite { ...@@ -46,7 +46,7 @@ struct GSTestSuite {
std::vector<BoxConstraint<double, BlockSize>> obstacles(size); std::vector<BoxConstraint<double, BlockSize>> obstacles(size);
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
for (size_t j = 0; j < BlockSize; ++j) for (size_t j = 0; j < BlockSize; ++j)
obstacles[i][j] = { -1, +1 }; obstacles[i][j] = { p.u_ex[i][j] + 2.0, p.u_ex[i][j] + 3.0 };
using LoopSolver = ::LoopSolver<Vector>; using LoopSolver = ::LoopSolver<Vector>;
using Step = LinearIterationStep<Matrix, Vector>; using Step = LinearIterationStep<Matrix, Vector>;
...@@ -182,6 +182,8 @@ struct GSTestSuite { ...@@ -182,6 +182,8 @@ struct GSTestSuite {
// test projected block GS // test projected block GS
if (trivialDirichletOnly) // TODO: missing feature in ProjectedBlockGS if (trivialDirichletOnly) // TODO: missing feature in ProjectedBlockGS
{ {
// Test 1: Without obstacles, we should get the same solution as with an
// unconstrained solver
size_t size = p.u.size(); size_t size = p.u.size();
using GSStep = ProjectedBlockGSStep<Matrix, Vector>; using GSStep = ProjectedBlockGSStep<Matrix, Vector>;
typename GSStep::HasObstacle hasObstacle(size, false); typename GSStep::HasObstacle hasObstacle(size, false);
...@@ -191,11 +193,50 @@ struct GSTestSuite { ...@@ -191,11 +193,50 @@ struct GSTestSuite {
test(&gsStep, "ProjectedBlockGS free"); test(&gsStep, "ProjectedBlockGS free");
} }
hasObstacle.setAll(); hasObstacle.setAll();
// Test2: Different initial iterates should lead to the same solution,
// which should, furthermore, not intersect the obstacles
{ {
ProjectedBlockGSStep<Matrix, Vector> gsStep; ProjectedBlockGSStep<Matrix, Vector> pGSStep1;
gsStep.hasObstacle_ = &hasObstacle; pGSStep1.hasObstacle_ = &hasObstacle;
gsStep.obstacles_ = &obstacles; pGSStep1.obstacles_ = &obstacles;
test(&gsStep, "ProjectedBlockGS obstacle"); ProjectedBlockGSStep<Matrix, Vector> pGSStep2;
pGSStep2.hasObstacle_ = &hasObstacle;
pGSStep2.obstacles_ = &obstacles;
Vector u_copy1 = p.u;
for (size_t i = 0; i < p.u.size(); ++i)
for (size_t j = 0; j < blocksize; ++j)
if (p.ignore[i][j])
u_copy1[i][j] += 2.25;
Vector u_copy2 = p.u;
for (size_t i = 0; i < p.u.size(); ++i)
for (size_t j = 0; j < blocksize; ++j)
if (p.ignore[i][j])
u_copy2[i][j] += 2.75;
auto result1 = solve(&pGSStep1, u_copy1, 1e-12, 2000);
auto result2 = solve(&pGSStep2, u_copy2, 1e-12, 2000);
for (size_t i = 0; i < p.u.size(); ++i)
for (size_t j = 0; j < blocksize; ++j)
if (std::abs(result1[i][j] -
obstacles[i][j].projectIn(result1[i][j])) > 1e-12 or
std::abs(result2[i][j] -
obstacles[i][j].projectIn(result2[i][j])) > 1e-12) {
std::cerr << "### error: obstacles not respected!" << std::endl;
passed = false;
break;
}
auto normDiff = p.energyNorm.diff(result1, result2);
// We cannot expect too much here (hence the low tolerance):
// We are solving a potentially large system using nothing but
// a smoother. Convergence will be very slow.
if (normDiff > 1e-6) {
std::cerr << "### error: Different initial iterates lead to "
"different solutions! (diff = "
<< normDiff << ")" << std::endl;
passed = false;
}
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment