// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- // vi: set et ts=4 sw=2 sts=2: #include #include #include #include #include #include #include "Tests.hpp" using namespace AMDiS; using ElliptParam = YaspGridBasis<2, 2, 2>; using ElliptProblem = ProblemStat; template bool comp(DOFVector const& U, DOFVector const& V) { if (U.localSize() != V.localSize() || U.globalSize() != V.globalSize()) return false; using size_type = typename DOFVector::GlobalBasis::LocalView::size_type; auto const& basis = U.basis(); if (basis.get() != V.basis().get()) return false; auto lv = basis->localView(); auto const& gv = basis->gridView(); for (auto const& e : elements(gv)) { lv.bind(e); for (size_type i = 0; i < lv.size(); ++i) { auto multiIndex = lv.index(i); if (std::abs(U.at(multiIndex) - V.at(multiIndex)) > AMDIS_TEST_TOL) return false; } } return true; } int main(int argc, char** argv) { Environment env(argc, argv); using namespace Dune::Indices; ElliptProblem prob("ellipt"); prob.initialize(INIT_ALL); // create 3 copies of the solution vector auto U0 = *prob.solutionVector(); auto U1 = *prob.solutionVector(); auto U2 = *prob.solutionVector(); auto u0 = makeDiscreteFunction(U0); auto u1 = makeDiscreteFunction(U1); auto u2 = makeDiscreteFunction(U2); // Test const and mutable construction auto const& U_c = *prob.solutionVector(); auto& U_m = *prob.solutionVector(); DiscreteFunction u0_c(U_c.coefficients(), *U_c.basis()); DiscreteFunction u0_m(U_m.coefficients(), *U_m.basis()); auto u1_c = makeDiscreteFunction(U_c); auto u1_m = makeDiscreteFunction(U_m); // sub-range view on DiscreteFunction auto su1_c = u1_c.child(); auto su1_c0 = u1_c.child(0); auto su1_m = u1_m.child(); auto su1_m0 = u1_m.child(0); using Range = typename decltype(u0)::Range; auto expr1 = [](auto const& x) { return Range{ 1 + x[0] + x[1], 2 + x[0] + x[1]}; }; u0.interpolate_noalias(expr1); u1.interpolate(expr1); u2 << expr1; AMDIS_TEST( comp(U0, U1) ); AMDIS_TEST( comp(U0, U2) ); auto expr2 = [](auto const& x) { return Range{ 1 + 2*x[0] - 3*x[1], 2 + 2*x[0] - 3*x[1]}; }; u0.interpolate_noalias(u2 + expr2); u1.interpolate(u1 + expr2); u2 += expr2; AMDIS_TEST( comp(U0, U1) ); AMDIS_TEST( comp(U0, U2) ); auto expr3 = [](auto const& x) { return Range{ 1 - 0.5*x[0] - 2*x[1], 2 - 0.5*x[0] - 2*x[1]}; }; u0.interpolate_noalias(u2 - expr3); u1.interpolate(u1 - expr3); u2 -= expr3; AMDIS_TEST( comp(U0, U1) ); AMDIS_TEST( comp(U0, U2) ); auto du0 = derivative(u0, tag::gradient{}); auto localFct = localFunction(u0); auto dlocalFct = derivative(localFct, tag::gradient{}); for (auto const& e : elements(prob.gridView())) { localFct.bind(e); auto geo = e.geometry(); auto local = referenceElement(geo).position(0,0); auto y0 = localFct(local); auto y1 = u0(geo.global(local)); for (auto it1 = y0.begin(), it2 = y1.begin(); it1 != y0.end(); ++it1, ++it2) AMDIS_TEST(std::abs(*it1 - *it2) < 1.e-10); localFct.unbind(); dlocalFct.bind(e); auto g0 = dlocalFct(local); auto g1 = du0(geo.global(local)); for (auto it1 = g0.begin(), it2 = g1.begin(); it1 != g0.end(); ++it1, ++it2) AMDIS_TEST(two_norm(*it1 - *it2) < 1.e-10); dlocalFct.unbind(); } auto V0 = makeDOFVector(prob.globalBasis()); auto v0 = makeDiscreteFunction(V0); v0 << expr1; // test discreteFunction int preTP1 = 0; std::integral_constant preTP2; auto tp = treepath(preTP1); auto W0 = *prob.solutionVector(); auto W1 = *prob.solutionVector(); auto W2 = *prob.solutionVector(); auto w0 = makeDiscreteFunction(W0, preTP1); auto w1 = makeDiscreteFunction(W1, preTP2); auto w2 = makeDiscreteFunction(W2, tp); // test discreteFunction with (pre)treepath argument auto expr = [](auto const& x) { return 1 + x[0] + x[1]; }; auto W3 = *prob.solutionVector(); auto W4 = *prob.solutionVector(); auto W5 = *prob.solutionVector(); auto W7 = *prob.solutionVector(); auto W8 = *prob.solutionVector(); auto w3 = makeDiscreteFunction(W3, preTP1); auto w4 = makeDiscreteFunction(W4, preTP2); auto w5 = makeDiscreteFunction(W5, tp); auto w6 = prob.solution(tp); auto& W6 = *prob.solutionVector(); w3 << expr; w4 << expr; w5 << expr; w6 << expr; AMDIS_TEST( comp(W3, W4) ); AMDIS_TEST( comp(W3, W5) ); AMDIS_TEST( comp(W3, W6) ); // test interpolation on subbasis auto w7 = makeDiscreteFunction(W7); auto w8_0 = makeDiscreteFunction(W8, 0); auto w8_1 = makeDiscreteFunction(W8, 1); w7 << expr; w8_0 << expr; w8_1 << expr; AMDIS_TEST( comp(W7, W8) ); return 0; }