Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add functions to connect well perforation to surface elements #3359

Open
wants to merge 24 commits into
base: pt/well-frac
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b7988a5
wip
Sep 18, 2024
5e61ed8
this should work
Sep 19, 2024
7858fd7
Update ElementSubRegionBase.hpp
paveltomin Sep 19, 2024
14422f2
Update SurfaceElementRegion.cpp
paveltomin Sep 19, 2024
1210866
fix hack
Sep 19, 2024
be90a23
Merge branch 'pt/connect-well-to-2d-elem' of https://github.com/GEOS-…
Sep 19, 2024
4d8a986
wip
Sep 19, 2024
418f18f
seems to work
Sep 19, 2024
cd30695
test case update
Sep 20, 2024
0c6bcef
Update WellElementSubRegion.cpp
paveltomin Sep 20, 2024
d2fc2a6
Update ComputationalGeometry.hpp
paveltomin Sep 20, 2024
0bc4a38
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Oct 25, 2024
2b47317
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Nov 4, 2024
6fe9518
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Nov 7, 2024
6ace57b
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Nov 11, 2024
02a5901
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Nov 17, 2024
cf4e21e
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Nov 22, 2024
2720743
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Dec 2, 2024
74924be
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Dec 2, 2024
624187d
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Dec 23, 2024
ec48635
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Jan 8, 2025
1021317
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Jan 13, 2025
799e4b4
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Jan 14, 2025
b5472e9
Merge branch 'pt/well-frac' into pt/connect-well-to-2d-elem
paveltomin Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

<ConstantPermeability
name="rockPerm"
permeabilityComponents="{ 1.0e-18, 1.0e-18, 1.0e-18 }" />
permeabilityComponents="{ 1.0e-14, 1.0e-14, 1.0e-14 }" />
<!-- Material inside the fault -->
<CompressibleSolidParallelPlatesPermeability
name="faultFilling"
Expand Down Expand Up @@ -188,14 +188,15 @@
logLevel="1"
wellRegionName="wellRegion2"
wellControlsName="wellControls2"
polylineNodeCoords="{ { -5400, -5400, 0 },
{ -5400, -5400, -2500 } }"
polylineNodeCoords="{ { 1200, -700, 0 },
{ 1200, -700, -2500 } }"
polylineSegmentConn="{ { 0, 1 } }"
radius="0.1"
numElementsPerSegment="1">
<Perforation
name="injector1_perf1"
distanceFromHead="2500"/>
targetRegion="Fault"
distanceFromHead="1700"/>
</InternalWell>
</VTKMesh>
</Mesh>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
targetRegions="{ Region, Fault, wellRegion1, wellRegion2 }">
<NonlinearSolverParameters
newtonMaxIter="40"
newtonTol="1e-4"
maxAllowedResidualNorm="1e+25"/>
<LinearSolverParameters
directParallel="0"/>
Expand Down
5 changes: 3 additions & 2 deletions src/coreComponents/mesh/DomainPartition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,11 @@ void DomainPartition::setupCommunications( bool use_nonblocking )
{
NodeManager & nodeManager = meshLevel.getNodeManager();
FaceManager & faceManager = meshLevel.getFaceManager();
ElementRegionManager & elemManager = meshLevel.getElemManager();

CommunicationTools::getInstance().setupGhosts( meshLevel, m_neighbors, use_nonblocking );
faceManager.sortAllFaceNodes( nodeManager, meshLevel.getElemManager() );
faceManager.computeGeometry( nodeManager );
faceManager.sortAllFaceNodes( nodeManager, elemManager );
faceManager.computeGeometry( nodeManager, elemManager );
}
else if( !meshLevel.isShallowCopyOf( meshBody.getMeshLevels().getGroup< MeshLevel >( 0 )) )
{
Expand Down
8 changes: 0 additions & 8 deletions src/coreComponents/mesh/EmbeddedSurfaceSubRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ EmbeddedSurfaceSubRegion::EmbeddedSurfaceSubRegion( string const & name,
{
m_elementType = ElementType::Polygon;

registerWrapper( viewKeyStruct::elementCenterString(), &m_elementCenter ).
setDescription( "The center of each EmbeddedSurface element." );

registerWrapper( viewKeyStruct::elementVolumeString(), &m_elementVolume ).
setApplyDefaultValue( -1.0 ).
setPlotLevel( dataRepository::PlotLevel::LEVEL_0 ).
setDescription( "The volume of each EmbeddedSurface element." );

registerWrapper( viewKeyStruct::connectivityIndexString(), &m_connectivityIndex ).
setApplyDefaultValue( 1 ).
setDescription( "Connectivity index of each EmbeddedSurface." );
Expand Down
15 changes: 8 additions & 7 deletions src/coreComponents/mesh/FaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ void FaceManager::setGeometricalRelations( CellBlockManagerABC const & cellBlock

if( isBaseMeshLevel )
{
computeGeometry( nodeManager );
computeGeometry( nodeManager, elemRegionManager );
}
}

Expand All @@ -217,7 +217,8 @@ void FaceManager::setupRelatedObjectsInRelations( NodeManager const & nodeManage
m_toElements.setElementRegionManager( elemRegionManager );
}

void FaceManager::computeGeometry( NodeManager const & nodeManager )
void FaceManager::computeGeometry( NodeManager const & nodeManager,
ElementRegionManager const & elemManager )
{
arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & X = nodeManager.referencePosition();

Expand All @@ -230,6 +231,11 @@ void FaceManager::computeGeometry( NodeManager const & nodeManager )
m_faceNormal[ faceIndex ] );

} );

elemManager.forElementSubRegions< CellElementSubRegion, FaceElementSubRegion >( [&] ( auto const & subRegion )
{
subRegion.calculateElementCenters( X );
} );
}

void FaceManager::setIsExternal()
Expand Down Expand Up @@ -258,11 +264,6 @@ void FaceManager::sortAllFaceNodes( NodeManager const & nodeManager,

ArrayOfArraysView< localIndex > const facesToNodes = nodeList().toView();

elemManager.forElementSubRegions< CellElementSubRegion, FaceElementSubRegion >( [&] ( auto const & subRegion )
{
subRegion.calculateElementCenters( X );
} );

ElementRegionManager::ElementViewAccessor< arrayView2d< real64 const > > elemCenter =
elemManager.constructArrayViewAccessor< real64, 2 >( ElementSubRegionBase::viewKeyStruct::elementCenterString() );

Expand Down
4 changes: 3 additions & 1 deletion src/coreComponents/mesh/FaceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,10 @@ class FaceManager : public ObjectManagerBase
/**
* @brief Compute faces center, area and normal.
* @param[in] nodeManager NodeManager associated with the current DomainPartition
* @param[in] elemManager element manager allowing access to the cell elements
*/
void computeGeometry( NodeManager const & nodeManager );
void computeGeometry( NodeManager const & nodeManager,
ElementRegionManager const & elemManager );

/**
* @brief Builds the face-on-domain-boundary indicator.
Expand Down
51 changes: 34 additions & 17 deletions src/coreComponents/mesh/PerforationData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,23 +233,40 @@ void PerforationData::getReservoirElementDimensions( MeshLevel const & mesh,
{
ElementRegionManager const & elemManager = mesh.getElemManager();
NodeManager const & nodeManager = mesh.getNodeManager();
CellElementRegion const & region = elemManager.getRegion< CellElementRegion >( er );
CellElementSubRegion const & subRegion = region.getSubRegion< CellElementSubRegion >( esr );

// compute the bounding box of the element
real64 boxDims[ 3 ];
computationalGeometry::getBoundingBox( ei,
subRegion.nodeList(),
nodeManager.referencePosition(),
boxDims );

// dx and dz from bounding box
dx = boxDims[ 0 ];
dy = boxDims[ 1 ];

// dz is computed as vol / (dx * dy)
dz = subRegion.getElementVolume()[ei];
dz /= dx * dy;
ElementRegionBase const & region = elemManager.getRegion< ElementRegionBase >( er );
ElementSubRegionBase const & subRegionBase = region.getSubRegion< ElementSubRegionBase >( esr );

region.applyLambdaToContainer< CellElementSubRegion, SurfaceElementSubRegion >( subRegionBase, [&]( auto const & subRegion )
{
// compute the bounding box of the element
real64 boxDims[ 3 ];
computationalGeometry::getBoundingBox( ei,
subRegion.nodeList(),
nodeManager.referencePosition(),
boxDims );

// dx and dz from bounding box
dx = boxDims[ 0 ];
dy = boxDims[ 1 ];
dz = boxDims[ 2 ];

if( dx < 1e-10 )
{
dx = subRegion.getElementVolume()[ei];
dx /= dy * dz;
}
else if( dy < 1e-10 )
{
dy = subRegion.getElementVolume()[ei];
dy /= dx * dz;
}
else
{
// dz is computed as vol / (dx * dy)
dz = subRegion.getElementVolume()[ei];
dz /= dx * dy;
}
} );
}

void PerforationData::connectToWellElements( LineBlockABC const & lineBlock,
Expand Down
68 changes: 59 additions & 9 deletions src/coreComponents/mesh/WellElementSubRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "common/MpiWrapper.hpp"
#include "LvArray/src/output.hpp"

#include <unordered_set>

namespace geos
{
Expand Down Expand Up @@ -143,7 +144,6 @@ bool isPointInsideElement( SUBREGION_TYPE const & GEOS_UNUSED_PARAM( subRegion )
arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & GEOS_UNUSED_PARAM( referencePosition ),
localIndex const & GEOS_UNUSED_PARAM( eiLocal ),
ArrayOfArraysView< localIndex const > const & GEOS_UNUSED_PARAM( facesToNodes ),
real64 const (&GEOS_UNUSED_PARAM( elemCenter ))[3],
real64 const (&GEOS_UNUSED_PARAM( location ))[3] )
{
// only CellElementSubRegion is currently supported
Expand All @@ -154,17 +154,72 @@ bool isPointInsideElement( CellElementSubRegion const & subRegion,
arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & referencePosition,
localIndex const & eiLocal,
ArrayOfArraysView< localIndex const > const & facesToNodes,
real64 const (&elemCenter)[3],
real64 const (&location)[3] )
{
arrayView2d< localIndex const > const elemsToFaces = subRegion.faceList();
arrayView2d< real64 const > const elemCenters = subRegion.getElementCenter();
real64 const elemCenter[3] = { elemCenters[eiLocal][0],
elemCenters[eiLocal][1],
elemCenters[eiLocal][2] };
return computationalGeometry::isPointInsidePolyhedron( referencePosition,
elemsToFaces[eiLocal],
facesToNodes,
elemCenter,
location );
}

// Define a hash function
template< typename POINT_TYPE >
struct PointHash
{
std::size_t operator()( POINT_TYPE const point ) const
{
std::size_t h1 = std::hash< real64 >()( point[0] );
std::size_t h2 = std::hash< real64 >()( point[1] );
std::size_t h3 = std::hash< real64 >()( point[2] );
return h1 ^ (h2 << 1) ^ (h3 << 2);
}
};

// Define equality operator
template< typename POINT_TYPE >
struct PointsEqual
{
bool operator()( POINT_TYPE const & p1, POINT_TYPE const & p2 ) const
{
return (std::abs( p1[0] - p2[0] ) < 1e-10) && (std::abs( p1[1] - p2[1] ) < 1e-10) && (std::abs( p1[2] - p2[2] ) < 1e-10);
}
};

bool isPointInsideElement( SurfaceElementSubRegion const & subRegion,
arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const & referencePosition,
localIndex const & eiLocal,
ArrayOfArraysView< localIndex const > const & GEOS_UNUSED_PARAM( facesToNodes ),
real64 const (&location)[3] )
{
typedef std::array< real64, 3 > Point3d;

// collect element nodes
integer const nV = subRegion.numNodesPerElement( eiLocal );
SurfaceElementSubRegion::NodeMapType const & nodeList = subRegion.nodeList();
std::vector< Point3d > polygon( nV );
for( integer i = 0; i < nV; ++i )
{
for( integer j = 0; j < 3; ++j )
{
polygon[i][j] = referencePosition[nodeList( eiLocal, i )][j];
}
}

// remove duplicates
std::unordered_set< Point3d, PointHash< Point3d >, PointsEqual< Point3d > >
unique_points( polygon.begin(), polygon.end());
polygon.clear();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is degenerated polygon possible here?

std::copy( unique_points.begin(), unique_points.end(), std::back_inserter( polygon ));

return computationalGeometry::isPointInPolygon3d( polygon, polygon.size(), location );
}

/**
* @brief Search the reservoir elements that can be accessed from the set "nodes".
Stop if a reservoir element containing the perforation is found.
Expand Down Expand Up @@ -336,22 +391,16 @@ bool visitNeighborElements( MeshLevel const & mesh,

ElementRegionBase const & region = elemManager.getRegion< ElementRegionBase >( er );
SUBREGION_TYPE const & subRegion = region.getSubRegion< SUBREGION_TYPE >( esr );
arrayView2d< real64 const > const elemCenters = subRegion.getElementCenter();

globalIndex const eiGlobal = subRegion.localToGlobalMap()[eiLocal];

// if this element has not been visited yet, save it
if( !elements.contains( eiGlobal ))
{
elements.insert( eiGlobal );

real64 const elemCenter[3] = { elemCenters[eiLocal][0],
elemCenters[eiLocal][1],
elemCenters[eiLocal][2] };

// perform the test to see if the point is in this reservoir element
// if the point is in the resevoir element, save the indices and stop the search
if( isPointInsideElement( subRegion, referencePosition, eiLocal, facesToNodes, elemCenter, location ) )
if( isPointInsideElement( subRegion, referencePosition, eiLocal, facesToNodes, location ) )
{
eiMatched = eiLocal;
giMatched = eiGlobal;
Expand Down Expand Up @@ -432,6 +481,7 @@ void initializeLocalSearch( MeshLevel const & mesh,
localIndex & eiInit )
{
ElementSubRegionBase const & subRegion = mesh.getElemManager().getRegion( targetRegionIndex ).getSubRegion( targetSubRegionIndex );

ElementRegionManager::ElementViewAccessor< arrayView2d< real64 const > >
resElemCenter = mesh.getElemManager().constructViewAccessor< array2d< real64 >,
arrayView2d< real64 const > >( ElementSubRegionBase::viewKeyStruct::elementCenterString() );
Expand Down
Loading
Loading