diff --git a/CMakeLists.txt b/CMakeLists.txt index 81f61794abc979ec3abd1f5a3aba88c3679750c4..909b1e5e4d4e274d0a631b1f9bb3421123709bc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,7 @@ endif() if (OPT_ENABLE_GPU_SOLVER) option(OPT_DEBUG_GPU "Enable GPU debugging" OFF) if (OPT_DEBUG_GPU) + add_definitions(-DCUDA_DEBUG) add_definitions(-DGPU_DEBUG) endif() endif() @@ -212,19 +213,17 @@ if (COMPILER_IS_CLANG OR COMPILER_IS_GNU) endif() endif() -option(OPT_ENABLE_CUDA_DEBUG_GUARDS "Enable CUDA debug guards") -if (OPT_ENABLE_CUDA_DEBUG_GUARDS AND HAVE_CUDA) - add_definitions(-DCUDA_DEBUG) +option(OPT_WRITE_TEST_OUTPUTS "Produce SILO files in tests" OFF) +if (OPT_WRITE_TEST_OUTPUTS) + add_definitions(-DWRITE_TEST_OUTPUTS) endif() +option(OPT_EXPENSIVE_ASSERTS "Enable expensive assert()s" OFF) +if (OPT_EXPENSIVE_ASSERTS) + add_definitions(-DEXPENSIVE_ASSERTS) +endif() ###################################################################### ## Enable/disable solver modules - -option(OPT_ENABLE_CPU_SOLVER "Enable CPU DG solver") -if (OPT_ENABLE_CPU_SOLVER) - add_definitions(-DENABLE_CPU_SOLVER) -endif() - option(OPT_DEBUG_PRINT "Print debug information") if (OPT_DEBUG_PRINT) add_definitions(-DENABLE_DEBUG_PRINT) @@ -261,6 +260,9 @@ target_link_libraries(test_mass gmshdg) add_executable(test_differentiation tests/test_differentiation.cpp) target_link_libraries(test_differentiation gmshdg) +add_executable(test_lifting tests/test_lifting.cpp) +target_link_libraries(test_lifting gmshdg) + add_executable(test_differentiation_gpu tests/test_differentiation_gpu.cpp) target_link_libraries(test_differentiation_gpu gmshdg) diff --git a/src/entity.cpp b/src/entity.cpp index 71f63439a6ffbfb5fa0fee9537211e6aea05d037..d6801d4006661d498773a8fcf4a763611f6eb895 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -532,6 +532,9 @@ entity::populate_lifting_matrices_planar(entity_data_cpu& ed, size_t base_row = iO * ed.num_bf; ed.lifting_matrices.block(base_row, 0, ed.num_bf, lm_cols) = mass_ldlt.solve(lm); + + //std::cout << "Orientation : " << iO << std::endl; + //std::cout << mass_ldlt.solve(lm) << std::endl; } } @@ -703,6 +706,7 @@ entity::populate_entity_data(entity_data_cpu& ed) const { auto& pe = physical_cells[iT]; auto cell_keys = pe.bf_keys(); + auto cell_base = iT * ed.num_bf; for (size_t iF = 0; iF < 4; iF++) { @@ -710,8 +714,7 @@ entity::populate_entity_data(entity_data_cpu& ed) const auto& pf = physical_faces[face_num]; auto face_keys = pf.bf_keys(); - auto face_base = (4*iT + iF) * ed.num_fluxes; - auto cell_base = iT * ed.num_bf; + auto face_base = face_num * ed.num_fluxes; for (size_t i = 0; i < face_keys.size(); i++) for (size_t j = 0; j < cell_keys.size(); j++) @@ -719,7 +722,6 @@ entity::populate_entity_data(entity_data_cpu& ed) const ed.fluxdofs_mine.at(face_base + i) = cell_base + j; } } - } diff --git a/tests/test_basics.cpp b/tests/test_basics.cpp index 5eee4db9208ef620be4e340bb815f6d02b74bc19..1235eb6d2c6630a6a06e90447f9160d594bf2da4 100644 --- a/tests/test_basics.cpp +++ b/tests/test_basics.cpp @@ -151,7 +151,7 @@ test_basics(int geometric_order, int approximation_order) return 0; } -#include <fstream> + int test_normals(int geometric_order, int approximation_order) { @@ -165,6 +165,8 @@ test_normals(int geometric_order, int approximation_order) std::cout << cyanfg << "Testing normals (order " << geometric_order; std::cout << ")" << reset << std::endl; + int errors = 0; + for (auto [dim, pgtag] : pgs) { std::vector<int> tags; @@ -200,6 +202,7 @@ test_normals(int geometric_order, int approximation_order) auto pf = e0.face(4*iT+iF); auto rf = e0.face_refelem(pf); auto qps = pf.integration_points(); + auto fbar = pf.barycenter(); auto ek = element_key(pf); if ( !std::binary_search(bm.begin(), bm.end(), ek) ) @@ -210,7 +213,7 @@ test_normals(int geometric_order, int approximation_order) for (size_t iQp = 0; iQp < num_qp; iQp++) { Eigen::Vector3d n = ed.normals.row((4*iT+iF)*num_qp + iQp); - point_3d p = qps[iQp].point(); + point_3d p = (geometric_order == 1) ? fbar : qps[iQp].point(); point_3d v = p - point_3d(0.5, 0.5, 0.5); Eigen::Vector3d nref; nref(0) = v.x(); nref(1) = v.y(); nref(2) = v.z(); @@ -218,9 +221,10 @@ test_normals(int geometric_order, int approximation_order) if ( n.cross(nref).norm() > 1e-2 ) { - std::cout << "Wrong normal. Expected: " << nref.transpose() << ", "; - std::cout << "got: " << n.transpose() << std::endl; - return 1; + std::cout << "Wrong normal. Expected: " << greenfg << nref.transpose(); + std::cout << reset << ", " << "got: " << redfg << n.transpose(); + std::cout << reset << " diff: " << (nref-n).transpose() << std::endl; + errors++; } } } @@ -228,6 +232,42 @@ test_normals(int geometric_order, int approximation_order) } } + return errors; +} + +int +test_normals_2() +{ + make_geometry(0, 0.1); + model mod(1, 1); + + vec3d totflux = vec3d::Zero(); + double tf = 0.0; + + for (const auto& e : mod) + { + entity_data_cpu ed; + e.populate_entity_data(ed); + + for (size_t iT = 0; iT < e.num_cells(); iT++) + { + vec3d flux = vec3d::Zero(); + + for (size_t iF = 0; iF < 4; iF++) + { + auto face_num = 4*iT+iF; + auto& pf = e.face(face_num); + vec3d n = ed.normals.row(face_num); + flux += n * pf.measure(); + } + tf += flux.norm(); + totflux += flux; + } + } + + COMPARE_VALUES_ABSOLUTE("Volume flux", tf, 0, 1e-14); + COMPARE_VALUES_ABSOLUTE("Volume flux", totflux.norm(), 0, 1e-14); + return 0; } @@ -240,7 +280,7 @@ int main(void) int failed_tests = 0; - +/* std::cout << Bmagentafg << " *** TESTING: BASIC OPERATIONS ***" << reset << std::endl; for (size_t go = 1; go < 5; go++) { @@ -249,10 +289,13 @@ int main(void) failed_tests += test_basics(go, ao); } } +*/ + //std::cout << Bmagentafg << " *** TESTING: NORMAL COMPUTATION ***" << reset << std::endl; + //for (size_t i = 1; i < 5; i++) + // test_normals(i,i); - std::cout << Bmagentafg << " *** TESTING: NORMAL COMPUTATION ***" << reset << std::endl; - for (size_t i = 1; i < 5; i++) - test_normals(i,i); + std::cout << Bmagentafg << " *** TESTING: NORMAL COMPUTATION (2) ***" << reset << std::endl; + test_normals_2(); return failed_tests; } \ No newline at end of file diff --git a/tests/test_differentiation_gpu.cpp b/tests/test_differentiation_gpu.cpp index 5b368d136c42f106f0c0a8b63029781131fa77ac..f074f0d7e51e4fa34bbe86e7c4505de995ec1c82 100644 --- a/tests/test_differentiation_gpu.cpp +++ b/tests/test_differentiation_gpu.cpp @@ -41,8 +41,6 @@ make_geometry(int order, double mesh_h) gmm::setSize(vp, mesh_h); } -#define WRITE_TEST_OUTPUTS - int test_differentiation_convergence(int geometric_order, int approximation_order) { std::vector<double> sizes({ 0.32, 0.16, 0.08, 0.04 }); diff --git a/tests/test_lifting.cpp b/tests/test_lifting.cpp index 154cccee435232ee017419bcf649732786d424f6..d6bd47cc96eb9a68813e049d8ea36d5789c9996b 100644 --- a/tests/test_lifting.cpp +++ b/tests/test_lifting.cpp @@ -70,15 +70,15 @@ int test_lifting(int geometric_order, int approximation_order) /* Test field */ auto Fx = [](const point_3d& pt) -> double { - return 1; //std::sin(M_PI*pt.x()); + return std::sin(M_PI*pt.x()); }; auto Fy = [](const point_3d& pt) -> double { - return 1; //std::sin(M_PI*pt.y()); + return std::sin(M_PI*pt.y()); }; auto Fz = [](const point_3d& pt) -> double { - return 1; //std::sin(M_PI*pt.z()); + return std::sin(M_PI*pt.z()); }; auto F = [&](const point_3d& pt) -> vecxd { @@ -91,7 +91,7 @@ int test_lifting(int geometric_order, int approximation_order) /* Expected divergence */ auto div_F = [](const point_3d& pt) -> double { - return 0; + //return 0; auto dFx_dx = M_PI*std::cos(M_PI*pt.x()); auto dFy_dy = M_PI*std::cos(M_PI*pt.y()); auto dFz_dz = M_PI*std::cos(M_PI*pt.z()); @@ -209,14 +209,20 @@ int test_lifting(int geometric_order, int approximation_order) const auto& pqp = pqps[iQp]; const vecxd phi = re.basis_functions(iQp); const matxd dphi = re.basis_gradients(iQp); + const mat3d J = pe.jacobian(iQp); mass += pqp.weight() * phi * phi.transpose(); - vol += pqp.weight() * dphi * F(pqp.point()); + vol += pqp.weight() * (dphi*J.inverse()) * F(pqp.point()); } vecxd expected = exp_field.segment(iT*num_bf, num_bf); vecxd lf = lift_field.segment(iT*num_bf, num_bf); + vecxd lfp = mass*lf; vecxd volp = mass.ldlt().solve(vol); + //std::cout << "***" << std::endl; + //std::cout << lfp.transpose() << std::endl; + //std::cout << vol.transpose() << std::endl; + vecxd comp_field = lf - volp; vecxd diff = comp_field - expected; double loc_err = diff.dot(mass*diff); @@ -257,4 +263,25 @@ int test_lifting(int geometric_order, int approximation_order) } return 0; -} \ No newline at end of file +} + +int main(void) +{ + gmsh::initialize(); + gmsh::option::setNumber("General.Terminal", 0); + gmsh::option::setNumber("Mesh.Algorithm", 1); + gmsh::option::setNumber("Mesh.Algorithm3D", 1); + + + int failed_tests = 0; + + std::cout << Bmagentafg << " *** TESTING: LIFTING ***" << reset << std::endl; + for (size_t ao = 1; ao < 5; ao++) + test_lifting(1, ao); + + gmsh::finalize(); + + return failed_tests; +} + +