mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
(#540) Range filter matching: Prioritize cell matches with collapsed eclipse cells less.
To make better matches when one or more corner of the range is in a collapsed cells area
This commit is contained in:
parent
9d106ec76b
commit
44d1aaa3f1
@ -186,7 +186,7 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
bool femIsDestination)
|
||||
{
|
||||
{
|
||||
struct RangeFilterCorner { RangeFilterCorner() : isExactMatch(false){} cvf::Vec3st ijk; bool isExactMatch; };
|
||||
struct RangeFilterCorner { RangeFilterCorner() : cellMatchType(APPROX_ON_COLLAPSED){} cvf::Vec3st ijk; CellMatchType cellMatchType; };
|
||||
|
||||
RangeFilterCorner rangeFilterMatches[8];
|
||||
|
||||
@ -210,7 +210,7 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
|
||||
if (femIsDestination)
|
||||
{
|
||||
rangeFilterMatches[cornerIdx].isExactMatch = findBestFemCellFromEclCell(eclGrid,
|
||||
rangeFilterMatches[cornerIdx].cellMatchType = findBestFemCellFromEclCell(eclGrid,
|
||||
srcRangeCube[cornerIdx][0],
|
||||
srcRangeCube[cornerIdx][1],
|
||||
srcRangeCube[cornerIdx][2],
|
||||
@ -219,7 +219,7 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
&(rangeFilterMatches[cornerIdx].ijk[1]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[2]));
|
||||
|
||||
rangeFilterMatches[diagIdx].isExactMatch = findBestFemCellFromEclCell(eclGrid,
|
||||
rangeFilterMatches[diagIdx].cellMatchType = findBestFemCellFromEclCell(eclGrid,
|
||||
srcRangeCube[diagIdx][0],
|
||||
srcRangeCube[diagIdx][1],
|
||||
srcRangeCube[diagIdx][2],
|
||||
@ -230,7 +230,7 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeFilterMatches[cornerIdx].isExactMatch = findBestEclCellFromFemCell(femPart,
|
||||
rangeFilterMatches[cornerIdx].cellMatchType = findBestEclCellFromFemCell(femPart,
|
||||
srcRangeCube[cornerIdx][0],
|
||||
srcRangeCube[cornerIdx][1],
|
||||
srcRangeCube[cornerIdx][2],
|
||||
@ -239,7 +239,7 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
&(rangeFilterMatches[cornerIdx].ijk[1]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[2]));
|
||||
|
||||
rangeFilterMatches[diagIdx].isExactMatch = findBestEclCellFromFemCell(femPart,
|
||||
rangeFilterMatches[diagIdx].cellMatchType = findBestEclCellFromFemCell(femPart,
|
||||
srcRangeCube[diagIdx][0],
|
||||
srcRangeCube[diagIdx][1],
|
||||
srcRangeCube[diagIdx][2],
|
||||
@ -249,7 +249,7 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
&(rangeFilterMatches[diagIdx].ijk[2]));
|
||||
}
|
||||
|
||||
if (rangeFilterMatches[cornerIdx].isExactMatch && rangeFilterMatches[diagIdx].isExactMatch)
|
||||
if (rangeFilterMatches[cornerIdx].cellMatchType == EXACT && rangeFilterMatches[diagIdx].cellMatchType == EXACT)
|
||||
{
|
||||
foundExactMatch = true;
|
||||
break;
|
||||
@ -269,9 +269,8 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
}
|
||||
else
|
||||
{
|
||||
// Todo: be even smarter, and use possible matching corners to add up an as best solution as possible.
|
||||
// For now we just take the first diagonal.
|
||||
|
||||
// Look at the matches for each "face" of the range filter cube,
|
||||
// and use first exact match to determine the position of that "face"
|
||||
size_t faceIJKs[6] = {cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T,cvf::UNDEFINED_SIZE_T,cvf::UNDEFINED_SIZE_T,cvf::UNDEFINED_SIZE_T,cvf::UNDEFINED_SIZE_T};
|
||||
for (int faceIdx = 0; faceIdx < 6; ++faceIdx)
|
||||
{
|
||||
@ -282,28 +281,40 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
|
||||
cvf::ubyte surfCorners[4];
|
||||
cvf::StructGridInterface::cellFaceVertexIndices((cvf::StructGridInterface::FaceType) faceIdx , surfCorners);
|
||||
bool foundExactMatch = false;
|
||||
std::vector<size_t> candidates;
|
||||
bool foundAcceptedMatch = false;
|
||||
for (int cIdx = 0; cIdx < 4; ++cIdx)
|
||||
{
|
||||
if (rangeFilterMatches[surfCorners[cIdx]].isExactMatch)
|
||||
if (rangeFilterMatches[surfCorners[cIdx]].cellMatchType == EXACT)
|
||||
{
|
||||
foundExactMatch = true;
|
||||
foundAcceptedMatch = true;
|
||||
|
||||
faceIJKs[faceIdx] = rangeFilterMatches[surfCorners[cIdx]].ijk[ijOrk];
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
candidates.push_back(rangeFilterMatches[surfCorners[cIdx]].ijk[ijOrk]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundExactMatch)
|
||||
if (!foundAcceptedMatch)
|
||||
{
|
||||
// Todo: Select the most common, or the max or the min or something clever.
|
||||
CVF_TIGHT_ASSERT(candidates.size() == 4);
|
||||
faceIJKs[faceIdx] = candidates[0];
|
||||
// Take first match that is not related to a collapsed eclipse cell
|
||||
for (int cIdx = 0; cIdx < 4; ++cIdx)
|
||||
{
|
||||
if (rangeFilterMatches[surfCorners[cIdx]].cellMatchType == APPROX)
|
||||
{
|
||||
foundAcceptedMatch = true;
|
||||
|
||||
faceIJKs[faceIdx] = rangeFilterMatches[surfCorners[cIdx]].ijk[ijOrk];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!foundAcceptedMatch)
|
||||
{
|
||||
// Only collapsed cell hits in this "face"
|
||||
// Todo: then use opposite face - range filter thickness
|
||||
// For now, just select the first
|
||||
faceIJKs[faceIdx] = rangeFilterMatches[surfCorners[0]].ijk[ijOrk];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,9 +335,10 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeE
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Return 0 for collapsed cell 1 for
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigCaseToCaseRangeFilterMapper::findBestFemCellFromEclCell(const RigMainGrid* masterEclGrid, size_t ei, size_t ej, size_t ek, const RigFemPart* dependentFemPart, size_t* fi, size_t * fj, size_t* fk)
|
||||
RigCaseToCaseRangeFilterMapper::CellMatchType
|
||||
RigCaseToCaseRangeFilterMapper::findBestFemCellFromEclCell(const RigMainGrid* masterEclGrid, size_t ei, size_t ej, size_t ek, const RigFemPart* dependentFemPart, size_t* fi, size_t * fj, size_t* fk)
|
||||
{
|
||||
// Find tolerance
|
||||
|
||||
@ -340,6 +352,8 @@ bool RigCaseToCaseRangeFilterMapper::findBestFemCellFromEclCell(const RigMainGri
|
||||
|
||||
size_t cellIdx = masterEclGrid->cellIndexFromIJK(ei, ej, ek);
|
||||
|
||||
bool isCollapsedCell = masterEclGrid->cells()[cellIdx].isCollapsedCell();
|
||||
|
||||
cvf::Vec3d geoMechConvertedEclCell[8];
|
||||
RigCaseToCaseCellMapperTools::estimatedFemCellFromEclCell(masterEclGrid, cellIdx, geoMechConvertedEclCell);
|
||||
|
||||
@ -393,13 +407,16 @@ bool RigCaseToCaseRangeFilterMapper::findBestFemCellFromEclCell(const RigMainGri
|
||||
(*fk) = cvf::UNDEFINED_SIZE_T;
|
||||
}
|
||||
|
||||
return foundExactMatch;
|
||||
if (foundExactMatch) return EXACT;
|
||||
if (isCollapsedCell) return APPROX_ON_COLLAPSED;
|
||||
return APPROX;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigCaseToCaseRangeFilterMapper::findBestEclCellFromFemCell(const RigFemPart* dependentFemPart, size_t fi, size_t fj, size_t fk, const RigMainGrid* masterEclGrid, size_t* ei, size_t* ej, size_t* ek)
|
||||
RigCaseToCaseRangeFilterMapper::CellMatchType
|
||||
RigCaseToCaseRangeFilterMapper::findBestEclCellFromFemCell(const RigFemPart* dependentFemPart, size_t fi, size_t fj, size_t fk, const RigMainGrid* masterEclGrid, size_t* ei, size_t* ej, size_t* ek)
|
||||
{
|
||||
// Find tolerance
|
||||
|
||||
@ -454,9 +471,11 @@ bool RigCaseToCaseRangeFilterMapper::findBestEclCellFromFemCell(const RigFemPart
|
||||
}
|
||||
}
|
||||
|
||||
bool isCollapsedCell = false;
|
||||
if (globCellIdxToBestMatch != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
masterEclGrid->ijkFromCellIndex(globCellIdxToBestMatch, ei, ej, ek);
|
||||
isCollapsedCell = masterEclGrid->cells()[globCellIdxToBestMatch].isCollapsedCell();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -465,5 +484,7 @@ bool RigCaseToCaseRangeFilterMapper::findBestEclCellFromFemCell(const RigFemPart
|
||||
(*ek) = cvf::UNDEFINED_SIZE_T;
|
||||
}
|
||||
|
||||
return foundExactMatch;
|
||||
if (foundExactMatch) return EXACT;
|
||||
if (isCollapsedCell) return APPROX_ON_COLLAPSED;
|
||||
return APPROX;
|
||||
}
|
||||
|
@ -45,11 +45,11 @@ private:
|
||||
const RigFemPart* femPart,
|
||||
bool femIsDestination);
|
||||
|
||||
|
||||
static bool findBestFemCellFromEclCell(const RigMainGrid* masterEclGrid, size_t ei, size_t ej, size_t ek,
|
||||
enum CellMatchType {APPROX_ON_COLLAPSED, APPROX, EXACT };
|
||||
static CellMatchType findBestFemCellFromEclCell(const RigMainGrid* masterEclGrid, size_t ei, size_t ej, size_t ek,
|
||||
const RigFemPart* dependentFemPart, size_t* fi, size_t * fj, size_t* fk);
|
||||
|
||||
static bool findBestEclCellFromFemCell(const RigFemPart* dependentFemPart, size_t fi, size_t fj, size_t fk,
|
||||
static CellMatchType findBestEclCellFromFemCell(const RigFemPart* dependentFemPart, size_t fi, size_t fj, size_t fk,
|
||||
const RigMainGrid* masterEclGrid, size_t* ei, size_t* ej, size_t* ek);
|
||||
};
|
||||
|
||||
|
@ -221,6 +221,49 @@ bool RigCell::isLongPyramidCell(double maxHeightFactor, double nodeNearTolerance
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigCell::isCollapsedCell(double nodeNearTolerance) const
|
||||
{
|
||||
const std::vector<cvf::Vec3d>& nodes = m_hostGrid->mainGrid()->nodes();
|
||||
|
||||
bool isPyramidCell = false;
|
||||
cvf::ubyte faceVertexIndices[4];
|
||||
cvf::ubyte oppFaceVertexIndices[4];
|
||||
|
||||
int face;
|
||||
for ( face = 0; face < 6 ; face += 2)
|
||||
{
|
||||
cvf::StructGridInterface::cellFaceVertexIndices(static_cast<cvf::StructGridInterface::FaceType>(face), faceVertexIndices);
|
||||
cvf::StructGridInterface::cellFaceVertexIndices(cvf::StructGridInterface::oppositeFace(static_cast<cvf::StructGridInterface::FaceType>(face)), oppFaceVertexIndices);
|
||||
|
||||
cvf::Vec3d c0 = nodes[m_cornerIndices[faceVertexIndices[0]]];
|
||||
cvf::Vec3d c1 = nodes[m_cornerIndices[faceVertexIndices[1]]];
|
||||
cvf::Vec3d c2 = nodes[m_cornerIndices[faceVertexIndices[2]]];
|
||||
cvf::Vec3d c3 = nodes[m_cornerIndices[faceVertexIndices[3]]];
|
||||
|
||||
cvf::Vec3d oc0 = nodes[m_cornerIndices[oppFaceVertexIndices[0]]];
|
||||
cvf::Vec3d oc1 = nodes[m_cornerIndices[oppFaceVertexIndices[1]]];
|
||||
cvf::Vec3d oc2 = nodes[m_cornerIndices[oppFaceVertexIndices[2]]];
|
||||
cvf::Vec3d oc3 = nodes[m_cornerIndices[oppFaceVertexIndices[3]]];
|
||||
|
||||
int zeroLengthEdgeCount = 0;
|
||||
if (isNear(c0, oc0, nodeNearTolerance)) { ++zeroLengthEdgeCount; }
|
||||
if (isNear(c1, oc3, nodeNearTolerance)) { ++zeroLengthEdgeCount; }
|
||||
if (isNear(c2, oc2, nodeNearTolerance)) { ++zeroLengthEdgeCount; }
|
||||
if (isNear(c3, oc1, nodeNearTolerance)) { ++zeroLengthEdgeCount; }
|
||||
|
||||
if (zeroLengthEdgeCount >= 4)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
|
||||
int firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectionPoint) const;
|
||||
bool isLongPyramidCell(double maxHeightFactor = 5, double nodeNearTolerance = 1e-3 ) const;
|
||||
bool isCollapsedCell( double nodeNearTolerance = 1e-3) const;
|
||||
private:
|
||||
caf::SizeTArray8 m_cornerIndices;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user