-
Elias Pipping authoredElias Pipping authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
test-gradient-sample.cc 2.00 KiB
/* Checks if the descent direction is computed correctly using the
analytic solution; also checks if the algorithm converges
regardless of where it starts */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <cassert>
#include <dune/common/shared_ptr.hh>
#include <dune/tectonic/ellipticenergy.hh>
#include "test-gradient-method-nicefunction.hh"
#include "test-gradient-method-helper.hh"
int main() {
int const dim = 2;
typedef Dune::EllipticEnergy<dim> Functional;
typedef Functional::SmallMatrix SmallMatrix;
typedef Functional::SmallVector SmallVector;
SmallMatrix const A = { { 3, 1.5 }, { 1.5, 4 } };
SmallVector const b = { 1, 2 };
auto const f = Dune::make_shared<Dune::SampleFunction<2> const>();
auto const phi = Dune::make_shared<Functional::NonlinearityType const>(f);
Functional const J(A, b, phi);
/*
j(x)
= Ax - b + 2/|x| x
= 17*(6, 9.5) - (1, 2) + 2/sqrt(5) (1, 2)
= (102 - 1 + 2/sqrt(5), 161.5 - 2 + 4/sqrt(5))
*/
SmallVector analytic_descent = { -(102 - 1 + 2 / std::sqrt(5)),
-(161.5 - 2 + 4 / std::sqrt(5)) };
SmallVector numerical_descent;
J.descentDirection(SmallVector({ 17, 34 }), numerical_descent);
assert(two_distance<dim>(analytic_descent, numerical_descent) < 1e-10);
double ret1;
{
SmallVector start = { 17, 34 };
ret1 = functionTester(J, start, 8);
SmallVector minimum;
functionTester2(J, minimum, 8);
assert(two_distance<dim>(start, minimum) < 1e-5);
}
double ret2;
{
// Something random
SmallVector start = { 279, -96 };
ret2 = functionTester(J, start, 10);
SmallVector minimum;
functionTester2(J, minimum, 10);
assert(two_distance<dim>(start, minimum) < 1e-5);
}
assert(std::abs(ret1 - ret2) < 1e-5);
double ret3;
{
SmallVector start = { 0, 0 };
ret3 = functionTester(J, start, 3);
SmallVector minimum;
functionTester2(J, minimum, 3);
assert(two_distance<dim>(start, minimum) < 1e-5);
}
assert(std::abs(ret1 - ret3) < 1e-5);
}