#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gtest/gtest.h" namespace mm { TEST(Operators, computeShapes) { /// [computeShapes usage example] BoxShape box(0.0, 1.0); DomainDiscretization d = box.discretizeWithStep(0.1); d.findSupport(FindClosest(9)); WLS> approx(2); auto shapes = d.computeShapes(approx); // implicit call via domain hook // direct call which overwrites shapes for Laplacian for internal nodes in given storage sh::operator_tuple::type operators; computeShapes(d, approx, d.interior(), operators, &shapes); /// [computeShapes usage example] int node = 12; approx.compute(d.pos(node), d.supportNodes(node)); Eigen::VectorXd sh = approx.getShape(Der1<2>(0)); // d/dx shape Eigen::VectorXd sh2 = shapes.d1(0, node); EXPECT_EQ(sh, sh2); node = 5; approx.compute(d.pos(node), d.supportNodes(node)); sh = approx.getShape(Der1<2>(1)); // d/dy shape sh2 = shapes.d1(1, node); EXPECT_EQ(sh, sh2); node = 34; approx.compute(d.pos(node), d.supportNodes(node)); sh = approx.getShape(Lap<2>()); // lap shape sh2 = shapes.laplace(node); EXPECT_EQ(sh, sh2); } TEST(Operators, computeShapesD2) { BoxShape box(0.0, 1.0); DomainDiscretization d = box.discretizeWithStep(0.1); d.findSupport(FindClosest(9)); WLS> approx(2); auto shapes = d.computeShapes(approx); int node = 22; approx.compute(d.pos(node), d.supportNodes(node)); Eigen::VectorXd sh = approx.getShape(Der2<2>(0)); // d/dx^2 shape Eigen::VectorXd sh2 = shapes.d2(0, 0, node); EXPECT_EQ(sh, sh2); node = 0; approx.compute(d.pos(node), d.supportNodes(node)); sh = approx.getShape(Der2<2>(1)); // d/dy^2 shape sh2 = shapes.d2(1, 1, node); EXPECT_EQ(sh, sh2); node = 46; approx.compute(d.pos(node), d.supportNodes(node)); sh = approx.getShape(Der2<2>(0, 1)); // d/dy^2 shape sh2 = shapes.d2(0, 1, node); EXPECT_EQ(sh, sh2); node = 78; approx.compute(d.pos(node), d.supportNodes(node)); sh = approx.getShape(Lap<2>()); // lap shape sh2 = shapes.laplace(node); EXPECT_EQ(sh, sh2); } /// [custom zero op] // Dummy zero operator struct Zero : Operator { template typename basis_t::scalar_t applyAt0( const basis_t&, int, const std::vector&, typename basis_t::scalar_t) const { return 0.0; } }; /// [custom zero op] TEST(Operators, ComputeShapesCustom) { BoxShape box(0.0, 1.0); DomainDiscretization d = box.discretizeWithStep(0.1); int n = 9; d.findSupport(FindClosest(n)); WLS> approx(2); /// [custom op usage] std::tuple, Der1s<2>, Zero> ops; auto shapes = d.computeShapes(ops, approx); shapes.get(3, 2); // coefficient 4 of shape for zero in 3rd node. shapes.get>(0, 3, 4); // coefficient 4 of shape for dx in 3rd node. /// [custom op usage] int N = d.size(); for (int i = 0; i < N; ++i) { for (int j = 0; j < n; ++j) { EXPECT_EQ(0, shapes.get(i, j)); } } } TEST(Operators, computeShapesEmptySupport) { BoxShape box(0.0, 1.0); DomainDiscretization d = box.discretizeWithStep(0.1); WLS> approx(2); UniformShapeStorage>> storage; sh::operator_tuple::type operators; EXPECT_DEATH(computeShapes(d, approx, d.interior(), operators, &storage), "Did you forget to find support before computing shapes?"); } } // namespace mm