mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-24 22:27:55 -05:00
Move Pressure Drop and Length and Depth from the segment collection to the well path completion settings. PRESSURE_COMPONENTS is now a dated WELSPECS attribute used for the WELSEGS header at export, and is rejected on SEGMENT events.
322 lines
15 KiB
C++
322 lines
15 KiB
C++
#include "gtest/gtest.h"
|
|
|
|
#include "RimCustomSegmentIntervalCollection.h"
|
|
#include "RimDiameterRoughnessInterval.h"
|
|
#include "RimDiameterRoughnessIntervalCollection.h"
|
|
#include "RimMswCompletionParameters.h"
|
|
#include "RimSegmentCollection.h"
|
|
#include "RimSegmentInterval.h"
|
|
#include "RimWellPath.h"
|
|
#include "RimWellPathCompletionSettings.h"
|
|
#include "RimWellPathCompletions.h"
|
|
|
|
#include "cafPdmDefaultObjectFactory.h"
|
|
#include "cafPdmUiFieldHandle.h"
|
|
#include "cafPdmUiObjectHandle.h"
|
|
#include "cafPdmUiOrdering.h"
|
|
#include "cafPdmUiTreeOrdering.h"
|
|
|
|
#include <memory>
|
|
|
|
TEST( RimWellPathCompletions, SegmentIntervalsDefineCustomSegmentation )
|
|
{
|
|
RimWellPath wellPath;
|
|
auto* segments = wellPath.segmentCollection();
|
|
|
|
segments->setLinerDiameter( 0.18 );
|
|
segments->setRoughnessFactor( 3.0e-5 );
|
|
auto* interval = segments->createInterval( 100.0, 200.0, 0.12, 2.0e-5 );
|
|
|
|
ASSERT_NE( nullptr, interval );
|
|
EXPECT_TRUE( segments->hasCustomSegmentIntervals() );
|
|
EXPECT_EQ( ( std::vector<std::pair<double, double>>{ { 100.0, 200.0 } } ), segments->getSegmentIntervals() );
|
|
EXPECT_DOUBLE_EQ( 0.12, segments->getDiameterAtMD( 150.0, RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
EXPECT_DOUBLE_EQ( 2.0e-5, segments->getRoughnessAtMD( 150.0, RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
EXPECT_DOUBLE_EQ( 0.18, segments->getDiameterAtMD( 250.0, RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
EXPECT_DOUBLE_EQ( 3.0e-5, segments->getRoughnessAtMD( 250.0, RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, SegmentIntervalFixedLengthIsExclusiveWithMinMax )
|
|
{
|
|
RimSegmentInterval interval;
|
|
EXPECT_FALSE( interval.fixedSegmentLength().has_value() );
|
|
EXPECT_FALSE( interval.minSegmentLength().has_value() );
|
|
EXPECT_FALSE( interval.maxSegmentLength().has_value() );
|
|
|
|
// Min and max can be combined
|
|
interval.setMinSegmentLength( 12.0 );
|
|
interval.setMaxSegmentLength( 30.0 );
|
|
EXPECT_EQ( std::optional<double>( 12.0 ), interval.minSegmentLength() );
|
|
EXPECT_EQ( std::optional<double>( 30.0 ), interval.maxSegmentLength() );
|
|
|
|
// Fixed replaces min and max
|
|
interval.setFixedSegmentLength( 20.0 );
|
|
EXPECT_EQ( std::optional<double>( 20.0 ), interval.fixedSegmentLength() );
|
|
EXPECT_FALSE( interval.minSegmentLength().has_value() );
|
|
EXPECT_FALSE( interval.maxSegmentLength().has_value() );
|
|
|
|
// Min or max replaces fixed
|
|
interval.setMaxSegmentLength( 8.0 );
|
|
EXPECT_FALSE( interval.fixedSegmentLength().has_value() );
|
|
EXPECT_EQ( std::optional<double>( 8.0 ), interval.maxSegmentLength() );
|
|
|
|
interval.setMinSegmentLength( std::nullopt );
|
|
EXPECT_FALSE( interval.minSegmentLength().has_value() );
|
|
|
|
// A length <= 0 is treated as not set
|
|
interval.setMaxSegmentLength( 0.0 );
|
|
EXPECT_FALSE( interval.maxSegmentLength().has_value() );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, SegmentIntervalSegmentationControlsArePersisted )
|
|
{
|
|
RimSegmentInterval original;
|
|
original.setMaxSegmentLength( 25.0 );
|
|
original.setMinSegmentLength( 5.0 );
|
|
const QString xml = original.writeObjectToXmlString();
|
|
|
|
RimSegmentInterval restored;
|
|
restored.readObjectFromXmlString( xml, caf::PdmDefaultObjectFactory::instance() );
|
|
EXPECT_FALSE( restored.fixedSegmentLength().has_value() );
|
|
EXPECT_EQ( std::optional<double>( 5.0 ), restored.minSegmentLength() );
|
|
EXPECT_EQ( std::optional<double>( 25.0 ), restored.maxSegmentLength() );
|
|
|
|
// A project written before the controls existed has all controls off
|
|
RimSegmentInterval legacy;
|
|
legacy.readObjectFromXmlString( "<SegmentInterval><StartMd>100</StartMd><EndMd>200</EndMd></SegmentInterval>",
|
|
caf::PdmDefaultObjectFactory::instance() );
|
|
EXPECT_FALSE( legacy.fixedSegmentLength().has_value() );
|
|
EXPECT_FALSE( legacy.minSegmentLength().has_value() );
|
|
EXPECT_FALSE( legacy.maxSegmentLength().has_value() );
|
|
EXPECT_DOUBLE_EQ( 200.0, legacy.endMD() );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, SegmentIntervalUiUsesMeasuredDepthNameAndMetricUnits )
|
|
{
|
|
RimWellPath wellPath;
|
|
auto* interval = wellPath.segmentCollection()->createInterval( 100.0, 200.0, 0.12, 2.0e-5 );
|
|
|
|
std::unique_ptr<caf::PdmUiTreeOrdering> treeOrdering( interval->uiCapability()->uiTreeOrdering() );
|
|
ASSERT_NE( nullptr, treeOrdering );
|
|
EXPECT_EQ( "100 - 200", interval->uiCapability()->uiName() );
|
|
|
|
caf::PdmUiOrdering uiOrdering;
|
|
interval->uiCapability()->uiOrdering( "", uiOrdering );
|
|
|
|
ASSERT_NE( nullptr, interval->findField( "StartMd" ) );
|
|
ASSERT_NE( nullptr, interval->findField( "EndMd" ) );
|
|
ASSERT_NE( nullptr, interval->findField( "Diameter" ) );
|
|
ASSERT_NE( nullptr, interval->findField( "RoughnessFactor" ) );
|
|
EXPECT_EQ( "Start MD [m]", interval->findField( "StartMd" )->uiCapability()->uiName() );
|
|
EXPECT_EQ( "End MD [m]", interval->findField( "EndMd" )->uiCapability()->uiName() );
|
|
EXPECT_EQ( "Diameter [m]", interval->findField( "Diameter" )->uiCapability()->uiName() );
|
|
EXPECT_EQ( "Roughness Factor [m]", interval->findField( "RoughnessFactor" )->uiCapability()->uiName() );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, SegmentIntervalUiUsesFieldUnits )
|
|
{
|
|
RimWellPath wellPath;
|
|
wellPath.setUnitSystem( RiaDefines::EclipseUnitSystem::UNITS_FIELD );
|
|
auto* interval = wellPath.segmentCollection()->createInterval( 100.0, 200.0, 0.5, 3.28e-5 );
|
|
|
|
caf::PdmUiOrdering uiOrdering;
|
|
interval->uiCapability()->uiOrdering( "", uiOrdering );
|
|
|
|
EXPECT_EQ( "Start MD [ft]", interval->findField( "StartMd" )->uiCapability()->uiName() );
|
|
EXPECT_EQ( "End MD [ft]", interval->findField( "EndMd" )->uiCapability()->uiName() );
|
|
EXPECT_EQ( "Diameter [ft]", interval->findField( "Diameter" )->uiCapability()->uiName() );
|
|
EXPECT_EQ( "Roughness Factor [ft]", interval->findField( "RoughnessFactor" )->uiCapability()->uiName() );
|
|
EXPECT_DOUBLE_EQ( 0.5, interval->diameter( RiaDefines::EclipseUnitSystem::UNITS_FIELD ) );
|
|
EXPECT_DOUBLE_EQ( 0.1524, interval->diameter( RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, LegacySegmentIntervalsAreMergedByBounds )
|
|
{
|
|
RimMswCompletionParameters legacyParameters;
|
|
legacyParameters.setLinerDiameter( 0.2 );
|
|
legacyParameters.setRoughnessFactor( 3.0e-5 );
|
|
legacyParameters.setDiameterRoughnessMode( RimMswCompletionParameters::DiameterRoughnessMode::INTERVALS );
|
|
legacyParameters.diameterRoughnessIntervals()->createInterval( 100.0, 200.0, 0.12, 2.0e-5 );
|
|
legacyParameters.customSegmentIntervals()->createInterval( 100.0 + 0.5e-6, 200.0 - 0.5e-6 );
|
|
legacyParameters.customSegmentIntervals()->createInterval( 300.0, 400.0 );
|
|
|
|
RimSegmentCollection segments;
|
|
segments.importLegacyData( &legacyParameters );
|
|
|
|
const auto intervals = segments.intervals();
|
|
ASSERT_EQ( 2, intervals.size() );
|
|
EXPECT_DOUBLE_EQ( 0.12, intervals[0]->diameter() );
|
|
EXPECT_DOUBLE_EQ( 2.0e-5, intervals[0]->roughnessFactor() );
|
|
EXPECT_DOUBLE_EQ( 300.0, intervals[1]->startMD() );
|
|
EXPECT_DOUBLE_EQ( 400.0, intervals[1]->endMD() );
|
|
EXPECT_DOUBLE_EQ( 0.2, intervals[1]->diameter() );
|
|
EXPECT_DOUBLE_EQ( 3.0e-5, intervals[1]->roughnessFactor() );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, LegacyUniformDiameterIntervalsRemainInactive )
|
|
{
|
|
RimMswCompletionParameters legacyParameters;
|
|
legacyParameters.diameterRoughnessIntervals()->createInterval( 100.0, 200.0, 0.12, 2.0e-5 );
|
|
|
|
RimSegmentCollection segments;
|
|
segments.importLegacyData( &legacyParameters );
|
|
|
|
EXPECT_TRUE( segments.intervals().empty() );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, LegacyMigrationPreservesDisabledSettings )
|
|
{
|
|
RimMswCompletionParameters legacyParameters;
|
|
legacyParameters.setManualReferenceMD( 123.0 );
|
|
auto* maxLength = dynamic_cast<caf::PdmField<double>*>( legacyParameters.findField( "MaxSegmentLength" ) );
|
|
auto* customValues = dynamic_cast<caf::PdmField<bool>*>( legacyParameters.findField( "CustomValuesForLateral" ) );
|
|
ASSERT_NE( nullptr, maxLength );
|
|
ASSERT_NE( nullptr, customValues );
|
|
maxLength->setValue( 345.0 );
|
|
customValues->setValue( true );
|
|
legacyParameters.setPressureDrop( RimMswCompletionParameters::PressureDropType::HYDROSTATIC_FRICTION_ACCELERATION );
|
|
legacyParameters.setLengthAndDepth( RimMswCompletionParameters::LengthAndDepthType::INC );
|
|
|
|
RimSegmentCollection segments;
|
|
segments.importLegacyData( &legacyParameters );
|
|
RimWellPathCompletionSettings completionSettings;
|
|
completionSettings.importLegacyMswData( &legacyParameters );
|
|
|
|
EXPECT_EQ( RimSegmentCollection::ReferenceMDType::AUTO_REFERENCE_MD, segments.referenceMDType() );
|
|
auto* migratedMaxLength = dynamic_cast<caf::PdmField<double>*>( segments.findField( "MaxSegmentLength" ) );
|
|
auto* migratedCustomValues = dynamic_cast<caf::PdmField<bool>*>( segments.findField( "CustomValuesForLateral" ) );
|
|
auto* enforceMaxLength = dynamic_cast<caf::PdmField<bool>*>( segments.findField( "EnforceMaxSegmentLength" ) );
|
|
ASSERT_NE( nullptr, migratedMaxLength );
|
|
ASSERT_NE( nullptr, migratedCustomValues );
|
|
ASSERT_NE( nullptr, enforceMaxLength );
|
|
EXPECT_DOUBLE_EQ( 345.0, migratedMaxLength->value() );
|
|
EXPECT_TRUE( migratedCustomValues->value() );
|
|
EXPECT_FALSE( enforceMaxLength->value() );
|
|
EXPECT_EQ( RimWellPathCompletionSettings::PressureDropType::HYDROSTATIC_FRICTION_ACCELERATION, completionSettings.pressureDrop() );
|
|
EXPECT_EQ( RimWellPathCompletionSettings::LengthAndDepthType::INC, completionSettings.lengthAndDepth() );
|
|
|
|
segments.setReferenceMDType( RimSegmentCollection::ReferenceMDType::MANUAL_REFERENCE_MD );
|
|
EXPECT_DOUBLE_EQ( 123.0, segments.manualReferenceMD() );
|
|
enforceMaxLength->setValue( true );
|
|
EXPECT_DOUBLE_EQ( 345.0, segments.maxSegmentLength() );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, DefaultLegacySettingsDoNotOverwriteSegments )
|
|
{
|
|
RimMswCompletionParameters legacyParameters;
|
|
RimSegmentCollection segments;
|
|
segments.setLinerDiameter( 0.3 );
|
|
segments.createInterval( 100.0, 200.0, 0.12, 2.0e-5 );
|
|
|
|
segments.importLegacyData( &legacyParameters );
|
|
|
|
EXPECT_DOUBLE_EQ( 0.3, segments.linerDiameter() );
|
|
EXPECT_EQ( 1u, segments.intervals().size() );
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, LegacyMigrationPreservesIntervalDateTime )
|
|
{
|
|
const auto startDate = QDateTime::fromString( "2026-09-14T13:45:12.123+02:00", Qt::ISODateWithMs );
|
|
ASSERT_TRUE( startDate.isValid() );
|
|
for ( bool useCustomDate : { false, true } )
|
|
{
|
|
RimMswCompletionParameters legacyParameters;
|
|
legacyParameters.setDiameterRoughnessMode( RimMswCompletionParameters::DiameterRoughnessMode::INTERVALS );
|
|
auto* oldInterval = legacyParameters.diameterRoughnessIntervals()->createInterval( 100.0, 200.0, 0.12, 2.0e-5 );
|
|
oldInterval->enableCustomStartDate( useCustomDate );
|
|
auto* dateField = dynamic_cast<caf::PdmField<QDateTime>*>( oldInterval->findField( "StartDate" ) );
|
|
ASSERT_NE( nullptr, dateField );
|
|
dateField->setValue( startDate );
|
|
|
|
RimSegmentCollection segments;
|
|
segments.importLegacyData( &legacyParameters );
|
|
|
|
ASSERT_EQ( 1u, segments.intervals().size() );
|
|
auto* interval = segments.intervals().front();
|
|
auto* migratedDate = dynamic_cast<caf::PdmField<QDateTime>*>( interval->findField( "StartDate" ) );
|
|
ASSERT_NE( nullptr, migratedDate );
|
|
EXPECT_EQ( startDate, migratedDate->value() );
|
|
EXPECT_EQ( startDate.offsetFromUtc(), migratedDate->value().offsetFromUtc() );
|
|
EXPECT_EQ( !useCustomDate, interval->isActiveOnDate( startDate.addMSecs( -1 ) ) );
|
|
EXPECT_TRUE( interval->isActiveOnDate( startDate ) );
|
|
}
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, LateralSegmentsInheritTopLevelSettings )
|
|
{
|
|
auto topLevelWell = std::make_unique<RimWellPath>();
|
|
RimWellPath lateral;
|
|
auto* localSegments = lateral.segmentCollection();
|
|
localSegments->setLinerDiameter( 0.1 );
|
|
localSegments->setRoughnessFactor( 1.0e-5 );
|
|
topLevelWell->segmentCollection()->setReferenceMDType( RimSegmentCollection::ReferenceMDType::MANUAL_REFERENCE_MD );
|
|
topLevelWell->segmentCollection()->setManualReferenceMD( 123.0 );
|
|
topLevelWell->segmentCollection()->setLinerDiameter( 0.2 );
|
|
topLevelWell->segmentCollection()->setRoughnessFactor( 3.0e-5 );
|
|
lateral.connectWellPaths( topLevelWell.get(), 100.0 );
|
|
|
|
EXPECT_EQ( localSegments, lateral.segmentCollection() );
|
|
EXPECT_DOUBLE_EQ( 123.0, localSegments->manualReferenceMD() );
|
|
EXPECT_DOUBLE_EQ( 0.2, localSegments->linerDiameter( RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
EXPECT_DOUBLE_EQ( 3.0e-5, localSegments->roughnessFactor( RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
|
|
topLevelWell->segmentCollection()->setManualReferenceMD( 456.0 );
|
|
const RimWellPath& constLateral = lateral;
|
|
EXPECT_DOUBLE_EQ( 456.0, constLateral.segmentCollection()->manualReferenceMD() );
|
|
|
|
topLevelWell.reset();
|
|
EXPECT_EQ( localSegments, lateral.segmentCollection() );
|
|
EXPECT_EQ( localSegments, constLateral.segmentCollection() );
|
|
EXPECT_DOUBLE_EQ( 0.1, localSegments->linerDiameter( RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
EXPECT_DOUBLE_EQ( 1.0e-5, localSegments->roughnessFactor( RiaDefines::EclipseUnitSystem::UNITS_METRIC ) );
|
|
}
|
|
|
|
/*
|
|
#include <QRegExpValidator>
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RimWellPathCompletions, WellNameRegExp )
|
|
{
|
|
std::vector<QString> validNames = { "RASASD", "gf0sdf", "sd-ASD12", "1-AA_b" };
|
|
std::vector<QString> invalidNames = { ".AdSD", "+gf0sdf", "sd ASD12", "ABCDEFGHIJKL" };
|
|
|
|
QRegExp rx = RimWellPathCompletionSettings::wellNameForExportRegExp();
|
|
EXPECT_TRUE( rx.isValid() );
|
|
|
|
for ( QString validName : validNames )
|
|
{
|
|
EXPECT_TRUE( rx.exactMatch( validName ) );
|
|
}
|
|
for ( QString invalidName : invalidNames )
|
|
{
|
|
EXPECT_FALSE( rx.exactMatch( invalidName ) );
|
|
}
|
|
}
|
|
|
|
TEST( RimWellPathCompletions, WellNameRegExpValidator )
|
|
{
|
|
std::vector<QString> validNames = { "RASASD", "gf0sdf", "sd-ASD12", "1-AA_b" };
|
|
std::vector<QString> invalidNames = { ".AdSD", "+gf0sdf", "sd ASD12", "ABCDEFGHIJKL" };
|
|
QString emptyString = "";
|
|
|
|
QRegExp rx = RimWellPathCompletionSettings::wellNameForExportRegExp();
|
|
QRegExpValidator validator( nullptr );
|
|
validator.setRegExp( rx );
|
|
|
|
for ( QString validName : validNames )
|
|
{
|
|
int dummyPos;
|
|
EXPECT_EQ( QValidator::Acceptable, validator.validate( validName, dummyPos ) );
|
|
}
|
|
for ( QString invalidName : invalidNames )
|
|
{
|
|
int dummyPos;
|
|
EXPECT_EQ( QValidator::Invalid, validator.validate( invalidName, dummyPos ) );
|
|
}
|
|
|
|
int dummyPos;
|
|
EXPECT_EQ( QValidator::Intermediate, validator.validate( emptyString, dummyPos ) );
|
|
}
|
|
*/
|