From 8fbc1d09535d07a980027d3faa24f1276c54022a Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Thu, 6 Dec 2018 10:11:06 +0100 Subject: [PATCH] #3779 Make sure we always have a super valve for segments that overlap with valves. --- ...ellPathExportCompletionDataFeatureImpl.cpp | 162 ++++++++++++------ ...cWellPathExportCompletionDataFeatureImpl.h | 16 +- 2 files changed, 120 insertions(+), 58 deletions(-) diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp index b33b4c4a03..71b88adc7f 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp @@ -1015,7 +1015,7 @@ void RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(RifEclips formatter.add(exportInfo.wellPath()->name()); formatter.add(completion->subSegments().front()->segmentNumber()); formatter.add(location->icdFlowCoefficient()); - formatter.add(QString("%1").arg(location->icdArea(), 8, 'f', 6)); + formatter.add(QString("%1").arg(location->icdArea(), 8, 'g', 4)); formatter.rowCompleted(); } } @@ -2050,8 +2050,10 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generatePerforation bool foundSubGridIntersections = false; MainBoreSegments mainBoreSegments = createMainBoreSegments(subSegIntersections, perforationIntervals, wellPath, exportSettings, &foundSubGridIntersections); - ValveCompletionMap primaryValveCompletions = assignPrimaryValveCompletions(mainBoreSegments, perforationIntervals); - assignSecondaryValveContributions(mainBoreSegments, perforationIntervals, primaryValveCompletions, unitSystem); + + assignSuperValveCompletions(mainBoreSegments, perforationIntervals); + assignValveContributionsToSuperValves(mainBoreSegments, perforationIntervals, unitSystem); + moveIntersectionsToSuperValves(mainBoreSegments); for (std::shared_ptr segment : mainBoreSegments) { @@ -2108,18 +2110,84 @@ RicWellPathExportCompletionDataFeatureImpl::createMainBoreSegments( return mainBoreSegments; } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportCompletionDataFeatureImpl::assignSecondaryValveContributions( +void RicWellPathExportCompletionDataFeatureImpl::assignSuperValveCompletions( std::vector>& mainBoreSegments, - const std::vector& perforationIntervals, - const ValveCompletionMap& primaryValveLocations, - RiaEclipseUnitTools::UnitSystem unitSystem) + const std::vector& perforationIntervals) { - ValveContributionMap slaveValves; + for (size_t nMainSegment = 0u; nMainSegment < mainBoreSegments.size(); ++nMainSegment) + { + std::shared_ptr segment = mainBoreSegments[nMainSegment]; + + std::shared_ptr superValve; + for (const RimPerforationInterval* interval : perforationIntervals) + { + std::vector perforationValves; + interval->descendantsIncludingThisOfType(perforationValves); + + for (const RimWellPathValve* valve : perforationValves) + { + for (size_t nSubValve = 0u; nSubValve < valve->valveLocations().size(); ++nSubValve) + { + double valveMD = valve->valveLocations()[nSubValve]; + + std::pair valveSegment = valve->valveSegments()[nSubValve]; + double overlapStart = std::max(valveSegment.first, segment->startMD()); + double overlapEnd = std::min(valveSegment.second, segment->endMD()); + double overlap = std::max(0.0, overlapEnd - overlapStart); + + if (segment->startMD() <= valveMD && valveMD < segment->endMD()) + { + QString valveLabel = QString("%1 #%2").arg("Combined Valve for segment").arg(nMainSegment + 2); + superValve.reset(new RicMswCompletion(RigCompletionData::PERFORATION_ICD, valveLabel)); + std::shared_ptr subSegment(new RicMswSubSegment(valveMD, 0.1, 0.0, 0.0)); + superValve->addSubSegment(subSegment); + } + else if (overlap > 0.0 && !superValve) + { + QString valveLabel = QString("%1 #%2").arg("Combined Valve for segment").arg(nMainSegment + 2); + superValve.reset(new RicMswCompletion(RigCompletionData::PERFORATION_ICD, valveLabel)); + std::shared_ptr subSegment(new RicMswSubSegment(overlapStart, 0.1, 0.0, 0.0)); + superValve->addSubSegment(subSegment); + } + } + } + } + + if (superValve) + { + segment->addCompletion(superValve); + } + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::assignValveContributionsToSuperValves( + const std::vector>& mainBoreSegments, + const std::vector& perforationIntervals, + RiaEclipseUnitTools::UnitSystem unitSystem) +{ + ValveContributionMap assignedRegularValves; for (std::shared_ptr segment : mainBoreSegments) { + std::shared_ptr superValve; + for (auto completion : segment->completions()) + { + if (completion->completionType() == RigCompletionData::PERFORATION_ICD) + { + superValve = completion; + break; + } + } + + if (!superValve) continue; + double totalIcdArea = 0.0; RiaWeightedMeanCalculator coeffMeanCalc; @@ -2140,12 +2208,7 @@ void RicWellPathExportCompletionDataFeatureImpl::assignSecondaryValveContributio if (overlap > 0.0) { - auto primaryValveLocIt = primaryValveLocations.find(std::make_pair(valve, nSubValve)); - if (primaryValveLocIt == primaryValveLocations.end()) continue; - - std::shared_ptr completion = primaryValveLocIt->second; - slaveValves[completion].insert(std::make_pair(valve, nSubValve)); - + assignedRegularValves[superValve].insert(std::make_pair(valve, nSubValve)); double icdOrificeRadius = valve->orificeDiameter(unitSystem) / 2; double icdArea = icdOrificeRadius * icdOrificeRadius * cvf::PI_D * overlap / valveSegmentLength; totalIcdArea += icdArea; @@ -2161,18 +2224,18 @@ void RicWellPathExportCompletionDataFeatureImpl::assignSecondaryValveContributio } } - for (auto slaveValvePair : slaveValves) + for (auto regularValvePair : assignedRegularValves) { - if (slaveValvePair.second.size()) + if (regularValvePair.second.size()) { QStringList valveLabels; - for (std::pair slaveValve : slaveValvePair.second) + for (std::pair regularValve : regularValvePair.second) { - QString valveLabel = QString("%1 #%2").arg(slaveValve.first->name()).arg(slaveValve.second + 1); + QString valveLabel = QString("%1 #%2").arg(regularValve.first->name()).arg(regularValve.second + 1); valveLabels.push_back(valveLabel); } QString valveContribLabel = QString(" with contribution from: %1").arg(valveLabels.join(", ")); - slaveValvePair.first->setLabel(slaveValvePair.first->label() + valveContribLabel); + regularValvePair.first->setLabel(regularValvePair.first->label() + valveContribLabel); } } } @@ -2180,45 +2243,41 @@ void RicWellPathExportCompletionDataFeatureImpl::assignSecondaryValveContributio //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicWellPathExportCompletionDataFeatureImpl::ValveCompletionMap - RicWellPathExportCompletionDataFeatureImpl::assignPrimaryValveCompletions( - std::vector>& mainBoreSegments, - const std::vector& perforationIntervals) +void RicWellPathExportCompletionDataFeatureImpl::moveIntersectionsToSuperValves(MainBoreSegments mainBoreSegments) { - ValveCompletionMap primaryValveLocations; - - for (size_t nMainSegment = 0u; nMainSegment < mainBoreSegments.size(); ++nMainSegment) + for (auto segmentPtr : mainBoreSegments) { - std::shared_ptr segment = mainBoreSegments[nMainSegment]; - - std::shared_ptr valveCompletion; - for (const RimPerforationInterval* interval : perforationIntervals) + std::shared_ptr superValve; + std::vector> perforations; + for (auto completionPtr : segmentPtr->completions()) { - std::vector perforationValves; - interval->descendantsIncludingThisOfType(perforationValves); - - for (const RimWellPathValve* valve : perforationValves) + if (completionPtr->completionType() == RigCompletionData::PERFORATION_ICD) { - for (size_t nSubValve = 0u; nSubValve < valve->valveLocations().size(); ++nSubValve) + superValve = completionPtr; + } + else + { + CVF_ASSERT(completionPtr->completionType() == RigCompletionData::PERFORATION); + perforations.push_back(completionPtr); + } + } + + if (superValve == nullptr) continue; + + CVF_ASSERT(superValve->subSegments().size() == 1u); + segmentPtr->completions().clear(); + segmentPtr->addCompletion(superValve); + for (auto perforationPtr : perforations) + { + for (auto subSegmentPtr : perforationPtr->subSegments()) + { + for (auto intersectionPtr : subSegmentPtr->intersections()) { - double valveMD = valve->valveLocations()[nSubValve]; - if (segment->startMD() <= valveMD && valveMD < segment->endMD()) - { - QString valveLabel = QString("%1 #%2").arg("Combined Valve for segment").arg(nMainSegment + 2); - if (!valveCompletion) - { - valveCompletion.reset(new RicMswCompletion(RigCompletionData::PERFORATION_ICD, valveLabel)); - std::shared_ptr valveSegment(new RicMswSubSegment(valveMD, 0.1, 0.0, 0.0)); - valveCompletion->addSubSegment(valveSegment); - segment->addCompletion(valveCompletion); - } - primaryValveLocations[std::make_pair(valve, nSubValve)] = valveCompletion; - } + superValve->subSegments()[0]->addIntersection(intersectionPtr); } } } } - return primaryValveLocations; } //-------------------------------------------------------------------------------------------------- @@ -2348,7 +2407,10 @@ void RicWellPathExportCompletionDataFeatureImpl::assignPerforationIntervalInters { size_t currCellId = cellIntInfo.globCellIndex; - std::shared_ptr subSegment(new RicMswSubSegment(cellIntInfo.startMD, cellIntInfo.endMD, cellIntInfo.startTVD, cellIntInfo.endTVD)); + std::shared_ptr subSegment(new RicMswSubSegment(cellIntInfo.startMD, + cellIntInfo.endMD - cellIntInfo.startMD, + cellIntInfo.startTVD, + cellIntInfo.endTVD - cellIntInfo.startTVD)); for (const RigCompletionData& compIntersection : completionData) { const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell(); diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h index 7f8fd4cbf9..a461ac0802 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h @@ -189,7 +189,6 @@ public: private: typedef std::vector> MainBoreSegments; - typedef std::map, std::shared_ptr> ValveCompletionMap; typedef std::map , std::set>> ValveContributionMap; static MainBoreSegments createMainBoreSegments(const std::vector& subSegIntersections, @@ -198,13 +197,14 @@ private: const RicExportCompletionDataSettingsUi& exportSettings, bool* foundSubGridIntersections); - static ValveCompletionMap assignPrimaryValveCompletions(std::vector>& mainBoreSegments, - const std::vector& perforationIntervals); + static void assignSuperValveCompletions(std::vector>& mainBoreSegments, + const std::vector& perforationIntervals); - static void assignSecondaryValveContributions(std::vector>& mainBoreSegments, - const std::vector& perforationIntervals, - const ValveCompletionMap& primaryValveLocations, - RiaEclipseUnitTools::UnitSystem unitSystem); + static void assignValveContributionsToSuperValves(const std::vector>& mainBoreSegments, + const std::vector& perforationIntervals, + RiaEclipseUnitTools::UnitSystem unitSystem); + + static void moveIntersectionsToSuperValves(MainBoreSegments mainBoreSegments); static double calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase, double skinFactor, @@ -308,5 +308,5 @@ private: static void exportCarfinForTemporaryLgrs(const RimEclipseCase* sourceCase, const QString& folder); - static bool isCompletionWellPathEqual(const RigCompletionData& completion, const RimWellPath* wellPath); + static bool isCompletionWellPathEqual(const RigCompletionData& completion, const RimWellPath* wellPath); };