#3527 Implement multiple ICD/AICDs for perforation intervals.

This commit is contained in:
Gaute Lindkvist committed 2018-10-22 09:35:35 +02:00
1 parent 43552fde88
commit 2194821609
11 files changed
+309 -127

No files matched your search

@@ -147,9 +147,10 @@ QString RimFishbonesMultipleSubs::generatedName() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFishbonesMultipleSubs::setMeasuredDepthAndCount(double measuredDepth, double spacing, int subCount)
void RimFishbonesMultipleSubs::setMeasuredDepthAndCount(double startMD, double spacing, int subCount)
{
m_valveLocations->setMeasuredDepthAndCount(measuredDepth, spacing, subCount);
double endMD = startMD + spacing * subCount;
m_valveLocations->initFields(RimMultipleValveLocations::VALVE_COUNT, startMD, endMD, spacing, subCount, {});
computeRangesAndLocations();
computeRotationAngles();
@@ -328,11 +329,10 @@ std::vector<double> RimFishbonesMultipleSubs::lateralLengths() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFishbonesMultipleSubs::valveLocationsUpdated()
void RimFishbonesMultipleSubs::geometryUpdated()
{
RimFishbonesCollection* collection;
this->firstAncestorOrThisOfTypeAsserted(collection);
computeSubLateralIndices();
collection->recalculateStartMD();
computeRotationAngles();
@@ -446,9 +446,9 @@ cvf::Color3f RimFishbonesMultipleSubs::defaultComponentColor() const
double RimFishbonesMultipleSubs::startMD() const
{
double measuredDepth = 0.0;
if (!m_valveLocations->locationOfValves().empty())
if (!m_valveLocations->valveLocations().empty())
{
measuredDepth = m_valveLocations->locationOfValves().front();
measuredDepth = m_valveLocations->valveLocations().front();
}
return measuredDepth;
@@ -460,9 +460,9 @@ double RimFishbonesMultipleSubs::startMD() const
double RimFishbonesMultipleSubs::endMD() const
{
double measuredDepth = 0.0;
if (!m_valveLocations->locationOfValves().empty())
if (!m_valveLocations->valveLocations().empty())
{
measuredDepth = m_valveLocations->locationOfValves().back();
measuredDepth = m_valveLocations->valveLocations().back();
}
return measuredDepth;
@@ -484,7 +484,7 @@ void RimFishbonesMultipleSubs::fieldChangedByUi(const caf::PdmFieldHandle* chang
computeSubLateralIndices();
}
valveLocationsUpdated();
geometryUpdated();
}
//--------------------------------------------------------------------------------------------------
@@ -509,7 +509,7 @@ caf::PdmFieldHandle* RimFishbonesMultipleSubs::objectToggleField()
void RimFishbonesMultipleSubs::computeRangesAndLocations()
{
m_valveLocations->computeRangesAndLocations();
valveLocationsUpdated();
geometryUpdated();
}
//--------------------------------------------------------------------------------------------------
@@ -602,7 +602,7 @@ void RimFishbonesMultipleSubs::initAfterRead()
{
initValveLocationFromLegacyData();
if (m_valveLocations->locationOfValves().size() != m_installationRotationAngles().size())
if (m_valveLocations->valveLocations().size() != m_installationRotationAngles().size())
{
computeRotationAngles();
}
@@ -639,7 +639,7 @@ void RimFishbonesMultipleSubs::computeRotationAngles()
{
std::vector<double> vals;
for (size_t i = 0; i < m_valveLocations->locationOfValves().size(); i++)
for (size_t i = 0; i < m_valveLocations->valveLocations().size(); i++)
{
vals.push_back(RimFishbonesMultipleSubs::randomValueFromRange(0, 360));
}
@@ -653,7 +653,7 @@ void RimFishbonesMultipleSubs::computeRotationAngles()
void RimFishbonesMultipleSubs::computeSubLateralIndices()
{
m_subLateralIndices.clear();
for (size_t subIndex = 0; subIndex < m_valveLocations->locationOfValves().size(); ++subIndex)
for (size_t subIndex = 0; subIndex < m_valveLocations->valveLocations().size(); ++subIndex)
{
SubLateralIndex subLateralIndex;
subLateralIndex.subIndex = subIndex;
@@ -664,7 +664,7 @@ void RimFishbonesMultipleSubs::computeSubLateralIndices()
}
m_subLateralIndices.push_back(subLateralIndex);
}
double numLaterals = static_cast<double>(m_valveLocations->locationOfValves().size() * m_lateralCountPerSub);
double numLaterals = static_cast<double>(m_valveLocations->valveLocations().size() * m_lateralCountPerSub);
int numToRemove = static_cast<int>(std::round((1 - m_lateralInstallSuccessFraction) * numLaterals));
srand(m_randomSeed());
while (numToRemove > 0)
@@ -737,7 +737,7 @@ void RimFishbonesMultipleSubs::initValveLocationFromLegacyData()
locationType = RimMultipleValveLocations::VALVE_CUSTOM;
}
m_valveLocations->initFieldsFromFishbones(locationType,
m_valveLocations->initFields(locationType,
m_rangeStart_OBSOLETE(),
m_rangeEnd_OBSOLETE(),
m_rangeSubSpacing_OBSOLETE(),
@@ -79,7 +79,7 @@ public:
bool isActive() const;
QString generatedName() const;
void setMeasuredDepthAndCount(double measuredDepth, double spacing, int subCount);
void setMeasuredDepthAndCount(double startMD, double spacing, int subCount);
double measuredDepth(size_t subIndex) const;
double rotationAngle(size_t subIndex) const;
@@ -97,7 +97,7 @@ public:
size_t icdCount() const { return m_icdCount(); }
std::vector<double> lateralLengths() const;
void valveLocationsUpdated();
void geometryUpdated();
const std::vector<SubLateralIndex>& installedLateralIndices() const { return m_subLateralIndices; };
std::vector<cvf::Vec3d> coordsForLateral(size_t subIndex, size_t lateralIndex) const;
@@ -21,7 +21,9 @@
#include "RigWellPath.h"
#include "RimFishbonesMultipleSubs.h"
#include "RimPerforationInterval.h"
#include "RimWellPath.h"
#include "RimWellPathValve.h"
#include "cafPdmUiDoubleValueEditor.h"
#include "cafPdmUiListEditor.h"
@@ -76,7 +78,23 @@ double RimMultipleValveLocations::measuredDepth(size_t valveIndex) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RimMultipleValveLocations::locationOfValves() const
double RimMultipleValveLocations::rangeStart() const
{
return m_rangeStart;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMultipleValveLocations::rangeEnd() const
{
return m_rangeEnd;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RimMultipleValveLocations::valveLocations() const
{
return m_locationOfValves();
}
@@ -89,19 +107,6 @@ void RimMultipleValveLocations::setLocationType(LocationType locationType)
m_locationType = locationType;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMultipleValveLocations::setMeasuredDepthAndCount(double measuredDepth, double spacing, int valveCount)
{
m_locationType = RimMultipleValveLocations::VALVE_SPACING;
m_rangeStart = measuredDepth;
m_rangeEnd = measuredDepth + spacing * valveCount;
m_rangeValveCount = valveCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -113,15 +118,15 @@ void RimMultipleValveLocations::computeRangesAndLocations()
if (m_rangeValveCount > 2) divisor = m_rangeValveCount - 1;
m_rangeValveSpacing = fabs(m_rangeStart - m_rangeEnd) / divisor;
if (m_rangeValveSpacing < minimumSpacingMeters())
{
m_rangeValveSpacing = minimumSpacingMeters();
m_rangeValveCount = rangeCountFromSpacing();
}
}
else if (m_locationType == VALVE_SPACING)
{
m_rangeValveCount = (fabs(m_rangeStart - m_rangeEnd) / m_rangeValveSpacing) + 1;
if (m_rangeValveCount < 1)
{
m_rangeValveCount = 1;
}
m_rangeValveCount = rangeCountFromSpacing();
}
if (m_locationType == VALVE_COUNT || m_locationType == VALVE_SPACING)
@@ -155,7 +160,7 @@ void RimMultipleValveLocations::computeRangesAndLocations()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMultipleValveLocations::initFieldsFromFishbones(LocationType locationType, double rangeStart, double rangeEnd, double valveSpacing, int valveCount, const std::vector<double>& locationOfValves)
void RimMultipleValveLocations::initFields(LocationType locationType, double rangeStart, double rangeEnd, double valveSpacing, int valveCount, const std::vector<double>& locationOfValves)
{
if (locationType != VALVE_UNDEFINED)
{
@@ -284,26 +289,13 @@ void RimMultipleValveLocations::fieldChangedByUi(const caf::PdmFieldHandle* chan
changedField == &m_rangeValveSpacing)
{
recomputeLocations = true;
RimWellPath* wellPath = nullptr;
this->firstAncestorOrThisOfTypeAsserted(wellPath);
RigWellPath* rigWellPathGeo = wellPath->wellPathGeometry();
if (rigWellPathGeo && !rigWellPathGeo->m_measuredDepths.empty())
{
double lastWellPathMD = rigWellPathGeo->m_measuredDepths.back();
m_rangeStart = cvf::Math::clamp(m_rangeStart(), 0.0, lastWellPathMD);
m_rangeEnd = cvf::Math::clamp(m_rangeEnd(), m_rangeStart(), lastWellPathMD);
}
m_rangeStart = cvf::Math::clamp(m_rangeStart(), rangeMin(), rangeMax());
m_rangeEnd = cvf::Math::clamp(m_rangeEnd(), rangeMin(), rangeMax());
}
if (changedField == &m_rangeValveSpacing)
{
// Minimum distance between fishbones is 13.0m
// Use 10.0m to allow for some flexibility
double minimumDistanceMeter = 10.0;
double minimumDistanceMeter = minimumSpacingMeters();
RimWellPath* wellPath = nullptr;
this->firstAncestorOrThisOfTypeAsserted(wellPath);
@@ -332,10 +324,16 @@ void RimMultipleValveLocations::fieldChangedByUi(const caf::PdmFieldHandle* chan
if (parentCompletion)
{
RimFishbonesMultipleSubs* fishbones = dynamic_cast<RimFishbonesMultipleSubs*>(parentCompletion);
RimWellPathValve* valve = dynamic_cast<RimWellPathValve*>(parentCompletion);
if (fishbones)
{
fishbones->valveLocationsUpdated();
fishbones->geometryUpdated();
}
else if (valve)
{
valve->geometryUpdated();
}
}
}
@@ -345,6 +343,71 @@ void RimMultipleValveLocations::fieldChangedByUi(const caf::PdmFieldHandle* chan
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimMultipleValveLocations::rangeCountFromSpacing() const
{
int rangeCount = (fabs(m_rangeStart - m_rangeEnd) / m_rangeValveSpacing) + 1;
if (rangeCount < 1)
{
rangeCount = 1;
}
return rangeCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMultipleValveLocations::minimumSpacingMeters() const
{
// Minimum distance between fishbones is 13.0m
// Use 10.0m to allow for some flexibility
return 10.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMultipleValveLocations::rangeMin() const
{
const RimPerforationInterval* perfInterval = nullptr;
this->firstAncestorOrThisOfType(perfInterval);
if (perfInterval)
{
return perfInterval->startMD();
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimMultipleValveLocations::rangeMax() const
{
const RimPerforationInterval* perfInterval = nullptr;
this->firstAncestorOrThisOfType(perfInterval);
if (perfInterval)
{
return perfInterval->endMD();
}
RimWellPath* wellPath = nullptr;
this->firstAncestorOrThisOfTypeAsserted(wellPath);
RigWellPath* rigWellPathGeo = wellPath->wellPathGeometry();
if (rigWellPathGeo && !rigWellPathGeo->m_measuredDepths.empty())
{
double lastWellPathMD = rigWellPathGeo->m_measuredDepths.back();
return lastWellPathMD;
}
return std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -42,23 +42,28 @@ public:
RimMultipleValveLocations();
double measuredDepth(size_t valveIndex) const;
const std::vector<double>& locationOfValves() const;
double rangeStart() const;
double rangeEnd() const;
const std::vector<double>& valveLocations() const;
void setLocationType(LocationType locationType);
void setMeasuredDepthAndCount(double measuredDepth, double spacing, int subCount);
void computeRangesAndLocations();
void initFieldsFromFishbones(LocationType locationType,
double rangeStart,
double rangeEnd,
double valveSpacing,
int valveCount,
const std::vector<double>& locationOfValves);
void initFields(LocationType locationType,
double rangeStart,
double rangeEnd,
double valveSpacing,
int valveCount,
const std::vector<double>& locationOfValves);
protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
private:
int rangeCountFromSpacing() const;
double minimumSpacingMeters() const;
double rangeMin() const;
double rangeMax() const;
static std::vector<double> locationsFromStartSpacingAndCount(double start, double spacing, size_t count);
private:
@@ -68,5 +73,5 @@ private:
caf::PdmField<double> m_rangeValveSpacing;
caf::PdmField<int> m_rangeValveCount;
caf::PdmField<std::vector<double>> m_locationOfValves; // Given in measured depth
caf::PdmField<std::vector<double>> m_locationOfValves; // Given in measured depth
};
@@ -24,6 +24,7 @@
#include "RigWellPath.h"
#include "RimMultipleValveLocations.h"
#include "RimPerforationInterval.h"
#include "RimProject.h"
#include "RimWellPath.h"
@@ -38,11 +39,19 @@ CAF_PDM_SOURCE_INIT(RimWellPathValve, "WellPathValve");
RimWellPathValve::RimWellPathValve()
{
CAF_PDM_InitObject("WellPathValve", ":/PerforationInterval16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_type, "CompletionType", "Type ", "", "", "");
m_type = RiaDefines::ICD;
CAF_PDM_InitField(&m_measuredDepth, "StartMeasuredDepth", 0.0, "Start MD", "", "", "");
m_measuredDepth.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&m_multipleValveLocations, "ValveLocations", "Valve Locations", "", "", "");
m_multipleValveLocations = new RimMultipleValveLocations;
m_multipleValveLocations.uiCapability()->setUiTreeHidden(true);
m_multipleValveLocations.uiCapability()->setUiTreeChildrenHidden(true);
nameField()->uiCapability()->setUiReadOnly(true);
m_type = RiaDefines::ICD;
}
//--------------------------------------------------------------------------------------------------
@@ -56,9 +65,42 @@ RimWellPathValve::~RimWellPathValve()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathValve::setMeasuredDepth(double measuredDepth)
void RimWellPathValve::setMeasuredDepthAndCount(double startMD, double spacing, int valveCount)
{
m_measuredDepth = measuredDepth;
m_measuredDepth = startMD;
double endMD = startMD + spacing * valveCount;
m_multipleValveLocations->initFields(RimMultipleValveLocations::VALVE_COUNT, startMD, endMD, spacing, valveCount, {});
m_multipleValveLocations->computeRangesAndLocations();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathValve::geometryUpdated()
{
m_measuredDepth = m_multipleValveLocations->valveLocations().front();
RimProject* proj;
this->firstAncestorOrThisOfTypeAsserted(proj);
proj->reloadCompletionTypeResultsInAllViews();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimWellPathValve::valveLocations() const
{
std::vector<double> valveDepths;
if (m_type() == RiaDefines::ICV)
{
valveDepths.push_back(m_measuredDepth);
}
else
{
valveDepths = m_multipleValveLocations->valveLocations();
}
return valveDepths;
}
//--------------------------------------------------------------------------------------------------
@@ -98,7 +140,18 @@ cvf::Color3f RimWellPathValve::defaultComponentColor() const
//--------------------------------------------------------------------------------------------------
double RimWellPathValve::startMD() const
{
return m_measuredDepth;
if (m_type() == RiaDefines::ICV)
{
return m_measuredDepth;
}
else if (m_multipleValveLocations()->valveLocations().empty())
{
return m_multipleValveLocations->rangeStart();
}
else
{
return m_multipleValveLocations()->valveLocations().front();
}
}
//--------------------------------------------------------------------------------------------------
@@ -106,7 +159,18 @@ double RimWellPathValve::startMD() const
//--------------------------------------------------------------------------------------------------
double RimWellPathValve::endMD() const
{
return m_measuredDepth + 0.5;
if (m_type() == RiaDefines::ICV)
{
return m_measuredDepth + 0.5;
}
else if (m_multipleValveLocations()->valveLocations().empty())
{
return m_multipleValveLocations->rangeEnd();
}
else
{
return m_multipleValveLocations()->valveLocations().back();
}
}
//--------------------------------------------------------------------------------------------------
@@ -144,6 +208,7 @@ void RimWellPathValve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering
{
uiOrdering.add(&m_type);
if (m_type() == RiaDefines::ICV)
{
RimWellPath* wellPath;
firstAncestorOrThisOfType(wellPath);
@@ -158,9 +223,14 @@ void RimWellPathValve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering
m_measuredDepth.uiCapability()->setUiName("Measured Depth [ft]");
}
}
uiOrdering.add(&m_measuredDepth);
}
uiOrdering.add(&m_measuredDepth);
else
{
caf::PdmUiGroup* group = uiOrdering.addNewGroup("Multiple Valve Locations");
m_multipleValveLocations->uiOrdering(uiConfigName, *group);
}
uiOrdering.skipRemainingFields(true);
}
//--------------------------------------------------------------------------------------------------
@@ -23,11 +23,13 @@
#include "cafPdmObject.h"
#include "cafAppEnum.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include <QList>
#include <QString>
class RimMultipleValveLocations;
class RimWellPath;
class RimWellPathValve : public RimCheckableNamedObject, public RimWellPathComponentInterface
@@ -39,7 +41,9 @@ public:
RimWellPathValve();
~RimWellPathValve() override;
void setMeasuredDepth(double measuredDepth);
void setMeasuredDepthAndCount(double startMD, double spacing, int valveCount);
void geometryUpdated();
std::vector<double> valveLocations() const;
// Overrides from RimWellPathCompletionInterface
RiaDefines::WellPathComponentType componentType() const override;
@@ -48,7 +52,7 @@ public:
cvf::Color3f defaultComponentColor() const override;
double startMD() const override;
double endMD() const override;
private:
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
@@ -57,10 +61,10 @@ private:
void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override;
private:
caf::PdmField<CompletionTypeEnum> m_type;
caf::PdmField<double> m_measuredDepth;
caf::PdmField<CompletionTypeEnum> m_type;
caf::PdmField<double> m_measuredDepth;
caf::PdmChildField<RimMultipleValveLocations*> m_multipleValveLocations;
protected:
};