From 2deabaf99563c463b7268b19974bf5ef6112c51c Mon Sep 17 00:00:00 2001 From: npillardou Date: Wed, 28 Jan 2026 15:54:13 +0100 Subject: [PATCH 1/4] Add attribute field to outputs --- .../mesh/CellElementSubRegion.cpp | 5 +++++ .../mesh/ElementSubRegionBase.cpp | 5 +++++ .../mesh/ElementSubRegionBase.hpp | 12 +++++++++++ .../mesh/FaceElementSubRegion.cpp | 7 +++++++ src/coreComponents/mesh/MeshFields.hpp | 8 +++++++ .../mesh/generators/CellBlock.hpp | 17 +++++++++++++++ .../mesh/generators/CellBlockABC.hpp | 6 ++++++ .../mesh/generators/CellBlockManager.cpp | 1 + .../mesh/generators/FaceBlock.hpp | 17 +++++++++++++++ .../mesh/generators/FaceBlockABC.hpp | 6 ++++++ .../mesh/generators/VTKFaceBlockUtilities.cpp | 21 ++++++++++++++++++- .../mesh/generators/VTKFaceBlockUtilities.hpp | 4 +++- .../mesh/generators/VTKMeshGenerator.cpp | 2 +- 13 files changed, 108 insertions(+), 3 deletions(-) diff --git a/src/coreComponents/mesh/CellElementSubRegion.cpp b/src/coreComponents/mesh/CellElementSubRegion.cpp index 95b2ac8b269..c605804ac1d 100644 --- a/src/coreComponents/mesh/CellElementSubRegion.cpp +++ b/src/coreComponents/mesh/CellElementSubRegion.cpp @@ -82,6 +82,11 @@ void CellElementSubRegion::copyFromCellBlock( CellBlockABC const & cellBlock ) m_toFacesRelation.resize( this->size(), m_numFacesPerElement ); this->resize( cellBlock.numElements() ); + // Fill regionAttribute array with constant value from CellBlock + integer const regionAttr = cellBlock.getRegionAttribute(); + m_regionAttribute.resize( cellBlock.numElements() ); + m_regionAttribute.setValues< serialPolicy >( regionAttr ); + this->nodeList() = cellBlock.getElemToNodes(); this->edgeList() = cellBlock.getElemToEdges(); this->faceList() = cellBlock.getElemToFaces(); diff --git a/src/coreComponents/mesh/ElementSubRegionBase.cpp b/src/coreComponents/mesh/ElementSubRegionBase.cpp index 6234dbaca94..dd2abd7303a 100644 --- a/src/coreComponents/mesh/ElementSubRegionBase.cpp +++ b/src/coreComponents/mesh/ElementSubRegionBase.cpp @@ -47,6 +47,11 @@ ElementSubRegionBase::ElementSubRegionBase( string const & name, Group * const p registerWrapper( viewKeyStruct::elementVolumeString(), &m_elementVolume ). setPlotLevel( PlotLevel::LEVEL_1 ); + + registerWrapper( viewKeyStruct::attributeString(), &m_regionAttribute ). + setPlotLevel( PlotLevel::NOPLOT ). + setApplyDefaultValue( -1 ). + setDescription( "Region attribute value from mesh input." ); } ElementSubRegionBase::~ElementSubRegionBase() diff --git a/src/coreComponents/mesh/ElementSubRegionBase.hpp b/src/coreComponents/mesh/ElementSubRegionBase.hpp index 21810289001..efd3198ba1c 100644 --- a/src/coreComponents/mesh/ElementSubRegionBase.hpp +++ b/src/coreComponents/mesh/ElementSubRegionBase.hpp @@ -197,6 +197,13 @@ class ElementSubRegionBase : public ObjectManagerBase ElementType getElementType() const { return m_elementType; } + /** + * @brief Get the region attribute array. + * @return A const view to the region attribute array. + */ + arrayView1d< integer const > getRegionAttribute() const + { return m_regionAttribute; } + /** * @brief Setter for m_elementType * @param elemType They type of element for this ElementSubRegion. @@ -229,6 +236,8 @@ class ElementSubRegionBase : public ObjectManagerBase static constexpr char const * elementCenterString() { return "elementCenter"; } /// @return String key for the member level field for the element volume. static constexpr char const * elementVolumeString() { return "elementVolume"; } + /// @return String key for the attribute field. + static constexpr char const * attributeString() { return "attribute"; } }; /** @@ -264,6 +273,9 @@ class ElementSubRegionBase : public ObjectManagerBase /// Type of element in this subregion. ElementType m_elementType; + /// Region attribute value for elements in this subregion. + array1d< integer > m_regionAttribute; + /** * @brief Compute the center of each element in the subregion. * @tparam NODE_MAP Type of the element to node mapping. diff --git a/src/coreComponents/mesh/FaceElementSubRegion.cpp b/src/coreComponents/mesh/FaceElementSubRegion.cpp index ca1a0a79970..3c02c23795c 100644 --- a/src/coreComponents/mesh/FaceElementSubRegion.cpp +++ b/src/coreComponents/mesh/FaceElementSubRegion.cpp @@ -105,6 +105,13 @@ void FaceElementSubRegion::copyFromCellBlock( FaceBlockABC const & faceBlock ) localIndex const num2dElements = faceBlock.num2dElements(); resize( num2dElements ); + // Copy regionAttribute from FaceBlock + array1d< integer > const regionAttr = faceBlock.getRegionAttribute(); + if( regionAttr.size() > 0 ) + { + m_regionAttribute = regionAttr; + } + m_toNodesRelation.base() = faceBlock.get2dElemToNodes(); m_toEdgesRelation.base() = faceBlock.get2dElemToEdges(); diff --git a/src/coreComponents/mesh/MeshFields.hpp b/src/coreComponents/mesh/MeshFields.hpp index b560fdea048..6118ee15232 100644 --- a/src/coreComponents/mesh/MeshFields.hpp +++ b/src/coreComponents/mesh/MeshFields.hpp @@ -187,6 +187,14 @@ DECLARE_FIELD( tangentVector2, WRITE_AND_READ, "Unit vector in the second tangent direction to the surface." ); +DECLARE_FIELD( attribute, + "attribute", + array1d< integer >, + -1, + NOPLOT, + WRITE_AND_READ, + "Region attribute value from mesh input (constant per cell block)." ); + } // namespace fields } // namespace geos diff --git a/src/coreComponents/mesh/generators/CellBlock.hpp b/src/coreComponents/mesh/generators/CellBlock.hpp index 4d79fca2c7a..87df84d176a 100644 --- a/src/coreComponents/mesh/generators/CellBlock.hpp +++ b/src/coreComponents/mesh/generators/CellBlock.hpp @@ -67,6 +67,20 @@ class CellBlock : public CellBlockABC ElementType getElementType() const override { return m_elementType; } + /** + * @brief Get the region attribute for this cell block. + * @return The region attribute value. + */ + integer getRegionAttribute() const override + { return m_regionAttribute; } + + /** + * @brief Set the region attribute for this cell block. + * @param regionAttribute The region attribute value to set. + */ + void setRegionAttribute( integer regionAttribute ) + { m_regionAttribute = regionAttribute; } + localIndex numNodesPerElement() const override { return m_numNodesPerElement; } @@ -261,6 +275,9 @@ class CellBlock : public CellBlockABC /// Type of element in this block. ElementType m_elementType; + /// Region attribute value for this cell block. + integer m_regionAttribute = -1; + std::list< dataRepository::WrapperBase const * > getExternalProperties() const override { std::list< dataRepository::WrapperBase const * > result; diff --git a/src/coreComponents/mesh/generators/CellBlockABC.hpp b/src/coreComponents/mesh/generators/CellBlockABC.hpp index 7749ce687fe..86458f8a12a 100644 --- a/src/coreComponents/mesh/generators/CellBlockABC.hpp +++ b/src/coreComponents/mesh/generators/CellBlockABC.hpp @@ -126,6 +126,12 @@ class CellBlockABC : public dataRepository::Group } } + /** + * @brief Get the region attribute for this cell block. + * @return The region attribute value, or -1 if not set. + */ + virtual integer getRegionAttribute() const { return -1; } + private: /** * @brief Returns the external properties under the form of WrapperBase pointers. diff --git a/src/coreComponents/mesh/generators/CellBlockManager.cpp b/src/coreComponents/mesh/generators/CellBlockManager.cpp index 7506e96b77e..862b8492287 100644 --- a/src/coreComponents/mesh/generators/CellBlockManager.cpp +++ b/src/coreComponents/mesh/generators/CellBlockManager.cpp @@ -774,6 +774,7 @@ CellBlock & CellBlockManager::registerCellBlock( string const & cellBlockName, integer regionAttribute ) { CellBlock & cb = this->getCellBlocks().registerGroup< CellBlock >( cellBlockName ); + cb.setRegionAttribute( regionAttribute ); m_regionAttributesCellBlocks.get_inserted( regionAttribute ).emplace( cellBlockName ); return cb; } diff --git a/src/coreComponents/mesh/generators/FaceBlock.hpp b/src/coreComponents/mesh/generators/FaceBlock.hpp index 55b0d5840b8..c6893884dc6 100644 --- a/src/coreComponents/mesh/generators/FaceBlock.hpp +++ b/src/coreComponents/mesh/generators/FaceBlock.hpp @@ -60,6 +60,13 @@ class FaceBlock : public FaceBlockABC array1d< globalIndex > localToGlobalMap() const override; + /** + * @brief Get the region attribute for each 2d element. + * @return The region attribute values. + */ + array1d< integer > getRegionAttribute() const override + { return m_regionAttribute; } + /** * @brief Defines the number of 2d elements. * @param num2DElements The input value. @@ -120,6 +127,13 @@ class FaceBlock : public FaceBlockABC */ void set2dElemsToCollocatedNodesBuckets( ArrayOfArrays< array1d< globalIndex > > && collocatedNodesBuckets ); + /** + * @brief Defines the region attribute for each 2d element. + * @param regionAttribute The input array. + */ + void setRegionAttribute( array1d< integer > && regionAttribute ) + { m_regionAttribute = std::move( regionAttribute ); } + private: localIndex m_num2dElements; @@ -135,6 +149,9 @@ class FaceBlock : public FaceBlockABC array1d< localIndex > m_2dFaceToEdge; array1d< globalIndex > m_localToGlobalMap; + + /// Region attribute for each 2d element + array1d< integer > m_regionAttribute; }; diff --git a/src/coreComponents/mesh/generators/FaceBlockABC.hpp b/src/coreComponents/mesh/generators/FaceBlockABC.hpp index 2df82db9913..498f0958d93 100644 --- a/src/coreComponents/mesh/generators/FaceBlockABC.hpp +++ b/src/coreComponents/mesh/generators/FaceBlockABC.hpp @@ -170,6 +170,12 @@ class FaceBlockABC : public dataRepository::Group * @return The mapping relationship as an array. */ virtual array1d< globalIndex > localToGlobalMap() const = 0; + + /** + * @brief Get the region attribute for each 2d element. + * @return The region attribute values, or empty array if not set. + */ + virtual array1d< integer > getRegionAttribute() const { return {}; } }; } diff --git a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp index 46eff42dfd2..98826b15c6d 100644 --- a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp +++ b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp @@ -616,7 +616,8 @@ array1d< globalIndex > buildLocalToGlobal( vtkIdTypeArray const * faceMeshCellGl void importFractureNetwork( string const & faceBlockName, vtkSmartPointer< vtkDataSet > faceMesh, vtkSmartPointer< vtkDataSet > mesh, - CellBlockManager & cellBlockManager ) + CellBlockManager & cellBlockManager, + string const & regionAttributeName ) { ArrayOfArrays< localIndex > const faceToNodes = cellBlockManager.getFaceToNodes(); vtk::internal::ElementToFace const elemToFaces( cellBlockManager.getCellBlocks() ); @@ -645,10 +646,28 @@ void importFractureNetwork( string const & faceBlockName, ArrayOfArrays< localIndex > const elem2dToFace2d = buildElem2dToFace2d( num2dElements, face2dToElems2d.toViewConst() ); ArrayOfArrays< localIndex > elem2dToEdges = buildElem2dToEdges( num2dElements, face2dToEdge.toViewConst(), elem2dToFace2d.toViewConst() ); + // Read regionAttribute from the face mesh if available + array1d< integer > regionAttribute; + regionAttribute.resize( num2dElements ); + vtkDataArray * regionAttrArray = faceMesh->GetCellData()->GetArray( regionAttributeName.c_str() ); + if( regionAttrArray != nullptr ) + { + for( vtkIdType i = 0; i < num2dElements; ++i ) + { + regionAttribute[i] = static_cast< integer >( regionAttrArray->GetTuple1( i ) ); + } + } + else + { + // Default to -1 if no attribute found + regionAttribute.setValues< serialPolicy >( -1 ); + } + // Mappings are now computed. Just create the face block by value. FaceBlock & faceBlock = cellBlockManager.registerFaceBlock( faceBlockName ); faceBlock.setNum2dElements( num2dElements ); + faceBlock.setRegionAttribute( std::move( regionAttribute ) ); faceBlock.setNum2dFaces( num2dFaces ); faceBlock.set2dElemToNodes( std::move( elem2dTo3d.elem2dToNodes ) ); faceBlock.set2dElemToEdges( std::move( elem2dToEdges ) ); diff --git a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.hpp b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.hpp index f812071440d..0176cd469e0 100644 --- a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.hpp +++ b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.hpp @@ -32,11 +32,13 @@ namespace geos::vtk * @param faceMesh[in] The vtk mesh for the face block. * @param mesh[in] The vtk volumic mesh. * @param cellBlockManager[inout] The cell block manager that will receive the face block information. + * @param regionAttributeName[in] The name of the region attribute in the VTK data (default: "attribute"). */ void importFractureNetwork( string const & faceBlockName, vtkSmartPointer< vtkDataSet > faceMesh, vtkSmartPointer< vtkDataSet > mesh, - CellBlockManager & cellBlockManager ); + CellBlockManager & cellBlockManager, + string const & regionAttributeName = "attribute" ); } #endif // include guard diff --git a/src/coreComponents/mesh/generators/VTKMeshGenerator.cpp b/src/coreComponents/mesh/generators/VTKMeshGenerator.cpp index 8f1d434ad45..c302b4b3075 100644 --- a/src/coreComponents/mesh/generators/VTKMeshGenerator.cpp +++ b/src/coreComponents/mesh/generators/VTKMeshGenerator.cpp @@ -243,7 +243,7 @@ void VTKMeshGenerator::fillCellBlockManager( CellBlockManager & cellBlockManager for( auto const & [name, mesh]: m_faceBlockMeshes ) { - vtk::importFractureNetwork( name, mesh, m_vtkMesh, cellBlockManager ); + vtk::importFractureNetwork( name, mesh, m_vtkMesh, cellBlockManager, m_regionAttributeName ); } GEOS_LOG_LEVEL_RANK_0( logInfo::VTKSteps, GEOS_FMT( "{} '{}': done!", catalogName(), getName() ) ); From 56fd85e4444601be67f9db928b2a4fda9ba2268b Mon Sep 17 00:00:00 2001 From: npillardou Date: Fri, 12 Jun 2026 11:42:24 +0200 Subject: [PATCH 2/4] Add feature for input propagation --- .../mesh/CellElementSubRegion.cpp | 9 +- .../mesh/ElementSubRegionBase.cpp | 4 - .../mesh/ElementSubRegionBase.hpp | 12 -- .../mesh/FaceElementSubRegion.cpp | 23 +-- src/coreComponents/mesh/MeshFields.hpp | 8 -- .../mesh/generators/CellBlock.hpp | 17 --- .../mesh/generators/CellBlockABC.hpp | 6 - .../mesh/generators/CellBlockManager.cpp | 1 - .../mesh/generators/FaceBlock.hpp | 37 +++-- .../mesh/generators/FaceBlockABC.hpp | 27 +++- .../mesh/generators/VTKFaceBlockUtilities.cpp | 136 +++++++++++++++--- .../mesh/generators/VTKFaceBlockUtilities.hpp | 5 +- .../mesh/generators/VTKMeshGenerator.cpp | 12 +- .../mesh/generators/VTKMeshGenerator.hpp | 4 + .../mesh/generators/VTKUtilities.cpp | 84 ++++++++++- .../mesh/generators/VTKUtilities.hpp | 4 +- 16 files changed, 285 insertions(+), 104 deletions(-) diff --git a/src/coreComponents/mesh/CellElementSubRegion.cpp b/src/coreComponents/mesh/CellElementSubRegion.cpp index 261e7aa37e4..fc0409290d5 100644 --- a/src/coreComponents/mesh/CellElementSubRegion.cpp +++ b/src/coreComponents/mesh/CellElementSubRegion.cpp @@ -78,11 +78,6 @@ void CellElementSubRegion::copyFromCellBlock( CellBlockABC const & cellBlock ) m_toFacesRelation.resize( this->size(), m_numFacesPerElement ); this->resize( cellBlock.numElements() ); - // Fill regionAttribute array with constant value from CellBlock - integer const regionAttr = cellBlock.getRegionAttribute(); - m_regionAttribute.resize( cellBlock.numElements() ); - m_regionAttribute.setValues< serialPolicy >( regionAttr ); - this->nodeList() = cellBlock.getElemToNodes(); this->edgeList() = cellBlock.getElemToEdges(); this->faceList() = cellBlock.getElemToFaces(); @@ -96,7 +91,9 @@ void CellElementSubRegion::copyFromCellBlock( CellBlockABC const & cellBlock ) { using ArrayType = camp::first< decltype( tupleOfTypes ) >; auto const src = Wrapper< ArrayType >::cast( wrapper ).reference().toViewConst(); - ArrayType & dst = this->registerWrapper( wrapper.getName(), std::make_unique< ArrayType >() ).reference(); + ArrayType & dst = this->registerWrapper( wrapper.getName(), std::make_unique< ArrayType >() ) + .setPlotLevel( wrapper.getPlotLevel() ) + .reference(); // This is a hack since Array's copy ctor does not accept ArrayView source dst.resize( ArrayType::NDIM, src.dims() ); std::copy( src.data(), src.data() + src.size(), dst.data() ); diff --git a/src/coreComponents/mesh/ElementSubRegionBase.cpp b/src/coreComponents/mesh/ElementSubRegionBase.cpp index dd2abd7303a..70662168d50 100644 --- a/src/coreComponents/mesh/ElementSubRegionBase.cpp +++ b/src/coreComponents/mesh/ElementSubRegionBase.cpp @@ -48,10 +48,6 @@ ElementSubRegionBase::ElementSubRegionBase( string const & name, Group * const p registerWrapper( viewKeyStruct::elementVolumeString(), &m_elementVolume ). setPlotLevel( PlotLevel::LEVEL_1 ); - registerWrapper( viewKeyStruct::attributeString(), &m_regionAttribute ). - setPlotLevel( PlotLevel::NOPLOT ). - setApplyDefaultValue( -1 ). - setDescription( "Region attribute value from mesh input." ); } ElementSubRegionBase::~ElementSubRegionBase() diff --git a/src/coreComponents/mesh/ElementSubRegionBase.hpp b/src/coreComponents/mesh/ElementSubRegionBase.hpp index bb3a1c53735..3af0767c53b 100644 --- a/src/coreComponents/mesh/ElementSubRegionBase.hpp +++ b/src/coreComponents/mesh/ElementSubRegionBase.hpp @@ -197,13 +197,6 @@ class ElementSubRegionBase : public ObjectManagerBase ElementType getElementType() const { return m_elementType; } - /** - * @brief Get the region attribute array. - * @return A const view to the region attribute array. - */ - arrayView1d< integer const > getRegionAttribute() const - { return m_regionAttribute; } - /** * @brief Setter for m_elementType * @param elemType They type of element for this ElementSubRegion. @@ -236,8 +229,6 @@ class ElementSubRegionBase : public ObjectManagerBase static constexpr char const * elementCenterString() { return "elementCenter"; } /// @return String key for the member level field for the element volume. static constexpr char const * elementVolumeString() { return "elementVolume"; } - /// @return String key for the attribute field. - static constexpr char const * attributeString() { return "attribute"; } }; /** @@ -273,9 +264,6 @@ class ElementSubRegionBase : public ObjectManagerBase /// Type of element in this subregion. ElementType m_elementType; - /// Region attribute value for elements in this subregion. - array1d< integer > m_regionAttribute; - /** * @brief Compute the center of each element in the subregion. * @tparam NODE_MAP Type of the element to node mapping. diff --git a/src/coreComponents/mesh/FaceElementSubRegion.cpp b/src/coreComponents/mesh/FaceElementSubRegion.cpp index 357b339e343..845b9f6d7d9 100644 --- a/src/coreComponents/mesh/FaceElementSubRegion.cpp +++ b/src/coreComponents/mesh/FaceElementSubRegion.cpp @@ -15,6 +15,7 @@ #include "FaceElementSubRegion.hpp" #include "common/GEOS_RAJA_Interface.hpp" +#include "common/TypeDispatch.hpp" #include "NodeManager.hpp" #include "MeshLevel.hpp" @@ -105,13 +106,6 @@ void FaceElementSubRegion::copyFromCellBlock( FaceBlockABC const & faceBlock ) localIndex const num2dElements = faceBlock.num2dElements(); resize( num2dElements ); - // Copy regionAttribute from FaceBlock - array1d< integer > const regionAttr = faceBlock.getRegionAttribute(); - if( regionAttr.size() > 0 ) - { - m_regionAttribute = regionAttr; - } - m_toNodesRelation.base() = faceBlock.get2dElemToNodes(); m_toEdgesRelation.base() = faceBlock.get2dElemToEdges(); @@ -221,7 +215,20 @@ void FaceElementSubRegion::copyFromCellBlock( FaceBlockABC const & faceBlock ) m_newFaceElements.insert( i ); } - // TODO We still need to be able to import fields on the FaceElementSubRegion. + faceBlock.forExternalProperties( [&]( WrapperBase const & wrapper ) + { + types::dispatch( types::ListofTypeList< types::StandardArrays >{}, [&]( auto tupleOfTypes ) + { + using ArrayType = camp::first< decltype( tupleOfTypes ) >; + auto const src = Wrapper< ArrayType >::cast( wrapper ).reference().toViewConst(); + ArrayType & dst = this->registerWrapper( wrapper.getName(), std::make_unique< ArrayType >() ) + .setPlotLevel( wrapper.getPlotLevel() ) + .reference(); + // This is a hack since Array's copy ctor does not accept ArrayView source + dst.resize( ArrayType::NDIM, src.dims() ); + std::copy( src.data(), src.data() + src.size(), dst.data() ); + }, wrapper ); + } ); } void FaceElementSubRegion::setupRelatedObjectsInRelations( MeshLevel const & mesh ) diff --git a/src/coreComponents/mesh/MeshFields.hpp b/src/coreComponents/mesh/MeshFields.hpp index 6118ee15232..b560fdea048 100644 --- a/src/coreComponents/mesh/MeshFields.hpp +++ b/src/coreComponents/mesh/MeshFields.hpp @@ -187,14 +187,6 @@ DECLARE_FIELD( tangentVector2, WRITE_AND_READ, "Unit vector in the second tangent direction to the surface." ); -DECLARE_FIELD( attribute, - "attribute", - array1d< integer >, - -1, - NOPLOT, - WRITE_AND_READ, - "Region attribute value from mesh input (constant per cell block)." ); - } // namespace fields } // namespace geos diff --git a/src/coreComponents/mesh/generators/CellBlock.hpp b/src/coreComponents/mesh/generators/CellBlock.hpp index 87df84d176a..4d79fca2c7a 100644 --- a/src/coreComponents/mesh/generators/CellBlock.hpp +++ b/src/coreComponents/mesh/generators/CellBlock.hpp @@ -67,20 +67,6 @@ class CellBlock : public CellBlockABC ElementType getElementType() const override { return m_elementType; } - /** - * @brief Get the region attribute for this cell block. - * @return The region attribute value. - */ - integer getRegionAttribute() const override - { return m_regionAttribute; } - - /** - * @brief Set the region attribute for this cell block. - * @param regionAttribute The region attribute value to set. - */ - void setRegionAttribute( integer regionAttribute ) - { m_regionAttribute = regionAttribute; } - localIndex numNodesPerElement() const override { return m_numNodesPerElement; } @@ -275,9 +261,6 @@ class CellBlock : public CellBlockABC /// Type of element in this block. ElementType m_elementType; - /// Region attribute value for this cell block. - integer m_regionAttribute = -1; - std::list< dataRepository::WrapperBase const * > getExternalProperties() const override { std::list< dataRepository::WrapperBase const * > result; diff --git a/src/coreComponents/mesh/generators/CellBlockABC.hpp b/src/coreComponents/mesh/generators/CellBlockABC.hpp index 86458f8a12a..7749ce687fe 100644 --- a/src/coreComponents/mesh/generators/CellBlockABC.hpp +++ b/src/coreComponents/mesh/generators/CellBlockABC.hpp @@ -126,12 +126,6 @@ class CellBlockABC : public dataRepository::Group } } - /** - * @brief Get the region attribute for this cell block. - * @return The region attribute value, or -1 if not set. - */ - virtual integer getRegionAttribute() const { return -1; } - private: /** * @brief Returns the external properties under the form of WrapperBase pointers. diff --git a/src/coreComponents/mesh/generators/CellBlockManager.cpp b/src/coreComponents/mesh/generators/CellBlockManager.cpp index ac1ee347f49..0150b2f35bd 100644 --- a/src/coreComponents/mesh/generators/CellBlockManager.cpp +++ b/src/coreComponents/mesh/generators/CellBlockManager.cpp @@ -774,7 +774,6 @@ CellBlock & CellBlockManager::registerCellBlock( string const & cellBlockName, integer regionAttribute ) { CellBlock & cb = this->getCellBlocks().registerGroup< CellBlock >( cellBlockName ); - cb.setRegionAttribute( regionAttribute ); m_regionAttributesCellBlocks.get_inserted( regionAttribute ).emplace( cellBlockName ); return cb; } diff --git a/src/coreComponents/mesh/generators/FaceBlock.hpp b/src/coreComponents/mesh/generators/FaceBlock.hpp index c6893884dc6..31060e8e03b 100644 --- a/src/coreComponents/mesh/generators/FaceBlock.hpp +++ b/src/coreComponents/mesh/generators/FaceBlock.hpp @@ -60,13 +60,6 @@ class FaceBlock : public FaceBlockABC array1d< globalIndex > localToGlobalMap() const override; - /** - * @brief Get the region attribute for each 2d element. - * @return The region attribute values. - */ - array1d< integer > getRegionAttribute() const override - { return m_regionAttribute; } - /** * @brief Defines the number of 2d elements. * @param num2DElements The input value. @@ -128,17 +121,36 @@ class FaceBlock : public FaceBlockABC void set2dElemsToCollocatedNodesBuckets( ArrayOfArrays< array1d< globalIndex > > && collocatedNodesBuckets ); /** - * @brief Defines the region attribute for each 2d element. - * @param regionAttribute The input array. + * @brief Add a property to the FaceBlock. + * @tparam T type of the property + * @param[in] propertyName the name of the property + * @return a non-const reference to the property */ - void setRegionAttribute( array1d< integer > && regionAttribute ) - { m_regionAttribute = std::move( regionAttribute ); } + template< typename T > + T & addProperty( string const & propertyName ) + { + m_externalPropertyNames.emplace_back( propertyName ); + return this->registerWrapper< T >( propertyName ).reference(); + } private: + std::list< dataRepository::WrapperBase const * > getExternalProperties() const override + { + std::list< dataRepository::WrapperBase const * > result; + for( string const & externalPropertyName : m_externalPropertyNames ) + { + result.push_back( &this->getWrapperBase( externalPropertyName ) ); + } + return result; + } + localIndex m_num2dElements; localIndex m_num2dFaces; + /// Names of the properties registered from an external mesh + string_array m_externalPropertyNames; + ArrayOfArrays< localIndex > m_2dElemToNodes; ArrayOfArrays< localIndex > m_2dElemToEdges; ArrayOfArrays< localIndex > m_2dElemToFaces; @@ -149,9 +161,6 @@ class FaceBlock : public FaceBlockABC array1d< localIndex > m_2dFaceToEdge; array1d< globalIndex > m_localToGlobalMap; - - /// Region attribute for each 2d element - array1d< integer > m_regionAttribute; }; diff --git a/src/coreComponents/mesh/generators/FaceBlockABC.hpp b/src/coreComponents/mesh/generators/FaceBlockABC.hpp index 498f0958d93..3708622349c 100644 --- a/src/coreComponents/mesh/generators/FaceBlockABC.hpp +++ b/src/coreComponents/mesh/generators/FaceBlockABC.hpp @@ -20,6 +20,8 @@ #include "dataRepository/Group.hpp" #include "common/DataTypes.hpp" +#include + namespace geos { @@ -172,10 +174,29 @@ class FaceBlockABC : public dataRepository::Group virtual array1d< globalIndex > localToGlobalMap() const = 0; /** - * @brief Get the region attribute for each 2d element. - * @return The region attribute values, or empty array if not set. + * @brief Apply a lambda to each external (passthrough) property registered on this face block. + * @tparam LAMBDA type of the lambda + * @param lambda the lambda to apply; receives a @p dataRepository::WrapperBase const & + */ + template< typename LAMBDA > + void forExternalProperties( LAMBDA && lambda ) const + { + for( auto * wrapperBase : this->getExternalProperties() ) + { + lambda( *wrapperBase ); + } + } + +private: + + /** + * @brief Returns the list of external (passthrough) property wrappers. + * @return List of pointers to external property wrappers. */ - virtual array1d< integer > getRegionAttribute() const { return {}; } + virtual std::list< dataRepository::WrapperBase const * > getExternalProperties() const + { + return {}; + } }; } diff --git a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp index 8af48cb41b0..34ba62cdab9 100644 --- a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp +++ b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp @@ -18,6 +18,7 @@ #include "mesh/generators/VTKUtilities.hpp" #include "mesh/generators/CollocatedNodes.hpp" +#include "common/MpiWrapper.hpp" #include "dataRepository/Group.hpp" #include @@ -624,11 +625,116 @@ array1d< globalIndex > buildLocalToGlobal( vtkIdTypeArray const * faceMeshCellGl } +/** + * @brief Register a passthrough field on a FaceBlock, ensuring MPI consistency. + * + * On ranks where the VTK array is absent (e.g. empty fracture partition), an empty + * wrapper of the correct type is still registered so all ranks have the same wrappers + * during ghost communication. + */ +static void writeFacePassthroughField( vtkDataSet & faceMesh, + localIndex const numElems, + string const & fieldName, + FaceBlock & faceBlock ) +{ + vtkDataArray * srcArray = faceMesh.GetCellData()->GetArray( fieldName.c_str() ); + + // Collectively determine type: isReal (1/0) and numComp, or -1 if absent on this rank. + int localIsReal = ( srcArray != nullptr ) + ? ( ( srcArray->GetDataType() == VTK_FLOAT || srcArray->GetDataType() == VTK_DOUBLE ) ? 1 : 0 ) + : -1; + int localNumComp = ( srcArray != nullptr ) ? srcArray->GetNumberOfComponents() : -1; + + int const globalIsReal = MpiWrapper::allReduce( localIsReal, MpiWrapper::Reduction::Max, MPI_COMM_GEOS ); + int const globalNumComp = MpiWrapper::allReduce( localNumComp, MpiWrapper::Reduction::Max, MPI_COMM_GEOS ); + + if( globalNumComp == -1 ) + { + // Field absent on every rank — not a passthrough field of this mesh. + GEOS_WARNING( GEOS_FMT( "Passthrough field '{}' not found in any fracture VTK CellData; skipping.", fieldName ) ); + return; + } + + if( srcArray == nullptr ) + { + // This rank has no data for this field (empty partition). Register an empty + // wrapper so ghost communication finds the same wrapper on all ranks. + if( globalIsReal == 1 ) + { + if( globalNumComp == 1 ) + { + faceBlock.addProperty< array1d< real64 > >( fieldName ).resize( numElems ); + } + else + { + faceBlock.addProperty< array2d< real64 > >( fieldName ).resize( numElems, globalNumComp ); + } + } + else + { + if( globalNumComp == 1 ) + { + faceBlock.addProperty< array1d< integer > >( fieldName ).resize( numElems ); + } + else + { + faceBlock.addProperty< array2d< integer > >( fieldName ).resize( numElems, globalNumComp ); + } + } + faceBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + return; + } + + // This rank has the data — fill it. + bool const isReal = ( globalIsReal == 1 ); + if( isReal ) + { + if( globalNumComp == 1 ) + { + array1d< real64 > & dst = faceBlock.addProperty< array1d< real64 > >( fieldName ); + dst.resize( numElems ); + faceBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + for( localIndex i = 0; i < numElems; ++i ) + dst[i] = static_cast< real64 >( srcArray->GetTuple1( i ) ); + } + else + { + array2d< real64 > & dst = faceBlock.addProperty< array2d< real64 > >( fieldName ); + dst.resize( numElems, globalNumComp ); + faceBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + for( localIndex i = 0; i < numElems; ++i ) + for( int c = 0; c < globalNumComp; ++c ) + dst( i, c ) = static_cast< real64 >( srcArray->GetComponent( i, c ) ); + } + } + else + { + if( globalNumComp == 1 ) + { + array1d< integer > & dst = faceBlock.addProperty< array1d< integer > >( fieldName ); + dst.resize( numElems ); + faceBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + for( localIndex i = 0; i < numElems; ++i ) + dst[i] = static_cast< integer >( srcArray->GetTuple1( i ) ); + } + else + { + array2d< integer > & dst = faceBlock.addProperty< array2d< integer > >( fieldName ); + dst.resize( numElems, globalNumComp ); + faceBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + for( localIndex i = 0; i < numElems; ++i ) + for( int c = 0; c < globalNumComp; ++c ) + dst( i, c ) = static_cast< integer >( srcArray->GetComponent( i, c ) ); + } + } +} + + void importFractureNetwork( string const & faceBlockName, vtkSmartPointer< vtkDataSet > faceMesh, vtkSmartPointer< vtkDataSet > mesh, CellBlockManager & cellBlockManager, - string const & regionAttributeName ) + Span< string const > passthroughFieldNames ) { ArrayOfArrays< localIndex > const faceToNodes = cellBlockManager.getFaceToNodes(); vtk::internal::ElementToFace const elemToFaces( cellBlockManager.getCellBlocks() ); @@ -657,28 +763,10 @@ void importFractureNetwork( string const & faceBlockName, ArrayOfArrays< localIndex > const elem2dToFace2d = buildElem2dToFace2d( num2dElements, face2dToElems2d.toViewConst() ); ArrayOfArrays< localIndex > elem2dToEdges = buildElem2dToEdges( num2dElements, face2dToEdge.toViewConst(), elem2dToFace2d.toViewConst() ); - // Read regionAttribute from the face mesh if available - array1d< integer > regionAttribute; - regionAttribute.resize( num2dElements ); - vtkDataArray * regionAttrArray = faceMesh->GetCellData()->GetArray( regionAttributeName.c_str() ); - if( regionAttrArray != nullptr ) - { - for( vtkIdType i = 0; i < num2dElements; ++i ) - { - regionAttribute[i] = static_cast< integer >( regionAttrArray->GetTuple1( i ) ); - } - } - else - { - // Default to -1 if no attribute found - regionAttribute.setValues< serialPolicy >( -1 ); - } - // Mappings are now computed. Just create the face block by value. FaceBlock & faceBlock = cellBlockManager.registerFaceBlock( faceBlockName ); faceBlock.setNum2dElements( num2dElements ); - faceBlock.setRegionAttribute( std::move( regionAttribute ) ); faceBlock.setNum2dFaces( num2dFaces ); faceBlock.set2dElemToNodes( std::move( elem2dTo3d.elem2dToNodes ) ); faceBlock.set2dElemToEdges( std::move( elem2dToEdges ) ); @@ -705,6 +793,16 @@ void importFractureNetwork( string const & faceBlockName, buildCollocatedNodesBucketsOf2dElemsMap( build2dElemTo2dNodes( faceMesh ), buildCollocatedNodesMap( collocatedNodes ) ) ); + + // Import passthrough fields from the face mesh CellData. + // writeFacePassthroughField performs an MPI_Allreduce to determine the field type + // collectively, ensuring all ranks register the same wrappers even when some ranks + // have an empty fracture partition (needed for ghost communication consistency). + localIndex const numElems = LvArray::integerConversion< localIndex >( num2dElements ); + for( string const & fieldName : passthroughFieldNames ) + { + writeFacePassthroughField( *faceMesh, numElems, fieldName, faceBlock ); + } } } // end of namespace diff --git a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.hpp b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.hpp index 0176cd469e0..b4efcb8d647 100644 --- a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.hpp +++ b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.hpp @@ -19,6 +19,7 @@ #include "CellBlockManager.hpp" #include "common/DataTypes.hpp" +#include "common/Span.hpp" #include #include @@ -32,13 +33,13 @@ namespace geos::vtk * @param faceMesh[in] The vtk mesh for the face block. * @param mesh[in] The vtk volumic mesh. * @param cellBlockManager[inout] The cell block manager that will receive the face block information. - * @param regionAttributeName[in] The name of the region attribute in the VTK data (default: "attribute"). + * @param passthroughFieldNames[in] Names of VTK CellData arrays to import and pass through to output as-is. */ void importFractureNetwork( string const & faceBlockName, vtkSmartPointer< vtkDataSet > faceMesh, vtkSmartPointer< vtkDataSet > mesh, CellBlockManager & cellBlockManager, - string const & regionAttributeName = "attribute" ); + Span< string const > passthroughFieldNames = {} ); } #endif // include guard diff --git a/src/coreComponents/mesh/generators/VTKMeshGenerator.cpp b/src/coreComponents/mesh/generators/VTKMeshGenerator.cpp index 8dd6fb17a58..c9d0d708173 100644 --- a/src/coreComponents/mesh/generators/VTKMeshGenerator.cpp +++ b/src/coreComponents/mesh/generators/VTKMeshGenerator.cpp @@ -20,6 +20,7 @@ #include "VTKMeshGenerator.hpp" #include "common/DataTypes.hpp" +#include "common/Span.hpp" #include "mesh/ExternalDataSourceManager.hpp" #include "mesh/LogLevelsInfo.hpp" #include "mesh/generators/VTKFaceBlockUtilities.hpp" @@ -98,6 +99,11 @@ VTKMeshGenerator::VTKMeshGenerator( string const & name, setInputFlag( InputFlags::OPTIONAL ). setDescription( "Name of the VTK data source" ); + registerWrapper( viewKeyStruct::passthroughFieldsString(), &m_passthroughFieldNames ). + setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Names of VTK CellData arrays to import and pass through to output as-is, without mapping to a GEOS field." ); + addLogLevel< logInfo::VTKSteps >(); } @@ -234,7 +240,8 @@ void VTKMeshGenerator::fillCellBlockManager( CellBlockManager & cellBlockManager writeNodes( getLogLevel(), *m_vtkMesh, m_nodesetNames, cellBlockManager, m_translate, m_scale ); GEOS_LOG_LEVEL_RANK_0( logInfo::VTKSteps, GEOS_FMT( "{} '{}': writing cells...", catalogName(), getName() ) ); - writeCells( getLogLevel(), *m_vtkMesh, m_cellMap, m_structuredIndexAttributeName, cellBlockManager ); + writeCells( getLogLevel(), *m_vtkMesh, m_cellMap, m_structuredIndexAttributeName, cellBlockManager, + Span< string const >( m_passthroughFieldNames.begin(), m_passthroughFieldNames.end() ) ); GEOS_LOG_LEVEL_RANK_0( logInfo::VTKSteps, GEOS_FMT( "{} '{}': writing surfaces...", catalogName(), getName() ) ); writeSurfaces( getLogLevel(), *m_vtkMesh, m_cellMap, cellBlockManager ); @@ -248,7 +255,8 @@ void VTKMeshGenerator::fillCellBlockManager( CellBlockManager & cellBlockManager for( auto const & [name, mesh]: m_faceBlockMeshes ) { - vtk::importFractureNetwork( name, mesh, m_vtkMesh, cellBlockManager, m_regionAttributeName ); + vtk::importFractureNetwork( name, mesh, m_vtkMesh, cellBlockManager, + Span< string const >( m_passthroughFieldNames.begin(), m_passthroughFieldNames.end() ) ); } GEOS_LOG_LEVEL_RANK_0( logInfo::VTKSteps, GEOS_FMT( "{} '{}': done!", catalogName(), getName() ) ); diff --git a/src/coreComponents/mesh/generators/VTKMeshGenerator.hpp b/src/coreComponents/mesh/generators/VTKMeshGenerator.hpp index e31ada4bb1e..5fc838121ed 100644 --- a/src/coreComponents/mesh/generators/VTKMeshGenerator.hpp +++ b/src/coreComponents/mesh/generators/VTKMeshGenerator.hpp @@ -117,6 +117,7 @@ class VTKMeshGenerator : public ExternalMeshGeneratorBase constexpr static char const * partitionFractureWeightString() { return "partitionFractureWeight"; } constexpr static char const * useGlobalIdsString() { return "useGlobalIds"; } constexpr static char const * dataSourceString() { return "dataSourceName"; } + constexpr static char const * passthroughFieldsString() { return "passThroughFields"; } }; struct groupKeyStruct @@ -180,6 +181,9 @@ class VTKMeshGenerator : public ExternalMeshGeneratorBase /// Repository of VTK objects VTKHierarchicalDataSource * m_dataSource; + /// Names of VTK CellData arrays to import and pass through to output as-is + string_array m_passthroughFieldNames; + }; } // namespace geos diff --git a/src/coreComponents/mesh/generators/VTKUtilities.cpp b/src/coreComponents/mesh/generators/VTKUtilities.cpp index 2bf0d4f02e5..9d07ae1c7a7 100644 --- a/src/coreComponents/mesh/generators/VTKUtilities.cpp +++ b/src/coreComponents/mesh/generators/VTKUtilities.cpp @@ -3561,12 +3561,89 @@ void writeStructuredIndex( vtkDataSet & mesh, } ); } +static void writePassthroughField( vtkDataSet & mesh, + Span< vtkIdType const > const cellIds, + string const & fieldName, + CellBlock & cellBlock ) +{ + vtkDataArray * srcArray = mesh.GetCellData()->GetArray( fieldName.c_str() ); + if( srcArray == nullptr ) + { + GEOS_WARNING( GEOS_FMT( "Passthrough field '{}' not found in VTK CellData; skipping.", fieldName ) ); + return; + } + + localIndex const numElems = LvArray::integerConversion< localIndex >( cellIds.size() ); + integer const numComp = srcArray->GetNumberOfComponents(); + + // Map VTK float types to real64; everything else (integers, id types) to integer. + bool const isRealArray = ( srcArray->GetDataType() == VTK_FLOAT || srcArray->GetDataType() == VTK_DOUBLE ); + + if( isRealArray ) + { + if( numComp == 1 ) + { + array1d< real64 > & dst = cellBlock.addProperty< array1d< real64 > >( fieldName ); + dst.resize( numElems ); + cellBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + forAll< parallelHostPolicy >( numElems, [&dst, srcArray, cellIds]( localIndex const i ) + { + dst[i] = static_cast< real64 >( srcArray->GetTuple1( cellIds[i] ) ); + } ); + } + else + { + array2d< real64 > & dst = cellBlock.addProperty< array2d< real64 > >( fieldName ); + dst.resize( numElems, numComp ); + cellBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + forAll< parallelHostPolicy >( numElems, [&dst, srcArray, cellIds, numComp]( localIndex const i ) + { + for( integer c = 0; c < numComp; ++c ) + dst( i, c ) = static_cast< real64 >( srcArray->GetComponent( cellIds[i], c ) ); + } ); + } + } + else + { + if( numComp == 1 ) + { + array1d< integer > & dst = cellBlock.addProperty< array1d< integer > >( fieldName ); + dst.resize( numElems ); + cellBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + forAll< parallelHostPolicy >( numElems, [&dst, srcArray, cellIds]( localIndex const i ) + { + dst[i] = static_cast< integer >( srcArray->GetTuple1( cellIds[i] ) ); + } ); + } + else + { + array2d< integer > & dst = cellBlock.addProperty< array2d< integer > >( fieldName ); + dst.resize( numElems, numComp ); + cellBlock.getWrapperBase( fieldName ).setPlotLevel( dataRepository::PlotLevel::LEVEL_1 ); + forAll< parallelHostPolicy >( numElems, [&dst, srcArray, cellIds, numComp]( localIndex const i ) + { + for( integer c = 0; c < numComp; ++c ) + dst( i, c ) = static_cast< integer >( srcArray->GetComponent( cellIds[i], c ) ); + } ); + } + } +} + void writeCells( integer const logLevel, vtkDataSet & mesh, vtk::CellMapType const & cellMap, string const & structuredIndexAttributeName, - CellBlockManager & cellBlockManager ) + CellBlockManager & cellBlockManager, + Span< string const > passthroughFieldNames ) { + if( !passthroughFieldNames.empty() ) + { + string fieldList; + for( string const & n : passthroughFieldNames ) + fieldList += "'" + n + "' "; + GEOS_LOG_RANK_0( GEOS_FMT( "VTKMesh: propagating passthrough fields: {}", fieldList ) ); + } + // Creates a new cell block for each region and for each type of cell. for( auto const & typeRegions : cellMap ) { @@ -3595,6 +3672,11 @@ void writeCells( integer const logLevel, { writeStructuredIndex( mesh, structuredIndexAttributeName, cellIds, cellBlock ); } + + for( string const & fieldName : passthroughFieldNames ) + { + writePassthroughField( mesh, cellIds, fieldName, cellBlock ); + } } } } diff --git a/src/coreComponents/mesh/generators/VTKUtilities.hpp b/src/coreComponents/mesh/generators/VTKUtilities.hpp index a0181fbfd8b..af919f43e93 100644 --- a/src/coreComponents/mesh/generators/VTKUtilities.hpp +++ b/src/coreComponents/mesh/generators/VTKUtilities.hpp @@ -288,12 +288,14 @@ void writeNodes( integer const logLevel, * @param[in] cellMap Map from the surfaces index to the list of cells in this surface in this rank. * @param[in] structuredIndexAttributeName name of the VTK cell array to use as "structured index" attribute (if non-empty) * @param[in] cellBlockManager The instance that stores the cell blocks. + * @param[in] passthroughFieldNames Names of VTK CellData arrays to import and pass through to output as-is. */ void writeCells( integer const logLevel, vtkDataSet & mesh, vtk::CellMapType const & cellMap, string const & structuredIndexAttributeName, - CellBlockManager & cellBlockManager ); + CellBlockManager & cellBlockManager, + Span< string const > passthroughFieldNames = {} ); /** * @brief Build the "surface" node sets from the surface information. From 7d42b43f50e4575faeb330606d79a5fe20108191 Mon Sep 17 00:00:00 2001 From: npillardou Date: Fri, 12 Jun 2026 16:52:08 +0200 Subject: [PATCH 3/4] uncrustify --- src/coreComponents/mesh/CellElementSubRegion.cpp | 4 ++-- src/coreComponents/mesh/FaceElementSubRegion.cpp | 4 ++-- .../mesh/generators/VTKFaceBlockUtilities.cpp | 2 +- src/coreComponents/mesh/generators/VTKUtilities.cpp | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coreComponents/mesh/CellElementSubRegion.cpp b/src/coreComponents/mesh/CellElementSubRegion.cpp index fc0409290d5..7bf60d54a40 100644 --- a/src/coreComponents/mesh/CellElementSubRegion.cpp +++ b/src/coreComponents/mesh/CellElementSubRegion.cpp @@ -92,8 +92,8 @@ void CellElementSubRegion::copyFromCellBlock( CellBlockABC const & cellBlock ) using ArrayType = camp::first< decltype( tupleOfTypes ) >; auto const src = Wrapper< ArrayType >::cast( wrapper ).reference().toViewConst(); ArrayType & dst = this->registerWrapper( wrapper.getName(), std::make_unique< ArrayType >() ) - .setPlotLevel( wrapper.getPlotLevel() ) - .reference(); + .setPlotLevel( wrapper.getPlotLevel() ) + .reference(); // This is a hack since Array's copy ctor does not accept ArrayView source dst.resize( ArrayType::NDIM, src.dims() ); std::copy( src.data(), src.data() + src.size(), dst.data() ); diff --git a/src/coreComponents/mesh/FaceElementSubRegion.cpp b/src/coreComponents/mesh/FaceElementSubRegion.cpp index 845b9f6d7d9..09990e0f55f 100644 --- a/src/coreComponents/mesh/FaceElementSubRegion.cpp +++ b/src/coreComponents/mesh/FaceElementSubRegion.cpp @@ -222,8 +222,8 @@ void FaceElementSubRegion::copyFromCellBlock( FaceBlockABC const & faceBlock ) using ArrayType = camp::first< decltype( tupleOfTypes ) >; auto const src = Wrapper< ArrayType >::cast( wrapper ).reference().toViewConst(); ArrayType & dst = this->registerWrapper( wrapper.getName(), std::make_unique< ArrayType >() ) - .setPlotLevel( wrapper.getPlotLevel() ) - .reference(); + .setPlotLevel( wrapper.getPlotLevel() ) + .reference(); // This is a hack since Array's copy ctor does not accept ArrayView source dst.resize( ArrayType::NDIM, src.dims() ); std::copy( src.data(), src.data() + src.size(), dst.data() ); diff --git a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp index 34ba62cdab9..c13c66408a6 100644 --- a/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp +++ b/src/coreComponents/mesh/generators/VTKFaceBlockUtilities.cpp @@ -645,7 +645,7 @@ static void writeFacePassthroughField( vtkDataSet & faceMesh, : -1; int localNumComp = ( srcArray != nullptr ) ? srcArray->GetNumberOfComponents() : -1; - int const globalIsReal = MpiWrapper::allReduce( localIsReal, MpiWrapper::Reduction::Max, MPI_COMM_GEOS ); + int const globalIsReal = MpiWrapper::allReduce( localIsReal, MpiWrapper::Reduction::Max, MPI_COMM_GEOS ); int const globalNumComp = MpiWrapper::allReduce( localNumComp, MpiWrapper::Reduction::Max, MPI_COMM_GEOS ); if( globalNumComp == -1 ) diff --git a/src/coreComponents/mesh/generators/VTKUtilities.cpp b/src/coreComponents/mesh/generators/VTKUtilities.cpp index 9d07ae1c7a7..baa80e40166 100644 --- a/src/coreComponents/mesh/generators/VTKUtilities.cpp +++ b/src/coreComponents/mesh/generators/VTKUtilities.cpp @@ -3562,9 +3562,9 @@ void writeStructuredIndex( vtkDataSet & mesh, } static void writePassthroughField( vtkDataSet & mesh, - Span< vtkIdType const > const cellIds, - string const & fieldName, - CellBlock & cellBlock ) + Span< vtkIdType const > const cellIds, + string const & fieldName, + CellBlock & cellBlock ) { vtkDataArray * srcArray = mesh.GetCellData()->GetArray( fieldName.c_str() ); if( srcArray == nullptr ) From d8caefd96dc8c69ea8b1dc02b2644b12d4e18797 Mon Sep 17 00:00:00 2001 From: npillardou Date: Fri, 19 Jun 2026 10:33:17 +0200 Subject: [PATCH 4/4] rebaseline --- .integrated_tests.yaml | 2 +- BASELINE_NOTES.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.integrated_tests.yaml b/.integrated_tests.yaml index 5076ede8bd3..8e8f20b5ff1 100644 --- a/.integrated_tests.yaml +++ b/.integrated_tests.yaml @@ -1,6 +1,6 @@ baselines: bucket: geosx - baseline: integratedTests/baseline_integratedTests-pr4040-16993-1393f80 + baseline: integratedTests/baseline_integratedTests-pr4077-17009-64cf777 allow_fail: all: '' diff --git a/BASELINE_NOTES.md b/BASELINE_NOTES.md index 024e6787153..9de6e3cc27c 100644 --- a/BASELINE_NOTES.md +++ b/BASELINE_NOTES.md @@ -5,6 +5,9 @@ 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 #4077 (2026-06-19) +Add input mesh parameter to output Pvd results + PR #4040 (2026-06-16) Move relperm driver to use new constitutive driver framework