#include #include #include #include #include "gtest/gtest.h" constexpr std::complex operator""_i(long double d) { return std::complex{0.0, static_cast(d)}; } namespace mm { TEST(End2end, ComplexNumbers) { BoxShape box(0.0, 1.0); DomainDiscretization domain = box.discretizeWithStep(0.05); int N = domain.size(); domain.findSupport(FindClosest(9)); WLS> wls({9, 30.0}, {}); auto storage = domain.computeShapes(wls); // Implicit scalar Eigen::SparseMatrix, Eigen::RowMajor> M(N, N); M.reserve(storage.supportSizes()); Eigen::VectorXcd rhs(N); rhs.setZero(); ImplicitOperators op(storage, M, rhs); double x, y; for (int i : domain.interior()) { x = domain.pos(i, 0); y = domain.pos(i, 1); 1.0_i * op.lap(i) = 2*PI*PI*std::sin(PI * x)*std::sin(PI * y); } for (int i : domain.boundary()) { op.value(i) = 0.0; } Eigen::BiCGSTAB>> solver; solver.compute(M); Eigen::VectorXcd u = solver.solve(rhs); EXPECT_NEAR(u.real().norm(), 0, 1e-10); for (int i : domain.interior()) { x = domain.pos(i, 0); y = domain.pos(i, 1); double e = std::abs(u[i] - 1.0_i*std::sin(PI * x)*std::sin(PI * y)); EXPECT_NEAR(e, 0, 1.5e-2); } // Implicit vector M.setZero(); M.reserve(storage.supportSizes()); rhs.setZero(); ImplicitOperators opv(storage, M, rhs); for (int i : domain.interior()) { x = domain.pos(i, 0); y = domain.pos(i, 1); 1.0_i * opv.lap(i) = 2*PI*PI*std::sin(PI * x)*std::sin(PI * y); } for (int i : domain.boundary()) { opv.value(i) = 0.0; } solver.compute(M); Eigen::VectorXcd uv = solver.solve(rhs); ASSERT_EQ(uv, u); auto vf = VectorField, 1>::fromLinear(uv); auto eop = storage.explicitOperators(); auto evop = storage.explicitVectorOperators(); for (int i : domain.interior()) { x = domain.pos(i, 0); y = domain.pos(i, 1); // Explicit scalar auto egrad = eop.grad(u, i); auto agrad = Eigen::Vector2cd(1.0_i*PI*std::cos(PI*x)*std::sin(PI*y), 1.0_i*PI*std::sin(PI*x)*std::cos(PI*y)); double e = (egrad - agrad).norm(); EXPECT_NEAR(e, 0, 1e-2); // Explicit vector auto m = evop.grad(vf, i).transpose(); EXPECT_EQ(m, egrad); } } } // namespace mm