#3630 2d Maps: schedule update of volumes when creating LGRs

This commit is contained in:
Gaute Lindkvist 2018-11-08 10:18:49 +01:00
parent 30f5a76ee4
commit ad9f86a517
9 changed files with 81 additions and 140 deletions

View File

@ -341,6 +341,7 @@ void RicCreateTemporaryLgrFeature::computeCachedData(RimEclipseCase* eclipseCase
if (cellResultsDataMatrix)
{
cellResultsDataMatrix->computeDepthRelatedResults();
cellResultsDataMatrix->computeCellVolumes();
}
if (cellResultsDataFracture)

View File

@ -100,8 +100,7 @@ cvf::BoundingBox Rim2dGridProjection::expandedBoundingBox() const
//--------------------------------------------------------------------------------------------------
void Rim2dGridProjection::generateGridMapping()
{
calculateCellRangeVisibility();
calculatePropertyFilterVisibility();
calculateTotalCellVisibility();
cvf::Vec3d gridExtent = expandedBoundingBox().extent();
@ -198,7 +197,7 @@ void Rim2dGridProjection::generateResults()
{
generateGridMapping();
int nVertices = vertexCount();
m_aggregatedResults.resize(nVertices, std::numeric_limits<double>::infinity());
m_aggregatedResults = std::vector<double>(nVertices, std::numeric_limits<double>::infinity());
RimEclipseView* view = nullptr;
firstAncestorOrThisOfTypeAsserted(view);
@ -395,7 +394,7 @@ double Rim2dGridProjection::value(uint i, uint j) const
//--------------------------------------------------------------------------------------------------
double Rim2dGridProjection::calculateValue(uint i, uint j) const
{
const std::vector<std::pair<size_t, float>>& matchingCells = cellsAtPos2d(i, j);
const std::vector<std::pair<size_t, double>>& matchingCells = cellsAtPos2d(i, j);
if (!matchingCells.empty())
{
switch (m_resultAggregation())
@ -408,7 +407,7 @@ double Rim2dGridProjection::calculateValue(uint i, uint j) const
}
case RESULTS_MEAN_VALUE:
{
RiaWeightedMeanCalculator<float> calculator;
RiaWeightedMeanCalculator<double> calculator;
for (auto cellIdxAndWeight : matchingCells)
{
size_t cellIdx = cellIdxAndWeight.first;
@ -518,7 +517,7 @@ double Rim2dGridProjection::calculateValue(uint i, uint j) const
//--------------------------------------------------------------------------------------------------
double Rim2dGridProjection::calculateVolumeSum(uint i, uint j) const
{
const std::vector<std::pair<size_t, float>>& matchingCells = cellsAtPos2d(i, j);
const std::vector<std::pair<size_t, double>>& matchingCells = cellsAtPos2d(i, j);
if (!matchingCells.empty())
{
double sum = 0.0;
@ -537,7 +536,7 @@ double Rim2dGridProjection::calculateVolumeSum(uint i, uint j) const
//--------------------------------------------------------------------------------------------------
double Rim2dGridProjection::calculateSoilSum(uint i, uint j) const
{
const std::vector<std::pair<size_t, float>>& matchingCells = cellsAtPos2d(i, j);
const std::vector<std::pair<size_t, double>>& matchingCells = cellsAtPos2d(i, j);
if (!matchingCells.empty())
{
double sum = 0.0;
@ -622,89 +621,12 @@ RimRegularLegendConfig* Rim2dGridProjection::legendConfig() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim2dGridProjection::calculateCellRangeVisibility()
void Rim2dGridProjection::calculateTotalCellVisibility()
{
RimEclipseView* view = nullptr;
firstAncestorOrThisOfTypeAsserted(view);
RimCellRangeFilterCollection* rangeFilterCollection = view->rangeFilterCollection();
const RigActiveCellInfo* activeCellInfo = eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL);
for (size_t gridIndex = 0u; gridIndex < mainGrid()->gridCount(); ++gridIndex)
{
const RigGridBase* grid = mainGrid()->gridByIndex(gridIndex);
cvf::ref<cvf::UByteArray> parentGridVisibilities;
bool isSubGrid = false;
if (!grid->isMainGrid())
{
size_t parentGridIndex = static_cast<const RigLocalGrid*>(grid)->parentGrid()->gridIndex();
parentGridVisibilities = m_cellGridIdxVisibilityMap[parentGridIndex];
isSubGrid = true;
}
m_cellGridIdxVisibilityMap[gridIndex] = new cvf::UByteArray(grid->cellCount());
#pragma omp parallel for
for (int cellIndex = 0; cellIndex < static_cast<int>(grid->cellCount()); ++cellIndex)
{
size_t globalCellIdx = grid->reservoirCellIndex(cellIndex);
(*m_cellGridIdxVisibilityMap[gridIndex])[cellIndex] = activeCellInfo->isActive(globalCellIdx);
}
if (rangeFilterCollection && rangeFilterCollection->isActive())
{
cvf::CellRangeFilter cellRangeFilter;
rangeFilterCollection->compoundCellRangeFilter(&cellRangeFilter, gridIndex);
if (rangeFilterCollection->hasActiveIncludeFilters())
{
#pragma omp parallel for
for (int cellIndex = 0; cellIndex < static_cast<int>(grid->cellCount()); ++cellIndex)
{
size_t i, j, k;
grid->ijkFromCellIndex(cellIndex, &i, &j, &k);
if ((*m_cellGridIdxVisibilityMap[gridIndex])[cellIndex])
{
const RigCell& cell = grid->cell(cellIndex);
bool visibleDueToParent = false;
if (isSubGrid)
{
size_t parentGridCellIndex = cell.parentCellIndex();
visibleDueToParent = parentGridVisibilities->get(parentGridCellIndex);
}
(*m_cellGridIdxVisibilityMap[gridIndex])[cellIndex] =
visibleDueToParent || cellRangeFilter.isCellVisible(i, j, k, isSubGrid);
}
}
}
#pragma omp parallel for
for (int cellIndex = 0; cellIndex < static_cast<int>(grid->cellCount()); ++cellIndex)
{
size_t i, j, k;
grid->ijkFromCellIndex(cellIndex, &i, &j, &k);
(*m_cellGridIdxVisibilityMap[gridIndex])[cellIndex] =
(*m_cellGridIdxVisibilityMap[gridIndex])[cellIndex] && !cellRangeFilter.isCellExcluded(i, j, k, isSubGrid);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim2dGridProjection::calculatePropertyFilterVisibility()
{
RimEclipseView* view = nullptr;
firstAncestorOrThisOfTypeAsserted(view);
int timeStep = view->currentTimeStep();
for (size_t gridIndex = 0u; gridIndex < mainGrid()->gridCount(); ++gridIndex)
{
const RigGridBase* grid = mainGrid()->gridByIndex(gridIndex);
RivReservoirViewPartMgr::computePropertyVisibility(m_cellGridIdxVisibilityMap[gridIndex].p(), grid, timeStep, m_cellGridIdxVisibilityMap[gridIndex].p(), view->eclipsePropertyFilterCollection());
}
m_cellGridIdxVisibility = view->currentTotalCellVisibility();
}
//--------------------------------------------------------------------------------------------------
@ -724,7 +646,7 @@ cvf::Vec2d Rim2dGridProjection::globalPos2d(uint i, uint j) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<std::pair<size_t, float>>& Rim2dGridProjection::cellsAtPos2d(uint i, uint j) const
const std::vector<std::pair<size_t, double>>& Rim2dGridProjection::cellsAtPos2d(uint i, uint j) const
{
return m_projected3dGridIndices[gridIndex(i, j)];
}
@ -732,7 +654,7 @@ const std::vector<std::pair<size_t, float>>& Rim2dGridProjection::cellsAtPos2d(u
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<size_t, float>> Rim2dGridProjection::visibleCellsAndWeightMatching2dPoint(const cvf::Vec2d& globalPos2d) const
std::vector<std::pair<size_t, double>> Rim2dGridProjection::visibleCellsAndWeightMatching2dPoint(const cvf::Vec2d& globalPos2d) const
{
cvf::BoundingBox gridBoundingBox = expandedBoundingBox();
cvf::Vec3d top2dElementCentroid(globalPos2d, gridBoundingBox.max().z());
@ -746,20 +668,22 @@ std::vector<std::pair<size_t, float>> Rim2dGridProjection::visibleCellsAndWeight
std::vector<size_t> allCellIndices;
mainGrid()->findIntersectingCells(bbox2dElement, &allCellIndices);
std::vector<std::tuple<size_t, float, float>> matchingVisibleCellsWeightAndHeight;
std::vector<std::tuple<size_t, double, double>> matchingVisibleCellsWeightAndHeight;
std::array<cvf::Vec3d, 8> hexCorners;
for (size_t globalCellIdx : allCellIndices)
{
size_t localCellIdx = 0u;
RigGridBase* localGrid = mainGrid()->gridAndGridLocalIdxFromGlobalCellIdx(globalCellIdx, &localCellIdx);
if ((*m_cellGridIdxVisibilityMap.at(localGrid->gridIndex()))[localCellIdx])
if ((*m_cellGridIdxVisibility)[globalCellIdx])
{
size_t localCellIdx = 0u;
RigGridBase* localGrid = mainGrid()->gridAndGridLocalIdxFromGlobalCellIdx(globalCellIdx, &localCellIdx);
localGrid->cellCornerVertices(localCellIdx, hexCorners.data());
cvf::BoundingBox overlapBBox = createHexOverlapEstimation(bbox2dElement, &hexCorners);
cvf::BoundingBox overlapBBox;
std::array<cvf::Vec3d, 8> overlapCorners = createHexOverlapEstimation(bbox2dElement, hexCorners, &overlapBBox);
double overlapVolume = RigCellGeometryTools::calculateCellVolume(hexCorners);
double overlapVolume = RigCellGeometryTools::calculateCellVolume(overlapCorners);
if (overlapVolume > 0.0)
{
@ -769,12 +693,12 @@ std::vector<std::pair<size_t, float>> Rim2dGridProjection::visibleCellsAndWeight
}
}
std::vector<std::pair<size_t, float>> matchingVisibleCellsAndWeight;
std::vector<std::pair<size_t, double>> matchingVisibleCellsAndWeight;
if (!matchingVisibleCellsWeightAndHeight.empty())
{
std::sort(matchingVisibleCellsWeightAndHeight.begin(),
matchingVisibleCellsWeightAndHeight.end(),
[](const std::tuple<size_t, float, float>& lhs, const std::tuple<size_t, float, float>& rhs) {
[](const std::tuple<size_t, double, double>& lhs, const std::tuple<size_t, double, double>& rhs) {
return std::get<2>(lhs) > std::get<2>(rhs);
});
@ -867,35 +791,36 @@ double Rim2dGridProjection::findSoilResult(size_t cellGlobalIdx) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::BoundingBox Rim2dGridProjection::createHexOverlapEstimation(const cvf::BoundingBox& bbox2dElement, std::array<cvf::Vec3d, 8>* hexCornersToModify) const
std::array<cvf::Vec3d, 8> Rim2dGridProjection::createHexOverlapEstimation(const cvf::BoundingBox& bbox2dElement, const std::array<cvf::Vec3d, 8>& hexCorners, cvf::BoundingBox* overlapBoundingBox) const
{
std::array<cvf::Vec3d, 8>& hexCorners = *hexCornersToModify;
CVF_ASSERT(overlapBoundingBox);
*overlapBoundingBox = cvf::BoundingBox();
std::array<cvf::Vec3d, 8> overlapCorners = hexCorners;
// A reasonable approximation to the overlap volume
cvf::Plane topPlane; topPlane.setFromPoints(hexCorners[0], hexCorners[1], hexCorners[2]);
cvf::Plane bottomPlane; bottomPlane.setFromPoints(hexCorners[4], hexCorners[5], hexCorners[6]);
cvf::BoundingBox overlapBBox;
for (size_t i = 0; i < 4; ++i)
{
cvf::Vec3d& corner = hexCorners[i];
cvf::Vec3d& corner = overlapCorners[i];
corner.x() = cvf::Math::clamp(corner.x(), bbox2dElement.min().x(), bbox2dElement.max().x());
corner.y() = cvf::Math::clamp(corner.y(), bbox2dElement.min().y(), bbox2dElement.max().y());
cvf::Vec3d maxZCorner = corner; maxZCorner.z() = bbox2dElement.max().z();
cvf::Vec3d minZCorner = corner; minZCorner.z() = bbox2dElement.min().z();
topPlane.intersect(maxZCorner, minZCorner, &corner);
overlapBBox.add(corner);
overlapBoundingBox->add(corner);
}
for (size_t i = 4; i < 8; ++i)
{
cvf::Vec3d& corner = hexCorners[i];
cvf::Vec3d& corner = overlapCorners[i];
corner.x() = cvf::Math::clamp(corner.x(), bbox2dElement.min().x(), bbox2dElement.max().x());
corner.y() = cvf::Math::clamp(corner.y(), bbox2dElement.min().y(), bbox2dElement.max().y());
cvf::Vec3d maxZCorner = corner; maxZCorner.z() = bbox2dElement.max().z();
cvf::Vec3d minZCorner = corner; minZCorner.z() = bbox2dElement.min().z();
bottomPlane.intersect(maxZCorner, minZCorner, &corner);
overlapBBox.add(corner);
overlapBoundingBox->add(corner);
}
return overlapBBox;
return overlapCorners;
}
//--------------------------------------------------------------------------------------------------
@ -1065,7 +990,7 @@ void Rim2dGridProjection::defineEditorAttribute(const caf::PdmFieldHandle* field
caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>(attribute);
if (myAttr)
{
myAttr->m_minimum = 0.5;
myAttr->m_minimum = 0.25;
myAttr->m_maximum = 2.0;
}
}

View File

@ -100,17 +100,16 @@ protected:
cvf::BoundingBox expandedBoundingBox() const;
void generateGridMapping();
void calculateCellRangeVisibility();
void calculatePropertyFilterVisibility();
void calculateTotalCellVisibility();
cvf::Vec2d globalPos2d(uint i, uint j) const;
const std::vector<std::pair<size_t, float>>& cellsAtPos2d(uint i, uint j) const;
const std::vector<std::pair<size_t, double>>& cellsAtPos2d(uint i, uint j) const;
std::vector<double> xPositions() const;
std::vector<double> yPositions() const;
std::vector<std::pair<size_t, float>> visibleCellsAndWeightMatching2dPoint(const cvf::Vec2d& globalPos2d) const;
std::vector<std::pair<size_t, double>> visibleCellsAndWeightMatching2dPoint(const cvf::Vec2d& globalPos2d) const;
double findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const;
double findSoilResult(size_t cellGlobalIdx) const;
cvf::BoundingBox createHexOverlapEstimation(const cvf::BoundingBox& bbox2dElement, std::array<cvf::Vec3d, 8>* hexCornersToModify) const;
std::array<cvf::Vec3d, 8> createHexOverlapEstimation(const cvf::BoundingBox& boundingBox2dExtrusion, const std::array<cvf::Vec3d, 8>& hexCorners, cvf::BoundingBox* overlapBoundingBox) const;
const RimEclipseResultCase* eclipseCase() const;
RigMainGrid* mainGrid() const;
@ -124,10 +123,10 @@ protected:
caf::PdmField<ResultAggregation> m_resultAggregation;
caf::PdmField<bool> m_showContourLines;
std::map<size_t, cvf::ref<cvf::UByteArray>> m_cellGridIdxVisibilityMap;
cvf::ref<cvf::UByteArray> m_cellGridIdxVisibility;
std::vector<double> m_aggregatedResults;
std::vector<std::vector<std::pair<size_t, float>>> m_projected3dGridIndices;
std::vector<double> m_aggregatedResults;
std::vector<std::vector<std::pair<size_t, double>>> m_projected3dGridIndices;
cvf::ref<RigResultAccessor> m_resultAccessor;
};

View File

@ -508,8 +508,8 @@ QString Rim3dOverlayInfoConfig::caseInfoText(RimEclipseView* eclipseView)
infoText += QString(
"<p><b>-- %1 --</b><p> "
"<b>Cell count. Total:</b> %2 <b>Valid Result:</b> %3 <br>"
"<b>2d Projection [%4] I,J, Aggregation Type:</b> %5, %6 <br>").arg(caseName, totCellCount, activeCellCountText, aggregationType, iSize, jSize);
"<b>2d Sample Count. Total:</b> %2 <b>Valid Result:</b> %3 <br>"
"<b>2d %4 Projection, 2d Grid I,J:</b> %5, %6 <br>").arg(caseName, totCellCount, activeCellCountText, aggregationType, iSize, jSize);
}
else if (eclipseView->mainGrid())
{

View File

@ -58,8 +58,9 @@ class Rim3dOverlayInfoConfig : public caf::PdmObject
double sum;
double weightedMean;
const std::vector<size_t>* histogram;
bool isValid(double parameter) { return parameter != HUGE_VAL && parameter != -HUGE_VAL; }
bool isValid() { return histogram && histogram->size() > 0 && min != HUGE_VAL && max != HUGE_VAL; }
bool isValid() { return histogram && histogram->size() > 0 && isValid(min) && isValid(max); }
};
public:

View File

@ -215,7 +215,6 @@ bool RimEclipseInputCase::openEclipseGridFile()
loadAndSyncronizeInputProperties();
}
RiaApplication* app = RiaApplication::instance();
if (app->preferences()->autocomputeDepthRelatedProperties)
{
@ -223,6 +222,8 @@ bool RimEclipseInputCase::openEclipseGridFile()
results(RiaDefines::FRACTURE_MODEL)->computeDepthRelatedResults();
}
results(RiaDefines::MATRIX_MODEL)->computeCellVolumes();
return true;
}

View File

@ -230,6 +230,8 @@ bool RimEclipseResultCase::importGridAndResultMetaData(bool showTimeStepFilter)
results(RiaDefines::FRACTURE_MODEL)->computeDepthRelatedResults();
}
results(RiaDefines::MATRIX_MODEL)->computeCellVolumes();
return true;
}

View File

@ -859,6 +859,15 @@ void RigCaseCellResultsData::createPlaceholderResultEntries()
}
}
// Oil Volume
{
size_t soilIndex = findOrCreateScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL", false);
if (soilIndex != cvf::UNDEFINED_SIZE_T)
{
findOrCreateScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::riOilVolumeResultName(), false);
}
}
// Completion type
{
size_t completionTypeIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::completionTypeResultName());
@ -966,16 +975,6 @@ void RigCaseCellResultsData::createPlaceholderResultEntries()
addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riCellVolumeResultName(), false, 0);
}
// Oil Volume
{
size_t soilIndex = findOrCreateScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL", false);
if (soilIndex != cvf::UNDEFINED_SIZE_T)
{
findOrCreateScalarResultIndex(RiaDefines::GENERATED, RiaDefines::riOilVolumeResultName(), false);
}
}
// Mobile Pore Volume
{
if (findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PORV") != cvf::UNDEFINED_SIZE_T)
@ -1155,15 +1154,6 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType
progressInfo.incrementProgress();
}
}
else if (resultName == RiaDefines::riCellVolumeResultName())
{
computeCellVolumes();
}
else if (resultName == RiaDefines::riOilVolumeResultName())
{
computeCellVolumes();
computeOilVolumes();
}
else if (resultName == RiaDefines::mobilePoreVolumeName())
{
computeMobilePV();
@ -1233,6 +1223,18 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType
}
}
if (resultName == RiaDefines::riCellVolumeResultName())
{
computeCellVolumes();
}
else if (resultName == RiaDefines::riOilVolumeResultName())
{
computeCellVolumes();
computeOilVolumes();
}
// Handle SourSimRL reading
if (type == RiaDefines::SOURSIMRL)
@ -2435,10 +2437,14 @@ void RigCaseCellResultsData::computeCellVolumes()
{
size_t cellVolIdx = this->findOrCreateScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riCellVolumeResultName(), false);
if (this->cellScalarResults(cellVolIdx).empty())
{
this->cellScalarResults(cellVolIdx).resize(1);
}
std::vector<double>& cellVolumeResults = this->cellScalarResults(cellVolIdx)[0];
size_t cellResultCount = m_activeCellInfo->reservoirCellResultCount();
cellVolumeResults.resize(cellResultCount, 0u);
cellVolumeResults.resize(cellResultCount, std::numeric_limits<double>::infinity());
#pragma omp parallel for
for (int nativeResvCellIndex = 0; nativeResvCellIndex < static_cast<int>(m_ownerMainGrid->globalCellArray().size()); nativeResvCellIndex++)
@ -2447,9 +2453,15 @@ void RigCaseCellResultsData::computeCellVolumes()
if (resultIndex != cvf::UNDEFINED_SIZE_T)
{
const RigCell& cell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex];
cellVolumeResults[resultIndex] = cell.volume();
if (!cell.subGrid())
{
cellVolumeResults[resultIndex] = cell.volume();
}
}
}
// Clear oil volume so it will have to be recalculated.
clearScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::riOilVolumeResultName());
}
//--------------------------------------------------------------------------------------------------
@ -2461,7 +2473,7 @@ void RigCaseCellResultsData::computeOilVolumes()
const std::vector<double>& cellVolumeResults = this->cellScalarResults(cellVolIdx)[0];
size_t soilIdx = this->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, "SOIL");
size_t oilVolIdx = this->findOrCreateScalarResultIndex(RiaDefines::GENERATED, RiaDefines::riOilVolumeResultName(), false);
size_t oilVolIdx = this->findOrCreateScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::riOilVolumeResultName(), false);
this->cellScalarResults(oilVolIdx).resize(this->maxTimeStepCount());
size_t cellResultCount = m_activeCellInfo->reservoirCellResultCount();

View File

@ -102,6 +102,7 @@ public:
void createPlaceholderResultEntries();
void computeDepthRelatedResults();
void computeCellVolumes();
void clearScalarResult(RiaDefines::ResultCatType type, const QString & resultName);
void clearScalarResult(const RigEclipseResultInfo& resultInfo);
@ -154,7 +155,6 @@ private: // from RimReservoirCellResultsStorage
void computeCompletionTypeForTimeStep(size_t timeStep);
double darchysValue();
void computeCellVolumes();
void computeOilVolumes();
void computeMobilePV();