From 21b313f945800a1550fd80e3b637b5373fbe453b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 14 Oct 2015 15:07:48 +0200 Subject: [PATCH] (#557, #560, #561) WLP: Guaranteed Pairwise ordering of intersections and endpoint handling. Now discarding out-of-pair points. Added well name and case in error message. --- .../RimWellLogPlotCollection.cpp | 6 +- .../RigEclipseWellLogExtractor.cpp | 4 +- .../RigEclipseWellLogExtractor.h | 2 +- .../RigGeoMechWellLogExtractor.cpp | 4 +- .../RigGeoMechWellLogExtractor.h | 2 +- .../RigWellLogExtractionTools.h | 2 +- .../RigWellLogExtractor.cpp | 103 ++++++++++++------ .../ReservoirDataModel/RigWellLogExtractor.h | 5 +- 8 files changed, 87 insertions(+), 41 deletions(-) diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp index 8ef5c92cc9..cb1bbec0ec 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp @@ -73,7 +73,8 @@ RigEclipseWellLogExtractor* RimWellLogPlotCollection::findOrCreateExtractor(RimW } } - cvf::ref extractor = new RigEclipseWellLogExtractor(eclCaseData, wellPathGeom); + std::string errorIdName = (wellPath->name() + " " + eclCase->caseUserDescription()).toStdString(); + cvf::ref extractor = new RigEclipseWellLogExtractor(eclCaseData, wellPathGeom, errorIdName); m_extractors.push_back(extractor.p()); return extractor.p(); @@ -99,7 +100,8 @@ RigGeoMechWellLogExtractor* RimWellLogPlotCollection::findOrCreateExtractor(RimW } } - cvf::ref extractor = new RigGeoMechWellLogExtractor(geomCaseData, wellPathGeom); + std::string errorIdName = (wellPath->name() + " " + geomCase->caseUserDescription()).toStdString(); + cvf::ref extractor = new RigGeoMechWellLogExtractor(geomCaseData, wellPathGeom, errorIdName); m_geomExtractors.push_back(extractor.p()); return extractor.p(); diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp index 6a0033796b..66b8b70e7e 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp @@ -32,8 +32,8 @@ /// //================================================================================================== -RigEclipseWellLogExtractor::RigEclipseWellLogExtractor(const RigCaseData* aCase, const RigWellPath* wellpath) - : m_caseData(aCase), RigWellLogExtractor(wellpath) +RigEclipseWellLogExtractor::RigEclipseWellLogExtractor(const RigCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName) + : m_caseData(aCase), RigWellLogExtractor(wellpath, wellCaseErrorMsgName) { calculateIntersection(); } diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h index 1eb401746f..d92a362377 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h @@ -43,7 +43,7 @@ namespace cvf { class RigEclipseWellLogExtractor : public RigWellLogExtractor { public: - RigEclipseWellLogExtractor(const RigCaseData* aCase, const RigWellPath* wellpath); + RigEclipseWellLogExtractor(const RigCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName); void curveData(const RigResultAccessor* resultAccessor, std::vector* values ); const RigCaseData* caseData() { return m_caseData.p();} diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp index 86a2576214..4870c93de6 100644 --- a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp @@ -31,8 +31,8 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigGeoMechWellLogExtractor::RigGeoMechWellLogExtractor(RigGeoMechCaseData* aCase, const RigWellPath* wellpath) - :m_caseData(aCase), RigWellLogExtractor(wellpath) +RigGeoMechWellLogExtractor::RigGeoMechWellLogExtractor(RigGeoMechCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName) + :m_caseData(aCase), RigWellLogExtractor(wellpath, wellCaseErrorMsgName) { calculateIntersection(); } diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h index fccfc47532..3121913339 100644 --- a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h @@ -43,7 +43,7 @@ namespace cvf { class RigGeoMechWellLogExtractor : public RigWellLogExtractor { public: - RigGeoMechWellLogExtractor(RigGeoMechCaseData* aCase, const RigWellPath* wellpath); + RigGeoMechWellLogExtractor(RigGeoMechCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName); void curveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector* values ); const RigGeoMechCaseData* caseData() { return m_caseData.p();} diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogExtractionTools.h b/ApplicationCode/ReservoirDataModel/RigWellLogExtractionTools.h index 5afbfe6b73..b9744c4608 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellLogExtractionTools.h +++ b/ApplicationCode/ReservoirDataModel/RigWellLogExtractionTools.h @@ -214,7 +214,7 @@ struct RigMDEnterLeaveCellIdxKey return (measuredDepth < other.measuredDepth); } - static bool isProperPair(const RigMDEnterLeaveCellIdxKey& key1, const RigMDEnterLeaveCellIdxKey& key2 ) + static bool isProperCellEnterLeavePair(const RigMDEnterLeaveCellIdxKey& key1, const RigMDEnterLeaveCellIdxKey& key2 ) { return ( key1.hexIndex == key2.hexIndex && key1.isEnteringCell && key2.isLeavingCell() diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp index bd33d3213d..45e3b7a0dd 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp @@ -24,7 +24,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigWellLogExtractor::RigWellLogExtractor(const RigWellPath* wellpath) : m_wellPath(wellpath) +RigWellLogExtractor::RigWellLogExtractor(const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName) : m_wellPath(wellpath), m_wellCaseErrorMsgName(wellCaseErrorMsgName) { } @@ -130,7 +130,7 @@ void RigWellLogExtractor::populateReturnArrays(std::mapsecond; firstLeavingPoint.m_intersectionPoint = m_wellPath->m_wellPathPoints[0]; - sortedUniqueIntersections.insert(std::make_pair(RigMDEnterLeaveCellIdxKey(m_wellPath->m_measuredDepths[0], firstLeavingPoint.m_hexIndex, true), + sortedUniqueIntersections.insert(std::make_pair(RigMDEnterLeaveCellIdxKey(m_wellPath->m_measuredDepths[0], true, firstLeavingPoint.m_hexIndex), firstLeavingPoint)); } @@ -141,18 +141,18 @@ void RigWellLogExtractor::populateReturnArrays(std::mapsecond; lastEnterPoint.m_intersectionPoint = m_wellPath->m_wellPathPoints.back(); + lastEnterPoint.m_isIntersectionEntering = false; - sortedUniqueIntersections.insert(std::make_pair(RigMDEnterLeaveCellIdxKey(m_wellPath->m_measuredDepths.back(), lastEnterPoint.m_hexIndex, false), + sortedUniqueIntersections.insert(std::make_pair(RigMDEnterLeaveCellIdxKey(m_wellPath->m_measuredDepths.back(), false, lastEnterPoint.m_hexIndex), lastEnterPoint)); } } - std::map filteredSortedIntersections; - { std::map::iterator it1 = sortedUniqueIntersections.begin(); std::map::iterator it2; + // 1-2 3 while (it1 != sortedUniqueIntersections.end()) { it2 = it1; @@ -160,37 +160,78 @@ void RigWellLogExtractor::populateReturnArrays(std::mapfirst, it2->first)) + if (RigMDEnterLeaveCellIdxKey::isProperCellEnterLeavePair(it1->first, it2->first)) { - //CVF_ASSERT(false); - cvf::Trace::show(cvf::String("Well log curve is inaccurate around MD: ") + cvf::String::number((double)(it1->first.measuredDepth)) + ", " + cvf::String::number((double)(it2->first.measuredDepth))); - } - { - filteredSortedIntersections.insert(std::make_pair(RigMDEnterLeaveKey(it1->first.measuredDepth, it1->first.isEnteringCell), - it1->second)); + appendIntersectionToArrays(it1->first.measuredDepth, it1->second); ++it1; - filteredSortedIntersections.insert(std::make_pair(RigMDEnterLeaveKey(it1->first.measuredDepth, it1->first.isEnteringCell), - it1->second)); + appendIntersectionToArrays(it1->first.measuredDepth, it1->second); ++it1; } + else + { + + // If we haven't a proper pair, try our best to recover these variants: + // 1-2 3 4 5 6 7 8 9 10 11-12 + // +---+ + // +---+ + // +---+ + + std::map::iterator it11 = it1; + std::map::iterator it21 = it2; + + // Check if we have overlapping cells (typically at a fault) + ++it21; + if (it21 != sortedUniqueIntersections.end() + && RigMDEnterLeaveCellIdxKey::isProperCellEnterLeavePair(it11->first, it21->first)) + { + // Found 3 to 5 connection + appendIntersectionToArrays(it11->first.measuredDepth, it11->second); + appendIntersectionToArrays(it21->first.measuredDepth, it21->second); + + ++it11; ++it21; + if (it21 != sortedUniqueIntersections.end() + && RigMDEnterLeaveCellIdxKey::isProperCellEnterLeavePair(it11->first, it21->first)) + { + // Found a 4 to 6 connection + appendIntersectionToArrays(it11->first.measuredDepth, it11->second); + appendIntersectionToArrays(it21->first.measuredDepth, it21->second); + + it1 = it21; + ++it1; + continue; + } + else + { + cvf::Trace::show(cvf::String("Well log from :") + m_wellCaseErrorMsgName + (" Discards a point at MD: ") + cvf::String::number((double)(it1->first.measuredDepth))); + + // Found that 8 to 10 is not connected, after finding 7 to 9 + it1 = it21; // Discard 8 by Jumping to 10 + continue; + } + } + else + { + cvf::Trace::show(cvf::String("Well log from :") + m_wellCaseErrorMsgName + (" Discards a point at MD: ") + cvf::String::number((double)(it1->first.measuredDepth))); + + // Found that 10 to 11 is not connected, and not 10 to 12 either + it1++; // Discard 10 and jump to 11 and hope that recovers us + continue; + } + + CVF_ASSERT(false); // Should not come here + } + + } } - - { - // Now populate the return arrays - std::map::iterator it; - - it = filteredSortedIntersections.begin(); - while (it != filteredSortedIntersections.end()) - { - m_measuredDepth.push_back(it->first.measuredDepth); - m_trueVerticalDepth.push_back(abs(it->second.m_intersectionPoint[2])); - m_intersections.push_back(it->second.m_intersectionPoint); - m_intersectedCells.push_back(it->second.m_hexIndex); - m_intersectedCellFaces.push_back(it->second.m_face); - ++it; - } - } + } +void RigWellLogExtractor::appendIntersectionToArrays(double measuredDepth, const HexIntersectionInfo& intersection) +{ + m_measuredDepth.push_back (measuredDepth); + m_trueVerticalDepth.push_back (abs(intersection.m_intersectionPoint[2])); + m_intersections.push_back (intersection.m_intersectionPoint); + m_intersectedCells.push_back (intersection.m_hexIndex); + m_intersectedCellFaces.push_back(intersection.m_face); +} diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.h index 603684ab50..a06ca717d6 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.h +++ b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.h @@ -37,7 +37,7 @@ class RigWellPath; class RigWellLogExtractor : public cvf::Object { public: - RigWellLogExtractor(const RigWellPath* wellpath); + RigWellLogExtractor(const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName); virtual ~RigWellLogExtractor(); const std::vector& measuredDepth() { return m_measuredDepth; } @@ -51,6 +51,7 @@ protected: std::map *uniqueIntersections); void populateReturnArrays(std::map &uniqueIntersections); + void appendIntersectionToArrays(double measuredDepth, const HexIntersectionInfo& intersection); std::vector m_measuredDepth; std::vector m_trueVerticalDepth; @@ -61,6 +62,8 @@ protected: m_intersectedCellFaces; cvf::cref m_wellPath; + + std::string m_wellCaseErrorMsgName; };