mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3553 Temp LGR. Handle overlapping completions. LGR for each completions are sorted by completion type
This commit is contained in:
parent
1b155ae71f
commit
04c07154b0
@ -98,9 +98,8 @@ void RicfExportLgrForCompletions::execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
auto completionTypes = (RicExportLgrUi::CompletionType)(RicExportLgrUi::CT_PERFORATION | RicExportLgrUi::CT_FRACTURE | RicExportLgrUi::CT_FISHBONE);
|
||||
feature->exportLgrsForWellPath(exportFolder, wellPath, eclipseCase, m_timeStep, lgrCellCounts, m_splitType(),
|
||||
completionTypes);
|
||||
{RigCompletionData::PERFORATION, RigCompletionData::FRACTURE, RigCompletionData::FISHBONES});
|
||||
}
|
||||
catch(CreateLgrException e)
|
||||
{
|
||||
|
@ -60,11 +60,86 @@
|
||||
#include <cafVecIjk.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <QDebug>
|
||||
#include <array>
|
||||
#include <set>
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicExportLgrFeature, "RicExportLgrFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int completionPriority(const RigCompletionData& completion)
|
||||
{
|
||||
return completion.completionType() == RigCompletionData::FRACTURE ? 1 :
|
||||
completion.completionType() == RigCompletionData::FISHBONES ? 2 :
|
||||
completion.completionType() == RigCompletionData::PERFORATION ? 3 : 4;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RigCompletionData> filterCompletionsOnType(const std::vector<RigCompletionData>& completions,
|
||||
const std::set<RigCompletionData::CompletionType>& includedCompletionTypes)
|
||||
{
|
||||
std::vector<RigCompletionData> filtered;
|
||||
for (auto completion : completions)
|
||||
{
|
||||
if (includedCompletionTypes.count(completion.completionType()) > 0) filtered.push_back(completion);
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//bool completionIncluded(const caf::PdmObject* object,
|
||||
// RicExportLgrUi::CompletionType includedCompletionTypes)
|
||||
//{
|
||||
// if (dynamic_cast<const RimPerforationInterval*>(object) && (includedCompletionTypes & RicExportLgrUi::CT_PERFORATION))
|
||||
// return true;
|
||||
// else if (dynamic_cast<const RimFracture*>(object) && (includedCompletionTypes & RicExportLgrUi::CT_FRACTURE))
|
||||
// return true;
|
||||
// else if (dynamic_cast<const RimFishbonesMultipleSubs*>(object) && (includedCompletionTypes & RicExportLgrUi::CT_FISHBONE))
|
||||
// return true;
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString completionName(const caf::PdmObject* object)
|
||||
{
|
||||
auto perf = dynamic_cast<const RimPerforationInterval*>(object);
|
||||
auto frac = dynamic_cast<const RimFracture*>(object);
|
||||
auto fish = dynamic_cast<const RimFishbonesMultipleSubs*>(object);
|
||||
|
||||
QString name;
|
||||
if (perf) name = perf->name();
|
||||
else if (frac) name = frac->name();
|
||||
else if (fish) name = fish->generatedName();
|
||||
return name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the completion having highest priority.
|
||||
/// Pri: 1. Fractures, 2. Fishbones, 3. Perforation intervals
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigCompletionData findCompletionByPriority(const std::vector<RigCompletionData>& completions)
|
||||
{
|
||||
std::vector<RigCompletionData> sorted = completions;
|
||||
|
||||
std::sort(sorted.begin(), sorted.end(),
|
||||
[](const RigCompletionData& c1, const RigCompletionData& c2 )
|
||||
{
|
||||
if (completionPriority(c1) == completionPriority(c2))
|
||||
{
|
||||
return completionName(c1.sourcePdmObject()) < completionName(c2.sourcePdmObject());
|
||||
}
|
||||
return completionPriority(c1) < completionPriority(c2);
|
||||
});
|
||||
return sorted.front();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -197,7 +272,7 @@ void RicExportLgrFeature::exportLgrsForWellPath(const QString& export
|
||||
size_t timeStep,
|
||||
caf::VecIjk lgrCellCounts,
|
||||
RicExportLgrUi::SplitType splitType,
|
||||
RicExportLgrUi::CompletionType completionTypes)
|
||||
const std::set<RigCompletionData::CompletionType>& completionTypes)
|
||||
{
|
||||
std::vector<LgrInfo> lgrs;
|
||||
|
||||
@ -234,7 +309,7 @@ std::vector<LgrInfo> RicExportLgrFeature::buildLgrsForWellPath(RimWellPath*
|
||||
size_t timeStep,
|
||||
caf::VecIjk lgrCellCounts,
|
||||
RicExportLgrUi::SplitType splitType,
|
||||
RicExportLgrUi::CompletionType completionTypes)
|
||||
const std::set<RigCompletionData::CompletionType>& completionTypes)
|
||||
{
|
||||
std::vector<LgrInfo> lgrs;
|
||||
bool intersectsWithExistingLgr = false;
|
||||
@ -363,7 +438,7 @@ std::vector<RigCompletionDataGridCell>
|
||||
RicExportLgrFeature::cellsIntersectingCompletions(RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
size_t timeStep,
|
||||
RicExportLgrUi::CompletionType completionTypes)
|
||||
const std::set<RigCompletionData::CompletionType>& completionTypes)
|
||||
{
|
||||
std::vector<RigCompletionDataGridCell> cells;
|
||||
|
||||
@ -374,8 +449,9 @@ RicExportLgrFeature::cellsIntersectingCompletions(RimEclipseCase* eclipseCase,
|
||||
|
||||
for (auto intCell : intCells)
|
||||
{
|
||||
QString name = completionNameIfIncluded(intCell.second.front().sourcePdmObject(), completionTypes);
|
||||
if (name.isEmpty()) continue;
|
||||
auto filteredCompletions = filterCompletionsOnType(intCell.second, completionTypes);
|
||||
|
||||
if (filteredCompletions.empty()) continue;
|
||||
|
||||
cells.push_back(intCell.first);
|
||||
}
|
||||
@ -390,7 +466,7 @@ std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>
|
||||
RicExportLgrFeature::cellsIntersectingCompletions_PerCompletion(RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
size_t timeStep,
|
||||
RicExportLgrUi::CompletionType completionTypes)
|
||||
const std::set<RigCompletionData::CompletionType>& completionTypes)
|
||||
{
|
||||
std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>> completionToCells;
|
||||
|
||||
@ -398,16 +474,27 @@ std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>
|
||||
if (completions)
|
||||
{
|
||||
auto intCells = completions->multipleCompletionsPerEclipseCell(wellPath, timeStep);
|
||||
CompletionInfo lastCompletionInfo;
|
||||
|
||||
// This loop assumes that cells are ordered downwards along well path
|
||||
for (auto intCell : intCells)
|
||||
{
|
||||
QString name = completionNameIfIncluded(intCell.second.front().sourcePdmObject(), completionTypes);
|
||||
if (name.isEmpty()) continue;
|
||||
auto filteredCompletions = filterCompletionsOnType(intCell.second, completionTypes);
|
||||
if (filteredCompletions.empty()) continue;
|
||||
|
||||
for (auto completion : intCell.second)
|
||||
auto completion = findCompletionByPriority(filteredCompletions);
|
||||
|
||||
QString name = completionName(completion.sourcePdmObject());
|
||||
CompletionInfo completionInfo(completion.completionType(), name, 0);
|
||||
|
||||
if (!lastCompletionInfo.isValid()) lastCompletionInfo = completionInfo;
|
||||
|
||||
if (completionInfo != lastCompletionInfo && completionToCells.count(completionInfo) > 0)
|
||||
{
|
||||
completionToCells[CompletionInfo(completion.completionType(), name)].push_back(intCell.first);
|
||||
completionInfo.number++;
|
||||
}
|
||||
completionToCells[completionInfo].push_back(intCell.first);
|
||||
lastCompletionInfo = completionInfo;
|
||||
}
|
||||
}
|
||||
return completionToCells;
|
||||
@ -535,22 +622,3 @@ int RicExportLgrFeature::firstAvailableLgrId(const RigMainGrid* mainGrid)
|
||||
return lastUsedId + 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RicExportLgrFeature::completionNameIfIncluded(const caf::PdmObject* object,
|
||||
RicExportLgrUi::CompletionType includedCompletionTypes)
|
||||
{
|
||||
auto perf = dynamic_cast<const RimPerforationInterval*>(object);
|
||||
auto frac = dynamic_cast<const RimFracture*>(object);
|
||||
auto fish = dynamic_cast<const RimFishbonesMultipleSubs*>(object);
|
||||
|
||||
QString name;
|
||||
if (perf && (includedCompletionTypes & RicExportLgrUi::CT_PERFORATION))
|
||||
name = perf->name();
|
||||
else if (frac && (includedCompletionTypes & RicExportLgrUi::CT_FRACTURE))
|
||||
name = frac->name();
|
||||
else if (fish && (includedCompletionTypes & RicExportLgrUi::CT_FISHBONE))
|
||||
name = fish->generatedName();
|
||||
return name;
|
||||
}
|
||||
|
@ -89,15 +89,43 @@ public:
|
||||
class CompletionInfo
|
||||
{
|
||||
public:
|
||||
CompletionInfo(RigCompletionData::CompletionType type, QString name)
|
||||
: type(type), name(name) {}
|
||||
CompletionInfo()
|
||||
: type(RigCompletionData::CT_UNDEFINED), name(""), number(-1) {}
|
||||
CompletionInfo(RigCompletionData::CompletionType type, QString name, int number)
|
||||
: type(type), name(name), number(number) {}
|
||||
|
||||
RigCompletionData::CompletionType type;
|
||||
QString name;
|
||||
int number;
|
||||
|
||||
bool isValid() const { return type != RigCompletionData::CT_UNDEFINED && !name.isEmpty() && number >= 0; }
|
||||
|
||||
int priority() const
|
||||
{
|
||||
return type == RigCompletionData::FRACTURE ? 1 :
|
||||
type == RigCompletionData::FISHBONES ? 2 :
|
||||
type == RigCompletionData::PERFORATION ? 3 : 4;
|
||||
}
|
||||
|
||||
// Sort by priority, then name, then number
|
||||
bool operator<(const CompletionInfo& other) const
|
||||
{
|
||||
return type < other.type || name < other.name;
|
||||
if (priority() == other.priority())
|
||||
{
|
||||
if (name == other.name) return number < other.number;
|
||||
return name < other.name;
|
||||
}
|
||||
return priority() < other.priority();
|
||||
}
|
||||
|
||||
bool operator==(const CompletionInfo& other) const
|
||||
{
|
||||
return type == other.type && name == other.name && number == other.number;
|
||||
}
|
||||
|
||||
bool operator!=(const CompletionInfo& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
@ -122,14 +150,14 @@ class RicExportLgrFeature : public caf::CmdFeature
|
||||
size_t timeStep,
|
||||
caf::VecIjk lgrCellCounts,
|
||||
RicExportLgrUi::SplitType splitType,
|
||||
RicExportLgrUi::CompletionType completionTypes);
|
||||
const std::set<RigCompletionData::CompletionType>& completionTypes);
|
||||
|
||||
static std::vector<LgrInfo> buildLgrsForWellPath(RimWellPath* wellPath,
|
||||
RimEclipseCase* eclipseCase,
|
||||
size_t timeStep,
|
||||
caf::VecIjk lgrCellCounts,
|
||||
RicExportLgrUi::SplitType splitType,
|
||||
RicExportLgrUi::CompletionType completionTypes);
|
||||
const std::set<RigCompletionData::CompletionType>& completionTypes);
|
||||
|
||||
static std::vector<RimWellPath*> selectedWellPaths();
|
||||
|
||||
@ -156,15 +184,14 @@ private:
|
||||
static std::vector<RigCompletionDataGridCell> cellsIntersectingCompletions(RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
size_t timeStep,
|
||||
RicExportLgrUi::CompletionType completionTypes);
|
||||
const std::set<RigCompletionData::CompletionType>& completionTypes);
|
||||
static std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>
|
||||
cellsIntersectingCompletions_PerCompletion(RimEclipseCase* eclipseCase,
|
||||
const RimWellPath* wellPath,
|
||||
size_t timeStep,
|
||||
RicExportLgrUi::CompletionType completionTypes);
|
||||
const std::set<RigCompletionData::CompletionType>& completionTypes);
|
||||
|
||||
static bool containsAnyNonMainGridCells(const std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>& cellsPerCompletion);
|
||||
static bool containsAnyNonMainGridCells(const std::vector<RigCompletionDataGridCell>& cells);
|
||||
static int firstAvailableLgrId(const RigMainGrid* mainGrid);
|
||||
static QString completionNameIfIncluded(const caf::PdmObject* object, RicExportLgrUi::CompletionType includedCompletionTypes);
|
||||
};
|
||||
|
@ -137,13 +137,13 @@ int RicExportLgrUi::timeStep() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicExportLgrUi::CompletionType RicExportLgrUi::completionTypes() const
|
||||
std::set<RigCompletionData::CompletionType> RicExportLgrUi::completionTypes() const
|
||||
{
|
||||
CompletionType ct = CT_NONE;
|
||||
if (m_includePerforations()) ct = ct | CompletionType::CT_PERFORATION;
|
||||
if (m_includeFractures()) ct = ct | CompletionType::CT_FRACTURE;
|
||||
if (m_includeFishbones()) ct = ct | CompletionType::CT_FISHBONE;
|
||||
return ct;
|
||||
std::set<RigCompletionData::CompletionType> cts;
|
||||
if (m_includePerforations()) cts.insert(RigCompletionData::PERFORATION);
|
||||
if (m_includeFractures()) cts.insert(RigCompletionData::FRACTURE);
|
||||
if (m_includeFishbones()) cts.insert(RigCompletionData::FISHBONES);
|
||||
return cts;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RigCompletionData.h"
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
@ -26,6 +28,8 @@
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include <set>
|
||||
|
||||
class RimEclipseCase;
|
||||
class RicCellRangeUi;
|
||||
|
||||
@ -44,8 +48,6 @@ public:
|
||||
enum SplitType { LGR_PER_CELL, LGR_PER_COMPLETION, LGR_PER_WELL};
|
||||
typedef caf::AppEnum<RicExportLgrUi::SplitType> LgrSplitTypeEnum;
|
||||
|
||||
enum CompletionType {CT_NONE = 0x0, CT_PERFORATION = 0x1, CT_FRACTURE = 0x2, CT_FISHBONE = 0x4};
|
||||
|
||||
RicExportLgrUi();
|
||||
|
||||
void setCase(RimEclipseCase* rimCase);
|
||||
@ -55,7 +57,7 @@ public:
|
||||
QString exportFolder() const;
|
||||
RimEclipseCase* caseToApply() const;
|
||||
int timeStep() const;
|
||||
CompletionType completionTypes() const;
|
||||
std::set<RigCompletionData::CompletionType> completionTypes() const;
|
||||
SplitType splitType() const;
|
||||
|
||||
void hideExportFolderField(bool hide);
|
||||
@ -84,8 +86,3 @@ private:
|
||||
|
||||
caf::PdmField<LgrSplitTypeEnum> m_splitType;
|
||||
};
|
||||
|
||||
inline RicExportLgrUi::CompletionType operator|(RicExportLgrUi::CompletionType a, RicExportLgrUi::CompletionType b)
|
||||
{
|
||||
return static_cast<RicExportLgrUi::CompletionType>(static_cast<int>(a) | static_cast<int>(b));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user