From 67cdb9a96a5c7b4721aee1072820555675f2c6fe Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 10:11:33 -0700 Subject: [PATCH 01/23] try some mfem openmp and mpi fixes --- cmake/thirdparty/SetupMFEM.cmake | 35 ++++++++++++++++++++++++++++++-- src/tests/CMakeLists.txt | 3 --- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/cmake/thirdparty/SetupMFEM.cmake b/cmake/thirdparty/SetupMFEM.cmake index 412fee6b..36cf39c6 100644 --- a/cmake/thirdparty/SetupMFEM.cmake +++ b/cmake/thirdparty/SetupMFEM.cmake @@ -19,6 +19,8 @@ set(_MFEM_DIR ${MFEM_DIR}) # Save MFEM_DIR as a non-cache variable find_package(MFEM CONFIG NO_DEFAULT_PATH PATHS "${MFEM_DIR}/lib/cmake/mfem") # find_package will overwrite MFEM_DIR, so restore it here set(MFEM_DIR ${_MFEM_DIR} CACHE PATH "" FORCE) +set(_mfem_uses_mpi FALSE) +set(_mfem_uses_openmp FALSE) if(MFEM_FOUND) # MFEM was built with CMake so use that config file @@ -26,6 +28,12 @@ if(MFEM_FOUND) set(MFEM_BUILT_WITH_CMAKE TRUE) # It looks like include directories are not always built into the target target_include_directories(mfem INTERFACE ${MFEM_INCLUDE_DIRS}) + if(MFEM_USE_MPI) + set(_mfem_uses_mpi TRUE) + endif() + if(MFEM_USE_OPENMP OR MFEM_USE_LEGACY_OPENMP) + set(_mfem_uses_openmp TRUE) + endif() else() set(MFEM_BUILT_WITH_CMAKE FALSE) find_path( @@ -68,6 +76,12 @@ else() # read config.mk file file(READ "${MFEM_CFG_DIR}/config.mk" mfem_cfg_file_txt) + if(mfem_cfg_file_txt MATCHES "MFEM_USE_MPI[ \\t]*\\+?=[ \\t]*YES") + set(_mfem_uses_mpi TRUE) + endif() + if(mfem_cfg_file_txt MATCHES "MFEM_USE_(LEGACY_)?OPENMP[ \\t]*\\+?=[ \\t]*YES") + set(_mfem_uses_openmp TRUE) + endif() # parse include flags string(REGEX MATCHALL "MFEM_TPLFLAGS [^\n]+\n" mfem_tpl_inc_flags ${mfem_cfg_file_txt}) @@ -129,17 +143,34 @@ else() EXPORTABLE ON) # Tribol edit - if(TRIBOL_USE_MPI) + if(_mfem_uses_mpi) + if(NOT TARGET blt::mpi) + message(FATAL_ERROR "MFEM was built with MPI support, but MPI is not enabled in BLT. Configure with ENABLE_MPI=ON.") + endif() # Note: -lmpifort is being added to MFEM's link line w/o a -L list(GET MPI_C_LIBRARIES 0 _first_mpi_lib) get_filename_component(_mpi_lib_dir ${_first_mpi_lib} DIRECTORY) target_link_directories(mfem INTERFACE ${_mpi_lib_dir}) - target_link_libraries(mfem INTERFACE mpi) + target_link_libraries(mfem INTERFACE blt::mpi) endif() # End Tribol edit endif() +if(MFEM_BUILT_WITH_CMAKE AND _mfem_uses_mpi) + if(NOT TARGET blt::mpi) + message(FATAL_ERROR "MFEM was built with MPI support, but MPI is not enabled in BLT. Configure with ENABLE_MPI=ON.") + endif() + target_link_libraries(mfem INTERFACE blt::mpi) +endif() + +if(_mfem_uses_openmp) + if(NOT TARGET blt::openmp) + message(FATAL_ERROR "MFEM was built with OpenMP support, but OpenMP is not enabled in BLT. Configure with ENABLE_OPENMP=ON.") + endif() + target_link_libraries(mfem INTERFACE blt::openmp) +endif() + include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set MFEM_FOUND to TRUE # if all listed variables are TRUE diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 088b821e..118ca0d9 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -251,9 +251,6 @@ endif() if( MFEM_FOUND ) set(mfem_smoke_depends mfem gtest) - # MFEM may require OpenMP even when Tribol does not, and FindMFEM.cmake does not propagate that dependency. - blt_list_append(TO mfem_smoke_depends ELEMENTS blt::openmp IF ENABLE_OPENMP ) - blt_list_append(TO mfem_smoke_depends ELEMENTS blt::mpi IF TRIBOL_USE_MPI ) blt_add_executable( NAME mfem_smoke_test SOURCES mfem_smoke.cpp From d92dd024ce028c245307a69df43a0a587cb48c41 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 11:31:46 -0700 Subject: [PATCH 02/23] revert to const for send buffers in the MPI routines --- src/tests/tribol_mfem_jacobian.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/tribol_mfem_jacobian.cpp b/src/tests/tribol_mfem_jacobian.cpp index 5ec6403b..f181799c 100644 --- a/src/tests/tribol_mfem_jacobian.cpp +++ b/src/tests/tribol_mfem_jacobian.cpp @@ -695,7 +695,7 @@ TEST_F( MfemJacobianTest, jacobian_primary_dual_assembles_in_ho_and_lor ) EXPECT_EQ( mat->Height(), ctx.mesh_data->GetParentCoords().ParFESpace()->GetTrueVSize() ); EXPECT_EQ( mat->Width(), ctx.submesh_data->GetSubmeshFESpace().GetTrueVSize() ); - int local_pairs = contributions[0].row_elem_ids.size(); + const int local_pairs = contributions[0].row_elem_ids.size(); int global_pairs = 0; MPI_Allreduce( &local_pairs, &global_pairs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); if ( global_pairs > 0 ) { @@ -724,7 +724,7 @@ TEST_F( MfemJacobianTest, jacobian_dual_primary_assembles_in_ho_and_lor ) EXPECT_EQ( mat->Height(), ctx.submesh_data->GetSubmeshFESpace().GetTrueVSize() ); EXPECT_EQ( mat->Width(), ctx.mesh_data->GetParentCoords().ParFESpace()->GetTrueVSize() ); - int local_pairs = contributions[0].row_elem_ids.size(); + const int local_pairs = contributions[0].row_elem_ids.size(); int global_pairs = 0; MPI_Allreduce( &local_pairs, &global_pairs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); if ( global_pairs > 0 ) { @@ -795,7 +795,7 @@ TEST_F( MfemJacobianTest, jacobian_primary_primary_aggregates_mortar_and_nonmort expected += AssembleSolverBlockJacobian( ctx, { nm }, SolverBlock::Primary, SolverBlock::Primary ); expected += AssembleSolverBlockJacobian( ctx, { nn }, SolverBlock::Primary, SolverBlock::Primary ); - int local_pairs = + const int local_pairs = mm.row_elem_ids.size() + mn.row_elem_ids.size() + nm.row_elem_ids.size() + nn.row_elem_ids.size(); int global_pairs = 0; MPI_Allreduce( &local_pairs, &global_pairs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); From f50e3048f0f49c8d83440e8a21d722bee2882322 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 11:54:58 -0700 Subject: [PATCH 03/23] build warnings as error option; make it the default --- cmake/Options.cmake | 1 + cmake/TribolCompilerFlags.cmake | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cmake/Options.cmake b/cmake/Options.cmake index f3d836da..4aca720c 100644 --- a/cmake/Options.cmake +++ b/cmake/Options.cmake @@ -19,6 +19,7 @@ endif() option(TRIBOL_USE_SINGLE_PRECISION "Use single-precision floating point" OFF) option(TRIBOL_USE_64BIT_INDEXTYPE "Use 64-bit index type" OFF) +option(TRIBOL_ENABLE_WARNINGS_AS_ERRORS "Treat compiler warnings as errors in Tribol" ON) option(TRIBOL_ENABLE_ASAN "Enable AddressSanitizer for memory checking (Clang or GCC only)" OFF) if(TRIBOL_ENABLE_ASAN) diff --git a/cmake/TribolCompilerFlags.cmake b/cmake/TribolCompilerFlags.cmake index 8985f91d..29d44201 100644 --- a/cmake/TribolCompilerFlags.cmake +++ b/cmake/TribolCompilerFlags.cmake @@ -10,6 +10,12 @@ if(TRIBOL_ENABLE_ASAN) endforeach() endif() +if(TRIBOL_ENABLE_WARNINGS_AS_ERRORS AND NOT ENABLE_WARNINGS_AS_ERRORS) + message(STATUS "Treating compiler warnings as errors in Tribol (TRIBOL_ENABLE_WARNINGS_AS_ERRORS)") + string(APPEND CMAKE_C_FLAGS " ${BLT_WARNINGS_AS_ERRORS_C_FLAG}") + string(APPEND CMAKE_CXX_FLAGS " ${BLT_WARNINGS_AS_ERRORS_CXX_FLAG}") +endif() + # Need to add symbols to dynamic symtab in order to be visible from stacktraces string(APPEND CMAKE_EXE_LINKER_FLAGS " -rdynamic") @@ -19,4 +25,3 @@ string(APPEND CMAKE_EXE_LINKER_FLAGS " -rdynamic") if(APPLE) string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-no_warn_duplicate_libraries") endif() - From aa23c720da3717b27e89963006841a0343e28625 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 13:01:17 -0700 Subject: [PATCH 04/23] use axom numeric limits instead --- src/tribol/geom/GeomUtilities.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tribol/geom/GeomUtilities.hpp b/src/tribol/geom/GeomUtilities.hpp index 88f9e461..7cc6bf41 100644 --- a/src/tribol/geom/GeomUtilities.hpp +++ b/src/tribol/geom/GeomUtilities.hpp @@ -8,8 +8,8 @@ #include #include -#include +#include "axom/core/NumericLimits.hpp" #include "axom/slic.hpp" #include "tribol/common/Parameters.hpp" @@ -1895,7 +1895,7 @@ TRIBOL_HOST_DEVICE inline void PolyInterYCentroid( const int namax, const RealT* RealT vol; // calculate origin shift to avoid roundoff errors - RealT realt_max = std::numeric_limits::max(); + RealT realt_max = axom::numeric_limits::max(); // clang-format off RealT xorg = realt_max; From b2e2140df37ccbbb362512ee3af9d1d7e56b9b7c Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 13:20:25 -0700 Subject: [PATCH 05/23] make spatial_dimension an int --- src/tribol/geom/CompGeom.hpp | 2 +- src/tribol/mesh/CouplingScheme.hpp | 4 ++-- src/tribol/mesh/MeshData.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tribol/geom/CompGeom.hpp b/src/tribol/geom/CompGeom.hpp index 5c420810..288c55a8 100644 --- a/src/tribol/geom/CompGeom.hpp +++ b/src/tribol/geom/CompGeom.hpp @@ -960,7 +960,7 @@ TRIBOL_HOST_DEVICE inline FaceGeomException CheckInterfacePairByMethod( InterfacePair& pair, const MeshData::Viewer& mesh1, const MeshData::Viewer& mesh2, const Parameters& params, ContactCase TRIBOL_UNUSED_PARAM( cCase ), bool& isInteracting, CompGeom::Viewer& cg, IndexT* plane_ct ) { - auto dim = static_cast( mesh1.spatialDimension() ); + auto dim = mesh1.spatialDimension(); T my_plane( &pair, params, dim ); FaceGeomException face_err = NO_FACE_GEOM_EXCEPTION; if ( dim == 3 ) { diff --git a/src/tribol/mesh/CouplingScheme.hpp b/src/tribol/mesh/CouplingScheme.hpp index 8b62ca86..9c77e984 100644 --- a/src/tribol/mesh/CouplingScheme.hpp +++ b/src/tribol/mesh/CouplingScheme.hpp @@ -128,7 +128,7 @@ class CouplingScheme { * * @return spatial dimension */ - TRIBOL_HOST_DEVICE int spatialDimension() const { return static_cast( m_mesh1.spatialDimension() ); } + TRIBOL_HOST_DEVICE int spatialDimension() const { return m_mesh1.spatialDimension(); } /** * @brief Return a view of the first mesh in the coupling scheme @@ -1072,7 +1072,7 @@ TRIBOL_HOST_DEVICE inline bool CouplingScheme::Viewer::pruneMethodFacePair( cons auto& mesh1 = this->getMesh1View(); auto& mesh2 = this->getMesh2View(); - int dim = static_cast( mesh1.spatialDimension() ); + int dim = mesh1.spatialDimension(); int num_nodes_face_1 = static_cast( mesh1.numberOfNodesPerElement() ); int num_nodes_face_2 = static_cast( mesh2.numberOfNodesPerElement() ); diff --git a/src/tribol/mesh/MeshData.hpp b/src/tribol/mesh/MeshData.hpp index 75d958b3..a145119b 100644 --- a/src/tribol/mesh/MeshData.hpp +++ b/src/tribol/mesh/MeshData.hpp @@ -159,7 +159,7 @@ class MeshData { * * @return spatial dimension */ - TRIBOL_HOST_DEVICE IndexT spatialDimension() const { return m_position.size(); } + TRIBOL_HOST_DEVICE int spatialDimension() const { return static_cast( m_position.size() ); } /** * @brief Number of nodes in the mesh From 9f5d514216af744033994c2735ceacb955cdda9d Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 13:23:18 -0700 Subject: [PATCH 06/23] MPICH wants non-const send buffers --- src/tests/tribol_mfem_jacobian.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/tribol_mfem_jacobian.cpp b/src/tests/tribol_mfem_jacobian.cpp index f181799c..5ec6403b 100644 --- a/src/tests/tribol_mfem_jacobian.cpp +++ b/src/tests/tribol_mfem_jacobian.cpp @@ -695,7 +695,7 @@ TEST_F( MfemJacobianTest, jacobian_primary_dual_assembles_in_ho_and_lor ) EXPECT_EQ( mat->Height(), ctx.mesh_data->GetParentCoords().ParFESpace()->GetTrueVSize() ); EXPECT_EQ( mat->Width(), ctx.submesh_data->GetSubmeshFESpace().GetTrueVSize() ); - const int local_pairs = contributions[0].row_elem_ids.size(); + int local_pairs = contributions[0].row_elem_ids.size(); int global_pairs = 0; MPI_Allreduce( &local_pairs, &global_pairs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); if ( global_pairs > 0 ) { @@ -724,7 +724,7 @@ TEST_F( MfemJacobianTest, jacobian_dual_primary_assembles_in_ho_and_lor ) EXPECT_EQ( mat->Height(), ctx.submesh_data->GetSubmeshFESpace().GetTrueVSize() ); EXPECT_EQ( mat->Width(), ctx.mesh_data->GetParentCoords().ParFESpace()->GetTrueVSize() ); - const int local_pairs = contributions[0].row_elem_ids.size(); + int local_pairs = contributions[0].row_elem_ids.size(); int global_pairs = 0; MPI_Allreduce( &local_pairs, &global_pairs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); if ( global_pairs > 0 ) { @@ -795,7 +795,7 @@ TEST_F( MfemJacobianTest, jacobian_primary_primary_aggregates_mortar_and_nonmort expected += AssembleSolverBlockJacobian( ctx, { nm }, SolverBlock::Primary, SolverBlock::Primary ); expected += AssembleSolverBlockJacobian( ctx, { nn }, SolverBlock::Primary, SolverBlock::Primary ); - const int local_pairs = + int local_pairs = mm.row_elem_ids.size() + mn.row_elem_ids.size() + nm.row_elem_ids.size() + nn.row_elem_ids.size(); int global_pairs = 0; MPI_Allreduce( &local_pairs, &global_pairs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); From 63eb7761fb3983bc964b26ce0895966f4d2799fb Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 13:31:05 -0700 Subject: [PATCH 07/23] move definitions in guarded code so they are only defined when used --- src/tribol/physics/ContactFormulationFactory.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tribol/physics/ContactFormulationFactory.cpp b/src/tribol/physics/ContactFormulationFactory.cpp index beaed413..8f01f2c0 100644 --- a/src/tribol/physics/ContactFormulationFactory.cpp +++ b/src/tribol/physics/ContactFormulationFactory.cpp @@ -18,11 +18,6 @@ std::unique_ptr createContactFormulation( CouplingScheme* cs } if ( cs->getContactMethod() == ENERGY_MORTAR ) { - // Default parameters for now, or extract from CouplingScheme if available - double k = 1000.0; - double delta = 0.1; - int N = 3; - bool enzyme_quadrature = true; // ENERGY_MORTAR supports a penalty-style mode driven by the kinematic penalty parameters, even if the coupling // scheme is registered with LM enforcement (which is often done to enable submesh/pressure infrastructure). const auto& penalty_opts = cs->getEnforcementOptions().penalty_options; @@ -30,6 +25,12 @@ std::unique_ptr createContactFormulation( CouplingScheme* cs bool use_penalty_ = penalty_opts.kinematic_calc_set; #if defined( TRIBOL_USE_ENZYME ) && defined( BUILD_REDECOMP ) + // Default parameters for now, or extract from CouplingScheme if available + double k = 1000.0; + double delta = 0.1; + int N = 3; + bool enzyme_quadrature = true; + if ( cs->hasMfemData() ) { // Attempt to get penalty from MfemMeshData if available auto* k1_ptr = cs->getMfemMeshData()->GetMesh1KinematicConstantPenalty(); From 55acae6697885a92b52b368e69670af3735415e8 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 13:51:47 -0700 Subject: [PATCH 08/23] move one more thing to guarded code --- src/tribol/physics/ContactFormulationFactory.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/tribol/physics/ContactFormulationFactory.cpp b/src/tribol/physics/ContactFormulationFactory.cpp index 8f01f2c0..22b682dc 100644 --- a/src/tribol/physics/ContactFormulationFactory.cpp +++ b/src/tribol/physics/ContactFormulationFactory.cpp @@ -18,12 +18,6 @@ std::unique_ptr createContactFormulation( CouplingScheme* cs } if ( cs->getContactMethod() == ENERGY_MORTAR ) { - // ENERGY_MORTAR supports a penalty-style mode driven by the kinematic penalty parameters, even if the coupling - // scheme is registered with LM enforcement (which is often done to enable submesh/pressure infrastructure). - const auto& penalty_opts = cs->getEnforcementOptions().penalty_options; - // TODO: Figure out how contact formulations interact with coupling scheme duplication (SRW) - bool use_penalty_ = penalty_opts.kinematic_calc_set; - #if defined( TRIBOL_USE_ENZYME ) && defined( BUILD_REDECOMP ) // Default parameters for now, or extract from CouplingScheme if available double k = 1000.0; @@ -31,6 +25,11 @@ std::unique_ptr createContactFormulation( CouplingScheme* cs int N = 3; bool enzyme_quadrature = true; + // ENERGY_MORTAR supports a penalty-style mode driven by the kinematic penalty parameters, even if the coupling + // scheme is registered with LM enforcement (which is often done to enable submesh/pressure infrastructure). + const auto& penalty_opts = cs->getEnforcementOptions().penalty_options; + bool use_penalty = penalty_opts.kinematic_calc_set; + if ( cs->hasMfemData() ) { // Attempt to get penalty from MfemMeshData if available auto* k1_ptr = cs->getMfemMeshData()->GetMesh1KinematicConstantPenalty(); @@ -46,7 +45,7 @@ std::unique_ptr createContactFormulation( CouplingScheme* cs return std::make_unique( *cs->getMfemMeshData(), *cs->getMfemSubmeshData(), *cs->getMfemJacobianData(), k, delta, N, enzyme_quadrature, - use_penalty_ ); + use_penalty ); #else SLIC_ERROR_ROOT( "ENERGY_MORTAR requires Enzyme and redecomp to be built." ); return nullptr; From 4ab4934d9852f43d6bea2225790d5e017f949277 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 14:11:02 -0700 Subject: [PATCH 09/23] fix uninitialized warning --- src/tribol/geom/CompGeom.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tribol/geom/CompGeom.hpp b/src/tribol/geom/CompGeom.hpp index 288c55a8..6f8a8263 100644 --- a/src/tribol/geom/CompGeom.hpp +++ b/src/tribol/geom/CompGeom.hpp @@ -2151,7 +2151,8 @@ TRIBOL_HOST_DEVICE inline FaceGeomException CommonPlanePair::computeOverlap3D( c cx[2], 1, &xInter_local, &yInter_local ); // get the local coordinates of the other face's centroid - RealT cx_other_local, cy_other_local; + RealT cx_other_local = 0; + RealT cy_other_local = 0; RealT cz = 0.; // dummy arg. VertexAvgCentroid( &x_other_local[0], &y_other_local[0], nullptr, num_nodes_other, cx_other_local, cy_other_local, cz ); From 32dad1a39d44eb862d4449fc7ec5c11bf894b0cc Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 14:20:02 -0700 Subject: [PATCH 10/23] order delete before return --- src/tests/tribol_comp_geom_3d.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/tribol_comp_geom_3d.cpp b/src/tests/tribol_comp_geom_3d.cpp index 86042237..3b104dc3 100644 --- a/src/tests/tribol_comp_geom_3d.cpp +++ b/src/tests/tribol_comp_geom_3d.cpp @@ -88,14 +88,14 @@ class CompGeomTest : public ::testing::Test { tribol::setKinematicConstantPenalty( meshId, 1.0 ); - return tribol::update( 1, 1., dt ); - delete[] fx; delete[] fy; delete[] fz; delete[] vx; delete[] vy; delete[] vz; + + return tribol::update( 1, 1., dt ); } protected: From 3f7abdc104b5b0f9383a81a4a0e355dfb4be829f Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 14:32:43 -0700 Subject: [PATCH 11/23] actually fix the delete issue --- src/tests/tribol_comp_geom_3d.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/tribol_comp_geom_3d.cpp b/src/tests/tribol_comp_geom_3d.cpp index 3b104dc3..523aebe3 100644 --- a/src/tests/tribol_comp_geom_3d.cpp +++ b/src/tests/tribol_comp_geom_3d.cpp @@ -88,6 +88,8 @@ class CompGeomTest : public ::testing::Test { tribol::setKinematicConstantPenalty( meshId, 1.0 ); + const int update_err = tribol::update( 1, 1., dt ); + delete[] fx; delete[] fy; delete[] fz; @@ -95,7 +97,7 @@ class CompGeomTest : public ::testing::Test { delete[] vy; delete[] vz; - return tribol::update( 1, 1., dt ); + return update_err; } protected: From a409987ba3fc02fdb07f33982fd68f2f9f2d0079 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 14:43:24 -0700 Subject: [PATCH 12/23] turn on warnings as errors using blt --- CMakeLists.txt | 3 +++ cmake/Options.cmake | 1 - cmake/TribolCompilerFlags.cmake | 6 ------ 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 773b9757..b361e0d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,9 @@ if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") set(BLT_REQUIRED_CLANGFORMAT_VERSION "19" CACHE STRING "") endif() +set(ENABLE_ALL_WARNINGS ON CACHE BOOL "") +set(ENABLE_WARNINGS_AS_ERRORS ON CACHE BOOL "") + include(${BLT_SOURCE_DIR}/SetupBLT.cmake) #------------------------------------------------------------------------------ diff --git a/cmake/Options.cmake b/cmake/Options.cmake index 4aca720c..f3d836da 100644 --- a/cmake/Options.cmake +++ b/cmake/Options.cmake @@ -19,7 +19,6 @@ endif() option(TRIBOL_USE_SINGLE_PRECISION "Use single-precision floating point" OFF) option(TRIBOL_USE_64BIT_INDEXTYPE "Use 64-bit index type" OFF) -option(TRIBOL_ENABLE_WARNINGS_AS_ERRORS "Treat compiler warnings as errors in Tribol" ON) option(TRIBOL_ENABLE_ASAN "Enable AddressSanitizer for memory checking (Clang or GCC only)" OFF) if(TRIBOL_ENABLE_ASAN) diff --git a/cmake/TribolCompilerFlags.cmake b/cmake/TribolCompilerFlags.cmake index 29d44201..59b47038 100644 --- a/cmake/TribolCompilerFlags.cmake +++ b/cmake/TribolCompilerFlags.cmake @@ -10,12 +10,6 @@ if(TRIBOL_ENABLE_ASAN) endforeach() endif() -if(TRIBOL_ENABLE_WARNINGS_AS_ERRORS AND NOT ENABLE_WARNINGS_AS_ERRORS) - message(STATUS "Treating compiler warnings as errors in Tribol (TRIBOL_ENABLE_WARNINGS_AS_ERRORS)") - string(APPEND CMAKE_C_FLAGS " ${BLT_WARNINGS_AS_ERRORS_C_FLAG}") - string(APPEND CMAKE_CXX_FLAGS " ${BLT_WARNINGS_AS_ERRORS_CXX_FLAG}") -endif() - # Need to add symbols to dynamic symtab in order to be visible from stacktraces string(APPEND CMAKE_EXE_LINKER_FLAGS " -rdynamic") From 4200e3ea0c347b27f326b18af76f80f064976a29 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 16:40:42 -0700 Subject: [PATCH 13/23] remove this from lambda capture on device --- src/tribol/search/InterfacePairFinder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tribol/search/InterfacePairFinder.cpp b/src/tribol/search/InterfacePairFinder.cpp index ad2bcb30..19031a94 100644 --- a/src/tribol/search/InterfacePairFinder.cpp +++ b/src/tribol/search/InterfacePairFinder.cpp @@ -490,7 +490,7 @@ class BvhSearch : public SearchBase { { auto boxes_view = boxes.view(); forAllExec( m_coupling_scheme->getExecutionMode(), mesh.numberOfElements(), - [this, mesh, boxes_view, binning_proximity] TRIBOL_HOST_DEVICE( IndexT i ) { + [mesh, boxes_view, binning_proximity] TRIBOL_HOST_DEVICE( IndexT i ) { BoxT box; auto num_nodes_per_elem = mesh.numberOfNodesPerElement(); for ( IndexT j{ 0 }; j < num_nodes_per_elem; ++j ) { @@ -516,7 +516,7 @@ class BvhSearch : public SearchBase { * Expands bounding box by projecting the face normal by a distance * equal to the effective face radius */ - TRIBOL_HOST_DEVICE void expandBBoxNormal( BoxT& bbox, const VectorT& faceNormal, const RealT faceRadius ) + TRIBOL_HOST_DEVICE static void expandBBoxNormal( BoxT& bbox, const VectorT& faceNormal, const RealT faceRadius ) { PointT p0 = bbox.getCentroid(); RayT outwardRay( p0, faceNormal ); From f06cc13479c0d2f3530971965efcd63563a93e7e Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 22:32:41 -0700 Subject: [PATCH 14/23] empty initializer to get rid of warning --- src/tribol/mesh/CouplingScheme.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tribol/mesh/CouplingScheme.hpp b/src/tribol/mesh/CouplingScheme.hpp index 9c77e984..b053d126 100644 --- a/src/tribol/mesh/CouplingScheme.hpp +++ b/src/tribol/mesh/CouplingScheme.hpp @@ -1111,7 +1111,8 @@ TRIBOL_HOST_DEVICE inline bool CouplingScheme::Viewer::pruneMethodFacePair( cons } } - RealT nrml[max_dim], cx[max_dim]; + RealT nrml[max_dim]{}; + RealT cx[max_dim]{}; switch ( m_contact_method ) { case ALIGNED_MORTAR: From 387b25d7f5dc5b0b8551fd2f7b366f30f2b19ef2 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 22:51:05 -0700 Subject: [PATCH 15/23] take care of some more uninitialized variables --- src/tribol/integ/FE.hpp | 7 +++++-- src/tribol/physics/AlignedMortar.cpp | 18 ++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/tribol/integ/FE.hpp b/src/tribol/integ/FE.hpp index 9281dc1e..56e9dc8d 100644 --- a/src/tribol/integ/FE.hpp +++ b/src/tribol/integ/FE.hpp @@ -472,6 +472,7 @@ TRIBOL_HOST_DEVICE inline void GalerkinEval( const RealT* const x, const RealT p TRIBOL_HOST_DEVICE inline void EvalBasis( const RealT* const x, const RealT pX, const RealT pY, const RealT pZ, const int numPoints, const int vertexId, RealT& phi ) { + phi = 0.; if ( numPoints > 2 ) { WachspressBasis( x, pX, pY, pZ, numPoints, vertexId, phi ); } else if ( numPoints == 2 ) { @@ -524,14 +525,16 @@ TRIBOL_HOST_DEVICE inline void SegmentBasis( const RealT* const x, const RealT p TRIBOL_HOST_DEVICE inline void WachspressBasis( const RealT* const x, const RealT pX, const RealT pY, const RealT pZ, const int numPoints, const int vertexId, RealT& phi ) { + constexpr int max_nodes_per_elem = 4; #ifdef TRIBOL_USE_HOST SLIC_ERROR_IF( numPoints < 3, "WachspressBasis: numPoints < 3." ); + SLIC_ERROR_IF( numPoints > max_nodes_per_elem, "WachspressBasis: numPoints > 4." ); + SLIC_ERROR_IF( vertexId < 0 || vertexId >= numPoints, "WachspressBasis: vertexId is out of bounds." ); #endif // first compute the areas of all the triangles formed by the i-1,i,i+1 vertices. // These consist of all the numerators in the Wachspress formulation // NOTE: this limits the routine to 4 noded quadrilaterals - constexpr int max_nodes_per_elem = 4; RealT triVertArea[max_nodes_per_elem]; for ( int i = 0; i < numPoints; ++i ) { // determine the i-1, i, i+1 vertices @@ -585,7 +588,7 @@ TRIBOL_HOST_DEVICE inline void WachspressBasis( const RealT* const x, const Real // third, compute all of the weights per Wachspress formulation RealT weight[max_nodes_per_elem]; - RealT myWeight; + RealT myWeight = 0.; RealT weightSum = 0.; for ( int i = 0; i < numPoints; ++i ) { int vId = i; diff --git a/src/tribol/physics/AlignedMortar.cpp b/src/tribol/physics/AlignedMortar.cpp index a9aac9ec..b91f0ef8 100644 --- a/src/tribol/physics/AlignedMortar.cpp +++ b/src/tribol/physics/AlignedMortar.cpp @@ -34,7 +34,9 @@ void ComputeAlignedMortarWeights( SurfaceContactElem& elem ) // also initializes the array elem.allocateMortarWts(); - RealT phiNonmortarA, phiNonmortarB, phiMortarA; + RealT phiNonmortarA = 0.; + RealT phiNonmortarB = 0.; + RealT phiMortarA = 0.; // loop over nodes "a", where node "a" can be a nonmortar node or a mortar node for ( int a = 0; a < elem.numFaceVert; ++a ) { @@ -84,8 +86,7 @@ void ComputeNodalGap( SurfaceContactElem& elem ) // set the distance magnitude tolerance as the longest edge of // the mortar face - RealT magTol; - RealT magTest = 0.; + RealT magTol = 0.; for ( int k = 0; k < elem.numFaceVert; ++k ) { int idPlus = ( k == ( elem.numFaceVert - 1 ) ) ? 0 : k + 1; RealT dx = elem.faceCoords1[elem.dim * idPlus] - elem.faceCoords1[elem.dim * k]; @@ -94,8 +95,7 @@ void ComputeNodalGap( SurfaceContactElem& elem ) RealT mag = magnitude( dx, dy, dz ); - magTol = ( mag > magTest ) ? mag : magTest; - magTest = mag; + magTol = ( mag > magTol ) ? mag : magTol; } // loop over nodes on nonmortar side @@ -113,7 +113,7 @@ void ComputeNodalGap( SurfaceContactElem& elem ) // determine which mortar node is aligned with // nonmortar node "a" ////////////////////////////////////////////// - int mortarNodeId; + int mortarNodeId = -1; RealT v[3] = { 0., 0., 0. }; RealT magTest = magTol; // loop over nodes on the mortar side @@ -130,6 +130,12 @@ void ComputeNodalGap( SurfaceContactElem& elem ) } } + SLIC_ERROR_IF( mortarNodeId < 0, + "ComputeNodalGap< ALIGNED_MORTAR >: unable to find an aligned mortar node." ); + if ( mortarNodeId < 0 ) { + continue; + } + // store local gap v[0] = elem.faceCoords1[elem.dim * mortarNodeId] - elem.faceCoords2[elem.dim * a]; v[1] = elem.faceCoords1[elem.dim * mortarNodeId + 1] - elem.faceCoords2[elem.dim * a + 1]; From 23d4e4944b5d6c2347636762860a699d337312aa Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 22:56:02 -0700 Subject: [PATCH 16/23] formatting --- src/tribol/physics/AlignedMortar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tribol/physics/AlignedMortar.cpp b/src/tribol/physics/AlignedMortar.cpp index b91f0ef8..fb216298 100644 --- a/src/tribol/physics/AlignedMortar.cpp +++ b/src/tribol/physics/AlignedMortar.cpp @@ -130,8 +130,7 @@ void ComputeNodalGap( SurfaceContactElem& elem ) } } - SLIC_ERROR_IF( mortarNodeId < 0, - "ComputeNodalGap< ALIGNED_MORTAR >: unable to find an aligned mortar node." ); + SLIC_ERROR_IF( mortarNodeId < 0, "ComputeNodalGap< ALIGNED_MORTAR >: unable to find an aligned mortar node." ); if ( mortarNodeId < 0 ) { continue; } From 5ecec5bfa51efae16ffd7b4eca4a04cf25a8da6d Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 23:06:02 -0700 Subject: [PATCH 17/23] more maybe uninitialized fixes --- src/tribol/physics/Mortar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tribol/physics/Mortar.cpp b/src/tribol/physics/Mortar.cpp index fd75170e..03303af1 100644 --- a/src/tribol/physics/Mortar.cpp +++ b/src/tribol/physics/Mortar.cpp @@ -56,7 +56,9 @@ void ComputeMortarWeights( SurfaceContactElem& elem ) // also initializes the array elem.allocateMortarWts(); - RealT phiNonmortarA, phiNonmortarB, phiMortarA; + RealT phiNonmortarA = 0.; + RealT phiNonmortarB = 0.; + RealT phiMortarA = 0.; // loop over number of nodes on the nonmortar or mortar depending on whether forming // nonmortar/nonmortar or mortar/nonmortar weights From 1a1c4151df42fb290d26949bd21183212805e982 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 23:11:52 -0700 Subject: [PATCH 18/23] another maybe uninitialized --- src/tribol/utils/TestUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tribol/utils/TestUtils.cpp b/src/tribol/utils/TestUtils.cpp index 533acdec..f09bd38c 100644 --- a/src/tribol/utils/TestUtils.cpp +++ b/src/tribol/utils/TestUtils.cpp @@ -1767,7 +1767,7 @@ void TestMesh::testMeshToVtk( const std::string& dir, int cycle, RealT time ) // specify integer id for each cell type. mesh << "CELL_TYPES " << this->numTotalElements << std::endl; - int element_id; + int element_id = -1; switch ( this->numNodesPerElement ) { case 8: element_id = 12; // vtk 8-node hexahedron From 38a79af2c4dba928df65267310883eb22301273a Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Tue, 11 Aug 2026 12:12:39 -0700 Subject: [PATCH 19/23] move warnings as errors to standalone build defaults Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b361e0d1..d548b957 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,11 +77,10 @@ if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") endforeach() set(BLT_REQUIRED_CLANGFORMAT_VERSION "19" CACHE STRING "") + set(ENABLE_ALL_WARNINGS ON CACHE BOOL "") + set(ENABLE_WARNINGS_AS_ERRORS ON CACHE BOOL "") endif() -set(ENABLE_ALL_WARNINGS ON CACHE BOOL "") -set(ENABLE_WARNINGS_AS_ERRORS ON CACHE BOOL "") - include(${BLT_SOURCE_DIR}/SetupBLT.cmake) #------------------------------------------------------------------------------ From 53adf13481c32de4ceaf7270ad9e0f0307481fc9 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Tue, 11 Aug 2026 14:00:18 -0700 Subject: [PATCH 20/23] merge mpi library logic --- cmake/thirdparty/SetupMFEM.cmake | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/cmake/thirdparty/SetupMFEM.cmake b/cmake/thirdparty/SetupMFEM.cmake index 36cf39c6..961c7e32 100644 --- a/cmake/thirdparty/SetupMFEM.cmake +++ b/cmake/thirdparty/SetupMFEM.cmake @@ -142,25 +142,18 @@ else() TREAT_INCLUDES_AS_SYSTEM ON EXPORTABLE ON) - # Tribol edit - if(_mfem_uses_mpi) - if(NOT TARGET blt::mpi) - message(FATAL_ERROR "MFEM was built with MPI support, but MPI is not enabled in BLT. Configure with ENABLE_MPI=ON.") - endif() - # Note: -lmpifort is being added to MFEM's link line w/o a -L - list(GET MPI_C_LIBRARIES 0 _first_mpi_lib) - get_filename_component(_mpi_lib_dir ${_first_mpi_lib} DIRECTORY) - target_link_directories(mfem INTERFACE ${_mpi_lib_dir}) - target_link_libraries(mfem INTERFACE blt::mpi) - endif() - # End Tribol edit - endif() -if(MFEM_BUILT_WITH_CMAKE AND _mfem_uses_mpi) +if(_mfem_uses_mpi) if(NOT TARGET blt::mpi) message(FATAL_ERROR "MFEM was built with MPI support, but MPI is not enabled in BLT. Configure with ENABLE_MPI=ON.") endif() + if(NOT MFEM_BUILT_WITH_CMAKE) + # Note: -lmpifort is being added to MFEM's link line w/o a -L + list(GET MPI_C_LIBRARIES 0 _first_mpi_lib) + get_filename_component(_mpi_lib_dir ${_first_mpi_lib} DIRECTORY) + target_link_directories(mfem INTERFACE ${_mpi_lib_dir}) + endif() target_link_libraries(mfem INTERFACE blt::mpi) endif() From 4536f11905e3fe2a49540efc62713dc618331049 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Tue, 11 Aug 2026 17:37:50 -0700 Subject: [PATCH 21/23] new unused variable --- src/tribol/geom/CompGeom.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tribol/geom/CompGeom.hpp b/src/tribol/geom/CompGeom.hpp index 6f8a8263..cffbb483 100644 --- a/src/tribol/geom/CompGeom.hpp +++ b/src/tribol/geom/CompGeom.hpp @@ -2466,6 +2466,9 @@ TRIBOL_HOST_DEVICE inline FaceGeomException CommonPlanePair::projectPointsAndCom << "input number of vertices to match number of nodes per element." ); } } +#else + TRIBOL_UNUSED_VAR( m1 ); + TRIBOL_UNUSED_VAR( m2 ); #endif constexpr int max_nodes_per_clipped_face = 5; From 1072f9c98b6f52923ffb6286e659ba5be0b535c9 Mon Sep 17 00:00:00 2001 From: "Eric B. Chin" Date: Mon, 10 Aug 2026 10:11:33 -0700 Subject: [PATCH 22/23] try some mfem openmp and mpi fixes --- cmake/thirdparty/SetupMFEM.cmake | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cmake/thirdparty/SetupMFEM.cmake b/cmake/thirdparty/SetupMFEM.cmake index 961c7e32..49e55140 100644 --- a/cmake/thirdparty/SetupMFEM.cmake +++ b/cmake/thirdparty/SetupMFEM.cmake @@ -164,6 +164,20 @@ if(_mfem_uses_openmp) target_link_libraries(mfem INTERFACE blt::openmp) endif() +if(MFEM_BUILT_WITH_CMAKE AND _mfem_uses_mpi) + if(NOT TARGET blt::mpi) + message(FATAL_ERROR "MFEM was built with MPI support, but MPI is not enabled in BLT. Configure with ENABLE_MPI=ON.") + endif() + target_link_libraries(mfem INTERFACE blt::mpi) +endif() + +if(_mfem_uses_openmp) + if(NOT TARGET blt::openmp) + message(FATAL_ERROR "MFEM was built with OpenMP support, but OpenMP is not enabled in BLT. Configure with ENABLE_OPENMP=ON.") + endif() + target_link_libraries(mfem INTERFACE blt::openmp) +endif() + include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set MFEM_FOUND to TRUE # if all listed variables are TRUE From 0dd873b6690ec19f0e340edf120fffb41e815f5a Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 12 Aug 2026 10:50:33 -0700 Subject: [PATCH 23/23] remove duplication --- cmake/thirdparty/SetupMFEM.cmake | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/cmake/thirdparty/SetupMFEM.cmake b/cmake/thirdparty/SetupMFEM.cmake index 49e55140..961c7e32 100644 --- a/cmake/thirdparty/SetupMFEM.cmake +++ b/cmake/thirdparty/SetupMFEM.cmake @@ -164,20 +164,6 @@ if(_mfem_uses_openmp) target_link_libraries(mfem INTERFACE blt::openmp) endif() -if(MFEM_BUILT_WITH_CMAKE AND _mfem_uses_mpi) - if(NOT TARGET blt::mpi) - message(FATAL_ERROR "MFEM was built with MPI support, but MPI is not enabled in BLT. Configure with ENABLE_MPI=ON.") - endif() - target_link_libraries(mfem INTERFACE blt::mpi) -endif() - -if(_mfem_uses_openmp) - if(NOT TARGET blt::openmp) - message(FATAL_ERROR "MFEM was built with OpenMP support, but OpenMP is not enabled in BLT. Configure with ENABLE_OPENMP=ON.") - endif() - target_link_libraries(mfem INTERFACE blt::openmp) -endif() - include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set MFEM_FOUND to TRUE # if all listed variables are TRUE