From acb99ecf747d50212c2c47db7582b38ff20fd4e1 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Thu, 26 Feb 2026 18:59:26 -0800 Subject: [PATCH 1/8] refactor traction boundary conditions. --- .../TractionBoundaryCondition.cpp | 203 ++++++++++++++++-- .../TractionBoundaryCondition.hpp | 3 + .../SolidMechanicsLagrangianFEM.cpp | 19 +- 3 files changed, 203 insertions(+), 22 deletions(-) diff --git a/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp b/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp index 2dab7ebfa4f..f1bdd9899f5 100644 --- a/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp +++ b/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp @@ -19,7 +19,10 @@ #include "TractionBoundaryCondition.hpp" +#include "finiteElement/elementFormulations/H1_TriangleFace_Lagrange1_Gauss.hpp" +#include "finiteElement/elementFormulations/H1_QuadrilateralFace_Lagrange1_GaussLegendre2.hpp" #include "functions/TableFunction.hpp" +#include "LvArray/src/math.hpp" namespace geos { @@ -132,15 +135,191 @@ void TractionBoundaryCondition::initializePreSubGroups() } +/** + * @brief Integrate a uniform traction over a face using a standard FE face formulation. + * + * @tparam FE_TYPE The finite element face type (e.g. H1_TriangleFace_Lagrange1_Gauss1_impl, + * H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl). + * Must provide: numNodes, numQuadraturePoints, calcN(), transformedQuadratureWeight(). + * @param traction The traction vector [3] to integrate. + * @param xFace The face node coordinates in FE ordering [numNodes][3]. + * @param permutation Mapping from FE node index to mesh face-local node index. + * Accounts for ordering differences (e.g. tensor-product vs CCW). + * @param faceToNodeMap The face-to-node connectivity map. + * @param kf The face index. + * @param blockLocalDofNumber Block-local DOF numbering. + * @param dofRankOffset The rank offset for DOFs. + * @param localRhs The local RHS vector to assemble into. + */ +template< typename FE_TYPE > +GEOS_HOST_DEVICE +inline +void integrateFaceTraction( real64 const ( &traction )[3], + real64 const ( &xFace )[FE_TYPE::numNodes][3], + int const ( &permutation )[FE_TYPE::numNodes], + ArrayOfArraysView< localIndex const > const & faceToNodeMap, + localIndex const kf, + arrayView1d< globalIndex const > const & blockLocalDofNumber, + globalIndex const dofRankOffset, + arrayView1d< real64 > const & localRhs ) +{ + constexpr localIndex numNodes = FE_TYPE::numNodes; + constexpr localIndex numQuadraturePoints = FE_TYPE::numQuadraturePoints; + + // Accumulate per-node integration weight: w_a = sum_q N_a(q) * |J(q)| * wq + real64 nodalWeight[numNodes] = { 0.0 }; + + for( localIndex q = 0; q < numQuadraturePoints; ++q ) + { + real64 N[numNodes]; + FE_TYPE::calcN( q, N ); + + real64 const detJxW = FE_TYPE::transformedQuadratureWeight( q, xFace ); + + for( localIndex a = 0; a < numNodes; ++a ) + { + nodalWeight[a] += N[a] * detJxW; + } + } + + // Assemble traction * nodalWeight into the RHS. + // Use the permutation to map FE node 'a' back to the mesh face-local node index. + for( localIndex a = 0; a < numNodes; ++a ) + { + localIndex const meshNodeIdx = permutation[a]; + localIndex const dof = blockLocalDofNumber[ faceToNodeMap( kf, meshNodeIdx ) ] - dofRankOffset; + if( dof < 0 || dof >= localRhs.size() ) + continue; + RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+0], traction[0] * nodalWeight[a] ); + RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+1], traction[1] * nodalWeight[a] ); + RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+2], traction[2] * nodalWeight[a] ); + } +} + +/** + * @brief Integrate a uniform traction over a general polygon face. + * + * This is a fallback for faces that are not triangles or quadrilaterals. + * + * @param traction The traction vector [3] to integrate. + * @param faceArea The area of the face. + * @param numNodes The number of nodes of the face. + * @param faceToNodeMap The face-to-node connectivity map. + * @param kf The face index. + * @param blockLocalDofNumber Block-local DOF numbering. + * @param dofRankOffset The rank offset for DOFs. + * @param localRhs The local RHS vector to assemble into. + */ +GEOS_HOST_DEVICE +inline +void integrateFaceTractionPolygon( real64 const ( &traction )[3], + real64 const faceArea, + localIndex const numNodes, + ArrayOfArraysView< localIndex const > const & faceToNodeMap, + localIndex const kf, + arrayView1d< globalIndex const > const & blockLocalDofNumber, + globalIndex const dofRankOffset, + arrayView1d< real64 > const & localRhs ) +{ + real64 const w = faceArea / numNodes; + for( localIndex a = 0; a < numNodes; ++a ) + { + localIndex const dof = blockLocalDofNumber[ faceToNodeMap( kf, a ) ] - dofRankOffset; + if( dof < 0 || dof >= localRhs.size() ) + continue; + RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+0], traction[0] * w ); + RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+1], traction[1] * w ); + RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+2], traction[2] * w ); + } +} + +/** + * @brief Dispatch face traction integration to the appropriate FE formulation. + * + * Selects the FE face type based on numNodes: + * - 3 nodes: H1_TriangleFace_Lagrange1_Gauss1_impl + * - 4 nodes: H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl + * - Other: Equal distribution fallback + * + * @param traction The traction vector [3]. + * @param numNodes The number of nodes of the face. + * @param faceArea The area of the face (only used for polygon fallback). + * @param faceToNodeMap The face-to-node connectivity map. + * @param kf The face index. + * @param nodePositions The reference positions of all nodes. + * @param blockLocalDofNumber Block-local DOF numbering. + * @param dofRankOffset The rank offset for DOFs. + * @param localRhs The local RHS vector to assemble into. + */ +GEOS_HOST_DEVICE +inline +void assembleFaceTraction( real64 const ( &traction )[3], + localIndex const numNodes, + real64 const faceArea, + ArrayOfArraysView< localIndex const > const & faceToNodeMap, + localIndex const kf, + arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & nodePositions, + arrayView1d< globalIndex const > const & blockLocalDofNumber, + globalIndex const dofRankOffset, + arrayView1d< real64 > const & localRhs ) +{ + using TriFace = finiteElement::H1_TriangleFace_Lagrange1_Gauss1_impl; + using QuadFace = finiteElement::H1_QuadrilateralFace_Lagrange1_GaussLegendre2_impl; + + if( numNodes == 3 ) + { + // Get the permutation mapping from FE node ordering to mesh face-local node ordering. + int permutation[TriFace::numNodes]; + TriFace::getPermutation( permutation ); + + // Gather coordinates in FE ordering: xFace[feNode] = coords of mesh node permutation[feNode] + real64 xFace[TriFace::numNodes][3]; + for( localIndex a = 0; a < TriFace::numNodes; ++a ) + { + localIndex const nodeIdx = faceToNodeMap( kf, permutation[a] ); + xFace[a][0] = nodePositions( nodeIdx, 0 ); + xFace[a][1] = nodePositions( nodeIdx, 1 ); + xFace[a][2] = nodePositions( nodeIdx, 2 ); + } + integrateFaceTraction< TriFace >( traction, xFace, permutation, faceToNodeMap, kf, + blockLocalDofNumber, dofRankOffset, localRhs ); + } + else if( numNodes == 4 ) + { + // Get the permutation mapping from FE node ordering to mesh face-local node ordering. + // For quads: FE uses Z-ordering (tensor product), mesh uses CCW ordering. + // getPermutation returns {0, 1, 3, 2} meaning FE node 2 → mesh node 3 and vice versa. + int permutation[QuadFace::numNodes]; + QuadFace::getPermutation( permutation ); + + // Gather coordinates in FE ordering: xFace[feNode] = coords of mesh node permutation[feNode] + real64 xFace[QuadFace::numNodes][3]; + for( localIndex a = 0; a < QuadFace::numNodes; ++a ) + { + localIndex const nodeIdx = faceToNodeMap( kf, permutation[a] ); + xFace[a][0] = nodePositions( nodeIdx, 0 ); + xFace[a][1] = nodePositions( nodeIdx, 1 ); + xFace[a][2] = nodePositions( nodeIdx, 2 ); + } + integrateFaceTraction< QuadFace >( traction, xFace, permutation, faceToNodeMap, kf, + blockLocalDofNumber, dofRankOffset, localRhs ); + } + else + { + integrateFaceTractionPolygon( traction, faceArea, numNodes, faceToNodeMap, kf, + blockLocalDofNumber, dofRankOffset, localRhs ); + } +} + + void TractionBoundaryCondition::launch( real64 const time, arrayView1d< globalIndex const > const blockLocalDofNumber, globalIndex const dofRankOffset, FaceManager const & faceManager, + arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const nodePositions, SortedArrayView< localIndex const > const & targetSet, arrayView1d< real64 > const & localRhs ) const { - - arrayView1d< real64 const > const faceArea = faceManager.faceArea(); arrayView2d< real64 const > const faceNormal = faceManager.faceNormal(); ArrayOfArraysView< localIndex const > const faceToNodeMap = faceManager.nodeList().toViewConst(); @@ -193,11 +372,9 @@ void TractionBoundaryCondition::launch( real64 const time, real64 const nodalScale = ( nodalScaleFlag == 1 ) ? scaleSet[i] : 1.0; - // TODO consider dispatch if appropriate real64 const tractionMagnitude = spatialFunction ? tractionMagnitudeArrayView[i] : (tractionMagnitude0 * nodalScale); real64 traction[3] = { 0 }; - // TODO consider dispatch if appropriate if( tractionType == TractionType::vector ) { traction[0] = tractionMagnitude * direction[0]; @@ -222,23 +399,11 @@ void TractionBoundaryCondition::launch( real64 const time, traction[1] = inputStress[5] * temp[0] + inputStress[1] * temp[1] + inputStress[3] * temp[2]; traction[2] = inputStress[4] * temp[0] + inputStress[3] * temp[1] + inputStress[2] * temp[2]; } - } - // TODO replace with proper FEM integration - traction[0] *= faceArea[kf] / numNodes; - traction[1] *= faceArea[kf] / numNodes; - traction[2] *= faceArea[kf] / numNodes; - - for( localIndex a=0; a= localRhs.size() ) - continue; - RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+0], traction[0] ); - RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+1], traction[1] ); - RAJA::atomicAdd< parallelDeviceAtomic >( &localRhs[dof+2], traction[2] ); - } + // Dispatch face traction integration to the appropriate FE formulation + assembleFaceTraction( traction, numNodes, faceArea[kf], faceToNodeMap, kf, + nodePositions, blockLocalDofNumber, dofRankOffset, localRhs ); } ); } } diff --git a/src/coreComponents/fieldSpecification/TractionBoundaryCondition.hpp b/src/coreComponents/fieldSpecification/TractionBoundaryCondition.hpp index 466f8cd4d2c..9d32b2becc0 100644 --- a/src/coreComponents/fieldSpecification/TractionBoundaryCondition.hpp +++ b/src/coreComponents/fieldSpecification/TractionBoundaryCondition.hpp @@ -23,6 +23,7 @@ #include "FieldSpecificationBase.hpp" #include "mesh/FaceManager.hpp" +#include "mesh/NodeManager.hpp" namespace geos { @@ -71,6 +72,7 @@ class TractionBoundaryCondition : public FieldSpecificationBase * @param blockLocalDofNumber Array of block local DOF numbers for the displacement. * @param dofRankOffset The rank offset for the DOF. * @param faceManager Reference to the face manager (Tractions are applied on faces) + * @param nodePositions The reference position of all nodes (used for proper FEM integration on faces) * @param targetSet The set of faces to apply the BC to. * @param localRhs The RHS of the system to add contributions to. */ @@ -78,6 +80,7 @@ class TractionBoundaryCondition : public FieldSpecificationBase arrayView1d< globalIndex const > const blockLocalDofNumber, globalIndex const dofRankOffset, FaceManager const & faceManager, + arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const nodePositions, SortedArrayView< localIndex const > const & targetSet, arrayView1d< real64 > const & localRhs ) const; diff --git a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp index dcf51ae7c19..1f86e3ad2d2 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp @@ -499,6 +499,18 @@ real64 SolidMechanicsLagrangianFEM::solverStep( real64 const & time_n, { int const maxNumResolves = m_maxNumResolves; int globallyFractured = 0; + + // Check if mesh was modified by an external event (e.g., SurfaceGen) before this solver step + // This ensures setupSystem is called before implicitStepSetup when topology changes occur + Timestamp const initialMeshModificationTimestamp = getMeshModificationTimestamp( domain ); + MeshLevel & meshLevel = domain.getMeshBody( 0 ).getMeshLevel( m_discretizationName ); + if( initialMeshModificationTimestamp > getSystemSetupTimestamp() || meshLevel.getModificationTimestamp() > getSystemSetupTimestamp() ) + { + m_dofManager.clear(); + setupSystem( domain, m_dofManager, m_localMatrix, m_rhs, m_solution, true ); + setSystemSetupTimestamp( std::max( initialMeshModificationTimestamp, meshLevel.getModificationTimestamp() ) ); + } + implicitStepSetup( time_n, dt, domain ); for( int solveIter=0; solveIter getSystemSetupTimestamp() || globallyFractured ) + if( meshModificationTimestamp > getSystemSetupTimestamp() || meshLevel.getModificationTimestamp() > getSystemSetupTimestamp() || globallyFractured ) { setupSystem( domain, m_dofManager, m_localMatrix, m_rhs, m_solution ); - setSystemSetupTimestamp( meshModificationTimestamp ); + setSystemSetupTimestamp( std::max( meshModificationTimestamp, meshLevel.getModificationTimestamp() ) ); } dtReturn = nonlinearImplicitStep( time_n, @@ -736,7 +748,7 @@ void SolidMechanicsLagrangianFEM::applyDisplacementBCImplicit( real64 const time // if the log level is 0, we don't need the reduction below (hence this early check) if( getLogLevel() >= 1 ) { - integer isDisplacementBCAppliedGlobal[3]{}; + integer isDisplacementBCAppliedGlobal[3]; MpiWrapper::reduce( isDisplacementBCApplied, isDisplacementBCAppliedGlobal, 3, @@ -798,6 +810,7 @@ void SolidMechanicsLagrangianFEM::applyTractionBC( real64 const time, blockLocalDofNumber, dofRankOffset, faceManager, + nodeManager.referencePosition(), targetSet, localRhs ); } ); From 968102e25c1588e2133f1218fcfa4de11fc22e15 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Thu, 26 Feb 2026 19:01:13 -0800 Subject: [PATCH 2/8] refactor traction boundary conditions II --- .../fieldSpecification/TractionBoundaryCondition.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp b/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp index f1bdd9899f5..fc32acbf408 100644 --- a/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp +++ b/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp @@ -22,7 +22,6 @@ #include "finiteElement/elementFormulations/H1_TriangleFace_Lagrange1_Gauss.hpp" #include "finiteElement/elementFormulations/H1_QuadrilateralFace_Lagrange1_GaussLegendre2.hpp" #include "functions/TableFunction.hpp" -#include "LvArray/src/math.hpp" namespace geos { From e4d2863048fc90f2e2a668568eaca93a0d60558b Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Thu, 26 Feb 2026 19:43:26 -0800 Subject: [PATCH 3/8] Triggering CI/CD pipeline From 4954fb783f97df4ee70c25f7c95b7665c7e43237 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Thu, 26 Feb 2026 19:44:55 -0800 Subject: [PATCH 4/8] Triggering CI/CD pipeline From beca407bb45aaa1c29425a03477415a5076ab0db Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Fri, 27 Feb 2026 07:56:00 -0800 Subject: [PATCH 5/8] Update src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp Co-authored-by: Nicola Castelletto <38361926+castelletto1@users.noreply.github.com> --- .../solidMechanics/SolidMechanicsLagrangianFEM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp index 1f86e3ad2d2..8a37f990227 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp @@ -508,7 +508,7 @@ real64 SolidMechanicsLagrangianFEM::solverStep( real64 const & time_n, { m_dofManager.clear(); setupSystem( domain, m_dofManager, m_localMatrix, m_rhs, m_solution, true ); - setSystemSetupTimestamp( std::max( initialMeshModificationTimestamp, meshLevel.getModificationTimestamp() ) ); + setSystemSetupTimestamp( LvArray::math::max( initialMeshModificationTimestamp, meshLevel.getModificationTimestamp() ) ); } implicitStepSetup( time_n, dt, domain ); From b6f4cebf9025cac889ffe0cad537c8aa7dcaecc5 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Fri, 27 Feb 2026 07:56:15 -0800 Subject: [PATCH 6/8] Update src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp Co-authored-by: Nicola Castelletto <38361926+castelletto1@users.noreply.github.com> --- .../solidMechanics/SolidMechanicsLagrangianFEM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp index 8a37f990227..38f8e59a8fe 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp @@ -522,7 +522,7 @@ real64 SolidMechanicsLagrangianFEM::solverStep( real64 const & time_n, if( meshModificationTimestamp > getSystemSetupTimestamp() || meshLevel.getModificationTimestamp() > getSystemSetupTimestamp() || globallyFractured ) { setupSystem( domain, m_dofManager, m_localMatrix, m_rhs, m_solution ); - setSystemSetupTimestamp( std::max( meshModificationTimestamp, meshLevel.getModificationTimestamp() ) ); + setSystemSetupTimestamp( LvArray::math::max( meshModificationTimestamp, meshLevel.getModificationTimestamp() ) ); } dtReturn = nonlinearImplicitStep( time_n, From 748722197606186e47709f1bc1db73a65e2d0799 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Fri, 27 Feb 2026 07:56:25 -0800 Subject: [PATCH 7/8] Update src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp Co-authored-by: Nicola Castelletto <38361926+castelletto1@users.noreply.github.com> --- .../fieldSpecification/TractionBoundaryCondition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp b/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp index fc32acbf408..5a98edb67c2 100644 --- a/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp +++ b/src/coreComponents/fieldSpecification/TractionBoundaryCondition.cpp @@ -166,7 +166,7 @@ void integrateFaceTraction( real64 const ( &traction )[3], constexpr localIndex numQuadraturePoints = FE_TYPE::numQuadraturePoints; // Accumulate per-node integration weight: w_a = sum_q N_a(q) * |J(q)| * wq - real64 nodalWeight[numNodes] = { 0.0 }; + real64 nodalWeight[numNodes] {}; for( localIndex q = 0; q < numQuadraturePoints; ++q ) { From 18498c581c671de106bb39f3b37bba4f4ee8a2e2 Mon Sep 17 00:00:00 2001 From: Omar Duran Date: Fri, 27 Feb 2026 12:31:16 -0800 Subject: [PATCH 8/8] fix: rebase and include {} initialization. --- .integrated_tests.yaml | 2 +- BASELINE_NOTES.md | 4 ++++ .../solidMechanics/SolidMechanicsLagrangianFEM.cpp | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.integrated_tests.yaml b/.integrated_tests.yaml index 8819a54e041..8bc92055db7 100644 --- a/.integrated_tests.yaml +++ b/.integrated_tests.yaml @@ -1,6 +1,6 @@ baselines: bucket: geosx - baseline: integratedTests/baseline_integratedTests-pr3970-15479-074f42a + baseline: integratedTests/baseline_integratedTests-pr3986-15734-7487221 allow_fail: all: '' diff --git a/BASELINE_NOTES.md b/BASELINE_NOTES.md index 0e0ad277a6d..3efe0e4b57c 100644 --- a/BASELINE_NOTES.md +++ b/BASELINE_NOTES.md @@ -6,6 +6,10 @@ This file is designed to track changes to the integrated test baselines. Any developer who updates the baseline ID in the .integrated_tests.yaml file is expected to create an entry in this file with the pull request number, date, and their justification for rebaselining. These notes should be in reverse-chronological order, and use the following time format: (YYYY-MM-DD). +PR #3970 (2026-02-27) +===================== +Corrected traction boundary conditions + PR #3970 (2026-02-11) ===================== Bypass well residual calculation for closed wells diff --git a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp index 38f8e59a8fe..525be734d47 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp @@ -748,7 +748,7 @@ void SolidMechanicsLagrangianFEM::applyDisplacementBCImplicit( real64 const time // if the log level is 0, we don't need the reduction below (hence this early check) if( getLogLevel() >= 1 ) { - integer isDisplacementBCAppliedGlobal[3]; + integer isDisplacementBCAppliedGlobal[3]{}; MpiWrapper::reduce( isDisplacementBCApplied, isDisplacementBCAppliedGlobal, 3,