diff --git a/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp b/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp index 81945cc7d5..0dfe93034b 100644 --- a/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp @@ -97,7 +97,7 @@ void RivContourMapProjectionPartMgr::appendPickPointVisToModel(cvf::ModelBasicLi //-------------------------------------------------------------------------------------------------- cvf::ref RivContourMapProjectionPartMgr::createTextureCoords() const { - cvf::Vec2ui patchSize = m_contourMapProjection->vertexGridSize(); + cvf::Vec2ui patchSize = m_contourMapProjection->numberOfVerticesIJ(); cvf::ref textureCoords = new cvf::Vec2fArray(m_contourMapProjection->numberOfVertices()); @@ -155,7 +155,7 @@ cvf::ref RivContourMapProjectionPartMgr::createProjectionMapDr { cvf::ref vertexArray = new cvf::Vec3fArray; m_contourMapProjection->generateVertices(vertexArray.p(), displayCoordTransform); - cvf::Vec2ui patchSize = m_contourMapProjection->vertexGridSize(); + cvf::Vec2ui patchSize = m_contourMapProjection->numberOfVerticesIJ(); // Surface cvf::ref faceList = new cvf::UIntArray; diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index 305ab13117..9d68b66ac2 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -502,8 +502,8 @@ QString Rim3dOverlayInfoConfig::caseInfoText(RimEclipseView* eclipseView) QString totCellCount = QString::number(contourMap->contourMapProjection()->numberOfCells()); cvf::uint validCellCount = contourMap->contourMapProjection()->numberOfValidCells(); QString activeCellCountText = QString::number(validCellCount); - QString iSize = QString::number(contourMap->contourMapProjection()->mapSize().x()); - QString jSize = QString::number(contourMap->contourMapProjection()->mapSize().y()); + QString iSize = QString::number(contourMap->contourMapProjection()->numberOfElementsIJ().x()); + QString jSize = QString::number(contourMap->contourMapProjection()->numberOfElementsIJ().y()); QString aggregationType = contourMap->contourMapProjection()->resultAggregationText(); QString weightingParameterString; if (contourMap->contourMapProjection()->weightingParameter() != "None") diff --git a/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp index 40bcac3de1..b495f5784b 100644 --- a/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp +++ b/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp @@ -98,58 +98,6 @@ RimContourMapProjection::~RimContourMapProjection() } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::generateGridMapping() -{ - calculateTotalCellVisibility(); - - RimEclipseResultCase* eclipseCase = nullptr; - firstAncestorOrThisOfTypeAsserted(eclipseCase); - - int nCells = numberOfCells(); - m_projected3dGridIndices.resize(nCells); - - const std::vector* weightingResultValues = nullptr; - if (m_weightByParameter()) - { - size_t gridScalarResultIdx = m_weightingResult->scalarResultIndex(); - if (gridScalarResultIdx != cvf::UNDEFINED_SIZE_T) - { - m_weightingResult->loadResult(); - int timeStep = 0; - if (m_weightingResult->hasDynamicResult()) - { - timeStep = view()->currentTimeStep(); - - } - weightingResultValues = &(m_weightingResult->currentGridCellResults()->cellScalarResults(gridScalarResultIdx)[timeStep]); - } - } - - if (isStraightSummationResult()) - { - for (int index = 0; index < nCells; ++index) - { - cvf::Vec2ui ij = ijFromCellIndex(index); - - cvf::Vec2d globalPos = globalCellCenterPosition(ij.x(), ij.y()); - m_projected3dGridIndices[index] = visibleCellsAndLengthInCellFrom2dPoint(globalPos, weightingResultValues); - } - } - else - { -#pragma omp parallel for - for (int index = 0; index < nCells; ++index) - { - cvf::Vec2ui ij = ijFromCellIndex(index); - - cvf::Vec2d globalPos = globalCellCenterPosition(ij.x(), ij.y()); - m_projected3dGridIndices[index] = visibleCellsAndOverlapVolumeFrom2dPoint(globalPos, weightingResultValues); - } - } -} //-------------------------------------------------------------------------------------------------- /// @@ -229,7 +177,7 @@ RimContourMapProjection::ContourPolygons RimContourMapProjection::generateContou /// //-------------------------------------------------------------------------------------------------- cvf::ref - RimContourMapProjection::generatePickPointPolygon(const caf::DisplayCoordTransform* displayCoordTransform) +RimContourMapProjection::generatePickPointPolygon(const caf::DisplayCoordTransform* displayCoordTransform) { cvf::ref pickPolygon; if (!m_pickPoint.isUndefined()) @@ -290,8 +238,7 @@ void RimContourMapProjection::generateResults() int timeStep = view()->currentTimeStep(); RimEclipseCellColors* cellColors = view()->cellResult(); - RimEclipseResultCase* eclipseCase = nullptr; - firstAncestorOrThisOfTypeAsserted(eclipseCase); + RimEclipseResultCase* eclipseCase = this->eclipseCase(); { if (!cellColors->isTernarySaturationSelected()) { @@ -338,6 +285,73 @@ void RimContourMapProjection::generateResults() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapProjection::ResultAggregation RimContourMapProjection::resultAggregation() const +{ + return m_resultAggregation(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::sampleSpacing() const +{ + return m_sampleSpacing; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::sampleSpacingFactor() const +{ + return m_relativeSampleSpacing(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::showContourLines() const +{ + return m_showContourLines(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimContourMapProjection::resultAggregationText() const +{ + return m_resultAggregation().uiText(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimContourMapProjection::resultDescriptionText() const +{ + QString resultText = resultAggregationText(); + if (!isColumnResult()) + { + resultText += QString(", %1").arg(view()->cellResult()->resultVariable()); + } + + return resultText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimContourMapProjection::weightingParameter() const +{ + QString parameter = "None"; + if (m_weightByParameter() && !m_weightingResult->isTernarySaturationSelected()) + { + parameter = m_weightingResult->resultVariableUiShortName(); + } + return parameter; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -406,23 +420,7 @@ double RimContourMapProjection::sumAllValues() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimContourMapProjection::sampleSpacing() const -{ - return m_sampleSpacing; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimContourMapProjection::sampleSpacingFactor() const -{ - return m_relativeSampleSpacing(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Vec2ui RimContourMapProjection::mapSize() const +cvf::Vec2ui RimContourMapProjection::numberOfElementsIJ() const { return m_mapSize; } @@ -430,80 +428,14 @@ cvf::Vec2ui RimContourMapProjection::mapSize() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Vec2ui RimContourMapProjection::vertexGridSize() const +cvf::Vec2ui RimContourMapProjection::numberOfVerticesIJ() const { - cvf::Vec2ui mapSize = this->mapSize(); + cvf::Vec2ui mapSize = this->numberOfElementsIJ(); mapSize.x() += 1u; mapSize.y() += 1u; return mapSize; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::showContourLines() const -{ - return m_showContourLines(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const std::vector& RimContourMapProjection::aggregatedResults() const -{ - return m_aggregatedResults; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimContourMapProjection::weightingParameter() const -{ - QString parameter = "None"; - if (m_weightByParameter() && !m_weightingResult->isTernarySaturationSelected()) - { - parameter = m_weightingResult->resultVariableUiShortName(); - } - return parameter; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::isMeanResult() const -{ - return m_resultAggregation() == RESULTS_MEAN_VALUE || - m_resultAggregation() == RESULTS_HARM_VALUE || - m_resultAggregation() == RESULTS_GEOM_VALUE; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::isSummationResult() const -{ - return isStraightSummationResult() || m_resultAggregation() == RESULTS_VOLUME_SUM; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::isStraightSummationResult() const -{ - return isStraightSummationResult(m_resultAggregation()); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::isStraightSummationResult(ResultAggregationEnum aggregationType) -{ - return aggregationType == RESULTS_OIL_COLUMN || - aggregationType == RESULTS_GAS_COLUMN || - aggregationType == RESULTS_HC_COLUMN || - aggregationType == RESULTS_SUM; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -519,7 +451,7 @@ bool RimContourMapProjection::isColumnResult() const //-------------------------------------------------------------------------------------------------- double RimContourMapProjection::valueAtVertex(uint i, uint j) const { - size_t index = vertexIndex(i, j); + size_t index = vertexIndexFromIJ(i, j); if (index < numberOfVertices()) { return m_aggregatedVertexResults.at(index); @@ -533,220 +465,10 @@ double RimContourMapProjection::valueAtVertex(uint i, uint j) const //-------------------------------------------------------------------------------------------------- bool RimContourMapProjection::hasResultAtVertex(uint i, uint j) const { - size_t index = vertexIndex(i, j); + size_t index = vertexIndexFromIJ(i, j); return m_aggregatedVertexResults[index] != std::numeric_limits::infinity(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimContourMapProjection::calculateValueAtVertex(uint vi, uint vj) const -{ - std::vector averageIs; - std::vector averageJs; - - if (vi > 0u) averageIs.push_back(vi - 1); - if (vj > 0u) averageJs.push_back(vj - 1); - if (vi < m_mapSize.x()) averageIs.push_back(vi); - if (vj < m_mapSize.y()) averageJs.push_back(vj); - - RiaWeightedMeanCalculator calc; - for (uint j : averageJs) - { - for (uint i : averageIs) - { - if (hasResultInCell(i, j)) - { - calc.addValueAndWeight(valueInCell(i, j), 1.0); - } - } - } - if (calc.validAggregatedWeight()) - { - return calc.weightedMean(); - } - return std::numeric_limits::infinity(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimContourMapProjection::calculateValueInCell(uint i, uint j) const -{ - if (!isColumnResult() && view()->cellResult()->scalarResultIndex() == cvf::UNDEFINED_SIZE_T) - { - return 0.0; // Special case of NONE-result. Show 0 all over to ensure we see something. - } - const std::vector>& matchingCells = cellsAtIJ(i, j); - if (!matchingCells.empty()) - { - switch (m_resultAggregation()) - { - case RESULTS_TOP_VALUE: - { - size_t cellIdx = matchingCells.front().first; - double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); - return cellValue; - } - case RESULTS_MEAN_VALUE: - { - RiaWeightedMeanCalculator calculator; - for (auto cellIdxAndWeight : matchingCells) - { - size_t cellIdx = cellIdxAndWeight.first; - double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); - calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); - } - if (calculator.validAggregatedWeight()) - { - return calculator.weightedMean(); - } - return std::numeric_limits::infinity(); - } - case RESULTS_GEOM_VALUE: - { - RiaWeightedGeometricMeanCalculator calculator; - for (auto cellIdxAndWeight : matchingCells) - { - size_t cellIdx = cellIdxAndWeight.first; - double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); - if (cellValue < 1.0e-8) - { - return 0.0; - } - calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); - } - if (calculator.validAggregatedWeight()) - { - return calculator.weightedMean(); - } - return std::numeric_limits::infinity(); - } - case RESULTS_HARM_VALUE: - { - RiaWeightedHarmonicMeanCalculator calculator; - for (auto cellIdxAndWeight : matchingCells) - { - size_t cellIdx = cellIdxAndWeight.first; - double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); - if (std::fabs(cellValue) < 1.0e-8) - { - return 0.0; - } - calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); - } - if (calculator.validAggregatedWeight()) - { - return calculator.weightedMean(); - } - return std::numeric_limits::infinity(); - } - case RESULTS_MAX_VALUE: - { - double maxValue = -std::numeric_limits::infinity(); - for (auto cellIdxAndWeight : matchingCells) - { - size_t cellIdx = cellIdxAndWeight.first; - double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); - maxValue = std::max(maxValue, cellValue); - } - return maxValue; - } - case RESULTS_MIN_VALUE: - { - double minValue = std::numeric_limits::infinity(); - for (auto cellIdxAndWeight : matchingCells) - { - size_t cellIdx = cellIdxAndWeight.first; - double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); - minValue = std::min(minValue, cellValue); - } - return minValue; - } - case RESULTS_VOLUME_SUM: - case RESULTS_SUM: - { - double sum = 0.0; - for (auto cellIdxAndWeight : matchingCells) - { - size_t cellIdx = cellIdxAndWeight.first; - double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); - sum += cellValue * cellIdxAndWeight.second; - } - return sum; - } - case RESULTS_OIL_COLUMN: - case RESULTS_GAS_COLUMN: - case RESULTS_HC_COLUMN: - { - double sum = 0.0; - for (auto cellIdxAndWeight : matchingCells) - { - size_t cellIdx = cellIdxAndWeight.first; - double cellValue = findColumnResult(m_resultAggregation(), cellIdx); - sum += cellValue * cellIdxAndWeight.second; - } - return sum; - } - default: - CVF_TIGHT_ASSERT(false); - } - } - return std::numeric_limits::infinity(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimContourMapProjection::valueInCell(uint i, uint j) const -{ - size_t index = cellIndex(i, j); - if (index < numberOfCells()) - { - return m_aggregatedResults.at(index); - } - return std::numeric_limits::infinity(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::hasResultInCell(uint i, uint j) const -{ - RimEclipseCellColors* cellColors = view()->cellResult(); - - if (cellColors->isTernarySaturationSelected()) - { - return false; - } - return !cellsAtIJ(i, j).empty(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -uint RimContourMapProjection::numberOfCells() const -{ - return m_mapSize.x() * m_mapSize.y(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -uint RimContourMapProjection::numberOfValidCells() const -{ - uint validCount = 0u; - for (uint i = 0; i < numberOfCells(); ++i) - { - cvf::Vec2ui ij = ijFromCellIndex(i); - if (hasResultInCell(ij.x(), ij.y())) - { - validCount++; - } - } - return validCount; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -755,317 +477,6 @@ RimRegularLegendConfig* RimContourMapProjection::legendConfig() const return view()->cellResult()->legendConfig(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::calculateTotalCellVisibility() -{ - m_cellGridIdxVisibility = view()->currentTotalCellVisibility(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Vec2d RimContourMapProjection::globalCellCenterPosition(uint i, uint j) const -{ - cvf::Vec3d gridExtent = m_fullBoundingBox.extent(); - cvf::Vec2d origin(m_fullBoundingBox.min().x(), m_fullBoundingBox.min().y()); - - cvf::Vec2d cellCorner = origin + cvf::Vec2d((i * gridExtent.x()) / (m_mapSize.x()), - (j * gridExtent.y()) / (m_mapSize.y())); - - return cellCorner + cvf::Vec2d(m_sampleSpacing*0.5, m_sampleSpacing * 0.5); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Vec2ui RimContourMapProjection::ijFromLocalPos(const cvf::Vec2d& localPos2d) const -{ - uint i = localPos2d.x() / m_sampleSpacing; - uint j = localPos2d.y() / m_sampleSpacing; - return cvf::Vec2ui(i, j); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector> RimContourMapProjection::cellsAtIJ(uint i, uint j) const -{ - size_t cellIndex = this->cellIndex(i, j); - if (cellIndex < m_projected3dGridIndices.size()) - { - return m_projected3dGridIndices[cellIndex]; - } - return std::vector>(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector> RimContourMapProjection::visibleCellsAndOverlapVolumeFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues) const -{ - cvf::Vec3d top2dElementCentroid(globalPos2d, m_fullBoundingBox.max().z()); - cvf::Vec3d bottom2dElementCentroid(globalPos2d, m_fullBoundingBox.min().z()); - cvf::Vec3d planarDiagonalVector(0.5 * m_sampleSpacing, 0.5 * m_sampleSpacing, 0.0); - cvf::Vec3d topNECorner = top2dElementCentroid + planarDiagonalVector; - cvf::Vec3d bottomSWCorner = bottom2dElementCentroid - planarDiagonalVector; - - cvf::BoundingBox bbox2dElement(bottomSWCorner, topNECorner); - - std::vector allCellIndices; - mainGrid()->findIntersectingCells(bbox2dElement, &allCellIndices); - - typedef std::map>> KLayerCellWeightMap; - KLayerCellWeightMap matchingVisibleCellsWeightPerKLayer; - - std::array hexCorners; - for (size_t globalCellIdx : allCellIndices) - { - if ((*m_cellGridIdxVisibility)[globalCellIdx]) - { - RigCell cell = mainGrid()->globalCellArray()[globalCellIdx]; - - size_t mainGridCellIdx = cell.mainGridCellIndex(); - size_t i, j, k; - mainGrid()->ijkFromCellIndex(mainGridCellIdx, &i, &j, &k); - - size_t localCellIdx = cell.gridLocalCellIndex(); - RigGridBase* localGrid = cell.hostGrid(); - - localGrid->cellCornerVertices(localCellIdx, hexCorners.data()); - - cvf::BoundingBox overlapBBox; - std::array overlapCorners = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(hexCorners, bbox2dElement, &overlapBBox); - - double overlapVolume = RigCellGeometryTools::calculateCellVolume(overlapCorners); - - if (overlapVolume > 0.0) - { - double weight = overlapVolume; - if (weightingResultValues) - { - const RigActiveCellInfo* activeCellInfo = eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); - size_t cellResultIdx = activeCellInfo->cellResultIndex(globalCellIdx); - double result = std::max((*weightingResultValues)[cellResultIdx], 0.0); - if (result < 1.0e-6) - { - result = 0.0; - } - weight *= result; - } - if (weight > 0.0) - { - matchingVisibleCellsWeightPerKLayer[k].push_back(std::make_pair(globalCellIdx, weight)); - } - } - } - } - - std::vector> matchingVisibleCellsAndWeight; - for (auto kLayerCellWeight : matchingVisibleCellsWeightPerKLayer) - { - for (auto cellWeight : kLayerCellWeight.second) - { - matchingVisibleCellsAndWeight.push_back(std::make_pair(cellWeight.first, cellWeight.second)); - } - } - - return matchingVisibleCellsAndWeight; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector> RimContourMapProjection::visibleCellsAndLengthInCellFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues /*= nullptr*/) const -{ - cvf::Vec3d highestPoint(globalPos2d, m_fullBoundingBox.max().z()); - cvf::Vec3d lowestPoint(globalPos2d, m_fullBoundingBox.min().z()); - - cvf::BoundingBox rayBBox; - rayBBox.add(highestPoint); - rayBBox.add(lowestPoint); - - std::vector allCellIndices; - mainGrid()->findIntersectingCells(rayBBox, &allCellIndices); - - std::map>> matchingVisibleCellsAndWeightPerKLayer; - - cvf::Vec3d hexCorners[8]; - for (size_t globalCellIdx : allCellIndices) - { - if ((*m_cellGridIdxVisibility)[globalCellIdx]) - { - RigCell cell = mainGrid()->globalCellArray()[globalCellIdx]; - - size_t mainGridCellIdx = cell.mainGridCellIndex(); - size_t i, j, k; - mainGrid()->ijkFromCellIndex(mainGridCellIdx, &i, &j, &k); - - size_t localCellIdx = cell.gridLocalCellIndex(); - RigGridBase* localGrid = cell.hostGrid(); - - localGrid->cellCornerVertices(localCellIdx, hexCorners); - std::vector intersections; - - if (RigHexIntersectionTools::lineHexCellIntersection(highestPoint, lowestPoint, hexCorners, 0, &intersections)) - { - double lengthInCell = (intersections.back().m_intersectionPoint - intersections.front().m_intersectionPoint).length(); - matchingVisibleCellsAndWeightPerKLayer[k].push_back(std::make_pair(globalCellIdx, lengthInCell)); - } - } - } - - std::vector> matchingVisibleCellsAndWeight; - for (auto kLayerCellWeight : matchingVisibleCellsAndWeightPerKLayer) - { - // Make sure the sum of all weights in the same K-layer is 1. - double weightSumThisKLayer = 0.0; - for (auto cellWeight : kLayerCellWeight.second) - { - weightSumThisKLayer += cellWeight.second; - } - - for (auto cellWeight : kLayerCellWeight.second) - { - matchingVisibleCellsAndWeight.push_back(std::make_pair(cellWeight.first, cellWeight.second / weightSumThisKLayer)); - } - } - - return matchingVisibleCellsAndWeight; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimContourMapProjection::findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const -{ - const RigCaseCellResultsData* resultData = eclipseCase()->results(RiaDefines::MATRIX_MODEL); - size_t poroResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PORO"); - size_t ntgResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "NTG"); - size_t dzResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "DZ"); - - if (poroResultIndex == cvf::UNDEFINED_SIZE_T || ntgResultIndex == cvf::UNDEFINED_SIZE_T) - { - return std::numeric_limits::infinity(); - } - - const std::vector& poroResults = resultData->cellScalarResults(poroResultIndex)[0]; - const std::vector& ntgResults = resultData->cellScalarResults(ntgResultIndex)[0]; - const std::vector& dzResults = resultData->cellScalarResults(dzResultIndex)[0]; - - const RigActiveCellInfo* activeCellInfo = eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); - size_t cellResultIdx = activeCellInfo->cellResultIndex(cellGlobalIdx); - - if (cellResultIdx >= poroResults.size() || cellResultIdx >= ntgResults.size()) - { - return std::numeric_limits::infinity(); - } - - double poro = poroResults.at(cellResultIdx); - double ntg = ntgResults.at(cellResultIdx); - double dz = dzResults.at(cellResultIdx); - - int timeStep = view()->currentTimeStep(); - - double resultValue = 0.0; - if (resultAggregation == RESULTS_OIL_COLUMN || resultAggregation == RESULTS_HC_COLUMN) - { - size_t soilResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL"); - const std::vector& soilResults = resultData->cellScalarResults(soilResultIndex)[timeStep]; - if (cellResultIdx < soilResults.size()) - { - resultValue = soilResults.at(cellResultIdx); - } - } - if (resultAggregation == RESULTS_GAS_COLUMN || resultAggregation == RESULTS_HC_COLUMN) - { - size_t sgasResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SGAS"); - const std::vector& sgasResults = resultData->cellScalarResults(sgasResultIndex)[timeStep]; - if (cellResultIdx < sgasResults.size()) - { - resultValue += sgasResults.at(cellResultIdx); - } - } - - return resultValue * poro * ntg * dz; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const RimEclipseResultCase* RimContourMapProjection::eclipseCase() const -{ - const RimEclipseResultCase* eclipseCase = nullptr; - firstAncestorOrThisOfType(eclipseCase); - return eclipseCase; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseResultCase* RimContourMapProjection::eclipseCase() -{ - RimEclipseResultCase* eclipseCase = nullptr; - firstAncestorOrThisOfType(eclipseCase); - return eclipseCase; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimContourMapView* RimContourMapProjection::view() const -{ - RimContourMapView* view = nullptr; - firstAncestorOrThisOfTypeAsserted(view); - return view; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RimContourMapProjection::cellIndex(uint i, uint j) const -{ - CVF_ASSERT(i < m_mapSize.x()); - CVF_ASSERT(j < m_mapSize.y()); - - return i + j * m_mapSize.x(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RimContourMapProjection::vertexIndex(uint i, uint j) const -{ - return i + j * (m_mapSize.x() + 1); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Vec2ui RimContourMapProjection::ijFromVertexIndex(size_t gridIndex) const -{ - cvf::Vec2ui gridSize = vertexGridSize(); - - uint quotientX = static_cast(gridIndex) / gridSize.x(); - uint remainderX = static_cast(gridIndex) % gridSize.x(); - - return cvf::Vec2ui(remainderX, quotientX); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Vec2ui RimContourMapProjection::ijFromCellIndex(size_t cellIndex) const -{ - CVF_TIGHT_ASSERT(cellIndex < numberOfCells()); - - uint quotientX = static_cast(cellIndex) / m_mapSize.x(); - uint remainderX = static_cast(cellIndex) % m_mapSize.x(); - - return cvf::Vec2ui(remainderX, quotientX); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1104,44 +515,40 @@ void RimContourMapProjection::updateLegend() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint RimContourMapProjection::numberOfCells() const +{ + return m_mapSize.x() * m_mapSize.y(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint RimContourMapProjection::numberOfValidCells() const +{ + uint validCount = 0u; + for (uint i = 0; i < numberOfCells(); ++i) + { + cvf::Vec2ui ij = ijFromCellIndex(i); + if (hasResultInCell(ij.x(), ij.y())) + { + validCount++; + } + } + return validCount; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RimContourMapProjection::numberOfVertices() const { - cvf::Vec2ui gridSize = vertexGridSize(); + cvf::Vec2ui gridSize = numberOfVerticesIJ(); return static_cast(gridSize.x()) * static_cast(gridSize.y()); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimContourMapProjection::ResultAggregation RimContourMapProjection::resultAggregation() const -{ - return m_resultAggregation(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimContourMapProjection::resultAggregationText() const -{ - return m_resultAggregation().uiText(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimContourMapProjection::resultDescriptionText() const -{ - QString resultText = resultAggregationText(); - if (!isColumnResult()) - { - resultText += QString(", %1").arg(view()->cellResult()->resultVariable()); - } - - return resultText; -} //-------------------------------------------------------------------------------------------------- /// @@ -1211,55 +618,9 @@ void RimContourMapProjection::setPickPoint(cvf::Vec2d pickedPoint) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimContourMapProjection::xVertexPositions() const -{ - double gridExtent = m_fullBoundingBox.extent().x(); - double origin = m_fullBoundingBox.min().x(); - - cvf::Vec2ui gridSize = vertexGridSize(); - std::vector positions; - positions.reserve(gridSize.x()); - for (uint i = 0; i < gridSize.x(); ++i) - { - positions.push_back(origin + (i * gridExtent) / (gridSize.x() - 1)); - } - - return positions; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimContourMapProjection::yVertexPositions() const -{ - double gridExtent = m_fullBoundingBox.extent().y(); - double origin = m_fullBoundingBox.min().y(); - - cvf::Vec2ui gridSize = vertexGridSize(); - std::vector positions; - positions.reserve(gridSize.y()); - for (uint j = 0; j < gridSize.y(); ++j) - { - positions.push_back(origin + (j * gridExtent) / (gridSize.y() - 1)); - } - - return positions; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigMainGrid* RimContourMapProjection::mainGrid() const -{ - RimEclipseResultCase* eclipseCase = nullptr; - firstAncestorOrThisOfTypeAsserted(eclipseCase); - return eclipseCase->eclipseCaseData()->mainGrid(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { legendConfig()->disableAllTimeStepsRange(!getLegendRangeFrom3dGrid()); @@ -1275,8 +636,10 @@ void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* change //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) -{ +void RimContourMapProjection::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) +{ if (&m_relativeSampleSpacing == field) { caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); @@ -1284,7 +647,7 @@ void RimContourMapProjection::defineEditorAttribute(const caf::PdmFieldHandle* f { myAttr->m_minimum = 0.25; myAttr->m_maximum = 2.0; - } + } } } @@ -1336,6 +699,593 @@ void RimContourMapProjection::initAfterRead() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::generateGridMapping() +{ + m_cellGridIdxVisibility = view()->currentTotalCellVisibility(); + + int nCells = numberOfCells(); + m_projected3dGridIndices.resize(nCells); + + const std::vector* weightingResultValues = nullptr; + if (m_weightByParameter()) + { + size_t gridScalarResultIdx = m_weightingResult->scalarResultIndex(); + if (gridScalarResultIdx != cvf::UNDEFINED_SIZE_T) + { + m_weightingResult->loadResult(); + int timeStep = 0; + if (m_weightingResult->hasDynamicResult()) + { + timeStep = view()->currentTimeStep(); + } + weightingResultValues = + &(m_weightingResult->currentGridCellResults()->cellScalarResults(gridScalarResultIdx)[timeStep]); + } + } + + if (isStraightSummationResult()) + { + for (int index = 0; index < nCells; ++index) + { + cvf::Vec2ui ij = ijFromCellIndex(index); + + cvf::Vec2d globalPos = globalCellCenterPosition(ij.x(), ij.y()); + m_projected3dGridIndices[index] = visibleCellsAndLengthInCellFrom2dPoint(globalPos, weightingResultValues); + } + } + else + { +#pragma omp parallel for + for (int index = 0; index < nCells; ++index) + { + cvf::Vec2ui ij = ijFromCellIndex(index); + + cvf::Vec2d globalPos = globalCellCenterPosition(ij.x(), ij.y()); + m_projected3dGridIndices[index] = visibleCellsAndOverlapVolumeFrom2dPoint(globalPos, weightingResultValues); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::valueInCell(uint i, uint j) const +{ + size_t index = cellIndexFromIJ(i, j); + if (index < numberOfCells()) + { + return m_aggregatedResults.at(index); + } + return std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::hasResultInCell(uint i, uint j) const +{ + RimEclipseCellColors* cellColors = view()->cellResult(); + + if (cellColors->isTernarySaturationSelected()) + { + return false; + } + return !cellsAtIJ(i, j).empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::calculateValueInCell(uint i, uint j) const +{ + if (!isColumnResult() && view()->cellResult()->scalarResultIndex() == cvf::UNDEFINED_SIZE_T) + { + return 0.0; // Special case of NONE-result. Show 0 all over to ensure we see something. + } + const std::vector>& matchingCells = cellsAtIJ(i, j); + if (!matchingCells.empty()) + { + switch (m_resultAggregation()) + { + case RESULTS_TOP_VALUE: + { + size_t cellIdx = matchingCells.front().first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + return cellValue; + } + case RESULTS_MEAN_VALUE: + { + RiaWeightedMeanCalculator calculator; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); + } + if (calculator.validAggregatedWeight()) + { + return calculator.weightedMean(); + } + return std::numeric_limits::infinity(); + } + case RESULTS_GEOM_VALUE: + { + RiaWeightedGeometricMeanCalculator calculator; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + if (cellValue < 1.0e-8) + { + return 0.0; + } + calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); + } + if (calculator.validAggregatedWeight()) + { + return calculator.weightedMean(); + } + return std::numeric_limits::infinity(); + } + case RESULTS_HARM_VALUE: + { + RiaWeightedHarmonicMeanCalculator calculator; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + if (std::fabs(cellValue) < 1.0e-8) + { + return 0.0; + } + calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); + } + if (calculator.validAggregatedWeight()) + { + return calculator.weightedMean(); + } + return std::numeric_limits::infinity(); + } + case RESULTS_MAX_VALUE: + { + double maxValue = -std::numeric_limits::infinity(); + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + maxValue = std::max(maxValue, cellValue); + } + return maxValue; + } + case RESULTS_MIN_VALUE: + { + double minValue = std::numeric_limits::infinity(); + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + minValue = std::min(minValue, cellValue); + } + return minValue; + } + case RESULTS_VOLUME_SUM: + case RESULTS_SUM: + { + double sum = 0.0; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + sum += cellValue * cellIdxAndWeight.second; + } + return sum; + } + case RESULTS_OIL_COLUMN: + case RESULTS_GAS_COLUMN: + case RESULTS_HC_COLUMN: + { + double sum = 0.0; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = findColumnResult(m_resultAggregation(), cellIdx); + sum += cellValue * cellIdxAndWeight.second; + } + return sum; + } + default: + CVF_TIGHT_ASSERT(false); + } + } + return std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::calculateValueAtVertex(uint vi, uint vj) const +{ + std::vector averageIs; + std::vector averageJs; + + if (vi > 0u) averageIs.push_back(vi - 1); + if (vj > 0u) averageJs.push_back(vj - 1); + if (vi < m_mapSize.x()) averageIs.push_back(vi); + if (vj < m_mapSize.y()) averageJs.push_back(vj); + + RiaWeightedMeanCalculator calc; + for (uint j : averageJs) + { + for (uint i : averageIs) + { + if (hasResultInCell(i, j)) + { + calc.addValueAndWeight(valueInCell(i, j), 1.0); + } + } + } + if (calc.validAggregatedWeight()) + { + return calc.weightedMean(); + } + return std::numeric_limits::infinity(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RimContourMapProjection::cellsAtIJ(uint i, uint j) const +{ + size_t cellIndex = this->cellIndexFromIJ(i, j); + if (cellIndex < m_projected3dGridIndices.size()) + { + return m_projected3dGridIndices[cellIndex]; + } + return std::vector>(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> + RimContourMapProjection::visibleCellsAndOverlapVolumeFrom2dPoint(const cvf::Vec2d& globalPos2d, + const std::vector* weightingResultValues) const +{ + cvf::Vec3d top2dElementCentroid(globalPos2d, m_fullBoundingBox.max().z()); + cvf::Vec3d bottom2dElementCentroid(globalPos2d, m_fullBoundingBox.min().z()); + cvf::Vec3d planarDiagonalVector(0.5 * m_sampleSpacing, 0.5 * m_sampleSpacing, 0.0); + cvf::Vec3d topNECorner = top2dElementCentroid + planarDiagonalVector; + cvf::Vec3d bottomSWCorner = bottom2dElementCentroid - planarDiagonalVector; + + cvf::BoundingBox bbox2dElement(bottomSWCorner, topNECorner); + + std::vector allCellIndices; + m_mainGrid->findIntersectingCells(bbox2dElement, &allCellIndices); + + typedef std::map>> KLayerCellWeightMap; + KLayerCellWeightMap matchingVisibleCellsWeightPerKLayer; + + std::array hexCorners; + for (size_t globalCellIdx : allCellIndices) + { + if ((*m_cellGridIdxVisibility)[globalCellIdx]) + { + RigCell cell = m_mainGrid->globalCellArray()[globalCellIdx]; + + size_t mainGridCellIdx = cell.mainGridCellIndex(); + size_t i, j, k; + m_mainGrid->ijkFromCellIndex(mainGridCellIdx, &i, &j, &k); + + size_t localCellIdx = cell.gridLocalCellIndex(); + RigGridBase* localGrid = cell.hostGrid(); + + localGrid->cellCornerVertices(localCellIdx, hexCorners.data()); + + cvf::BoundingBox overlapBBox; + std::array overlapCorners = + RigCellGeometryTools::estimateHexOverlapWithBoundingBox(hexCorners, bbox2dElement, &overlapBBox); + + double overlapVolume = RigCellGeometryTools::calculateCellVolume(overlapCorners); + + if (overlapVolume > 0.0) + { + double weight = overlapVolume; + if (weightingResultValues) + { + const RigActiveCellInfo* activeCellInfo = + eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + size_t cellResultIdx = activeCellInfo->cellResultIndex(globalCellIdx); + double result = std::max((*weightingResultValues)[cellResultIdx], 0.0); + if (result < 1.0e-6) + { + result = 0.0; + } + weight *= result; + } + if (weight > 0.0) + { + matchingVisibleCellsWeightPerKLayer[k].push_back(std::make_pair(globalCellIdx, weight)); + } + } + } + } + + std::vector> matchingVisibleCellsAndWeight; + for (auto kLayerCellWeight : matchingVisibleCellsWeightPerKLayer) + { + for (auto cellWeight : kLayerCellWeight.second) + { + matchingVisibleCellsAndWeight.push_back(std::make_pair(cellWeight.first, cellWeight.second)); + } + } + + return matchingVisibleCellsAndWeight; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RimContourMapProjection::visibleCellsAndLengthInCellFrom2dPoint( + const cvf::Vec2d& globalPos2d, + const std::vector* weightingResultValues /*= nullptr*/) const +{ + cvf::Vec3d highestPoint(globalPos2d, m_fullBoundingBox.max().z()); + cvf::Vec3d lowestPoint(globalPos2d, m_fullBoundingBox.min().z()); + + cvf::BoundingBox rayBBox; + rayBBox.add(highestPoint); + rayBBox.add(lowestPoint); + + std::vector allCellIndices; + m_mainGrid->findIntersectingCells(rayBBox, &allCellIndices); + + std::map>> matchingVisibleCellsAndWeightPerKLayer; + + cvf::Vec3d hexCorners[8]; + for (size_t globalCellIdx : allCellIndices) + { + if ((*m_cellGridIdxVisibility)[globalCellIdx]) + { + RigCell cell = m_mainGrid->globalCellArray()[globalCellIdx]; + + size_t mainGridCellIdx = cell.mainGridCellIndex(); + size_t i, j, k; + m_mainGrid->ijkFromCellIndex(mainGridCellIdx, &i, &j, &k); + + size_t localCellIdx = cell.gridLocalCellIndex(); + RigGridBase* localGrid = cell.hostGrid(); + + localGrid->cellCornerVertices(localCellIdx, hexCorners); + std::vector intersections; + + if (RigHexIntersectionTools::lineHexCellIntersection(highestPoint, lowestPoint, hexCorners, 0, &intersections)) + { + double lengthInCell = + (intersections.back().m_intersectionPoint - intersections.front().m_intersectionPoint).length(); + matchingVisibleCellsAndWeightPerKLayer[k].push_back(std::make_pair(globalCellIdx, lengthInCell)); + } + } + } + + std::vector> matchingVisibleCellsAndWeight; + for (auto kLayerCellWeight : matchingVisibleCellsAndWeightPerKLayer) + { + // Make sure the sum of all weights in the same K-layer is 1. + double weightSumThisKLayer = 0.0; + for (auto cellWeight : kLayerCellWeight.second) + { + weightSumThisKLayer += cellWeight.second; + } + + for (auto cellWeight : kLayerCellWeight.second) + { + matchingVisibleCellsAndWeight.push_back(std::make_pair(cellWeight.first, cellWeight.second / weightSumThisKLayer)); + } + } + + return matchingVisibleCellsAndWeight; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const +{ + const RigCaseCellResultsData* resultData = eclipseCase()->results(RiaDefines::MATRIX_MODEL); + size_t poroResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PORO"); + size_t ntgResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "NTG"); + size_t dzResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "DZ"); + + if (poroResultIndex == cvf::UNDEFINED_SIZE_T || ntgResultIndex == cvf::UNDEFINED_SIZE_T) + { + return std::numeric_limits::infinity(); + } + + const std::vector& poroResults = resultData->cellScalarResults(poroResultIndex)[0]; + const std::vector& ntgResults = resultData->cellScalarResults(ntgResultIndex)[0]; + const std::vector& dzResults = resultData->cellScalarResults(dzResultIndex)[0]; + + const RigActiveCellInfo* activeCellInfo = eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + size_t cellResultIdx = activeCellInfo->cellResultIndex(cellGlobalIdx); + + if (cellResultIdx >= poroResults.size() || cellResultIdx >= ntgResults.size()) + { + return std::numeric_limits::infinity(); + } + + double poro = poroResults.at(cellResultIdx); + double ntg = ntgResults.at(cellResultIdx); + double dz = dzResults.at(cellResultIdx); + + int timeStep = view()->currentTimeStep(); + + double resultValue = 0.0; + if (resultAggregation == RESULTS_OIL_COLUMN || resultAggregation == RESULTS_HC_COLUMN) + { + size_t soilResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL"); + const std::vector& soilResults = resultData->cellScalarResults(soilResultIndex)[timeStep]; + if (cellResultIdx < soilResults.size()) + { + resultValue = soilResults.at(cellResultIdx); + } + } + if (resultAggregation == RESULTS_GAS_COLUMN || resultAggregation == RESULTS_HC_COLUMN) + { + size_t sgasResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SGAS"); + const std::vector& sgasResults = resultData->cellScalarResults(sgasResultIndex)[timeStep]; + if (cellResultIdx < sgasResults.size()) + { + resultValue += sgasResults.at(cellResultIdx); + } + } + + return resultValue * poro * ntg * dz; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isMeanResult() const +{ + return m_resultAggregation() == RESULTS_MEAN_VALUE || m_resultAggregation() == RESULTS_HARM_VALUE || + m_resultAggregation() == RESULTS_GEOM_VALUE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isSummationResult() const +{ + return isStraightSummationResult() || m_resultAggregation() == RESULTS_VOLUME_SUM; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isStraightSummationResult() const +{ + return isStraightSummationResult(m_resultAggregation()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isStraightSummationResult(ResultAggregationEnum aggregationType) +{ + return aggregationType == RESULTS_OIL_COLUMN || aggregationType == RESULTS_GAS_COLUMN || + aggregationType == RESULTS_HC_COLUMN || aggregationType == RESULTS_SUM; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimContourMapProjection::cellIndexFromIJ(uint i, uint j) const +{ + CVF_ASSERT(i < m_mapSize.x()); + CVF_ASSERT(j < m_mapSize.y()); + + return i + j * m_mapSize.x(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimContourMapProjection::vertexIndexFromIJ(uint i, uint j) const +{ + return i + j * (m_mapSize.x() + 1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::ijFromVertexIndex(size_t gridIndex) const +{ + cvf::Vec2ui gridSize = numberOfVerticesIJ(); + + uint quotientX = static_cast(gridIndex) / gridSize.x(); + uint remainderX = static_cast(gridIndex) % gridSize.x(); + + return cvf::Vec2ui(remainderX, quotientX); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::ijFromCellIndex(size_t cellIndex) const +{ + CVF_TIGHT_ASSERT(cellIndex < numberOfCells()); + + uint quotientX = static_cast(cellIndex) / m_mapSize.x(); + uint remainderX = static_cast(cellIndex) % m_mapSize.x(); + + return cvf::Vec2ui(remainderX, quotientX); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::ijFromLocalPos(const cvf::Vec2d& localPos2d) const +{ + uint i = localPos2d.x() / m_sampleSpacing; + uint j = localPos2d.y() / m_sampleSpacing; + return cvf::Vec2ui(i, j); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2d RimContourMapProjection::globalCellCenterPosition(uint i, uint j) const +{ + cvf::Vec3d gridExtent = m_fullBoundingBox.extent(); + cvf::Vec2d origin(m_fullBoundingBox.min().x(), m_fullBoundingBox.min().y()); + + cvf::Vec2d cellCorner = origin + cvf::Vec2d((i * gridExtent.x()) / (m_mapSize.x()), (j * gridExtent.y()) / (m_mapSize.y())); + + return cellCorner + cvf::Vec2d(m_sampleSpacing * 0.5, m_sampleSpacing * 0.5); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimContourMapProjection::xVertexPositions() const +{ + double gridExtent = m_fullBoundingBox.extent().x(); + double origin = m_fullBoundingBox.min().x(); + + cvf::Vec2ui gridSize = numberOfVerticesIJ(); + std::vector positions; + positions.reserve(gridSize.x()); + for (uint i = 0; i < gridSize.x(); ++i) + { + positions.push_back(origin + (i * gridExtent) / (gridSize.x() - 1)); + } + + return positions; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimContourMapProjection::yVertexPositions() const +{ + double gridExtent = m_fullBoundingBox.extent().y(); + double origin = m_fullBoundingBox.min().y(); + + cvf::Vec2ui gridSize = numberOfVerticesIJ(); + std::vector positions; + positions.reserve(gridSize.y()); + for (uint j = 0; j < gridSize.y(); ++j) + { + positions.push_back(origin + (j * gridExtent) / (gridSize.y() - 1)); + } + + return positions; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1357,11 +1307,10 @@ bool RimContourMapProjection::getLegendRangeFrom3dGrid() const //-------------------------------------------------------------------------------------------------- void RimContourMapProjection::updateGridInformation() { - m_sampleSpacing = m_relativeSampleSpacing * mainGrid()->characteristicIJCellSize(); - + m_mainGrid = eclipseCase()->eclipseCaseData()->mainGrid(); + m_sampleSpacing = m_relativeSampleSpacing * m_mainGrid->characteristicIJCellSize(); m_fullBoundingBox = eclipseCase()->activeCellsBoundingBox(); - - m_mapSize = calculateMapSize(); + m_mapSize = calculateMapSize(); // Re-jig max point to be an exact multiple of cell size cvf::Vec3d minPoint = m_fullBoundingBox.min(); @@ -1384,3 +1333,22 @@ cvf::Vec2ui RimContourMapProjection::calculateMapSize() const return cvf::Vec2ui(projectionSizeX, projectionSizeY); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultCase* RimContourMapProjection::eclipseCase() const +{ + RimEclipseResultCase* eclipseCase = nullptr; + firstAncestorOrThisOfType(eclipseCase); + return eclipseCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapView* RimContourMapProjection::view() const +{ + RimContourMapView* view = nullptr; + firstAncestorOrThisOfTypeAsserted(view); + return view; +} diff --git a/ApplicationCode/ProjectDataModel/RimContourMapProjection.h b/ApplicationCode/ProjectDataModel/RimContourMapProjection.h index dbb4c7124d..05c5fbedc9 100644 --- a/ApplicationCode/ProjectDataModel/RimContourMapProjection.h +++ b/ApplicationCode/ProjectDataModel/RimContourMapProjection.h @@ -65,105 +65,116 @@ public: RimContourMapProjection(); ~RimContourMapProjection() override; - void generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform); - + void generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform); ContourPolygons generateContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform); cvf::ref generatePickPointPolygon(const caf::DisplayCoordTransform* displayCoordTransform); - void generateResults(); + + ResultAggregation resultAggregation() const; + double sampleSpacing() const; + double sampleSpacingFactor() const; + bool showContourLines() const; + + QString resultAggregationText() const; + QString resultDescriptionText() const; + QString weightingParameter() const; + double maxValue() const; double minValue() const; double meanValue() const; double sumAllValues() const; - double sampleSpacing() const; - double sampleSpacingFactor() const; - cvf::Vec2ui mapSize() const; - cvf::Vec2ui vertexGridSize() const; - bool showContourLines() const; + cvf::Vec2ui numberOfElementsIJ() const; + cvf::Vec2ui numberOfVerticesIJ() const; - const std::vector& aggregatedResults() const; - QString weightingParameter() const; - bool isMeanResult() const; - bool isSummationResult() const; - bool isStraightSummationResult() const; - static bool isStraightSummationResult(ResultAggregationEnum aggregationType); bool isColumnResult() const; double valueAtVertex(uint i, uint j) const; bool hasResultAtVertex(uint i, uint j) const; RimRegularLegendConfig* legendConfig() const; - - size_t cellIndex(uint i, uint j) const; - size_t vertexIndex(uint i, uint j) const; - cvf::Vec2ui ijFromVertexIndex(size_t gridIndex) const; - cvf::Vec2ui ijFromCellIndex(size_t mapIndex) const; void updateLegend(); - size_t numberOfVertices() const; uint numberOfCells() const; uint numberOfValidCells() const; + size_t numberOfVertices() const; - ResultAggregation resultAggregation() const; - QString resultAggregationText() const; - QString resultDescriptionText() const; void updatedWeightingResult(); - bool checkForMapIntersection(const cvf::Vec3d& localPoint3d, cvf::Vec2d* contourMapPoint, cvf::Vec2ui* contourMapCell, double* valueAtPoint) const; - void setPickPoint(cvf::Vec2d pickedPoint); + bool checkForMapIntersection(const cvf::Vec3d& localPoint3d, cvf::Vec2d* contourMapPoint, cvf::Vec2ui* contourMapCell, double* valueAtPoint) const; + void setPickPoint(cvf::Vec2d pickedPoint); protected: - double valueInCell(uint i, uint j) const; - bool hasResultInCell(uint i, uint j) const; - - double calculateValueInCell(uint i, uint j) const; - double calculateValueAtVertex(uint i, uint j) const; - - void generateGridMapping(); - void calculateTotalCellVisibility(); - cvf::Vec2d globalCellCenterPosition(uint i, uint j) const; - cvf::Vec2ui ijFromLocalPos(const cvf::Vec2d& localPos2d) const; - - std::vector> cellsAtIJ(uint i, uint j) const; - std::vector xVertexPositions() const; - std::vector yVertexPositions() const; - - std::vector> visibleCellsAndOverlapVolumeFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues = nullptr) const; - std::vector> visibleCellsAndLengthInCellFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues = nullptr) const; - double findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const; - const RimEclipseResultCase* eclipseCase() const; - RimEclipseResultCase* eclipseCase(); - RimContourMapView* view() const; - RigMainGrid* mainGrid() const; - void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - void initAfterRead() override; - bool getLegendRangeFrom3dGrid() const; - void updateGridInformation(); - cvf::Vec2ui calculateMapSize() const; + void initAfterRead() override; + +private: + typedef std::pair CellIndexAndResult; + +private: + void generateGridMapping(); + + double valueInCell(uint i, uint j) const; + bool hasResultInCell(uint i, uint j) const; + + double calculateValueInCell(uint i, uint j) const; + double calculateValueAtVertex(uint i, uint j) const; + + + std::vector cellsAtIJ(uint i, uint j) const; + + std::vector visibleCellsAndOverlapVolumeFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues = nullptr) const; + std::vector visibleCellsAndLengthInCellFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues = nullptr) const; + double findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const; + + bool isMeanResult() const; + bool isSummationResult() const; + bool isStraightSummationResult() const; + static bool isStraightSummationResult(ResultAggregationEnum aggregationType); + + size_t cellIndexFromIJ(uint i, uint j) const; + size_t vertexIndexFromIJ(uint i, uint j) const; + + cvf::Vec2ui ijFromVertexIndex(size_t gridIndex) const; + cvf::Vec2ui ijFromCellIndex(size_t mapIndex) const; + cvf::Vec2ui ijFromLocalPos(const cvf::Vec2d& localPos2d) const; + cvf::Vec2d globalCellCenterPosition(uint i, uint j) const; + + std::vector xVertexPositions() const; + std::vector yVertexPositions() const; + + bool getLegendRangeFrom3dGrid() const; + void updateGridInformation(); + cvf::Vec2ui calculateMapSize() const; + + RimEclipseResultCase* eclipseCase() const; + RimContourMapView* view() const; protected: - caf::PdmField m_relativeSampleSpacing; - caf::PdmField m_resultAggregation; - caf::PdmField m_showContourLines; - caf::PdmField m_weightByParameter; - caf::PdmChildField m_weightingResult; - cvf::ref m_cellGridIdxVisibility; + caf::PdmField m_relativeSampleSpacing; + caf::PdmField m_resultAggregation; + caf::PdmField m_showContourLines; + caf::PdmField m_weightByParameter; + caf::PdmChildField m_weightingResult; + cvf::ref m_cellGridIdxVisibility; - std::vector m_aggregatedResults; - std::vector m_aggregatedVertexResults; + std::vector m_aggregatedResults; + std::vector m_aggregatedVertexResults; std::vector>> m_projected3dGridIndices; - cvf::ref m_resultAccessor; + cvf::ref m_resultAccessor; - cvf::Vec2d m_pickPoint; + cvf::Vec2d m_pickPoint; - cvf::Vec2ui m_mapSize; - cvf::BoundingBox m_fullBoundingBox; - double m_sampleSpacing; + caf::PdmPointer m_eclipseCase; + cvf::ref m_mainGrid; + cvf::Vec2ui m_mapSize; + cvf::BoundingBox m_fullBoundingBox; + double m_sampleSpacing; };