From feaefa718d69ff81dcac68550ba4b151dbb9298c Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Thu, 4 Jun 2026 20:36:18 +0200 Subject: [PATCH] Fix distance mini-app BVH robustness Fix distance mini-app BVH robustness Fixes #66 --- CMakeLists.txt | 101 ++++++++++++++++----------- src/app-feelpp-distance/README.adoc | 9 ++- src/app-feelpp-distance/distance.cpp | 33 ++++++--- 3 files changed, 93 insertions(+), 50 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e2ba3ae..6ba87c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,15 +38,37 @@ endif() find_package(Python REQUIRED COMPONENTS Interpreter Development.Module) find_package(pybind11 CONFIG REQUIRED) -find_package(Feel++ REQUIRED COMPONENTS Toolboxes PATHS ${FEELPP_DIR}/share/feelpp/feel/cmake/modules $ENV{FEELPP_DIR}/share/feelpp/feel/cmake/modules /usr/share/feelpp/feel/cmake/modules /usr/local/share/feelpp/feel/cmake/modules ) -if(NOT FEELPP_FOUND) - message(FATAL_ERROR "Feel++ was not found on your system. Make sure to install it and specify the FEELPP_DIR to reference the installation directory.") +option(FEELPP_PROJECT_REQUIRE_TOOLBOXES "Require Feel++ Toolboxes to run cfg/json configurations" ON) + +if ( NOT TARGET Feelpp::feelpp ) + find_package(Feel++ CONFIG REQUIRED COMPONENTS Toolboxes + PATHS + ${FEELPP_DIR}/share/feelpp/feel/cmake/modules + $ENV{FEELPP_DIR}/share/feelpp/feel/cmake/modules + /usr/share/feelpp/feel/cmake/modules + /usr/local/share/feelpp/feel/cmake/modules + ) +endif() + +if ( NOT TARGET Feelpp::feelpp ) + message(FATAL_ERROR "Feel++ target Feelpp::feelpp is not available.") endif() -if ( NOT FEELPP_TOOLBOXES_FOUND ) - message(WARNING "Feel++ Toolboxes SDK is not found on your system. The toolbox application is now disabled.") +if ( NOT COMMAND feelpp_add_application ) + message(FATAL_ERROR "Feel++ CMake macro feelpp_add_application is not available.") endif() -add_compile_options(-Wall -Werror -Wextra) +set(USE_FEELPP_TOOLBOXES OFF) +if ( FEELPP_HAS_TOOLBOXES OR FEELPP_TOOLBOXES_FOUND ) + set(USE_FEELPP_TOOLBOXES ON) +endif() +if ( FEELPP_PROJECT_REQUIRE_TOOLBOXES AND NOT USE_FEELPP_TOOLBOXES ) + message(FATAL_ERROR "Feel++ Toolboxes SDK is required to run the cfg/json configurations. Enable FEELPP_ENABLE_TOOLBOXES in-tree or install Feel++ with Toolboxes for standalone builds.") +endif() + +option(FEELPP_PROJECT_ENABLE_WERROR "Treat warnings as errors in apps-feelpp" OFF) +if ( FEELPP_PROJECT_ENABLE_WERROR ) + add_compile_options(-Werror) +endif() enable_testing() @@ -69,37 +91,38 @@ list(APPEND CPACK_SOURCE_IGNORE_FILES .appveyor.yml ) -set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${EXTRA_VERSION}") -set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}${EXTRA_VERSION}") -SET(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${EXTRA_VERSION}-${CMAKE_SYSTEM_NAME}") -set(CPACK_PACKAGE_DIRECTORY "${PROJECT_BINARY_DIR}/assets") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Cemosis feelpp-app template application") -set(CPACK_PACKAGE_DESCRIPTION "Cemosis provides a Feel++ template application.") -set(CPACK_PACKAGE_VENDOR "Cemosis") -set(CPACK_PACKAGE_CONTACT "Christophe Prud'homme ") -set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") -set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") -set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") - - -set(CPACK_GENERATOR "TGZ;DEB") -set(CPACK_SOURCE_GENERATOR "TGZ") - - -set(CPACK_DEBIAN_PACKAGE_NAME "${PROJECT_NAME}") -set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_CONTACT}") -if ( USE_FEELPP_TOOLBOXES ) - set(CPACK_DEBIAN_PACKAGE_DEPENDS "libfeelpp1 (>= 0.109)") # add depends with relevant toolbox lib -else() - set(CPACK_DEBIAN_PACKAGE_DEPENDS "libfeelpp1 (>= 0.109)") +if ( PROJECT_IS_TOP_LEVEL ) + set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${EXTRA_VERSION}") + set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}${EXTRA_VERSION}") + SET(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${EXTRA_VERSION}-${CMAKE_SYSTEM_NAME}") + set(CPACK_PACKAGE_DIRECTORY "${PROJECT_BINARY_DIR}/assets") + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Cemosis feelpp-app template application") + set(CPACK_PACKAGE_DESCRIPTION "Cemosis provides a Feel++ template application.") + set(CPACK_PACKAGE_VENDOR "Cemosis") + set(CPACK_PACKAGE_CONTACT "Christophe Prud'homme ") + set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") + set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") + set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") + + + set(CPACK_GENERATOR "TGZ;DEB") + set(CPACK_SOURCE_GENERATOR "TGZ") + + + set(CPACK_DEBIAN_PACKAGE_NAME "${PROJECT_NAME}") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_CONTACT}") + if ( USE_FEELPP_TOOLBOXES ) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "libfeelpp1 (>= 0.109)") # add depends with relevant toolbox lib + else() + set(CPACK_DEBIAN_PACKAGE_DEPENDS "libfeelpp1 (>= 0.109)") + endif() + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION_SUMMARY "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}") + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION}") + set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") + set(CPACK_DEBIAN_PACKAGE_SECTION "science") + set(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}${EXTRA_VERSION}") + set(CPACK_DEBIAN_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}") + # set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/debian/postinst") + + include(CPack) endif() -set(CPACK_DEBIAN_PACKAGE_DESCRIPTION_SUMMARY "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}") -set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION}") -set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") -set(CPACK_DEBIAN_PACKAGE_SECTION "science") -set(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}${EXTRA_VERSION}") -set(CPACK_DEBIAN_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}") -# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/debian/postinst") - -include(CPack) - diff --git a/src/app-feelpp-distance/README.adoc b/src/app-feelpp-distance/README.adoc index 735d5f1..e59fe22 100644 --- a/src/app-feelpp-distance/README.adoc +++ b/src/app-feelpp-distance/README.adoc @@ -13,6 +13,13 @@ feelpp_app_distance [--h --M --gmsh.filename ] - `M` is the number of ray casted for the BVH method - `gmsh.filename` is the path to the geometry (or the mesh). This geometry should contain a physical marker named `boundary`. +Quick local smoke check with a coarse mesh and a small number of rays: + +[source, bash] +---- +feelpp_app_distance --gmsh.filename ./dist.geo --h 0.5 --M 8 --repository.append.np 0 +---- + [source, bash] ---- @@ -23,4 +30,4 @@ feelpp-benchmarking-exec --machine-config src/config/gaya/gaya.json --benchmark- [source, bash] ---- feelpp-benchmarking-render --plot-configs src/app-feelpp-distance/plots.json --patch-reports gaya:all:all:all -sp ----- \ No newline at end of file +---- diff --git a/src/app-feelpp-distance/distance.cpp b/src/app-feelpp-distance/distance.cpp index 05ff080..25053bb 100644 --- a/src/app-feelpp-distance/distance.cpp +++ b/src/app-feelpp-distance/distance.cpp @@ -1,6 +1,9 @@ #include +#include #include +#include +#include #include #include #include @@ -84,6 +87,8 @@ int main(int argc, char**argv ) double h_ = doption(_name="h"); int M = ioption(_name="M"); std::string filename = soption(_name="gmsh.filename"); + if ( M <= 0 ) + throw std::invalid_argument( "M must be a positive number of rays" ); // Load the mesh tic(); @@ -127,8 +132,8 @@ int main(int argc, char**argv ) Eigen::Vector3d origin; std::unordered_set pointIDs; - std::vector origins(Xh_->nLocalDof()); - size_type next_origin = 0; + std::vector origins; + origins.reserve(Xh_->nLocalDof()); for ( auto const& eltWrap : elements(mesh_) ) // on parcourt tous les éléments du maillage { @@ -138,8 +143,9 @@ int main(int argc, char**argv ) { auto const & point = elt.point(p); - // pas sure si isGhostCell est la bonne fonction - if (!point.isOnBoundary() && !point.isGhostCell()) // on ne considère pas les points qui se trouvent au bord ni les dof ghosts + // Keep shared/ghost dofs here: local element evaluations need those + // values even when the dof owner is another rank. + if (!point.isOnBoundary()) { size_type id_p = Xh_->dof()->localToGlobal( elt.id(), p ).index(); auto [it,inserted] = pointIDs.insert(id_p); @@ -147,8 +153,7 @@ int main(int argc, char**argv ) if (inserted) { origin << point.node()[0], point.node()[1], point.node()[2]; - origins[next_origin] = Points_list{id_p, origin}; - next_origin++; + origins.push_back(Points_list{id_p, origin}); } } } @@ -180,15 +185,23 @@ int main(int argc, char**argv ) //toc("intersection"); //tic(); // Get distance - std::vector dist(M, 0.0); + std::vector dist(M, std::numeric_limits::max()); for (auto const& [fid,rirs] : enumerate(multiRayIntersectionResult)) { + int rayIndex = fid % M; + if ( rayIndex == 0 ) + std::fill(dist.begin(), dist.end(), std::numeric_limits::max()); + if (!rirs.empty()) // on check l'intersection - dist[fid % M] = rirs.front().distance(); + dist[rayIndex] = rirs.front().distance(); - if (fid % M == M - 1) - d_BVH[origins[static_cast(fid / M)].id] = *(std::min_element(dist.begin(), dist.end())); + if ( rayIndex == M - 1 ) + { + auto minDistance = *(std::min_element(dist.begin(), dist.end())); + if ( minDistance < std::numeric_limits::max() ) + d_BVH[origins[static_cast(fid / M)].id] = minDistance; + } } double time_BVH = toc("bvh"); e_->add( "d_BVH", d_BVH );