Skip to content

Commit

Permalink
Add more context to errors - mesh/ files (#2450)
Browse files Browse the repository at this point in the history
  • Loading branch information
MelReyCG authored and ouassimkh committed Feb 16, 2024
1 parent a329c94 commit 9005a00
Show file tree
Hide file tree
Showing 23 changed files with 219 additions and 138 deletions.
3 changes: 2 additions & 1 deletion src/coreComponents/dataRepository/GroupContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ string GroupContext::toString() const
for( auto info = parentsInfo.rbegin(); info != parentsInfo.rend(); ++info )
{
path << ( std::prev( info.base() ) == lastFileInfo ? // Is `info` pointing to the last file info?
GEOS_FMT( "/{}({},l.{})", info->m_targetName, info->m_filePath, info->m_line ) :
GEOS_FMT( "/{}({},l.{})",
info->m_targetName, splitPath( info->m_filePath ).second, info->m_line ) :
GEOS_FMT( "/{}", info->m_targetName ));
}
return path.str();
Expand Down
26 changes: 17 additions & 9 deletions src/coreComponents/mainInterface/ProblemManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,17 +434,25 @@ void ProblemManager::parseXMLDocument( xmlWrapper::xmlDocument & xmlDocument )
for( xmlWrapper::xmlNode regionNode : elementRegionsNode.children() )
{
string const regionName = regionNode.attribute( "name" ).value();
string const
regionMeshBodyName = ElementRegionBase::verifyMeshBodyName( meshBodies,
regionNode.attribute( "meshBody" ).value() );
try
{
string const
regionMeshBodyName = ElementRegionBase::verifyMeshBodyName( meshBodies,
regionNode.attribute( "meshBody" ).value() );

MeshBody & meshBody = domain.getMeshBody( regionMeshBodyName );
meshBody.forMeshLevels( [&]( MeshLevel & meshLevel )
MeshBody & meshBody = domain.getMeshBody( regionMeshBodyName );
meshBody.forMeshLevels( [&]( MeshLevel & meshLevel )
{
ElementRegionManager & elementManager = meshLevel.getElemManager();
Group * newRegion = elementManager.createChild( regionNode.name(), regionName );
newRegion->processInputFileRecursive( xmlDocument, regionNode );
} );
}
catch( InputError const & e )
{
ElementRegionManager & elementManager = meshLevel.getElemManager();
Group * newRegion = elementManager.createChild( regionNode.name(), regionName );
newRegion->processInputFileRecursive( xmlDocument, regionNode );
} );
string const nodePosString = xmlDocument.getNodePosition( regionNode ).toString();
throw InputError( e, "Error while parsing region " + regionName + " (" + nodePosString + "):\n" );
}
}

// Parse particle regions
Expand Down
2 changes: 1 addition & 1 deletion src/coreComponents/mesh/CellElementRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ CellElementRegion::CellElementRegion( string const & name, Group * const parent
ElementRegionBase( name, parent )
{
registerWrapper( viewKeyStruct::sourceCellBlockNamesString(), &m_cellBlockNames ).
setInputFlag( InputFlags::OPTIONAL );
setInputFlag( InputFlags::REQUIRED );

registerWrapper( viewKeyStruct::coarseningRatioString(), &m_coarseningRatio ).
setInputFlag( InputFlags::OPTIONAL );
Expand Down
4 changes: 2 additions & 2 deletions src/coreComponents/mesh/CellElementSubRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,13 +390,13 @@ void CellElementSubRegion::
default:
{
GEOS_ERROR( GEOS_FMT( "Volume calculation not supported for element type {} in subregion {}",
m_elementType, getName() ) );
m_elementType, getDataContext() ) );
}
}

GEOS_ERROR_IF( m_elementVolume[k] <= 0.0,
GEOS_FMT( "Negative volume for element {} type {} in subregion {}",
k, m_elementType, getName() ) );
k, m_elementType, getDataContext() ) );
}

void CellElementSubRegion::calculateElementGeometricQuantities( NodeManager const & nodeManager,
Expand Down
3 changes: 3 additions & 0 deletions src/coreComponents/mesh/ElementType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ ENUM_STRINGS( ElementType,
"HendecagonalPrism",
"Polyhedron" );

/// String available for mesh errors
inline auto constexpr generalMeshErrorAdvice = "\nPlease consider checking the validity of your mesh with the `mesh_doctor` GEOS python tools.";

} // namespace geos

#endif //GEOS_MESH_ELEMENTTYPE_HPP
21 changes: 16 additions & 5 deletions src/coreComponents/mesh/FaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "mesh/NodeManager.hpp"
#include "mesh/utilities/MeshMapUtilities.hpp"
#include "utilities/ComputationalGeometry.hpp"
#include "CellElementRegion.hpp"

namespace geos
{
Expand Down Expand Up @@ -264,12 +265,15 @@ void FaceManager::sortAllFaceNodes( NodeManager const & nodeManager,
ElementRegionManager::ElementViewAccessor< arrayView2d< real64 const > > elemCenter =
elemManager.constructArrayViewAccessor< real64, 2 >( ElementSubRegionBase::viewKeyStruct::elementCenterString() );

forAll< parallelHostPolicy >( size(), [=, elemCenter = elemCenter.toNestedViewConst()]( localIndex const faceIndex )
forAll< parallelHostPolicy >( size(), [=, elemCenter = elemCenter.toNestedViewConst(), &elemManager]( localIndex const faceIndex )
{
// The face should be connected to at least one element.
if( facesToElements( faceIndex, 0 ) < 0 && facesToElements( faceIndex, 1 ) < 0 )
{
GEOS_ERROR( "Face " << faceIndex << " is not connected to an element." );
GEOS_ERROR( getDataContext() << ": Face " << faceIndex << " is not connected to any cell." <<
"You might have forgotten one cell type in the " <<
elemManager.getWrapperDataContext( CellElementRegion::viewKeyStruct::sourceCellBlockNamesString() ) <<
", or your mesh might be invalid" );
}

// Take the first defined face-to-(elt/region/sub region) to sorting direction.
Expand All @@ -281,10 +285,17 @@ void FaceManager::sortAllFaceNodes( NodeManager const & nodeManager,

if( er < 0 || esr < 0 || ei < 0 )
{
GEOS_ERROR( GEOS_FMT( "Face {} is connected to an invalid element ({}/{}/{}).", faceIndex, er, esr, ei ) );
GEOS_ERROR( GEOS_FMT( "{0}: Face {1} is connected to an invalid element ({2}/{3}/{4}).",
getDataContext().toString(), faceIndex, er, esr, ei ) );
}

sortFaceNodes( X, elemCenter[er][esr][ei], facesToNodes[faceIndex] );
try
{
sortFaceNodes( X, elemCenter[er][esr][ei], facesToNodes[faceIndex] );
} catch( std::runtime_error const & e )
{
throw std::runtime_error( getDataContext().toString() + ": " + e.what() );
}
} );
}

Expand All @@ -293,7 +304,7 @@ void FaceManager::sortFaceNodes( arrayView2d< real64 const, nodes::REFERENCE_POS
Span< localIndex > const faceNodes )
{
localIndex const numFaceNodes = LvArray::integerConversion< localIndex >( faceNodes.size() );
GEOS_ERROR_IF_GT_MSG( numFaceNodes, MAX_FACE_NODES, "Node per face limit exceeded" );
GEOS_THROW_IF_GT_MSG( numFaceNodes, MAX_FACE_NODES, "The number of maximum nodes allocated per cell face has been reached.", std::runtime_error );

localIndex const firstNodeIndex = faceNodes[0];

Expand Down
3 changes: 2 additions & 1 deletion src/coreComponents/mesh/Perforation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ Perforation::Perforation( string const & name, Group * const parent )
void Perforation::postProcessInput()
{
GEOS_ERROR_IF( m_distanceFromHead <= 0,
"Invalid distance well head to perforation " << getName() );
getWrapperDataContext( viewKeyStruct::distanceFromHeadString() ) <<
": distance from well head to perforation cannot be negative." );
}


Expand Down
12 changes: 8 additions & 4 deletions src/coreComponents/mesh/PerforationData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,11 @@ void PerforationData::computeWellTransmissibility( MeshLevel const & mesh,
WellElementRegion const & wellRegion = dynamicCast< WellElementRegion const & >( wellElemSubRegion.getParent().getParent() );
GEOS_UNUSED_VAR( wellRegion ); // unused if geos_error_if is nulld
GEOS_LOG_RANK_IF( isZero( m_wellTransmissibility[iperf] ),
"\n \nWarning! A perforation is defined with a zero transmissibility in " << wellRegion.getWellGeneratorName() << "! \n" <<
"\n \nWarning! Perforation " << wellRegion.getWellGeneratorName() <<
" is defined with a zero transmissibility.\n" <<
"The simulation is going to proceed with this zero transmissibility,\n" <<
"but a better strategy to shut down a perforation is to remove the <Perforation> block from the XML\n \n" );
"but a better strategy to shut down a perforation is to remove the " <<
"<Perforation> block from the XML\n \n" );
continue;
}

Expand All @@ -150,7 +152,8 @@ void PerforationData::computeWellTransmissibility( MeshLevel const & mesh,
if( dx <= 0 || dy <= 0 || dz <= 0 )
{
WellElementRegion const & wellRegion = dynamicCast< WellElementRegion const & >( wellElemSubRegion.getParent().getParent() );
GEOS_THROW( "The reservoir element dimensions (dx, dy, and dz) should be positive in " << wellRegion.getWellGeneratorName(),
GEOS_THROW( "The reservoir element dimensions (dx, dy, and dz) should be positive in " <<
wellRegion.getWellGeneratorName(),
InputError );
}

Expand Down Expand Up @@ -212,7 +215,8 @@ void PerforationData::computeWellTransmissibility( MeshLevel const & mesh,
if( m_wellTransmissibility[iperf] <= 0 )
{
WellElementRegion const & wellRegion = dynamicCast< WellElementRegion const & >( wellElemSubRegion.getParent().getParent() );
GEOS_THROW( "The well index is negative or equal to zero in " << wellRegion.getWellGeneratorName(),
GEOS_THROW( "The well index is negative or equal to zero in " <<
wellRegion.getWellGeneratorName(),
InputError );
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/coreComponents/mesh/SurfaceElementRegion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ class SurfaceElementRegion : public ElementRegionBase
subRegionNames.push_back( sr.getName() );
} );
GEOS_ERROR_IF( subRegionNames.size() != 1,
"Surface region \"" << getName() << "\" should have one unique sub region. \"" << subRegionNames.size() << "\" found." );
"Surface region \"" << getDataContext() <<
"\" should have one unique sub region (" << subRegionNames.size() << " found)." );
return subRegionNames.front();
}

Expand Down
4 changes: 3 additions & 1 deletion src/coreComponents/mesh/WellElementRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "common/MpiWrapper.hpp"
#include "mesh/WellElementSubRegion.hpp"
#include "mesh/generators/InternalWellGenerator.hpp"

namespace geos
{
Expand Down Expand Up @@ -64,7 +65,8 @@ void WellElementRegion::generateWell( MeshLevel & mesh,

globalIndex const matchedPerforations = MpiWrapper::sum( perforationData->size() );
GEOS_THROW_IF( matchedPerforations != numPerforationsGlobal,
"Invalid mapping perforation-to-element in well " << lineBlock.getName() << "." <<
"Invalid mapping perforation-to-element in "<<
InternalWellGenerator::catalogName() << " " << getWellGeneratorName() << "." <<
" This happens when GEOSX cannot match a perforation with a reservoir element." <<
" There are two common reasons for this error:\n" <<
" 1- The most common reason for this error is that a perforation is on a section of " <<
Expand Down
4 changes: 2 additions & 2 deletions src/coreComponents/mesh/WellElementSubRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ void WellElementSubRegion::generate( MeshLevel & mesh,
// if they belong to the same well element. This is a temporary solution.
// TODO: split the well elements that contain multiple perforations, so that no element is shared
GEOS_THROW_IF( sharedElems.size() > 0,
"Well " << lineBlock.getName() << " contains shared well elements",
"Well " << lineBlock.getDataContext() << " contains shared well elements",
InputError );

// In Steps 1 and 2 we determine the local objects on this rank (elems and nodes)
Expand Down Expand Up @@ -519,7 +519,7 @@ void WellElementSubRegion::checkPartitioningValidity( LineBlockABC const & lineB
globalIndex const prevGlobal = prevElemIdsGlobal[iwelemGlobal][numBranches-1];

GEOS_THROW_IF( prevGlobal <= iwelemGlobal || prevGlobal < 0,
"The structure of well " << lineBlock.getName() << " is invalid. " <<
"The structure of well " << lineBlock.getDataContext() << " is invalid. " <<
" The main reason for this error is that there may be no perforation" <<
" in the bottom well element of the well, which is required to have" <<
" a well-posed problem.",
Expand Down
2 changes: 1 addition & 1 deletion src/coreComponents/mesh/generators/CellBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ void CellBlock::setElementType( ElementType elementType )
}
default:
{
GEOS_ERROR( "Invalid element type " << m_elementType << " for CellBlock " << getName() );
GEOS_ERROR( "Invalid element type " << m_elementType << " for CellBlock " << getDataContext() );
}
}

Expand Down
Loading

0 comments on commit 9005a00

Please sign in to comment.