#3553 Temp LGR. Handle overlapping completions. LGR for each completions are sorted by completion type

This commit is contained in:
Bjørn Erik Jensen 2018-10-26 14:24:56 +02:00
parent 1b155ae71f
commit 04c07154b0
5 changed files with 146 additions and 55 deletions

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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;
}
//--------------------------------------------------------------------------------------------------

View File

@ -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));
}