#3515 LGR Export/Temp LGR. New split type: One LGR per Completion

This commit is contained in:
Bjørn Erik Jensen
2018-10-23 11:13:12 +02:00
parent cdda4d74df
commit ffa1a85187
15 changed files with 358 additions and 127 deletions

View File

@@ -41,18 +41,6 @@
CAF_PDM_SOURCE_INIT(RicfExportLgrForCompletions, "exportLgrForCompletions"); CAF_PDM_SOURCE_INIT(RicfExportLgrForCompletions, "exportLgrForCompletions");
namespace caf
{
template<>
void RicfExportLgrForCompletions::LgrSplitType::setUp()
{
addItem(ExportLgr::ONE_LGR_PER_GRID_CELL, "ONE_LGR_PER_GRID_CELL", "One LGR per Main Grid Cell");
addItem(ExportLgr::SINGLE_LGR_ALL_GRID_CELLS, "SINGLE_LGR_ALL_GRID_CELLS", "One Single LGR for all Main Grid Cells");
setDefault(ExportLgr::NONE);
}
} // namespace caf
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -64,7 +52,7 @@ RicfExportLgrForCompletions::RicfExportLgrForCompletions()
RICF_InitField(&m_refinementI, "refinementI", -1, "RefinementI", "", "", ""); RICF_InitField(&m_refinementI, "refinementI", -1, "RefinementI", "", "", "");
RICF_InitField(&m_refinementJ, "refinementJ", -1, "RefinementJ", "", "", ""); RICF_InitField(&m_refinementJ, "refinementJ", -1, "RefinementJ", "", "", "");
RICF_InitField(&m_refinementK, "refinementK", -1, "RefinementK", "", "", ""); RICF_InitField(&m_refinementK, "refinementK", -1, "RefinementK", "", "", "");
RICF_InitField(&m_splitType, "splitType", LgrSplitType(ExportLgr::ONE_LGR_PER_GRID_CELL), "SplitType", "", "", ""); RICF_InitField(&m_splitType, "splitType", LgrSplitType(), "SplitType", "", "", "");
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -107,7 +95,11 @@ void RicfExportLgrForCompletions::execute()
{ {
if (wellPath) if (wellPath)
{ {
if (!feature->exportLgrsForWellPath(exportFolder, wellPath, eclipseCase, m_timeStep, lgrCellCounts, m_splitType == ExportLgr::SINGLE_LGR_ALL_GRID_CELLS)) try
{
feature->exportLgrsForWellPath(exportFolder, wellPath, eclipseCase, m_timeStep, lgrCellCounts, m_splitType());
}
catch(CreateLgrException e)
{ {
lgrIntersected = true; lgrIntersected = true;
} }

View File

@@ -20,20 +20,13 @@
#include "RicfCommandObject.h" #include "RicfCommandObject.h"
#include "ExportCommands/RicExportLgrUi.h"
#include "cafAppEnum.h" #include "cafAppEnum.h"
#include "cafPdmField.h" #include "cafPdmField.h"
class RimWellPath; class RimWellPath;
namespace ExportLgr
{
enum SplitType
{
NONE,
ONE_LGR_PER_GRID_CELL,
SINGLE_LGR_ALL_GRID_CELLS
};
}
//================================================================================================== //==================================================================================================
// //
@@ -44,7 +37,7 @@ class RicfExportLgrForCompletions : public RicfCommandObject
{ {
CAF_PDM_HEADER_INIT; CAF_PDM_HEADER_INIT;
typedef caf::AppEnum<ExportLgr::SplitType> LgrSplitType; typedef caf::AppEnum<RicExportLgrUi::SplitType> LgrSplitType;
public: public:
RicfExportLgrForCompletions(); RicfExportLgrForCompletions();

View File

@@ -743,6 +743,7 @@ std::vector<RigCompletionData> RicExportFractureCompletionsImpl::generateCompdat
double diameter = 2.0 * fracture->wellRadius(); double diameter = 2.0 * fracture->wellRadius();
compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter); compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter);
compDat.addMetadata(fracture->name(), QString::number(trans)); compDat.addMetadata(fracture->name(), QString::number(trans));
compDat.setSourcePdmObject(fracture);
allCompletionsForOneFracture.push_back(compDat); allCompletionsForOneFracture.push_back(compDat);
} }

View File

@@ -36,6 +36,9 @@
#include "RimWellPath.h" #include "RimWellPath.h"
#include "RimWellPathCompletions.h" #include "RimWellPathCompletions.h"
#include <cafPdmObject.h>
#include <cafPdmPointer.h>
//================================================================================================== //==================================================================================================
/// ///
//================================================================================================== //==================================================================================================
@@ -60,6 +63,9 @@ struct WellBorePartForTransCalc
double intersectionWithWellMeasuredDepth; double intersectionWithWellMeasuredDepth;
size_t lateralIndex; size_t lateralIndex;
void setSourcePdmObject(const caf::PdmObject* sourcePdmObj) { this->sourcePdmObject = const_cast<caf::PdmObject*>(sourcePdmObj); }
caf::PdmPointer<caf::PdmObject> sourcePdmObject;
}; };
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -161,7 +167,7 @@ std::vector<RigCompletionData>
transmissibility, wellBorePart.skinFactor, wellBorePart.wellRadius * 2, direction, wellBorePart.isMainBore); transmissibility, wellBorePart.skinFactor, wellBorePart.wellRadius * 2, direction, wellBorePart.isMainBore);
completion.addMetadata(wellBorePart.metaData, QString::number(transmissibility)); completion.addMetadata(wellBorePart.metaData, QString::number(transmissibility));
completion.setSourcePdmObject(wellBorePart.sourcePdmObject);
completionData.push_back(completion); completionData.push_back(completion);
} }
} }
@@ -203,6 +209,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell
wellBorePart.intersectionWithWellMeasuredDepth = location.endMD(); wellBorePart.intersectionWithWellMeasuredDepth = location.endMD();
wellBorePart.lateralIndex = completion.index(); wellBorePart.lateralIndex = completion.index();
wellBorePart.setSourcePdmObject(location.sourcePdmObject());
wellBorePartsInCells[intersection.globalCellIndex()].push_back(wellBorePart); wellBorePartsInCells[intersection.globalCellIndex()].push_back(wellBorePart);
} }
@@ -231,7 +238,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWell
endMD += 0.5; endMD += 0.5;
} }
appendMainWellBoreParts(wellBorePartsInCells, wellPath, settings, skinFactor, holeRadius, startMD, endMD); appendMainWellBoreParts(wellBorePartsInCells, wellPath, settings, skinFactor, holeRadius, startMD, endMD, fishboneDefinition);
} }
} }
} }
@@ -290,7 +297,8 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts(
double skinFactor, double skinFactor,
double holeRadius, double holeRadius,
double startMeasuredDepth, double startMeasuredDepth,
double endMeasuredDepth) double endMeasuredDepth,
const RimFishbonesMultipleSubs* fishbonesDefintions)
{ {
if (!wellPath) return; if (!wellPath) return;
if (!wellPath->wellPathGeometry()) return; if (!wellPath->wellPathGeometry()) return;
@@ -299,7 +307,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts(
bool isMainBore = true; bool isMainBore = true;
std::pair<std::vector<cvf::Vec3d>, std::vector<double>> fishbonePerfWellPathCoords = std::pair<std::vector<cvf::Vec3d>, std::vector<double>> fishbonePerfWellPathCoords =
wellPath->wellPathGeometry()->clippedPointSubset(startMeasuredDepth, endMeasuredDepth); wellPath->wellPathGeometry()->clippedPointSubset(startMeasuredDepth, endMeasuredDepth);
std::vector<WellPathCellIntersectionInfo> intersectedCellsIntersectionInfo = std::vector<WellPathCellIntersectionInfo> intersectedCellsIntersectionInfo =
RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath( RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(
@@ -313,6 +321,7 @@ void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts(
wellBorePart.intersectionWithWellMeasuredDepth = cellIntersectionInfo.startMD; wellBorePart.intersectionWithWellMeasuredDepth = cellIntersectionInfo.startMD;
wellBorePart.setSourcePdmObject(fishbonesDefintions);
wellBorePartsInCells[cellIntersectionInfo.globCellIndex].push_back(wellBorePart); wellBorePartsInCells[cellIntersectionInfo.globCellIndex].push_back(wellBorePart);
} }
} }

View File

@@ -27,6 +27,7 @@
class RigCompletionData; class RigCompletionData;
class RimWellPath; class RimWellPath;
class RimFishbonesMultipleSubs;
class RicExportCompletionDataSettingsUi; class RicExportCompletionDataSettingsUi;
class RigEclipseCaseData; class RigEclipseCaseData;
@@ -58,5 +59,6 @@ private:
double skinFactor, double skinFactor,
double holeRadius, double holeRadius,
double startMeasuredDepth, double startMeasuredDepth,
double endMeasuredDepth); double endMeasuredDepth,
const RimFishbonesMultipleSubs* fishbonesDefintions);
}; };

View File

@@ -459,6 +459,22 @@ void RicMswSegment::addCompletion(const RicMswCompletion& completion)
m_completions.push_back(completion); m_completions.push_back(completion);
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswSegment::setSourcePdmObject(const caf::PdmObject* object)
{
m_sourcePdmObject = const_cast<caf::PdmObject*>(object);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::PdmObject* RicMswSegment::sourcePdmObject() const
{
return m_sourcePdmObject;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -161,6 +161,9 @@ public:
void setSegmentNumber(int segmentNumber); void setSegmentNumber(int segmentNumber);
void addCompletion(const RicMswCompletion& completion); void addCompletion(const RicMswCompletion& completion);
void setSourcePdmObject(const caf::PdmObject* object);
const caf::PdmObject* sourcePdmObject() const;
bool operator<(const RicMswSegment& rhs) const; bool operator<(const RicMswSegment& rhs) const;
private: private:
@@ -181,6 +184,8 @@ private:
int m_segmentNumber; int m_segmentNumber;
std::vector<RicMswCompletion> m_completions; std::vector<RicMswCompletion> m_completions;
caf::PdmPointer<caf::PdmObject> m_sourcePdmObject;
}; };
class RicMswExportInfo class RicMswExportInfo

View File

@@ -1708,6 +1708,7 @@ std::vector<RigCompletionData> RicWellPathExportCompletionDataFeatureImpl::gener
completion.addMetadata("Perforation Completion", completion.addMetadata("Perforation Completion",
QString("MD In: %1 - MD Out: %2").arg(cell.startMD).arg(cell.endMD) + QString("MD In: %1 - MD Out: %2").arg(cell.startMD).arg(cell.endMD) +
QString(" Transmissibility: ") + QString::number(transmissibility)); QString(" Transmissibility: ") + QString::number(transmissibility));
completion.setSourcePdmObject(interval);
completionData.push_back(completion); completionData.push_back(completion);
} }
} }
@@ -1775,6 +1776,7 @@ RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMs
location.setIcdFlowCoefficient(subs->icdFlowCoefficient()); location.setIcdFlowCoefficient(subs->icdFlowCoefficient());
double icdOrificeRadius = subs->icdOrificeDiameter(unitSystem) / 2; double icdOrificeRadius = subs->icdOrificeDiameter(unitSystem) / 2;
location.setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount()); location.setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount());
location.setSourcePdmObject(subs);
if (ssi == 0) if (ssi == 0)
{ {

View File

@@ -42,6 +42,10 @@
#include "RiuPlotMainWindow.h" #include "RiuPlotMainWindow.h"
#include "RimPerforationInterval.h"
#include "RimFracture.h"
#include "RimFishbonesMultipleSubs.h"
#include <QAction> #include <QAction>
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>
@@ -57,6 +61,8 @@
#include <limits> #include <limits>
#include <QDebug>
CAF_CMD_SOURCE_INIT(RicExportLgrFeature, "RicExportLgrFeature"); CAF_CMD_SOURCE_INIT(RicExportLgrFeature, "RicExportLgrFeature");
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -185,71 +191,140 @@ void RicExportLgrFeature::exportLgrs(QTextStream& stream, const std::vector<LgrI
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RicExportLgrFeature::exportLgrsForWellPath(const QString& exportFolder, void RicExportLgrFeature::exportLgrsForWellPath(const QString& exportFolder,
RimWellPath* wellPath, RimWellPath* wellPath,
RimEclipseCase* eclipseCase, RimEclipseCase* eclipseCase,
size_t timeStep, size_t timeStep,
caf::VecIjk lgrCellCounts, caf::VecIjk lgrCellCounts,
bool oneSingleLgr) RicExportLgrUi::SplitType splitType)
{ {
auto intersectingCells = cellsIntersectingCompletions(eclipseCase, wellPath, timeStep);
if (containsAnyNonMainGridCells(intersectingCells))
{
return false;
}
std::vector<LgrInfo> lgrs; std::vector<LgrInfo> lgrs;
if (oneSingleLgr)
lgrs = buildSingleLgr(eclipseCase, intersectingCells, lgrCellCounts); try
else {
lgrs = buildOneLgrPerMainCell(eclipseCase, intersectingCells, lgrCellCounts); lgrs = buildLgrsForWellPath(wellPath,
eclipseCase,
timeStep,
lgrCellCounts,
splitType);
// Export // Export
QFile file; QFile file;
QString fileName = caf::Utils::makeValidFileBasename(QString("LGR_%1").arg(wellPath->name())) + ".dat"; QString fileName = caf::Utils::makeValidFileBasename(QString("LGR_%1").arg(wellPath->name())) + ".dat";
openFileForExport(exportFolder, fileName, &file); openFileForExport(exportFolder, fileName, &file);
QTextStream stream(&file); QTextStream stream(&file);
stream.setRealNumberNotation(QTextStream::FixedNotation); stream.setRealNumberNotation(QTextStream::FixedNotation);
stream.setRealNumberPrecision(2); stream.setRealNumberPrecision(2);
exportLgrs(stream, lgrs); exportLgrs(stream, lgrs);
file.close(); file.close();
return true; }
catch (CreateLgrException e)
{
throw;
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<LgrInfo> RicExportLgrFeature::buildOneLgrPerMainCell(RimEclipseCase* eclipseCase, std::vector<LgrInfo> RicExportLgrFeature::buildLgrsForWellPath(RimWellPath* wellPath,
const std::vector<RigCompletionDataGridCell>& intersectingCells, RimEclipseCase* eclipseCase,
const caf::VecIjk& lgrSizes) size_t timeStep,
caf::VecIjk lgrCellCounts,
RicExportLgrUi::SplitType splitType)
{ {
std::vector<LgrInfo> lgrs; std::vector<LgrInfo> lgrs;
int firstLgrId = firstAvailableLgrId(eclipseCase->mainGrid()); bool intersectsWithExistingLgr = false;
int lgrCount = 0; if (splitType == RicExportLgrUi::LGR_PER_CELL)
for (const auto& intersectingCell : intersectingCells)
{ {
caf::VecIjk mainGridFirstCell(intersectingCell.localCellIndexI(), auto intersectingCells = cellsIntersectingCompletions(eclipseCase, wellPath, timeStep);
intersectingCell.localCellIndexJ(),
intersectingCell.localCellIndexK());
caf::VecIjk mainGridEndCell(intersectingCell.localCellIndexI(),
intersectingCell.localCellIndexJ(),
intersectingCell.localCellIndexK());
int currLgrId = firstLgrId + lgrCount++; if (containsAnyNonMainGridCells(intersectingCells))
LgrInfo lgrInfo(currLgrId, QString("LGR_%1").arg(currLgrId), lgrSizes, mainGridFirstCell, mainGridEndCell); {
lgrs.push_back(lgrInfo); intersectsWithExistingLgr = true;
}
else
{
lgrs = buildLgrsPerMainCell(eclipseCase, intersectingCells, lgrCellCounts);
}
}
else if (splitType == RicExportLgrUi::LGR_PER_COMPLETION)
{
auto intersectingCells = cellsIntersectingCompletions_PerCompletion(eclipseCase, wellPath, timeStep);
if (containsAnyNonMainGridCells(intersectingCells))
{
intersectsWithExistingLgr = true;
}
else
{
lgrs = buildLgrsPerCompletion(eclipseCase, intersectingCells, lgrCellCounts);
}
}
else if (splitType == RicExportLgrUi::LGR_PER_WELL)
{
auto intersectingCells = cellsIntersectingCompletions(eclipseCase, wellPath, timeStep);
if (containsAnyNonMainGridCells(intersectingCells))
{
intersectsWithExistingLgr = true;
}
else
{
int lgrId = firstAvailableLgrId(eclipseCase->mainGrid());
lgrs.push_back(buildLgr(lgrId, eclipseCase, intersectingCells, lgrCellCounts));
}
} }
if (intersectsWithExistingLgr)
{
throw CreateLgrException("At least one completion intersects with an existing LGR");
}
return lgrs; return lgrs;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<LgrInfo> RicExportLgrFeature::buildSingleLgr(RimEclipseCase* eclipseCase, std::vector<LgrInfo> RicExportLgrFeature::buildLgrsPerMainCell(RimEclipseCase* eclipseCase,
const std::vector<RigCompletionDataGridCell>& intersectingCells, const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizesPerMainGridCell) const caf::VecIjk& lgrSizes)
{
std::vector<LgrInfo> lgrs;
int lgrId = firstAvailableLgrId(eclipseCase->mainGrid());
for (auto intersectionCell : intersectingCells)
{
lgrs.push_back(buildLgr(lgrId++, eclipseCase, { intersectionCell }, lgrSizes));
}
return lgrs;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<LgrInfo> RicExportLgrFeature::buildLgrsPerCompletion(RimEclipseCase* eclipseCase,
const std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>& intersectingCells,
const caf::VecIjk& lgrSizesPerMainGridCell)
{
std::vector<LgrInfo> lgrs;
int lgrId = firstAvailableLgrId(eclipseCase->mainGrid());
for (auto intersectionInfo : intersectingCells)
{
lgrs.push_back(buildLgr(lgrId++, eclipseCase, intersectionInfo.second, lgrSizesPerMainGridCell));
}
return lgrs;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LgrInfo RicExportLgrFeature::buildLgr(int lgrId,
RimEclipseCase* eclipseCase,
const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizesPerMainGridCell)
{ {
std::vector<LgrInfo> lgrs; std::vector<LgrInfo> lgrs;
@@ -268,25 +343,22 @@ std::vector<LgrInfo> RicExportLgrFeature::buildSingleLgr(RimEclipseCase* eclipse
kRange.second = std::max(cell.localCellIndexK(), kRange.second); kRange.second = std::max(cell.localCellIndexK(), kRange.second);
} }
int lgrId = firstAvailableLgrId(eclipseCase->mainGrid());
caf::VecIjk lgrSizes((iRange.second - iRange.first + 1) * lgrSizesPerMainGridCell.i(), caf::VecIjk lgrSizes((iRange.second - iRange.first + 1) * lgrSizesPerMainGridCell.i(),
(jRange.second - jRange.first + 1) * lgrSizesPerMainGridCell.j(), (jRange.second - jRange.first + 1) * lgrSizesPerMainGridCell.j(),
(kRange.second - kRange.first + 1) * lgrSizesPerMainGridCell.k()); (kRange.second - kRange.first + 1) * lgrSizesPerMainGridCell.k());
caf::VecIjk mainGridStartCell(iRange.first, jRange.first, kRange.first); caf::VecIjk mainGridStartCell(iRange.first, jRange.first, kRange.first);
caf::VecIjk mainGridEndCell(iRange.second, jRange.second, kRange.second); caf::VecIjk mainGridEndCell(iRange.second, jRange.second, kRange.second);
LgrInfo lgrInfo(lgrId, QString("LGR_%1").arg(lgrId), lgrSizes, mainGridStartCell, mainGridEndCell); return LgrInfo(lgrId, QString("LGR_%1").arg(lgrId), lgrSizes, mainGridStartCell, mainGridEndCell);
lgrs.push_back(lgrInfo);
return lgrs;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RigCompletionDataGridCell> RicExportLgrFeature::cellsIntersectingCompletions(RimEclipseCase* eclipseCase, std::vector<RigCompletionDataGridCell>
const RimWellPath* wellPath, RicExportLgrFeature::cellsIntersectingCompletions(RimEclipseCase* eclipseCase,
size_t timeStep) const RimWellPath* wellPath,
size_t timeStep)
{ {
std::vector<RigCompletionDataGridCell> cells; std::vector<RigCompletionDataGridCell> cells;
@@ -303,6 +375,47 @@ std::vector<RigCompletionDataGridCell> RicExportLgrFeature::cellsIntersectingCom
return cells; return cells;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>
RicExportLgrFeature::cellsIntersectingCompletions_PerCompletion(RimEclipseCase* eclipseCase,
const RimWellPath* wellPath,
size_t timeStep)
{
std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>> completionToCells;
auto completions = eclipseCase->computeAndGetVirtualPerforationTransmissibilities();
if (completions)
{
auto intCells = completions->multipleCompletionsPerEclipseCell(wellPath, timeStep);
for (auto intCell : intCells)
{
auto pdmSrcObj = intCell.second.front().sourcePdmObject();
auto perf = dynamic_cast<const RimPerforationInterval*>(pdmSrcObj);
auto frac = dynamic_cast<const RimFracture*>(pdmSrcObj);
auto fish = dynamic_cast<const RimFishbonesMultipleSubs*>(pdmSrcObj);
QString name;
if (perf)
name = perf->name();
else if (frac)
name = frac->name();
else if (fish)
name = fish->generatedName();
if (name.isEmpty()) continue;
for (auto compl : intCell.second)
{
completionToCells[CompletionInfo(compl.completionType(), name)].push_back(intCell.first);
}
}
}
return completionToCells;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -339,16 +452,20 @@ void RicExportLgrFeature::onActionTriggered(bool isChecked)
auto lgrCellCounts = dialogData->lgrCellCount(); auto lgrCellCounts = dialogData->lgrCellCount();
size_t timeStep = dialogData->timeStep(); size_t timeStep = dialogData->timeStep();
bool lgrIntersected = false; bool intersectsExistingLgr = false;
for (const auto& wellPath : wellPaths) for (const auto& wellPath : wellPaths)
{ {
if (!exportLgrsForWellPath(dialogData->exportFolder(), wellPath, eclipseCase, timeStep, lgrCellCounts, dialogData->singleLgrSplit())) try
{ {
lgrIntersected = true; exportLgrsForWellPath(dialogData->exportFolder(), wellPath, eclipseCase, timeStep, lgrCellCounts, dialogData->splitType());
}
catch(CreateLgrException e)
{
intersectsExistingLgr = true;
} }
} }
if (lgrIntersected) if (intersectsExistingLgr)
{ {
QMessageBox::warning(nullptr, "LGR cells intersected", "At least one completion intersects with an LGR. No output for those completions produced"); QMessageBox::warning(nullptr, "LGR cells intersected", "At least one completion intersects with an LGR. No output for those completions produced");
} }
@@ -381,6 +498,19 @@ std::vector<RimWellPath*> RicExportLgrFeature::selectedWellPaths()
return wellPaths; return wellPaths;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicExportLgrFeature::containsAnyNonMainGridCells(
const std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>& cellsPerCompletion)
{
for (auto cells : cellsPerCompletion)
{
if (containsAnyNonMainGridCells(cells.second)) return true;
}
return false;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -19,6 +19,10 @@
#pragma once #pragma once
#include "RigCompletionDataGridCell.h" #include "RigCompletionDataGridCell.h"
#include "RigCompletionData.h"
#include "RicExportLgrUi.h"
#include "cafCmdFeature.h" #include "cafCmdFeature.h"
#include <cafVecIjk.h> #include <cafVecIjk.h>
#include <memory> #include <memory>
@@ -27,10 +31,21 @@
class RimEclipseCase; class RimEclipseCase;
class RimSimWellInView; class RimSimWellInView;
class RimWellPath; class RimWellPath;
class RicExportLgrUi;
class QFile; class QFile;
class QTextStream; class QTextStream;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class CreateLgrException
{
public:
CreateLgrException(const QString& message)
: message(message)
{
}
QString message;
};
//================================================================================================== //==================================================================================================
/// ///
@@ -73,6 +88,24 @@ public:
caf::VecIjk mainGridEndCell; caf::VecIjk mainGridEndCell;
}; };
//==================================================================================================
///
//==================================================================================================
class CompletionInfo
{
public:
CompletionInfo(RigCompletionData::CompletionType type, QString name)
: type(type), name(name) {}
RigCompletionData::CompletionType type;
QString name;
bool operator<(const CompletionInfo& other) const
{
return type < other.type || name < other.name;
}
};
//================================================================================================== //==================================================================================================
/// ///
//================================================================================================== //==================================================================================================
@@ -85,23 +118,18 @@ class RicExportLgrFeature : public caf::CmdFeature
static RicExportLgrUi* openDialog(const QString& dialogTitle, RimEclipseCase* defaultCase = nullptr, int defaultTimeStep = 0); static RicExportLgrUi* openDialog(const QString& dialogTitle, RimEclipseCase* defaultCase = nullptr, int defaultTimeStep = 0);
static bool openFileForExport(const QString& folderName, const QString& fileName, QFile* exportFile); static bool openFileForExport(const QString& folderName, const QString& fileName, QFile* exportFile);
static void exportLgrs(QTextStream& stream, const std::vector<LgrInfo>& lgrInfos); static void exportLgrsForWellPath(const QString& exportFolder,
static bool exportLgrsForWellPath(const QString& exportFolder,
RimWellPath* wellPath, RimWellPath* wellPath,
RimEclipseCase* eclipseCase, RimEclipseCase* eclipseCase,
size_t timeStep, size_t timeStep,
caf::VecIjk lgrCellCounts, caf::VecIjk lgrCellCounts,
bool oneSingleLgr); RicExportLgrUi::SplitType splitType);
static std::vector<LgrInfo> buildOneLgrPerMainCell(RimEclipseCase* eclipseCase,
const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizes);
static std::vector<LgrInfo> buildSingleLgr(RimEclipseCase* eclipseCase,
const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizesPerMainGridCell);
static std::vector<RigCompletionDataGridCell> cellsIntersectingCompletions(RimEclipseCase* eclipseCase, static std::vector<LgrInfo> buildLgrsForWellPath(RimWellPath* wellPath,
const RimWellPath* wellPath, RimEclipseCase* eclipseCase,
size_t timeStep); size_t timeStep,
caf::VecIjk lgrCellCounts,
RicExportLgrUi::SplitType splitType);
protected: protected:
bool isCommandEnabled() override; bool isCommandEnabled() override;
@@ -109,7 +137,26 @@ protected:
void setupActionLook(QAction* actionToSetup) override; void setupActionLook(QAction* actionToSetup) override;
private: private:
static void exportLgrs(QTextStream& stream, const std::vector<LgrInfo>& lgrInfos);
static std::vector<LgrInfo> buildLgrsPerMainCell(RimEclipseCase* eclipseCase,
const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizes);
static std::vector<LgrInfo>
buildLgrsPerCompletion(RimEclipseCase* eclipseCase,
const std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>& intersectingCells,
const caf::VecIjk& lgrSizesPerMainGridCell);
static LgrInfo buildLgr(int lgrId,
RimEclipseCase* eclipseCase,
const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizesPerMainGridCell);
static std::vector<RigCompletionDataGridCell>
cellsIntersectingCompletions(RimEclipseCase* eclipseCase, const RimWellPath* wellPath, size_t timeStep);
static std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>
cellsIntersectingCompletions_PerCompletion(RimEclipseCase* eclipseCase, const RimWellPath* wellPath, size_t timeStep);
static std::vector<RimWellPath*> selectedWellPaths(); static std::vector<RimWellPath*> selectedWellPaths();
static bool containsAnyNonMainGridCells(const std::map<CompletionInfo, std::vector<RigCompletionDataGridCell>>& cellsPerCompletion);
static bool containsAnyNonMainGridCells(const std::vector<RigCompletionDataGridCell>& cells); static bool containsAnyNonMainGridCells(const std::vector<RigCompletionDataGridCell>& cells);
static int firstAvailableLgrId(const RigMainGrid* mainGrid); static int firstAvailableLgrId(const RigMainGrid* mainGrid);
}; };

View File

@@ -37,10 +37,11 @@ namespace caf
template<> template<>
void RicExportLgrUi::LgrSplitTypeEnum::setUp() void RicExportLgrUi::LgrSplitTypeEnum::setUp()
{ {
addItem(RicExportLgrUi::PER_CELL_LGR, "PER_CELL_LGR", "LGR Per Cell"); addItem(RicExportLgrUi::LGR_PER_CELL, "LGR_PER_CELL", "LGR Per Cell");
addItem(RicExportLgrUi::SINGLE_LGR, "SINGLE_LGR", "Single LGR"); addItem(RicExportLgrUi::LGR_PER_COMPLETION, "LGR_PER_COMPLETION", "LGR Per Completion");
addItem(RicExportLgrUi::LGR_PER_WELL, "LGR_PER_WELL", "LGR Per Well");
setDefault(RicExportLgrUi::PER_CELL_LGR); setDefault(RicExportLgrUi::LGR_PER_COMPLETION);
} }
} }
@@ -131,9 +132,9 @@ int RicExportLgrUi::timeStep() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RicExportLgrUi::singleLgrSplit() const RicExportLgrUi::SplitType RicExportLgrUi::splitType() const
{ {
return m_splitType == SINGLE_LGR; return m_splitType();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -38,8 +38,8 @@ class RicExportLgrUi : public caf::PdmObject
CAF_PDM_HEADER_INIT; CAF_PDM_HEADER_INIT;
public: public:
enum LgrSplitType { PER_CELL_LGR, SINGLE_LGR}; enum SplitType { LGR_PER_CELL, LGR_PER_COMPLETION, LGR_PER_WELL};
typedef caf::AppEnum<LgrSplitType> LgrSplitTypeEnum; typedef caf::AppEnum<RicExportLgrUi::SplitType> LgrSplitTypeEnum;
RicExportLgrUi(); RicExportLgrUi();
@@ -50,7 +50,7 @@ public:
QString exportFolder() const; QString exportFolder() const;
RimEclipseCase* caseToApply() const; RimEclipseCase* caseToApply() const;
int timeStep() const; int timeStep() const;
bool singleLgrSplit() const; SplitType splitType() const;
void setExportFolder(const QString& folder); void setExportFolder(const QString& folder);

View File

@@ -101,49 +101,57 @@ void RicCreateTemporaryLgrFeature::onActionTriggered(bool isChecked)
auto eclipseCase = dialogData->caseToApply(); auto eclipseCase = dialogData->caseToApply();
auto lgrCellCounts = dialogData->lgrCellCount(); auto lgrCellCounts = dialogData->lgrCellCount();
size_t timeStep = dialogData->timeStep(); size_t timeStep = dialogData->timeStep();
auto splitType = dialogData->splitType();
auto eclipseCaseData = eclipseCase->eclipseCaseData(); auto eclipseCaseData = eclipseCase->eclipseCaseData();
RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::MATRIX_MODEL); RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::MATRIX_MODEL);
RigActiveCellInfo* fractureActiveCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::FRACTURE_MODEL); RigActiveCellInfo* fractureActiveCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::FRACTURE_MODEL);
bool lgrIntersected = false; bool intersectsExistingLgr = false;
for (const auto& wellPath : wellPaths) for (const auto& wellPath : wellPaths)
{ {
auto intersectingCells = RicExportLgrFeature::cellsIntersectingCompletions(eclipseCase, wellPath, timeStep);
if (containsAnyNonMainGridCells(intersectingCells))
{
lgrIntersected = true;
continue;
}
eclipseCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->freeAllocatedResultsData();
std::vector<LgrInfo> lgrs; std::vector<LgrInfo> lgrs;
if (dialogData->singleLgrSplit())
lgrs = RicExportLgrFeature::buildSingleLgr(eclipseCase, intersectingCells, lgrCellCounts);
else
lgrs = RicExportLgrFeature::buildOneLgrPerMainCell(eclipseCase, intersectingCells, lgrCellCounts);
auto mainGrid = eclipseCase->eclipseCaseData()->mainGrid(); try
for (auto lgr : lgrs)
{ {
int totalCellCountBeforLgr = (int)mainGrid->globalCellArray().size(); lgrs = RicExportLgrFeature::buildLgrsForWellPath(wellPath,
eclipseCase,
timeStep,
lgrCellCounts,
splitType);
createLgr(lgr, eclipseCase->eclipseCaseData()->mainGrid()); auto mainGrid = eclipseCase->eclipseCaseData()->mainGrid();
int lgrCellCount = lgr.cellCount(); for (auto lgr : lgrs)
{
int totalCellCountBeforLgr = (int)mainGrid->globalCellArray().size();
activeCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount); createLgr(lgr, eclipseCase->eclipseCaseData()->mainGrid());
fractureActiveCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount);
int lgrCellCount = lgr.cellCount();
activeCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount);
fractureActiveCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount);
}
mainGrid->calculateFaults(activeCellInfo, true);
}
catch (CreateLgrException e)
{
intersectsExistingLgr = true;
} }
mainGrid->calculateFaults(activeCellInfo, true);
} }
eclipseCase->eclipseCaseData()->clearWellCellsInGridCache(); eclipseCase->eclipseCaseData()->clearWellCellsInGridCache();
eclipseCase->eclipseCaseData()->mainGrid()->computeCachedData(); eclipseCase->eclipseCaseData()->mainGrid()->computeCachedData();
activeView->loadDataAndUpdate(); activeView->loadDataAndUpdate();
if (intersectsExistingLgr)
{
QMessageBox::warning(nullptr,
"LGR cells intersected",
"At least one completion intersects with an LGR. No output for those completions produced");
}
} }
} }

View File

@@ -393,6 +393,22 @@ double RigCompletionData::secondOrderingValue() const
return m_secondOrderingValue; return m_secondOrderingValue;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCompletionData::setSourcePdmObject(const caf::PdmObject* object)
{
m_sourcePdmObject = const_cast<caf::PdmObject*>(object);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::PdmObject* RigCompletionData::sourcePdmObject() const
{
return m_sourcePdmObject;
}
//================================================================================================== //==================================================================================================
/// ///
//================================================================================================== //==================================================================================================
@@ -415,4 +431,5 @@ void RigCompletionData::copy(RigCompletionData& target, const RigCompletionData&
target.m_completionType = from.m_completionType; target.m_completionType = from.m_completionType;
target.m_firstOrderingValue = from.m_firstOrderingValue; target.m_firstOrderingValue = from.m_firstOrderingValue;
target.m_secondOrderingValue = from.m_secondOrderingValue; target.m_secondOrderingValue = from.m_secondOrderingValue;
target.m_sourcePdmObject = from.m_sourcePdmObject;
} }

View File

@@ -22,6 +22,9 @@
#include <QString> #include <QString>
#include <cafPdmPointer.h>
#include <cafPdmObject.h>
#include <vector> #include <vector>
//================================================================================================== //==================================================================================================
@@ -132,6 +135,9 @@ public:
double firstOrderingValue() const; double firstOrderingValue() const;
double secondOrderingValue() const; double secondOrderingValue() const;
void setSourcePdmObject(const caf::PdmObject* object);
const caf::PdmObject* sourcePdmObject() const;
std::vector<RigCompletionMetaData> m_metadata; std::vector<RigCompletionMetaData> m_metadata;
private: private:
@@ -156,6 +162,8 @@ private:
double m_firstOrderingValue; double m_firstOrderingValue;
double m_secondOrderingValue; double m_secondOrderingValue;
caf::PdmPointer<caf::PdmObject> m_sourcePdmObject;
private: private:
static void copy(RigCompletionData& target, const RigCompletionData& from); static void copy(RigCompletionData& target, const RigCompletionData& from);
}; };