diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 1887983892..e8391ca9b3 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -42,6 +42,7 @@ #include "RimGridTimeHistoryCurve.h" #include "RimIntersectionCollection.h" #include "RimPlotCurve.h" +#include "RimProject.h" #include "RimReservoirCellResultsStorage.h" #include "RimTools.h" #include "RimViewLinker.h" @@ -91,6 +92,9 @@ RimEclipseResultDefinition::RimEclipseResultDefinition() &m_timeLapseBaseTimestep, "TimeLapseBaseTimeStep", RigEclipseResultAddress::NO_TIME_LAPSE, "Base Time Step", "", "", ""); m_timeLapseBaseTimestep.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_differenceCase, "DifferenceCase", "Difference Case", "", "", ""); + m_differenceCase.uiCapability()->setUiHidden(true); + // One single tracer list has been split into injectors and producers. // The old list is defined as injectors and we'll have to move any producers in old projects. CAF_PDM_InitFieldNoDefault(&m_selectedTracers_OBSOLETE, "SelectedTracers", "Tracers", "", "", ""); @@ -130,6 +134,9 @@ RimEclipseResultDefinition::RimEclipseResultDefinition() ""); m_timeLapseBaseTimestepUiField.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&m_differenceCaseUiField, "MDifferenceCase", "Difference Case", "", "", ""); + m_differenceCaseUiField.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&m_flowSolutionUiField, "MFlowDiagSolution", "Solution", "", "", ""); m_flowSolutionUiField.xmlCapability()->disableIO(); m_flowSolutionUiField.uiCapability()->setUiHidden(true); // For now since there are only one to choose from @@ -245,6 +252,7 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha m_resultType = m_resultTypeUiField; m_resultVariable = m_resultVariableUiField; m_timeLapseBaseTimestep = m_timeLapseBaseTimestepUiField; + m_differenceCase = m_differenceCaseUiField(); if (m_resultTypeUiField() == RiaDefines::FLOW_DIAGNOSTICS) { @@ -259,7 +267,7 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha loadDataAndUpdate(); } - if (&m_timeLapseBaseTimestepUiField == changedField) + if (&m_timeLapseBaseTimestepUiField == changedField || &m_differenceCaseUiField == changedField) { m_resultVariableUiField = ""; } @@ -637,6 +645,30 @@ QList RimEclipseResultDefinition::calculateValueOptions( options.push_back(caf::PdmOptionItemInfo(displayString, static_cast(stepIdx))); } } + else if (fieldNeedingOptions == &m_differenceCaseUiField) + { + options.push_back(caf::PdmOptionItemInfo("None", nullptr)); + + RimEclipseCase* eclipseCase = nullptr; + this->firstAncestorOrThisOfTypeAsserted(eclipseCase); + if (eclipseCase && eclipseCase->eclipseCaseData() && eclipseCase->eclipseCaseData()->mainGrid()) + { + RimProject* proj = nullptr; + eclipseCase->firstAncestorOrThisOfTypeAsserted(proj); + + std::vector allCases = proj->eclipseCases(); + for (RimEclipseCase* otherCase : allCases) + { + if (otherCase == eclipseCase) continue; + + if (otherCase->eclipseCaseData() && otherCase->eclipseCaseData()->mainGrid()) + { + options.push_back( + caf::PdmOptionItemInfo(otherCase->caseUserDescription(), otherCase, false, otherCase->uiIcon())); + } + } + } + } } (*useOptionsOnly) = true; @@ -654,10 +686,20 @@ RigEclipseResultAddress RimEclipseResultDefinition::eclipseResultAddress() const const RigCaseCellResultsData* gridCellResults = this->currentGridCellResults(); if (gridCellResults) { + int timelapseTimeStep = RigEclipseResultAddress::NO_TIME_LAPSE; + int diffCaseId = RigEclipseResultAddress::NO_CASE_DIFF; + if (isTimeDiffResult()) - return RigEclipseResultAddress(m_resultType(), m_resultVariable(), m_timeLapseBaseTimestep()); - else - return RigEclipseResultAddress(m_resultType(), m_resultVariable()); + { + timelapseTimeStep = m_timeLapseBaseTimestep(); + } + + if (isCaseDifferenceResult()) + { + diffCaseId = m_differenceCase->caseId(); + } + + return RigEclipseResultAddress(m_resultType(), m_resultVariable(), timelapseTimeStep, diffCaseId); } else { @@ -776,6 +818,11 @@ QString RimEclipseResultDefinition::resultVariableUiName() const return timeDiffResultName(m_resultVariable(), m_timeLapseBaseTimestep()); } + if (isCaseDifferenceResult()) + { + return caseDiffResultName(m_resultVariable(), m_differenceCase()->caseId()); + } + return m_resultVariable(); } @@ -794,6 +841,11 @@ QString RimEclipseResultDefinition::resultVariableUiShortName() const return timeDiffResultName(m_resultVariable(), m_timeLapseBaseTimestep()); } + if (isCaseDifferenceResult()) + { + return caseDiffResultName(m_resultVariable(), m_differenceCase()->caseId()); + } + return m_resultVariable(); } @@ -813,10 +865,19 @@ void RimEclipseResultDefinition::loadResult() } } + if (m_differenceCase) + { + if (!m_differenceCase->ensureReservoirCaseIsOpen()) + { + RiaLogging::error("Could not open the Eclipse Grid file: " + m_eclipseCase->gridFileName()); + return; + } + } + RigCaseCellResultsData* gridCellResults = this->currentGridCellResults(); if (gridCellResults) { - if (isTimeDiffResult()) + if (isTimeDiffResult() || isCaseDifferenceResult()) { gridCellResults->createResultEntry(this->eclipseResultAddress(), false); } @@ -918,6 +979,7 @@ void RimEclipseResultDefinition::initAfterRead() m_resultTypeUiField = m_resultType; m_resultVariableUiField = m_resultVariable; m_timeLapseBaseTimestepUiField = m_timeLapseBaseTimestep; + m_differenceCaseUiField = m_differenceCase(); m_flowSolutionUiField = m_flowSolution(); m_selectedInjectorTracersUiField = m_selectedInjectorTracers; @@ -1150,6 +1212,7 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm { caf::PdmUiGroup* timeLapseGr = uiOrdering.addNewGroup("Time Difference Options"); timeLapseGr->add(&m_timeLapseBaseTimestepUiField); + timeLapseGr->add(&m_differenceCaseUiField); } uiOrdering.skipRemainingFields(true); @@ -1310,7 +1373,15 @@ QString RimEclipseResultDefinition::timeDiffResultName(const QString& resultName //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimEclipseResultDefinition::convertToTimeDiffUiVarName(const QString& resultName) +QString RimEclipseResultDefinition::caseDiffResultName(const QString& resultName, int caseId) +{ + return resultName + " (diff case - " + QString::number(caseId) + ")"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::convertToTimeOrCaseDiffUiVarName(const QString& resultName) { if (m_timeLapseBaseTimestepUiField() >= 0 && (m_resultTypeUiField() == RiaDefines::DYNAMIC_NATIVE || m_resultTypeUiField() == RiaDefines::GENERATED)) @@ -1318,6 +1389,11 @@ QString RimEclipseResultDefinition::convertToTimeDiffUiVarName(const QString& re return timeDiffResultName(resultName, m_timeLapseBaseTimestepUiField()); } + if (m_differenceCaseUiField()) + { + return caseDiffResultName(resultName, m_differenceCaseUiField()->caseId()); + } + return resultName; } @@ -1361,7 +1437,7 @@ QList RimEclipseResultDefinition::calcOptionsForVariable // Cell Center result names foreach (QString s, cellCenterResultNames) { - optionList.push_back(caf::PdmOptionItemInfo(convertToTimeDiffUiVarName(s), s)); + optionList.push_back(caf::PdmOptionItemInfo(convertToTimeOrCaseDiffUiVarName(s), s)); } // Ternary Result @@ -1393,11 +1469,11 @@ QList RimEclipseResultDefinition::calcOptionsForVariable { if (showDerivedResultsFirstInList) { - optionList.push_front(caf::PdmOptionItemInfo(convertToTimeDiffUiVarName(s), s)); + optionList.push_front(caf::PdmOptionItemInfo(convertToTimeOrCaseDiffUiVarName(s), s)); } else { - optionList.push_back(caf::PdmOptionItemInfo(convertToTimeDiffUiVarName(s), s)); + optionList.push_back(caf::PdmOptionItemInfo(convertToTimeOrCaseDiffUiVarName(s), s)); } } @@ -1816,3 +1892,11 @@ bool RimEclipseResultDefinition::isTimeDiffResult() const { return m_timeLapseBaseTimestep() >= 0; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::isCaseDifferenceResult() const +{ + return m_differenceCase() != nullptr; +} diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index a2685fff40..e6af0ffa5f 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -133,6 +133,8 @@ protected: caf::PdmField m_resultVariable; caf::PdmField m_timeLapseBaseTimestep; + caf::PdmPtrField m_differenceCase; + caf::PdmPtrField m_flowSolution; caf::PdmField > m_selectedInjectorTracers; caf::PdmField > m_selectedProducerTracers; @@ -149,6 +151,8 @@ protected: caf::PdmField m_resultVariableUiField; caf::PdmField m_timeLapseBaseTimestepUiField; + caf::PdmPtrField m_differenceCaseUiField; + caf::PdmField< caf::AppEnum< FlowTracerSelectionType > > m_flowTracerSelectionMode; caf::PdmPtrField m_flowSolutionUiField; caf::PdmField< RigFlowDiagResultAddress::PhaseSelectionEnum > m_phaseSelection; @@ -176,9 +180,11 @@ private: bool hasDualPorFractureResult(); QString flowDiagResUiText(bool shortLabel, int maxTracerStringLength = std::numeric_limits::max()) const; - static QString timeDiffResultName(const QString& resultName, int timeStepIndex); - QString convertToTimeDiffUiVarName(const QString& resultName); + static QString timeDiffResultName(const QString& resultName, int timeStepIndex); + static QString caseDiffResultName(const QString& resultName, int caseId); + + QString convertToTimeOrCaseDiffUiVarName(const QString& resultName); QList calcOptionsForVariableUiFieldStandard(); QList calcOptionsForSelectedTracerField(bool injector); @@ -201,5 +207,6 @@ private: void syncProducerToInjectorSelection(); bool isTimeDiffResult() const; + bool isCaseDifferenceResult() const; }; diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index 1091bb68f8..6236bf2ef2 100644 --- a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -67,6 +67,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigWellPathGeometryTools.h ${CMAKE_CURRENT_LIST_DIR}/RigCaseRealizationParameters.h ${CMAKE_CURRENT_LIST_DIR}/RigGeoMechBoreHoleStressCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RigPolyLinesData.h +${CMAKE_CURRENT_LIST_DIR}/RigCaseCellResultCalculator.h ) @@ -132,7 +133,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigWellPathGeometryTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RigCaseRealizationParameters.cpp ${CMAKE_CURRENT_LIST_DIR}/RigGeoMechBoreHoleStressCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RigPolyLinesData.cpp - +${CMAKE_CURRENT_LIST_DIR}/RigCaseCellResultCalculator.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultCalculator.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultCalculator.cpp new file mode 100644 index 0000000000..a17227af3c --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultCalculator.cpp @@ -0,0 +1,162 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigCaseCellResultCalculator.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "RigCaseCellResultsData.h" +#include "RigEclipseCaseData.h" +#include "RigEclipseResultAddress.h" +#include "RigGridManager.h" +#include "RigMainGrid.h" +#include "RigResultAccessorFactory.h" +#include "RigResultModifier.h" +#include "RigResultModifierFactory.h" + +#include "RimEclipseCase.h" +#include "RimProject.h" + +#include "cvfAssert.h" + +#include +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCaseCellResultCalculator::computeDifference(RigEclipseCaseData* sourceCase, + RiaDefines::PorosityModelType porosityModel, + const RigEclipseResultAddress& address) +{ + CVF_ASSERT(address.isValid()); + CVF_ASSERT(address.hasDifferenceCase()); + + // Assume at this stage that data for the case is available + // It is up to the caller to make sure the case is read from file + + RigEclipseCaseData* otherCase = nullptr; + + { + auto eclipseCases = RiaApplication::instance()->project()->eclipseCases(); + for (RimEclipseCase* c : eclipseCases) + { + if (c->caseId() == address.m_differenceCaseId) + { + if (c && c->eclipseCaseData()) + { + otherCase = c->eclipseCaseData(); + } + } + } + } + + if (!otherCase || !sourceCase) + { + RiaLogging::error("Missing input case for difference calculator"); + + return false; + } + + RigMainGrid* sourceMainGrid = sourceCase->mainGrid(); + RigMainGrid* otherMainGrid = otherCase->mainGrid(); + + if (!RigGridManager::isEqual(sourceMainGrid, otherMainGrid)) + { + RiaLogging::error("Case difference : Grid cases do not match"); + + return false; + } + + RigCaseCellResultsData* otherCaseResults = otherCase->results(porosityModel); + RigCaseCellResultsData* sourceCaseResults = sourceCase->results(porosityModel); + + if (!otherCaseResults || !sourceCaseResults) + { + RiaLogging::error("Missing result data for difference calculator"); + + return false; + } + + RigEclipseResultAddress nativeAddress(address); + nativeAddress.m_differenceCaseId = RigEclipseResultAddress::NO_CASE_DIFF; + if (!sourceCaseResults->ensureKnownResultLoaded(nativeAddress)) + { + RiaLogging::error("Failed to load destination diff result"); + + return false; + } + + if (!otherCaseResults->ensureKnownResultLoaded(nativeAddress)) + { + RiaLogging::error("Failed to load difference result"); + + return false; + } + + // Initialize difference result with infinity for correct number of time steps and values per time step + { + const std::vector>& srcFrames = sourceCaseResults->cellScalarResults(nativeAddress); + std::vector>& diffResultFrames = sourceCaseResults->modifiableCellScalarResultTimesteps(address); + diffResultFrames.resize(srcFrames.size()); + for (size_t fIdx = 0; fIdx < srcFrames.size(); ++fIdx) + { + const std::vector& srcVals = srcFrames[fIdx]; + std::vector& dstVals = diffResultFrames[fIdx]; + + dstVals.resize(srcVals.size(), std::numeric_limits::infinity()); + } + } + + size_t otherFrameCount = otherCaseResults->cellScalarResults(nativeAddress).size(); + size_t sourceFrameCount = sourceCaseResults->cellScalarResults(nativeAddress).size(); + size_t maxFrameCount = std::min(otherFrameCount, sourceFrameCount); + + for (size_t gridIdx = 0; gridIdx < sourceMainGrid->gridCount(); ++gridIdx) + { + auto grid = sourceMainGrid->gridByIndex(gridIdx); + const RigActiveCellInfo* activeCellInfo = sourceCaseResults->activeCellInfo(); + + for (size_t fIdx = 0; fIdx < maxFrameCount; ++fIdx) + { + cvf::ref sourceResultAccessor = + RigResultAccessorFactory::createFromResultAddress(sourceCase, gridIdx, porosityModel, fIdx, nativeAddress); + + cvf::ref otherResultAccessor = + RigResultAccessorFactory::createFromResultAddress(otherCase, gridIdx, porosityModel, fIdx, nativeAddress); + + cvf::ref resultModifier = + RigResultModifierFactory::createResultModifier(sourceCase, gridIdx, porosityModel, fIdx, address); + + for (size_t localGridCellIdx = 0; localGridCellIdx < grid->cellCount(); localGridCellIdx++) + { + size_t reservoirCellIndex = grid->reservoirCellIndex(localGridCellIdx); + if (activeCellInfo->isActive(reservoirCellIndex)) + { + double sourceVal = sourceResultAccessor->cellScalar(localGridCellIdx); + double otherVal = otherResultAccessor->cellScalar(localGridCellIdx); + + double difference = otherVal - sourceVal; + + resultModifier->setCellScalar(localGridCellIdx, difference); + } + } + } + } + + return true; +} diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultCalculator.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultCalculator.h new file mode 100644 index 0000000000..7e6beff785 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultCalculator.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaPorosityModel.h" + +class RigEclipseCaseData; +class RigEclipseResultAddress; + +//================================================================================================== +/// +//================================================================================================== +class RigCaseCellResultCalculator +{ +public: + static bool computeDifference(RigEclipseCaseData* destination, + RiaDefines::PorosityModelType porosityModel, + const RigEclipseResultAddress& address); +}; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 9318928754..86e1526919 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -23,10 +23,12 @@ #include "RiaApplication.h" #include "RiaLogging.h" +#include "RigCaseCellResultCalculator.h" #include "RigEclipseCaseData.h" #include "RigEclipseMultiPropertyStatCalc.h" #include "RigEclipseNativeStatCalc.h" #include "RigEclipseResultInfo.h" +#include "RigFormationNames.h" #include "RigMainGrid.h" #include "RigStatisticsDataCache.h" #include "RigStatisticsMath.h" @@ -44,7 +46,6 @@ #include #include -#include "RigFormationNames.h" //-------------------------------------------------------------------------------------------------- /// @@ -404,7 +405,9 @@ QStringList RigCaseCellResultsData::resultNames(RiaDefines::ResultCatType resTyp std::vector::const_iterator it; for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it) { - if (it->resultType() == resType && !it->eclipseResultAddress().isTimeLapse()) + if (it->resultType() == resType && + !it->eclipseResultAddress().isTimeLapse() && + !it->eclipseResultAddress().hasDifferenceCase()) { varList.push_back(it->resultName()); } @@ -1122,6 +1125,15 @@ size_t RigCaseCellResultsData::findOrLoadKnownScalarResult(const RigEclipseResul return scalarResultIndex; } + else if (resVarAddr.hasDifferenceCase()) + { + if (!RigCaseCellResultCalculator::computeDifference(this->m_ownerCaseData, RiaDefines::MATRIX_MODEL, resVarAddr)) + { + return cvf::UNDEFINED_SIZE_T; + } + + return scalarResultIndex; + } // Load dependency data sets diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseResultAddress.h b/ApplicationCode/ReservoirDataModel/RigEclipseResultAddress.h index 3db9267d60..9aca81e1bd 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseResultAddress.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseResultAddress.h @@ -18,6 +18,7 @@ #pragma once #include "RiaDefines.h" + #include class RigEclipseResultAddress @@ -26,20 +27,24 @@ public: RigEclipseResultAddress() : m_resultCatType(RiaDefines::UNDEFINED) , m_timeLapseBaseFrameIdx(NO_TIME_LAPSE) + , m_differenceCaseId(NO_CASE_DIFF) {} explicit RigEclipseResultAddress(const QString& resultName) : m_resultCatType(RiaDefines::UNDEFINED) , m_resultName(resultName) , m_timeLapseBaseFrameIdx(NO_TIME_LAPSE) + , m_differenceCaseId(NO_CASE_DIFF) {} - explicit RigEclipseResultAddress(RiaDefines::ResultCatType type, const QString& resultName, int timeLapseBaseTimeStep = NO_TIME_LAPSE) + explicit RigEclipseResultAddress(RiaDefines::ResultCatType type, const QString& resultName, int timeLapseBaseTimeStep = NO_TIME_LAPSE, int differenceCaseId = NO_CASE_DIFF) : m_resultCatType(type) , m_resultName(resultName) , m_timeLapseBaseFrameIdx(timeLapseBaseTimeStep) + , m_differenceCaseId(differenceCaseId) {} + bool isValid() const { if (m_resultName.isEmpty() || m_resultName == RiaDefines::undefinedResultName()) @@ -54,12 +59,20 @@ public: static const int ALL_TIME_LAPSES = -2; static const int NO_TIME_LAPSE = -1; + static const int NO_CASE_DIFF = -1; bool isTimeLapse() const { return m_timeLapseBaseFrameIdx > NO_TIME_LAPSE;} bool representsAllTimeLapses() const { return m_timeLapseBaseFrameIdx == ALL_TIME_LAPSES;} + bool hasDifferenceCase() const { return m_differenceCaseId > NO_CASE_DIFF; } + bool operator< (const RigEclipseResultAddress& other ) const { + if (m_differenceCaseId != other.m_differenceCaseId) + { + return (m_differenceCaseId < other.m_differenceCaseId); + } + if (m_timeLapseBaseFrameIdx != other.m_timeLapseBaseFrameIdx) { return (m_timeLapseBaseFrameIdx < other.m_timeLapseBaseFrameIdx); @@ -77,7 +90,8 @@ public: { if ( m_resultCatType != other.m_resultCatType || m_resultName != other.m_resultName - || m_timeLapseBaseFrameIdx != other.m_timeLapseBaseFrameIdx) + || m_timeLapseBaseFrameIdx != other.m_timeLapseBaseFrameIdx + || m_differenceCaseId != other.m_differenceCaseId) { return false; } @@ -87,8 +101,9 @@ public: RiaDefines::ResultCatType m_resultCatType; QString m_resultName; + int m_timeLapseBaseFrameIdx; - + int m_differenceCaseId; };