Am Montag, 13. Mai 2022, finden Wartungsarbeiten am Gitlab-Server (Update auf neue Version statt). Der Dienst wird daher am Montag für einige Zeit nicht verfügbar sein.
On Monday, May 13th 2022, the Gitlab server will be updated. The service will therefore not be accessible for some time on Monday.

GradientTest.cpp 2.93 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:

#include <iostream>

#include <amdis/AMDiS.hpp>
#include <amdis/LinearAlgebra.hpp>
#include <amdis/GridFunctions.hpp>
#include <amdis/Integrate.hpp>

#include "Tests.hpp"

using namespace AMDiS;

template <std::size_t p>
void test()
{
  using Grid = Dune::YaspGrid<2>;
  using Basis1 = LagrangeBasis<Grid,p,p>;

  Grid grid({1.0, 1.0}, {16,16});
  auto gridView = grid.leafGridView();
  auto basis = Basis1::create(gridView);

  auto uVector = makeDOFVector(basis);

  auto u = makeDOFVectorView(uVector);
  auto u_0 = makeDOFVectorView(uVector, 0);
  auto u_1 = makeDOFVectorView(uVector, 1);

  // eval a functor at global coordinates (at quadrature points)
  u_0 << evalAtQP([](auto const& x) { return x[0] + x[1]; });
  u_1 << evalAtQP([](auto const& x) { return -2*x[0] + 3*x[1]; });

  // test gradient
  AMDIS_TEST_APPROX((std::sqrt(integrate(unary_dot(gradientAtQP(u_0)), gridView))), std::sqrt(2.0));
  AMDIS_TEST_APPROX((std::sqrt(integrate(unary_dot(gradientAtQP(u_1)), gridView))), std::sqrt(13.0));

  // test divergence
  AMDIS_TEST_APPROX((integrate(divergenceAtQP(u), gridView)), 4.0);

  // test partial derivative
  double d0u_0 = integrate(partialAtQP(u_0,0), gridView);
  double d1u_1 = integrate(partialAtQP(u_1,1), gridView);
  AMDIS_TEST_APPROX(d0u_0, 1.0);
  AMDIS_TEST_APPROX(d1u_1, 3.0);

  auto gf_d0u_0 = makeGridFunction(partialAtQP(u_0,0), gridView);
  auto lf_d0u_0 = localFunction(gf_d0u_0);
  for (auto const& e : elements(gridView)) {
    lf_d0u_0.bind(e);
    double v = lf_d0u_0(e.geometry().center());
    AMDIS_TEST_APPROX(v, 1.0);
    lf_d0u_0.unbind();
  }

  u_0 << evalAtQP([](auto const& x) { return std::sin(x[0]) + std::cos(x[1]); });
  u_1 << evalAtQP([](auto const& x) { return -std::sin(x[0]) * std::cos(x[1]); });

  AMDIS_TEST_APPROX((integrate(divergenceAtQP(u), gridView)), (integrate(partialAtQP(u_0,0) + partialAtQP(u_1,1), gridView)));

  auto vVector(uVector);
  auto v = makeDOFVectorView(vVector);
  auto v_0 = makeDOFVectorView(vVector, 0);
  auto v_1 = makeDOFVectorView(vVector, 1);

  // test gradient
  v << evalAtQP([](auto const& x) { return Dune::FieldVector<double,2>{std::cos(x[0]), -std::sin(x[1])}; });
  AMDIS_TEST((std::sqrt(integrate(unary_dot(v - gradientAtQP(u_0)), gridView))) < 0.05);

  // test divergence
  v_0 << evalAtQP([](auto const& x) { return std::cos(x[0]) + std::sin(x[0])*std::sin(x[1]); });
  AMDIS_TEST((integrate(v_0 - divergenceAtQP(u), gridView)) < 0.05);

  // test partial derivative
  v_0 << evalAtQP([](auto const& x) { return std::cos(x[0]); });
  v_1 << evalAtQP([](auto const& x) { return std::sin(x[0])*std::sin(x[1]); });
  AMDIS_TEST((integrate(v_0 - partialAtQP(u_0,0), gridView)) < 0.05);
  AMDIS_TEST((integrate(v_1 - partialAtQP(u_1,1), gridView)) < 0.05);
}

int main(int argc, char** argv)
{
  Environment env(argc, argv);

  test<1u>();
  test<2u>();
  test<3u>();

  return report_errors();
}