Skip to content

Commit 9986b16

Browse files
committed
Merge pull request #142 from memmett/feature/rel_residual
Compute relative residuals as well as absolute residuals.
2 parents 06fa723 + 586c356 commit 9986b16

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

examples/advection_diffusion/vanilla_sdc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace pfasst
2323
{
2424
namespace advection_diffusion
2525
{
26-
error_map run_vanilla_sdc(double abs_residual_tol)
26+
error_map run_vanilla_sdc(double abs_residual_tol, double rel_residual_tol=0.0)
2727
{
2828
SDC<> sdc;
2929

@@ -38,7 +38,7 @@ namespace pfasst
3838

3939
sweeper->set_quadrature(quad);
4040
sweeper->set_factory(factory);
41-
sweeper->set_residual_tolerances(abs_residual_tol, 0.0);
41+
sweeper->set_residual_tolerances(abs_residual_tol, rel_residual_tol);
4242

4343
sdc.add_level(sweeper);
4444
sdc.set_duration(0.0, 4*0.01, 0.01, 4);

include/pfasst/encap/encap_sweeper.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -250,21 +250,21 @@ namespace pfasst
250250
{
251251
if (this->abs_residual_tol > 0.0 || this->rel_residual_tol > 0.0) {
252252
if (this->residuals.size() == 0) {
253-
for (auto x: this->get_nodes()) {
254-
UNUSED(x);
253+
for (size_t m = 0; m < this->get_nodes().size(); m++) {
255254
this->residuals.push_back(this->get_factory()->create(pfasst::encap::solution));
256255
}
257256
}
258257
this->residual(this->get_controller()->get_time_step(), this->residuals);
259-
vector<time> rnorms;
260-
for (auto r: this->residuals) {
261-
rnorms.push_back(r->norm0());
258+
vector<time> anorms, rnorms;
259+
for (size_t m = 0; m < this->get_nodes().size(); m++) {
260+
anorms.push_back(this->residuals[m]->norm0());
261+
rnorms.push_back(anorms.back() / this->get_state(m)->norm0());
262262
}
263+
auto amax = *std::max_element(anorms.begin(), anorms.end());
263264
auto rmax = *std::max_element(rnorms.begin(), rnorms.end());
264-
if (rmax < this->abs_residual_tol) {
265+
if (amax < this->abs_residual_tol || rmax < this->rel_residual_tol) {
265266
return true;
266267
}
267-
// XXX: check rel norms too
268268
}
269269
return false;
270270
}

tests/examples/advection_diffusion/test_advection_diffusion.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,29 @@ TEST(AdaptiveErrorTest, VanillaSDC)
7474
ASSERT_EQ(max_iter, (size_t) 2);
7575
}
7676

77+
TEST(RelativeAdaptiveErrorTest, VanillaSDC)
78+
{
79+
typedef error_map::value_type vtype;
80+
81+
auto get_iter = [](const vtype x) { return get<1>(get<0>(x)); };
82+
auto get_error = [](const vtype x) { return get<1>(x); };
83+
84+
auto errors = run_vanilla_sdc(0.0, 1.e-6);
85+
auto max_iter = get_iter(*std::max_element(errors.begin(), errors.end(),
86+
[get_iter](const vtype p1, const vtype p2) { return get_iter(p1) < get_iter(p2); }));
87+
88+
vector<double> tol = { 5e-8, 5e-8, 5e-8, 5e-8 };
89+
vector<double> err;
90+
for (auto& x: errors) {
91+
if (get_iter(x) == max_iter) {
92+
err.push_back(get_error(x));
93+
}
94+
}
95+
96+
EXPECT_THAT(err, testing::Pointwise(DoubleLess(), tol));
97+
ASSERT_EQ(max_iter, (size_t) 2);
98+
}
99+
77100
TEST(ErrorTest, SerialMLSDC)
78101
{
79102
typedef error_map::value_type vtype;

0 commit comments

Comments
 (0)