mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
(#540) Range filter mapping now works fem->ecl and opposite.
We need to test more, but now it is getting there.
This commit is contained in:
parent
53826f4966
commit
00b56b7440
@ -70,23 +70,31 @@ struct RigRangeEndPoints
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void RigCaseToCaseRangeFilterMapper::convertRangeFilter(RimCellRangeFilter* srcFilter, RimCellRangeFilter* dstFilter,
|
||||
const RigMainGrid* eclGrid, const RigFemPart* femPart,
|
||||
void RigCaseToCaseRangeFilterMapper::convertRangeFilter(const RimCellRangeFilter* srcFilter,
|
||||
RimCellRangeFilter* dstFilter,
|
||||
const RigMainGrid* eclGrid,
|
||||
const RigFemPart* femPart,
|
||||
bool femIsDestination)
|
||||
{
|
||||
CVF_ASSERT(srcFilter && eclGrid && dstFilter && femPart);
|
||||
CVF_ASSERT(srcFilter->gridIndex() == 0); // LGR not supported yet
|
||||
|
||||
|
||||
RigRangeEndPoints src;
|
||||
src.StartI = srcFilter->startIndexI() - 1;
|
||||
src.StartJ = srcFilter->startIndexJ() - 1;
|
||||
src.StartK = srcFilter->startIndexK() - 1;
|
||||
// Convert the (start, count) range filter vars to end point cell ijk
|
||||
{
|
||||
src.StartI = srcFilter->startIndexI() - 1;
|
||||
src.StartJ = srcFilter->startIndexJ() - 1;
|
||||
src.StartK = srcFilter->startIndexK() - 1;
|
||||
|
||||
// Needs to subtract one more to have the end idx beeing the last cell in the selection, not the first outside
|
||||
src.EndI = src.StartI + srcFilter->cellCountI() - 1;
|
||||
src.EndJ = src.StartJ + srcFilter->cellCountJ() - 1;
|
||||
src.EndK = src.StartK + srcFilter->cellCountK() - 1;
|
||||
// Needs to subtract one more to have the end idx beeing
|
||||
// the last cell in the selection, not the first outside
|
||||
src.EndI = src.StartI + srcFilter->cellCountI() - 1;
|
||||
src.EndJ = src.StartJ + srcFilter->cellCountJ() - 1;
|
||||
src.EndK = src.StartK + srcFilter->cellCountK() - 1;
|
||||
}
|
||||
|
||||
// Clamp the src end points to be inside the src model
|
||||
{
|
||||
size_t maxIIndex;
|
||||
size_t maxJIndex;
|
||||
@ -101,11 +109,6 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilter(RimCellRangeFilter* srcF
|
||||
}
|
||||
else
|
||||
{
|
||||
// When using femPart as source we need to clamp the fem srcRange filter
|
||||
// to the extents of the ecl grid within the fem part before
|
||||
// doing the mapping. If not, the range filter corners will most likely be outside
|
||||
// the ecl grid, resulting in an undefined conversion.
|
||||
|
||||
maxIIndex = femPart->structGrid()->cellCountI()- 1;
|
||||
maxJIndex = femPart->structGrid()->cellCountJ()- 1;
|
||||
maxKIndex = femPart->structGrid()->cellCountK()- 1;
|
||||
@ -116,104 +119,35 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilter(RimCellRangeFilter* srcF
|
||||
src.EndK = CVF_MIN(src.EndK, maxKIndex);
|
||||
}
|
||||
|
||||
// When using femPart as source we need to clamp the fem srcRange filter
|
||||
// to the extents of the ecl grid within the fem part before
|
||||
// doing the mapping. If not, the range filter corners will most likely be outside
|
||||
// the ecl grid, resulting in an undefined conversion.
|
||||
if (!femIsDestination)
|
||||
{
|
||||
RigRangeEndPoints eclMaxMin;
|
||||
eclMaxMin.StartI = 0;
|
||||
eclMaxMin.StartJ = 0;
|
||||
eclMaxMin.StartK = 0;
|
||||
eclMaxMin.EndI = eclGrid->cellCountI() - 1;
|
||||
eclMaxMin.EndJ = eclGrid->cellCountJ() - 1;
|
||||
eclMaxMin.EndK = eclGrid->cellCountK() - 1;
|
||||
RigRangeEndPoints eclExtInFem;
|
||||
|
||||
convertRangeFilterEndPoints(eclMaxMin, eclExtInFem, eclGrid, femPart, true);
|
||||
|
||||
src.StartI = CVF_MAX(src.StartI, eclExtInFem.StartI);
|
||||
src.StartJ = CVF_MAX(src.StartJ, eclExtInFem.StartJ);
|
||||
src.StartK = CVF_MAX(src.StartK, eclExtInFem.StartK);
|
||||
src.EndI = CVF_MIN(src.EndI , eclExtInFem.EndI);
|
||||
src.EndJ = CVF_MIN(src.EndJ , eclExtInFem.EndJ);
|
||||
src.EndK = CVF_MIN(src.EndK , eclExtInFem.EndK);
|
||||
}
|
||||
|
||||
RigRangeEndPoints dst;
|
||||
|
||||
{
|
||||
struct RangeFilterCorner { RangeFilterCorner() : isExactMatch(false){} cvf::Vec3st ijk; bool isExactMatch; };
|
||||
convertRangeFilterEndPoints(src, dst, eclGrid, femPart, femIsDestination);
|
||||
|
||||
RangeFilterCorner rangeFilterMatches[8];
|
||||
|
||||
cvf::Vec3st srcRangeCube[8];
|
||||
srcRangeCube[0] = cvf::Vec3st(src.StartI, src.StartJ, src.StartK);
|
||||
srcRangeCube[1] = cvf::Vec3st(src.EndI, src.StartJ, src.StartK);
|
||||
srcRangeCube[2] = cvf::Vec3st(src.EndI, src.EndJ, src.StartK);
|
||||
srcRangeCube[3] = cvf::Vec3st(src.StartI, src.EndJ, src.StartK);
|
||||
srcRangeCube[4] = cvf::Vec3st(src.StartI, src.StartJ, src.EndK);
|
||||
srcRangeCube[5] = cvf::Vec3st(src.EndI, src.StartJ, src.EndK);
|
||||
srcRangeCube[6] = cvf::Vec3st(src.EndI, src.EndJ, src.EndK);
|
||||
srcRangeCube[7] = cvf::Vec3st(src.StartI, src.EndJ, src.EndK);
|
||||
|
||||
|
||||
|
||||
bool foundExactMatch = false;
|
||||
int cornerIdx = 0;
|
||||
int diagIdx = 6;// Index to diagonal corner
|
||||
|
||||
for (cornerIdx = 0; cornerIdx < 4; ++cornerIdx)
|
||||
{
|
||||
diagIdx = (cornerIdx < 2) ? cornerIdx + 6 : cornerIdx + 2;
|
||||
|
||||
if (femIsDestination)
|
||||
{
|
||||
rangeFilterMatches[cornerIdx].isExactMatch = findBestFemCellFromEclCell(eclGrid,
|
||||
srcRangeCube[cornerIdx][0],
|
||||
srcRangeCube[cornerIdx][1],
|
||||
srcRangeCube[cornerIdx][2],
|
||||
femPart,
|
||||
&(rangeFilterMatches[cornerIdx].ijk[0]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[1]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[2]));
|
||||
|
||||
rangeFilterMatches[diagIdx].isExactMatch = findBestFemCellFromEclCell(eclGrid,
|
||||
srcRangeCube[diagIdx][0],
|
||||
srcRangeCube[diagIdx][1],
|
||||
srcRangeCube[diagIdx][2],
|
||||
femPart,
|
||||
&(rangeFilterMatches[diagIdx].ijk[0]),
|
||||
&(rangeFilterMatches[diagIdx].ijk[1]),
|
||||
&(rangeFilterMatches[diagIdx].ijk[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeFilterMatches[cornerIdx].isExactMatch = findBestEclCellFromFemCell(femPart,
|
||||
srcRangeCube[cornerIdx][0],
|
||||
srcRangeCube[cornerIdx][1],
|
||||
srcRangeCube[cornerIdx][2],
|
||||
eclGrid,
|
||||
&(rangeFilterMatches[cornerIdx].ijk[0]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[1]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[2]));
|
||||
|
||||
rangeFilterMatches[diagIdx].isExactMatch = findBestEclCellFromFemCell(femPart,
|
||||
srcRangeCube[diagIdx][0],
|
||||
srcRangeCube[diagIdx][1],
|
||||
srcRangeCube[diagIdx][2],
|
||||
eclGrid,
|
||||
&(rangeFilterMatches[diagIdx].ijk[0]),
|
||||
&(rangeFilterMatches[diagIdx].ijk[1]),
|
||||
&(rangeFilterMatches[diagIdx].ijk[2]));
|
||||
}
|
||||
|
||||
if (rangeFilterMatches[cornerIdx].isExactMatch && rangeFilterMatches[diagIdx].isExactMatch)
|
||||
{
|
||||
foundExactMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the start and end IJK from the matched corners
|
||||
if (foundExactMatch)
|
||||
{
|
||||
// Populate dst range filter from the diagonal that matches exact
|
||||
dst.StartI = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[0], rangeFilterMatches[diagIdx].ijk[0]);
|
||||
dst.StartJ = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[1], rangeFilterMatches[diagIdx].ijk[1]);
|
||||
dst.StartK = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[2], rangeFilterMatches[diagIdx].ijk[2]);
|
||||
dst.EndI = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[0], rangeFilterMatches[diagIdx].ijk[0]);
|
||||
dst.EndJ = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[1], rangeFilterMatches[diagIdx].ijk[1]);
|
||||
dst.EndK = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[2], rangeFilterMatches[diagIdx].ijk[2]);
|
||||
}
|
||||
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.
|
||||
dst.StartI = rangeFilterMatches[0].ijk[0];
|
||||
dst.StartJ = rangeFilterMatches[0].ijk[1];
|
||||
dst.StartK = rangeFilterMatches[0].ijk[2];
|
||||
dst.EndI = rangeFilterMatches[6].ijk[0];
|
||||
dst.EndJ = rangeFilterMatches[6].ijk[1];
|
||||
dst.EndK = rangeFilterMatches[6].ijk[2];
|
||||
}
|
||||
}
|
||||
// Populate the dst range filter with new data
|
||||
|
||||
if ( dst.StartI != cvf::UNDEFINED_SIZE_T
|
||||
@ -243,6 +177,112 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilter(RimCellRangeFilter* srcF
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeEndPoints &src,
|
||||
RigRangeEndPoints &dst,
|
||||
const RigMainGrid* eclGrid,
|
||||
const RigFemPart* femPart,
|
||||
bool femIsDestination)
|
||||
{
|
||||
{
|
||||
struct RangeFilterCorner { RangeFilterCorner() : isExactMatch(false){} cvf::Vec3st ijk; bool isExactMatch; };
|
||||
|
||||
RangeFilterCorner rangeFilterMatches[8];
|
||||
|
||||
cvf::Vec3st srcRangeCube[8];
|
||||
srcRangeCube[0] = cvf::Vec3st(src.StartI, src.StartJ, src.StartK);
|
||||
srcRangeCube[1] = cvf::Vec3st(src.EndI , src.StartJ, src.StartK);
|
||||
srcRangeCube[2] = cvf::Vec3st(src.EndI , src.EndJ , src.StartK);
|
||||
srcRangeCube[3] = cvf::Vec3st(src.StartI, src.EndJ , src.StartK);
|
||||
srcRangeCube[4] = cvf::Vec3st(src.StartI, src.StartJ, src.EndK);
|
||||
srcRangeCube[5] = cvf::Vec3st(src.EndI , src.StartJ, src.EndK);
|
||||
srcRangeCube[6] = cvf::Vec3st(src.EndI , src.EndJ , src.EndK);
|
||||
srcRangeCube[7] = cvf::Vec3st(src.StartI, src.EndJ , src.EndK);
|
||||
|
||||
bool foundExactMatch = false;
|
||||
int cornerIdx = 0;
|
||||
int diagIdx = 6;// Index to diagonal corner
|
||||
|
||||
for (cornerIdx = 0; cornerIdx < 4; ++cornerIdx)
|
||||
{
|
||||
diagIdx = (cornerIdx < 2) ? cornerIdx + 6 : cornerIdx + 2;
|
||||
|
||||
if (femIsDestination)
|
||||
{
|
||||
rangeFilterMatches[cornerIdx].isExactMatch = findBestFemCellFromEclCell(eclGrid,
|
||||
srcRangeCube[cornerIdx][0],
|
||||
srcRangeCube[cornerIdx][1],
|
||||
srcRangeCube[cornerIdx][2],
|
||||
femPart,
|
||||
&(rangeFilterMatches[cornerIdx].ijk[0]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[1]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[2]));
|
||||
|
||||
rangeFilterMatches[diagIdx].isExactMatch = findBestFemCellFromEclCell(eclGrid,
|
||||
srcRangeCube[diagIdx][0],
|
||||
srcRangeCube[diagIdx][1],
|
||||
srcRangeCube[diagIdx][2],
|
||||
femPart,
|
||||
&(rangeFilterMatches[diagIdx].ijk[0]),
|
||||
&(rangeFilterMatches[diagIdx].ijk[1]),
|
||||
&(rangeFilterMatches[diagIdx].ijk[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeFilterMatches[cornerIdx].isExactMatch = findBestEclCellFromFemCell(femPart,
|
||||
srcRangeCube[cornerIdx][0],
|
||||
srcRangeCube[cornerIdx][1],
|
||||
srcRangeCube[cornerIdx][2],
|
||||
eclGrid,
|
||||
&(rangeFilterMatches[cornerIdx].ijk[0]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[1]),
|
||||
&(rangeFilterMatches[cornerIdx].ijk[2]));
|
||||
|
||||
rangeFilterMatches[diagIdx].isExactMatch = findBestEclCellFromFemCell(femPart,
|
||||
srcRangeCube[diagIdx][0],
|
||||
srcRangeCube[diagIdx][1],
|
||||
srcRangeCube[diagIdx][2],
|
||||
eclGrid,
|
||||
&(rangeFilterMatches[diagIdx].ijk[0]),
|
||||
&(rangeFilterMatches[diagIdx].ijk[1]),
|
||||
&(rangeFilterMatches[diagIdx].ijk[2]));
|
||||
}
|
||||
|
||||
if (rangeFilterMatches[cornerIdx].isExactMatch && rangeFilterMatches[diagIdx].isExactMatch)
|
||||
{
|
||||
foundExactMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the start and end IJK from the matched corners
|
||||
if (foundExactMatch)
|
||||
{
|
||||
// Populate dst range filter from the diagonal that matches exact
|
||||
dst.StartI = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[0], rangeFilterMatches[diagIdx].ijk[0]);
|
||||
dst.StartJ = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[1], rangeFilterMatches[diagIdx].ijk[1]);
|
||||
dst.StartK = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[2], rangeFilterMatches[diagIdx].ijk[2]);
|
||||
dst.EndI = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[0], rangeFilterMatches[diagIdx].ijk[0]);
|
||||
dst.EndJ = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[1], rangeFilterMatches[diagIdx].ijk[1]);
|
||||
dst.EndK = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[2], rangeFilterMatches[diagIdx].ijk[2]);
|
||||
}
|
||||
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.
|
||||
dst.StartI = rangeFilterMatches[0].ijk[0];
|
||||
dst.StartJ = rangeFilterMatches[0].ijk[1];
|
||||
dst.StartK = rangeFilterMatches[0].ijk[2];
|
||||
dst.EndI = rangeFilterMatches[6].ijk[0];
|
||||
dst.EndJ = rangeFilterMatches[6].ijk[1];
|
||||
dst.EndK = rangeFilterMatches[6].ijk[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -387,4 +427,3 @@ bool RigCaseToCaseRangeFilterMapper::findBestEclCellFromFemCell(const RigFemPart
|
||||
|
||||
return foundExactMatch;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
class RimCellRangeFilter;
|
||||
class RigMainGrid;
|
||||
class RigFemPart;
|
||||
struct RigRangeEndPoints;
|
||||
|
||||
class RigCaseToCaseRangeFilterMapper
|
||||
{
|
||||
@ -34,10 +35,16 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
static void convertRangeFilter(RimCellRangeFilter* srcFilter, RimCellRangeFilter* dstFilter,
|
||||
static void convertRangeFilter(const RimCellRangeFilter* srcFilter, RimCellRangeFilter* dstFilter,
|
||||
const RigMainGrid* eclGrid, const RigFemPart* femPart,
|
||||
bool femIsDestination);
|
||||
|
||||
static void convertRangeFilterEndPoints(const RigRangeEndPoints &src,
|
||||
RigRangeEndPoints &dst,
|
||||
const RigMainGrid* eclGrid,
|
||||
const RigFemPart* femPart,
|
||||
bool femIsDestination);
|
||||
|
||||
|
||||
static bool 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);
|
||||
|
Loading…
Reference in New Issue
Block a user