#3779 Preliminary AICD output

This commit is contained in:
Gaute Lindkvist 2018-12-07 15:48:11 +01:00
parent ddd454077f
commit 15576a9ae3
11 changed files with 493 additions and 126 deletions

View File

@ -220,3 +220,69 @@ RigCompletionData::CompletionType RicMswPerforationICD::completionType() const
{
return RigCompletionData::PERFORATION_ICD;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicMswPerforationAICD::RicMswPerforationAICD(const QString& label,
size_t index /*= cvf::UNDEFINED_SIZE_T*/,
int branchNumber /*= cvf::UNDEFINED_INT*/)
: RicMswValve(label, index, branchNumber), m_valid(false), m_deviceOpen(false)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigCompletionData::CompletionType RicMswPerforationAICD::completionType() const
{
return RigCompletionData::PERFORATION_AICD;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicMswPerforationAICD::isValid() const
{
return m_valid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswPerforationAICD::setIsValid(bool valid)
{
m_valid = valid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicMswPerforationAICD::isOpen() const
{
return m_deviceOpen;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswPerforationAICD::setIsOpen(bool deviceOpen)
{
m_deviceOpen = deviceOpen;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::array<double, AICD_NUM_PARAMS>& RicMswPerforationAICD::values() const
{
return m_parameters;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::array<double, AICD_NUM_PARAMS>& RicMswPerforationAICD::values()
{
return m_parameters;
}

View File

@ -21,6 +21,8 @@
#include "RigCompletionData.h"
#include "RimWellPathAicdParameters.h"
#include "cvfBase.h"
#include "cvfMath.h"
@ -134,3 +136,26 @@ public:
RicMswPerforationICD(const QString& label, size_t index = cvf::UNDEFINED_SIZE_T, int branchNumber = cvf::UNDEFINED_INT);
RigCompletionData::CompletionType completionType() const override;
};
//==================================================================================================
///
//==================================================================================================
class RicMswPerforationAICD : public RicMswValve
{
public:
RicMswPerforationAICD(const QString& label, size_t index = cvf::UNDEFINED_SIZE_T, int branchNumber = cvf::UNDEFINED_INT);
RigCompletionData::CompletionType completionType() const override;
bool isValid() const;
void setIsValid(bool valid);
bool isOpen() const;
void setIsOpen(bool deviceOpen);
const std::array<double, AICD_NUM_PARAMS>& values() const;
std::array<double, AICD_NUM_PARAMS>& values();
private:
bool m_valid;
bool m_deviceOpen;
std::array<double, AICD_NUM_PARAMS> m_parameters;
};

View File

@ -1,5 +1,24 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicMswValveAccumulators.h"
#include "RiaStatisticsTools.h"
#include "RicMswCompletions.h"
#include "RimWellPathValve.h"
@ -16,13 +35,19 @@ RicMswICDAccumulator::RicMswICDAccumulator(RiaEclipseUnitTools::UnitSystem unitS
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswICDAccumulator::accumulateValveParameters(const RimWellPathValve* wellPathValve, double contributionFraction)
bool RicMswICDAccumulator::accumulateValveParameters(const RimWellPathValve* wellPathValve, double contributionFraction)
{
double icdOrificeRadius = wellPathValve->orificeDiameter(m_unitSystem) / 2;
double icdArea = icdOrificeRadius * icdOrificeRadius * cvf::PI_D;
CVF_ASSERT(wellPathValve);
if (wellPathValve->componentType() == RiaDefines::ICV || wellPathValve->componentType() == RiaDefines::ICD)
{
double icdOrificeRadius = wellPathValve->orificeDiameter(m_unitSystem) / 2;
double icdArea = icdOrificeRadius * icdOrificeRadius * cvf::PI_D;
m_areaSum += icdArea * contributionFraction;
m_coefficientCalculator.addValueAndWeight(wellPathValve->flowCoefficient(), icdArea * contributionFraction);
m_areaSum += icdArea * contributionFraction;
m_coefficientCalculator.addValueAndWeight(wellPathValve->flowCoefficient(), icdArea * contributionFraction);
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
@ -39,4 +64,65 @@ void RicMswICDAccumulator::applyToSuperValve(std::shared_ptr<RicMswValve> valve)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicMswAICDAccumulator::RicMswAICDAccumulator(RiaEclipseUnitTools::UnitSystem unitSystem)
: RicMswValveAccumulator(unitSystem), m_valid(false), m_deviceOpen(false)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicMswAICDAccumulator::accumulateValveParameters(const RimWellPathValve* wellPathValve, double contributionFraction)
{
CVF_ASSERT(wellPathValve);
if (wellPathValve->componentType() == RiaDefines::AICD)
{
const RimWellPathAicdParameters* params = wellPathValve->aicdParameters();
if (params->isValid())
{
m_valid = true;
m_deviceOpen = m_deviceOpen || params->isOpen();
std::array<double, AICD_NUM_PARAMS> values = params->doubleValues();
for (size_t i = 0; i < (size_t)AICD_NUM_PARAMS; ++i)
{
if (RiaStatisticsTools::isValidNumber(values[i]))
{
m_meanCalculators[i].addValueAndWeight(values[i], contributionFraction);
}
}
}
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicMswAICDAccumulator::applyToSuperValve(std::shared_ptr<RicMswValve> valve)
{
std::shared_ptr<RicMswPerforationAICD> aicd = std::dynamic_pointer_cast<RicMswPerforationAICD>(valve);
if (aicd)
{
std::array<double, AICD_NUM_PARAMS> values;
for (size_t i = 0; i < (size_t) AICD_NUM_PARAMS; ++i)
{
if (m_meanCalculators[i].validAggregatedWeight())
{
values[i] = m_meanCalculators[i].weightedMean();
}
else
{
values[i] = std::numeric_limits<double>::infinity();
}
}
aicd->setIsValid(m_valid);
aicd->setIsOpen(m_deviceOpen);
aicd->values() = values;
}
}

View File

@ -19,7 +19,9 @@
#include "RiaEclipseUnitTools.h"
#include "RiaWeightedMeanCalculator.h"
#include "RimWellPathAicdParameters.h"
#include <array>
#include <memory>
class RimWellPathValve;
@ -32,7 +34,7 @@ class RicMswValveAccumulator
{
public:
RicMswValveAccumulator(RiaEclipseUnitTools::UnitSystem unitSystem) : m_unitSystem(unitSystem) {}
virtual void accumulateValveParameters(const RimWellPathValve* wellPathValve, double contributionFraction) = 0;
virtual bool accumulateValveParameters(const RimWellPathValve* wellPathValve, double contributionFraction) = 0;
virtual void applyToSuperValve(std::shared_ptr<RicMswValve> valve) = 0;
protected:
@ -46,7 +48,7 @@ class RicMswICDAccumulator : public RicMswValveAccumulator
{
public:
RicMswICDAccumulator(RiaEclipseUnitTools::UnitSystem unitSystem);
void accumulateValveParameters(const RimWellPathValve* wellPathValve, double contributionFraction) override;
bool accumulateValveParameters(const RimWellPathValve* wellPathValve, double contributionFraction) override;
void applyToSuperValve(std::shared_ptr<RicMswValve> valve) override;
private:
@ -54,4 +56,18 @@ private:
double m_areaSum;
};
//==================================================================================================
///
//==================================================================================================
class RicMswAICDAccumulator : public RicMswValveAccumulator
{
public:
RicMswAICDAccumulator(RiaEclipseUnitTools::UnitSystem unitSystem);
bool accumulateValveParameters(const RimWellPathValve* wellPathValve, double contributionFraction) override;
void applyToSuperValve(std::shared_ptr<RicMswValve> valve) override;
private:
bool m_valid;
bool m_deviceOpen;
std::array<RiaWeightedMeanCalculator<double>, AICD_NUM_PARAMS> m_meanCalculators;
};

View File

@ -244,6 +244,7 @@ void RicWellPathExportMswCompletionsImpl::exportWellSegmentsForPerforations(
generateWelsegsTable(formatter, exportInfo);
generateCompsegTables(formatter, exportInfo);
generateWsegvalvTable(formatter, exportInfo);
generateWsegAicdTable(formatter, exportInfo);
}
//--------------------------------------------------------------------------------------------------
@ -334,7 +335,7 @@ void RicWellPathExportMswCompletionsImpl::generateWelsegsTable(RifEclipseDataTab
{
generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FISHBONES_ICD, RigCompletionData::FISHBONES});
generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FRACTURE});
generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::PERFORATION_ICD});
generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::PERFORATION_ICD, RigCompletionData::PERFORATION_AICD});
}
formatter.tableCompleted();
@ -362,7 +363,8 @@ void RicWellPathExportMswCompletionsImpl::generateWelsegsSegments(
}
if (completion->completionType() == RigCompletionData::FISHBONES_ICD ||
completion->completionType() == RigCompletionData::PERFORATION_ICD) // Found ICD
completion->completionType() == RigCompletionData::PERFORATION_ICD ||
completion->completionType() == RigCompletionData::PERFORATION_AICD) // Found ICD
{
if (!completion->subSegments().empty())
{
@ -441,7 +443,7 @@ void RicWellPathExportMswCompletionsImpl::generateWelsegsCompletionCommentHeader
formatter.comment("Diam: MSW - Tubing Radius");
formatter.comment("Rough: MSW - Open Hole Roughness Factor");
}
else if (completionType == RigCompletionData::PERFORATION_ICD)
else if (completionType == RigCompletionData::PERFORATION_ICD || completionType == RigCompletionData::PERFORATION_AICD)
{
formatter.comment("Perforation Valve Segments");
formatter.comment("Diam: MSW - Tubing Radius");
@ -487,7 +489,8 @@ void RicWellPathExportMswCompletionsImpl::generateCompsegTables(RifEclipseDataTa
{
std::set<RigCompletionData::CompletionType> perforationTypes = {RigCompletionData::PERFORATION,
RigCompletionData::PERFORATION_ICD};
RigCompletionData::PERFORATION_ICD,
RigCompletionData::PERFORATION_AICD };
generateCompsegTable(formatter, exportInfo, false, perforationTypes);
if (exportInfo.hasSubGridIntersections())
{
@ -672,6 +675,91 @@ void RicWellPathExportMswCompletionsImpl::generateWsegvalvTable(RifEclipseDataTa
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicWellPathExportMswCompletionsImpl::generateWsegAicdTable(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo)
{
bool foundValve = false;
for (std::shared_ptr<RicMswSegment> location : exportInfo.wellSegmentLocations())
{
for (std::shared_ptr<RicMswCompletion> completion : location->completions())
{
if (completion->completionType() == RigCompletionData::PERFORATION_AICD)
{
if (!foundValve)
{
formatter.keyword("WSEGAICD");
std::vector<RifEclipseOutputTableColumn> header = {
RifEclipseOutputTableColumn("Well"),
RifEclipseOutputTableColumn("Seg1"),
RifEclipseOutputTableColumn("Seg2"),
RifEclipseOutputTableColumn("str"),
RifEclipseOutputTableColumn("len"),
RifEclipseOutputTableColumn("rho"),
RifEclipseOutputTableColumn("mu"),
RifEclipseOutputTableColumn("#8"),
RifEclipseOutputTableColumn("#9"),
RifEclipseOutputTableColumn("#10"),
RifEclipseOutputTableColumn("#11"),
RifEclipseOutputTableColumn("x"),
RifEclipseOutputTableColumn("y"),
RifEclipseOutputTableColumn("o"),
RifEclipseOutputTableColumn("#15"),
RifEclipseOutputTableColumn("#16"),
RifEclipseOutputTableColumn("#17"),
RifEclipseOutputTableColumn("#18"),
RifEclipseOutputTableColumn("#19"),
RifEclipseOutputTableColumn("#20"),
RifEclipseOutputTableColumn("#21"),
};
formatter.header(header);
foundValve = true;
}
{
std::shared_ptr<RicMswPerforationAICD> aicd = std::static_pointer_cast<RicMswPerforationAICD>(completion);
if (!aicd->subSegments().empty())
{
CVF_ASSERT(aicd->subSegments().size() == 1u);
formatter.comment(aicd->label());
formatter.add(exportInfo.wellPath()->name());
formatter.add(aicd->subSegments().front()->segmentNumber());
formatter.add(aicd->subSegments().front()->segmentNumber());
std::array<double, AICD_NUM_PARAMS> values = aicd->values();
formatter.add(values[AICD_STRENGTH]);
formatter.add(values[AICD_LENGTH]);
formatter.add(values[AICD_DENSITY_CALIB_FLUID]);
formatter.add(values[AICD_VISCOSITY_CALIB_FLUID]);
formatter.add(values[AICD_CRITICAL_WATER_IN_LIQUID_FRAC]);
formatter.add(values[AICD_EMULSION_VISC_TRANS_REGION]);
formatter.add(values[AICD_MAX_RATIO_EMULSION_VISC]);
formatter.add(1);
formatter.add(values[AICD_MAX_FLOW_RATE]);
formatter.add(values[AICD_VOL_FLOW_EXP]);
formatter.add(values[AICD_VISOSITY_FUNC_EXP]);
formatter.add(aicd->isOpen() ? "OPEN" : "SHUT");
formatter.add(values[AICD_EXP_OIL_FRAC_DENSITY]);
formatter.add(values[AICD_EXP_WATER_FRAC_DENSITY]);
formatter.add(values[AICD_EXP_GAS_FRAC_DENSITY]);
formatter.add(values[AICD_EXP_OIL_FRAC_VISCOSITY]);
formatter.add(values[AICD_EXP_WATER_FRAC_VISCOSITY]);
formatter.add(values[AICD_EXP_GAS_FRAC_VISCOSITY]);
formatter.rowCompleted();
}
}
}
}
}
if (foundValve)
{
formatter.tableCompleted();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1003,7 +1091,12 @@ void RicWellPathExportMswCompletionsImpl::assignSuperValveCompletions(
{
std::shared_ptr<RicMswSegment> segment = mainBoreSegments[nMainSegment];
std::shared_ptr<RicMswPerforationICD> superValve;
std::shared_ptr<RicMswPerforationICD> superICD;
std::shared_ptr<RicMswPerforationAICD> superAICD;
double totalICDOverlap = 0.0;
double totalAICDOverlap = 0.0;
for (const RimPerforationInterval* interval : perforationIntervals)
{
std::vector<const RimWellPathValve*> perforationValves;
@ -1011,6 +1104,7 @@ void RicWellPathExportMswCompletionsImpl::assignSuperValveCompletions(
for (const RimWellPathValve* valve : perforationValves)
{
bool isAicd = valve->componentType() == RiaDefines::AICD;
for (size_t nSubValve = 0u; nSubValve < valve->valveLocations().size(); ++nSubValve)
{
double valveMD = valve->valveLocations()[nSubValve];
@ -1023,24 +1117,56 @@ void RicWellPathExportMswCompletionsImpl::assignSuperValveCompletions(
if (segment->startMD() <= valveMD && valveMD < segment->endMD())
{
QString valveLabel = QString("%1 #%2").arg("Combined Valve for segment").arg(nMainSegment + 2);
superValve.reset(new RicMswPerforationICD(valveLabel));
std::shared_ptr<RicMswSubSegment> subSegment(new RicMswSubSegment(valveMD, 0.1, 0.0, 0.0));
superValve->addSubSegment(subSegment);
if (isAicd)
{
superAICD.reset(new RicMswPerforationAICD(valveLabel));
superAICD->addSubSegment(subSegment);
}
else
{
superICD.reset(new RicMswPerforationICD(valveLabel));
superICD->addSubSegment(subSegment);
}
}
else if (overlap > 0.0 && !superValve)
else if (overlap > 0.0 && (!isAicd && !superICD))
{
QString valveLabel = QString("%1 #%2").arg("Combined Valve for segment").arg(nMainSegment + 2);
superValve.reset(new RicMswPerforationICD(valveLabel));
std::shared_ptr<RicMswSubSegment> subSegment(new RicMswSubSegment(overlapStart, 0.1, 0.0, 0.0));
superValve->addSubSegment(subSegment);
superICD.reset(new RicMswPerforationICD(valveLabel));
superICD->addSubSegment(subSegment);
}
else if (overlap > 0.0 && (isAicd && !superAICD))
{
QString valveLabel = QString("%1 #%2").arg("Combined Valve for segment").arg(nMainSegment + 2);
std::shared_ptr<RicMswSubSegment> subSegment(new RicMswSubSegment(overlapStart, 0.1, 0.0, 0.0));
superAICD.reset(new RicMswPerforationAICD(valveLabel));
superAICD->addSubSegment(subSegment);
}
if (isAicd)
{
totalAICDOverlap += overlap;
}
else
{
totalICDOverlap += overlap;
}
}
}
}
if (superValve)
if (totalICDOverlap > 0.0 || totalAICDOverlap > 0.0)
{
segment->addCompletion(superValve);
if (totalAICDOverlap > totalICDOverlap)
{
segment->addCompletion(superAICD);
}
else
{
segment->addCompletion(superICD);
}
}
}
}
@ -1074,6 +1200,10 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperValves(
{
accumulator.reset(new RicMswICDAccumulator(unitSystem));
}
else if (std::dynamic_pointer_cast<const RicMswPerforationAICD>(superValve))
{
accumulator.reset(new RicMswAICDAccumulator(unitSystem));
}
for (const RimPerforationInterval* interval : perforationIntervals)
{
@ -1092,8 +1222,10 @@ void RicWellPathExportMswCompletionsImpl::assignValveContributionsToSuperValves(
if (overlap > 0.0 && accumulator)
{
assignedRegularValves[superValve].insert(std::make_pair(valve, nSubValve));
accumulator->accumulateValveParameters(valve, overlap / valveSegmentLength);
if (accumulator->accumulateValveParameters(valve, overlap / valveSegmentLength))
{
assignedRegularValves[superValve].insert(std::make_pair(valve, nSubValve));
}
}
}
}
@ -1131,7 +1263,8 @@ void RicWellPathExportMswCompletionsImpl::moveIntersectionsToSuperValves(MainBor
std::vector<std::shared_ptr<RicMswCompletion>> perforations;
for (auto completionPtr : segmentPtr->completions())
{
if (completionPtr->completionType() == RigCompletionData::PERFORATION_ICD)
if (completionPtr->completionType() == RigCompletionData::PERFORATION_ICD ||
completionPtr->completionType() == RigCompletionData::PERFORATION_AICD)
{
superValve = completionPtr;
}

View File

@ -54,48 +54,47 @@ public:
int timeStep,
const std::vector<const RimPerforationInterval*>& perforationIntervals);
static RicMswExportInfo generateFishbonesMswExportInfo(const RimEclipseCase* caseToApply,
const RimWellPath* wellPath,
bool enableSegmentSplitting);
static RicMswExportInfo generateFishbonesMswExportInfo(const RimEclipseCase* caseToApply,
const RimWellPath* wellPath,
bool enableSegmentSplitting);
private:
static RicMswExportInfo generateFishbonesMswExportInfo(const RimEclipseCase* caseToApply,
const RimWellPath* wellPath,
const std::vector<RimFishbonesMultipleSubs*>& fishbonesSubs,
bool enableSegmentSplitting);
static RicMswExportInfo generateFishbonesMswExportInfo(const RimEclipseCase* caseToApply,
const RimWellPath* wellPath,
const std::vector<RimFishbonesMultipleSubs*>& fishbonesSubs,
bool enableSegmentSplitting);
static RicMswExportInfo generateFracturesMswExportInfo(RimEclipseCase* caseToApply,
const RimWellPath* wellPath);
static RicMswExportInfo generateFracturesMswExportInfo(RimEclipseCase* caseToApply, const RimWellPath* wellPath);
static RicMswExportInfo generateFracturesMswExportInfo(RimEclipseCase* caseToApply,
const RimWellPath* wellPath,
const std::vector<RimWellPathFracture*>& fractures);
static RicMswExportInfo generateFracturesMswExportInfo(RimEclipseCase* caseToApply,
const RimWellPath* wellPath,
const std::vector<RimWellPathFracture*>& fractures);
static RicMswExportInfo generatePerforationsMswExportInfo(RimEclipseCase* eclipseCase,
const RimWellPath* wellPath,
int timeStep,
const std::vector<const RimPerforationInterval*>& perforationIntervals);
static RicMswExportInfo
generatePerforationsMswExportInfo(RimEclipseCase* eclipseCase,
const RimWellPath* wellPath,
int timeStep,
const std::vector<const RimPerforationInterval*>& perforationIntervals);
static void generateWelsegsTable(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo);
static void generateWelsegsTable(RifEclipseDataTableFormatter& formatter, const RicMswExportInfo& exportInfo);
static void generateWelsegsSegments(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo,
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes);
static void generateWelsegsCompletionCommentHeader(RifEclipseDataTableFormatter& formatter,
RigCompletionData::CompletionType completionType);
static void generateCompsegTables(RifEclipseDataTableFormatter& formatter, const RicMswExportInfo& exportInfo);
static void generateCompsegTable(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo,
bool exportSubGridIntersections,
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes);
static void generateCompsegHeader(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo,
RigCompletionData::CompletionType completionType,
bool exportSubGridIntersections);
static void generateWsegvalvTable(RifEclipseDataTableFormatter& formatter, const RicMswExportInfo& exportInfo);
static void generateWsegAicdTable(RifEclipseDataTableFormatter& formatter, const RicMswExportInfo& exportInfo);
static void generateWelsegsSegments(RifEclipseDataTableFormatter &formatter,
const RicMswExportInfo &exportInfo,
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes);
static void generateWelsegsCompletionCommentHeader(RifEclipseDataTableFormatter &formatter,
RigCompletionData::CompletionType completionType);
static void generateCompsegTables(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo);
static void generateCompsegTable(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo,
bool exportSubGridIntersections,
const std::set<RigCompletionData::CompletionType>& exportCompletionTypes);
static void generateCompsegHeader(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo,
RigCompletionData::CompletionType completionType,
bool exportSubGridIntersections);
static void generateWsegvalvTable(RifEclipseDataTableFormatter& formatter,
const RicMswExportInfo& exportInfo);
private:
typedef std::vector<std::shared_ptr<RicMswSegment>> MainBoreSegments;
typedef std::map<std::shared_ptr<RicMswCompletion>, std::set<std::pair<const RimWellPathValve*, size_t>>>

View File

@ -25,6 +25,8 @@
#include <QDoubleValidator>
#include <limits>
CAF_PDM_SOURCE_INIT(RimWellPathAicdParameters, "WellPathAicdParameters");
class NumericStringValidator : public QDoubleValidator
@ -60,26 +62,25 @@ RimWellPathAicdParameters::RimWellPathAicdParameters()
// clang-format off
CAF_PDM_InitObject("RimWellPathAicdParameters", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_strengthOfAICD, "StrengthAICD", "Strength of AICD", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_densityOfCalibrationFluid, "DensityCalibrationFluid", "Calibration Fluid Density (kg/m^3)", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_viscosityOfCalibrationFluid, "ViscosityCalibrationFluid", "Calibration Fluid Viscosity (cP)", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_volumeFlowRateExponent, "VolumeFlowRateExponent", "Volume Flow Rate Exponent", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_viscosityFunctionExponent, "ViscosityFunctionExponent", "Viscosity Function Exponent", "", "", "");
CAF_PDM_InitField(&m_deviceOpen, "DeviceOpen", true, "Device Open?", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_aicdParameterFields[AICD_STRENGTH], "StrengthAICD", "Strength of AICD", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_aicdParameterFields[AICD_DENSITY_CALIB_FLUID], "DensityCalibrationFluid", "Calibration Fluid Density (kg/m^3)", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_aicdParameterFields[AICD_VISCOSITY_CALIB_FLUID], "ViscosityCalibrationFluid", "Calibration Fluid Viscosity (cP)", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_aicdParameterFields[AICD_VOL_FLOW_EXP], "VolumeFlowRateExponent", "Volume Flow Rate Exponent", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_aicdParameterFields[AICD_VISOSITY_FUNC_EXP], "ViscosityFunctionExponent", "Viscosity Function Exponent", "", "", "");
CAF_PDM_InitField(&m_lengthOfAICD, "LengthOfAICD", 12.0, "Length of AICD (m)", "", "", "");
m_lengthOfAICD.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName());
CAF_PDM_InitField(&m_criticalWaterInLiquidFractionEmulsions, "CriticalWaterLiquidFractionEmul", QString("1*"), "Critical Water in Liquid Fraction for emulsions", "", "", "");
CAF_PDM_InitField(&m_emulsionViscosityTransitionRegion, "ViscosityTransitionRegionEmul", QString("1*"), "Emulsion Viscosity Transition Region", "", "", "");
CAF_PDM_InitField(&m_maxRatioOfEmulsionVisc, "MaxRatioOfEmulsionVisc", QString("1*"), "Max Ratio of Emulsion to Continuous Viscosity", "", "", "");
CAF_PDM_InitField(&m_maxFlowRate, "MaxFlowRate", QString("1*"), "Max Flow Rate for AICD Device (m^3 / day)", "", "", "");
CAF_PDM_InitField(&m_exponentOilFractionInDensityMixCalc, "ExponentOilDensity", QString("1*"), "Density Exponent of Oil Fraction", "", "", "");
CAF_PDM_InitField(&m_exponentWaterFractionInDensityMixCalc, "ExponentWaterDensity", QString("1*"), "Density Exponent of Water Fraction", "", "", "");
CAF_PDM_InitField(&m_exponentGasFractionInDensityMixCalc, "ExponentGasDensity", QString("1*"), "Density Exponent of Gas Fraction", "", "", "");
CAF_PDM_InitField(&m_exponentOilFractionInViscosityMixCalc, "ExponentOilViscosity", QString("1*"), "Viscosity Exponent of Oil Fraction", "", "", "");
CAF_PDM_InitField(&m_exponentWaterFractionInViscosityMixCalc, "ExponentWaterViscosity", QString("1*"), "Viscosity Exponent of Water Fraction", "", "", "");
CAF_PDM_InitField(&m_exponentGasFractionInViscosityMixCalc, "ExponentGasViscosity", QString("1*"), "Viscosity Exponent of Gas Fraction", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_LENGTH], "LengthAICD", QString("12.0"), "Length of AICD", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_CRITICAL_WATER_IN_LIQUID_FRAC], "CriticalWaterLiquidFractionEmul", QString("1*"), "Critical Water in Liquid Fraction for emulsions", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_EMULSION_VISC_TRANS_REGION], "ViscosityTransitionRegionEmul", QString("1*"), "Emulsion Viscosity Transition Region", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_MAX_RATIO_EMULSION_VISC], "MaxRatioOfEmulsionVisc", QString("1*"), "Max Ratio of Emulsion to Continuous Viscosity", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_MAX_FLOW_RATE], "MaxFlowRate", QString("1*"), "Max Flow Rate for AICD Device (m^3 / day)", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_EXP_OIL_FRAC_DENSITY], "ExponentOilDensity", QString("1*"), "Density Exponent of Oil Fraction", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_EXP_WATER_FRAC_DENSITY], "ExponentWaterDensity", QString("1*"), "Density Exponent of Water Fraction", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_EXP_GAS_FRAC_DENSITY], "ExponentGasDensity", QString("1*"), "Density Exponent of Gas Fraction", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_EXP_OIL_FRAC_VISCOSITY], "ExponentOilViscosity", QString("1*"), "Viscosity Exponent of Oil Fraction", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_EXP_WATER_FRAC_VISCOSITY], "ExponentWaterViscosity", QString("1*"), "Viscosity Exponent of Water Fraction", "", "", "");
CAF_PDM_InitField(&m_aicdParameterFields[AICD_EXP_GAS_FRAC_VISCOSITY], "ExponentGasViscosity", QString("1*"), "Viscosity Exponent of Gas Fraction", "", "", "");
std::vector<caf::PdmFieldHandle*> allFields;
this->fields(allFields);
@ -115,32 +116,55 @@ bool RimWellPathAicdParameters::isValid() const
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPathAicdParameters::isOpen() const
{
return m_deviceOpen;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::array<double, AICD_NUM_PARAMS> RimWellPathAicdParameters::doubleValues() const
{
std::array<double, AICD_NUM_PARAMS> doubleValues;
for (int i = 0; i < (int)AICD_NUM_PARAMS; ++i)
{
NumericStringValidator validator(nullptr);
QString stringValue = m_aicdParameterFields[(AICDParameters)i].value();
bool ok = true;
double doubleValue = stringValue.toDouble(&ok);
if (ok)
{
doubleValues[i] = doubleValue;
}
else
{
doubleValues[i] = std::numeric_limits<double>::infinity();
}
}
return doubleValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathAicdParameters::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
caf::PdmUiGroup* requiredGroup = uiOrdering.addNewGroup("Required Parameters");
requiredGroup->add(&m_strengthOfAICD);
requiredGroup->add(&m_densityOfCalibrationFluid);
requiredGroup->add(&m_viscosityOfCalibrationFluid);
requiredGroup->add(&m_volumeFlowRateExponent);
requiredGroup->add(&m_viscosityFunctionExponent);
requiredGroup->add(&m_deviceOpen);
for (int i = 0; i < (int)AICD_NUM_REQ_PARAMS; ++i)
{
requiredGroup->add(&m_aicdParameterFields[(AICDParameters) i]);
}
caf::PdmUiGroup* additionalGroup = uiOrdering.addNewGroup("Additional Parameters");
additionalGroup->add(&m_deviceOpen);
additionalGroup->add(&m_lengthOfAICD);
additionalGroup->add(&m_criticalWaterInLiquidFractionEmulsions);
additionalGroup->add(&m_emulsionViscosityTransitionRegion);
additionalGroup->add(&m_maxRatioOfEmulsionVisc);
additionalGroup->add(&m_maxFlowRate);
additionalGroup->add(&m_exponentOilFractionInDensityMixCalc);
additionalGroup->add(&m_exponentWaterFractionInDensityMixCalc);
additionalGroup->add(&m_exponentGasFractionInDensityMixCalc);
additionalGroup->add(&m_exponentOilFractionInViscosityMixCalc);
additionalGroup->add(&m_exponentWaterFractionInViscosityMixCalc);
additionalGroup->add(&m_exponentGasFractionInViscosityMixCalc);
for (int i = (int)AICD_LENGTH; i < (int)AICD_NUM_PARAMS; ++i)
{
additionalGroup->add(&m_aicdParameterFields[(AICDParameters) i]);
}
additionalGroup->setCollapsedByDefault(true);
}
@ -171,11 +195,11 @@ void RimWellPathAicdParameters::defineEditorAttribute(const caf::PdmFieldHandle*
//--------------------------------------------------------------------------------------------------
std::set<const caf::PdmField<QString>*> RimWellPathAicdParameters::stringFieldsWithNoValidDefault() const
{
std::set<const caf::PdmField<QString>*> fields = {&m_strengthOfAICD,
&m_densityOfCalibrationFluid,
&m_viscosityOfCalibrationFluid,
&m_volumeFlowRateExponent,
&m_viscosityFunctionExponent};
std::set<const caf::PdmField<QString>*> fields;
for (int i = 0; i < (int)AICD_NUM_REQ_PARAMS; ++i)
{
fields.insert(&m_aicdParameterFields[(AICDParameters) i]);
}
return fields;
}
@ -186,15 +210,15 @@ void RimWellPathAicdParameters::setUnitLabels()
{
if (isMetric())
{
m_densityOfCalibrationFluid.uiCapability()->setUiName("Calibration Fluid Density (kg / m ^ 3)");
m_lengthOfAICD.uiCapability()->setUiName("Length of AICD (m)");
m_maxFlowRate.uiCapability()->setUiName("Max Flow Rate for AICD Device(m ^ 3 / day)");
m_aicdParameterFields[AICD_DENSITY_CALIB_FLUID].uiCapability()->setUiName("Calibration Fluid Density (kg / m ^ 3)");
m_aicdParameterFields[AICD_LENGTH].uiCapability()->setUiName("Length of AICD (m)");
m_aicdParameterFields[AICD_MAX_FLOW_RATE].uiCapability()->setUiName("Max Flow Rate for AICD Device(m ^ 3 / day)");
}
else
{
m_densityOfCalibrationFluid.uiCapability()->setUiName("Calibration Fluid Density (lb / ft ^3)");
m_lengthOfAICD.uiCapability()->setUiName("Length of AICD (ft)");
m_maxFlowRate.uiCapability()->setUiName("Max Flow Rate for AICD Device(ft ^ 3 / day)");
m_aicdParameterFields[AICD_DENSITY_CALIB_FLUID].uiCapability()->setUiName("Calibration Fluid Density (lb / ft ^3)");
m_aicdParameterFields[AICD_LENGTH].uiCapability()->setUiName("Length of AICD (ft)");
m_aicdParameterFields[AICD_MAX_FLOW_RATE].uiCapability()->setUiName("Max Flow Rate for AICD Device(ft ^ 3 / day)");
}
}

View File

@ -21,6 +21,30 @@
#include "cafPdmObject.h"
#include "cafPdmField.h"
#include <array>
enum AICDParameters
{
AICD_STRENGTH = 0,
AICD_DENSITY_CALIB_FLUID,
AICD_VISCOSITY_CALIB_FLUID,
AICD_VOL_FLOW_EXP,
AICD_VISOSITY_FUNC_EXP,
AICD_NUM_REQ_PARAMS,
AICD_LENGTH = AICD_NUM_REQ_PARAMS,
AICD_CRITICAL_WATER_IN_LIQUID_FRAC,
AICD_EMULSION_VISC_TRANS_REGION,
AICD_MAX_RATIO_EMULSION_VISC,
AICD_MAX_FLOW_RATE,
AICD_EXP_OIL_FRAC_DENSITY,
AICD_EXP_WATER_FRAC_DENSITY,
AICD_EXP_GAS_FRAC_DENSITY,
AICD_EXP_OIL_FRAC_VISCOSITY,
AICD_EXP_WATER_FRAC_VISCOSITY,
AICD_EXP_GAS_FRAC_VISCOSITY,
AICD_NUM_PARAMS
};
class RimWellPathAicdParameters : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
@ -29,6 +53,8 @@ public:
~RimWellPathAicdParameters();
bool isValid() const;
bool isOpen() const;
std::array<double, AICD_NUM_PARAMS> doubleValues() const;
protected:
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override;
@ -38,27 +64,8 @@ private:
void setUnitLabels();
bool isMetric() const;
private:
// Required parameters
caf::PdmField<QString> m_strengthOfAICD;
caf::PdmField<QString> m_densityOfCalibrationFluid;
caf::PdmField<QString> m_viscosityOfCalibrationFluid;
caf::PdmField<QString> m_volumeFlowRateExponent;
caf::PdmField<QString> m_viscosityFunctionExponent;
// Additional parameters
caf::PdmField<bool> m_deviceOpen;
caf::PdmField<double> m_lengthOfAICD;
caf::PdmField<QString> m_criticalWaterInLiquidFractionEmulsions;
caf::PdmField<QString> m_emulsionViscosityTransitionRegion;
caf::PdmField<QString> m_maxRatioOfEmulsionVisc;
caf::PdmField<QString> m_maxFlowRate;
caf::PdmField<QString> m_exponentOilFractionInDensityMixCalc;
caf::PdmField<QString> m_exponentWaterFractionInDensityMixCalc;
caf::PdmField<QString> m_exponentGasFractionInDensityMixCalc;
caf::PdmField<QString> m_exponentOilFractionInViscosityMixCalc;
caf::PdmField<QString> m_exponentWaterFractionInViscosityMixCalc;
caf::PdmField<QString> m_exponentGasFractionInViscosityMixCalc;
caf::PdmField<bool> m_deviceOpen;
std::array<caf::PdmField<QString>, AICD_NUM_PARAMS> m_aicdParameterFields;
};

View File

@ -150,6 +150,14 @@ void RimWellPathValve::setUnitSpecificDefaults()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimWellPathAicdParameters* RimWellPathValve::aicdParameters() const
{
return m_aicdParameters();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -51,6 +51,8 @@ public:
double flowCoefficient() const;
void setUnitSpecificDefaults();
const RimWellPathAicdParameters* aicdParameters() const;
static double convertOrificeDiameter(double orificeDiameterUi,
RiaEclipseUnitTools::UnitSystem wellPathUnitSystem,
RiaEclipseUnitTools::UnitSystem wantedUnitSystem);

View File

@ -68,6 +68,7 @@ public:
PERFORATION,
FISHBONES_ICD,
PERFORATION_ICD,
PERFORATION_AICD,
CT_UNDEFINED
};