diff --git a/ApplicationLibCode/FileInterface/RifStimPlanXmlReader.cpp b/ApplicationLibCode/FileInterface/RifStimPlanXmlReader.cpp index e3694a7c3d..2c08b87ee2 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanXmlReader.cpp +++ b/ApplicationLibCode/FileInterface/RifStimPlanXmlReader.cpp @@ -32,7 +32,8 @@ //-------------------------------------------------------------------------------------------------- /// Internal functions //-------------------------------------------------------------------------------------------------- -bool hasNegativeValues( std::vector xs ); +bool hasNegativeValues( std::vector xs ); +RigStimPlanFractureDefinition::Orientation mapTextToOrientation( const QString text ); //-------------------------------------------------------------------------------------------------- /// @@ -105,18 +106,18 @@ cvf::ref RifStimPlanXmlReader::readStimPlanXMLFil if ( xmlStream2.isStartElement() ) { - if ( xmlStream2.name() == "properties" ) + if ( isTextEqual( xmlStream2.name(), "properties" ) ) { propertiesElementCount++; } - else if ( xmlStream2.name() == "property" ) + else if ( isTextEqual( xmlStream2.name(), "property" ) ) { unit = getAttributeValueString( xmlStream2, "uom" ); parameter = getAttributeValueString( xmlStream2, "name" ); RiaLogging::info( QString( "%1 [%2]" ).arg( parameter, unit ) ); } - else if ( xmlStream2.name() == "time" ) + else if ( isTextEqual( xmlStream2.name(), "time" ) ) { double timeStepValue = getAttributeValueDouble( xmlStream2, "value" ); @@ -185,6 +186,9 @@ void RifStimPlanXmlReader::readStimplanGridAndTimesteps( QXmlStreamReader& double tvdToBotPerf = HUGE_VAL; double mdToTopPerf = HUGE_VAL; double mdToBotPerf = HUGE_VAL; + double formationDip = HUGE_VAL; + + RigStimPlanFractureDefinition::Orientation orientation = RigStimPlanFractureDefinition::Orientation::UNDEFINED; int gridSectionCount = 0; @@ -197,16 +201,16 @@ void RifStimPlanXmlReader::readStimplanGridAndTimesteps( QXmlStreamReader& { RiaDefines::EclipseUnitSystem destinationUnit = requiredUnit; - if ( xmlStream.name() == "grid" ) + if ( isTextEqual( xmlStream.name(), "grid" ) ) { // Support for one grid per file if ( gridSectionCount < 1 ) { QString gridunit = getAttributeValueString( xmlStream, "uom" ); - if ( gridunit == "m" ) + if ( gridunit.compare( "m", Qt::CaseInsensitive ) == 0 ) stimPlanFileData->m_unitSet = RiaDefines::EclipseUnitSystem::UNITS_METRIC; - else if ( gridunit == "ft" ) + else if ( gridunit.compare( "ft", Qt::CaseInsensitive ) == 0 ) stimPlanFileData->m_unitSet = RiaDefines::EclipseUnitSystem::UNITS_FIELD; else stimPlanFileData->m_unitSet = RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN; @@ -232,32 +236,42 @@ void RifStimPlanXmlReader::readStimplanGridAndTimesteps( QXmlStreamReader& gridSectionCount++; } - else if ( xmlStream.name() == "perf" ) + else if ( isTextEqual( xmlStream.name(), "perf" ) ) { QString perfUnit = getAttributeValueString( xmlStream, "uom" ); QString fracName = getAttributeValueString( xmlStream, "frac" ); } - else if ( xmlStream.name() == "topTVD" ) + else if ( isTextEqual( xmlStream.name(), "topTVD" ) ) { auto valText = xmlStream.readElementText(); tvdToTopPerf = valText.toDouble(); } - else if ( xmlStream.name() == "bottomTVD" ) + else if ( isTextEqual( xmlStream.name(), "bottomTVD" ) ) { auto valText = xmlStream.readElementText(); tvdToBotPerf = valText.toDouble(); } - else if ( xmlStream.name() == "topMD" ) + else if ( isTextEqual( xmlStream.name(), "topMD" ) ) { auto valText = xmlStream.readElementText(); mdToTopPerf = valText.toDouble(); } - else if ( xmlStream.name() == "bottomMD" ) + else if ( isTextEqual( xmlStream.name(), "bottomMD" ) ) { auto valText = xmlStream.readElementText(); mdToBotPerf = valText.toDouble(); } - else if ( xmlStream.name() == "xs" ) + else if ( isTextEqual( xmlStream.name(), "FmDip" ) ) + { + auto valText = xmlStream.readElementText(); + formationDip = valText.toDouble(); + } + else if ( isTextEqual( xmlStream.name(), "orientation" ) ) + { + auto valText = xmlStream.readElementText(); + orientation = mapTextToOrientation( valText.trimmed() ); + } + else if ( isTextEqual( xmlStream.name(), "xs" ) ) { std::vector gridValuesXs; { @@ -272,8 +286,8 @@ void RifStimPlanXmlReader::readStimplanGridAndTimesteps( QXmlStreamReader& stimPlanFileData->m_fileXs = gridValuesXs; - stimPlanFileData->generateXsFromFileXs( mirrorMode == MIRROR_AUTO ? !hasNegativeValues( gridValuesXs ) - : (bool)mirrorMode ); + stimPlanFileData->generateXsFromFileXs( + mirrorMode == MirrorMode::MIRROR_AUTO ? !hasNegativeValues( gridValuesXs ) : (bool)mirrorMode ); } else if ( xmlStream.name() == "ys" ) { @@ -324,6 +338,16 @@ void RifStimPlanXmlReader::readStimplanGridAndTimesteps( QXmlStreamReader& stimPlanFileData->setMdToBottomPerf( mdToBotPerf ); } + if ( formationDip != HUGE_VAL ) + { + stimPlanFileData->setFormationDip( formationDip ); + } + + if ( orientation != RigStimPlanFractureDefinition::Orientation::UNDEFINED ) + { + stimPlanFileData->setOrientation( orientation ); + } + if ( startNegValuesYs > 0 ) { RiaLogging::error( QString( "Negative depth values detected in XML file" ) ); @@ -337,11 +361,11 @@ std::vector> RifStimPlanXmlReader::getAllDepthDataAtTimeStep { std::vector> propertyValuesAtTimestep; - while ( !( xmlStream.isEndElement() && xmlStream.name() == "time" ) ) + while ( !( xmlStream.isEndElement() && isTextEqual( xmlStream.name(), "time" ) ) ) { xmlStream.readNext(); - if ( xmlStream.name() == "depth" ) + if ( isTextEqual( xmlStream.name(), "depth" ) ) { xmlStream.readElementText().toDouble(); std::vector propertyValuesAtDepth; @@ -432,6 +456,14 @@ double RifStimPlanXmlReader::valueInRequiredUnitSystem( RiaDefines::EclipseUnitS return value; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifStimPlanXmlReader::isTextEqual( const QStringRef& text, const QString& compareText ) +{ + return text.compare( compareText, Qt::CaseInsensitive ) == 0; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -442,7 +474,7 @@ void RifStimPlanXmlReader::getGriddingValues( QXmlStreamReader& xmlStream, QString gridValuesString = xmlStream.readElementText().replace( '\n', ' ' ); gridValuesString = gridValuesString.replace( '[', ' ' ).replace( ']', ' ' ); - for ( QString value : gridValuesString.split( ' ', QString::SkipEmptyParts ) ) + for ( const QString& value : gridValuesString.split( ' ', QString::SkipEmptyParts ) ) { if ( value.size() > 0 ) { @@ -461,7 +493,7 @@ double RifStimPlanXmlReader::getAttributeValueDouble( QXmlStreamReader& xmlStrea double value = HUGE_VAL; for ( const QXmlStreamAttribute& attr : xmlStream.attributes() ) { - if ( attr.name() == parameterName ) + if ( isTextEqual( attr.name(), parameterName ) ) { value = attr.value().toString().toDouble(); } @@ -477,7 +509,7 @@ QString RifStimPlanXmlReader::getAttributeValueString( QXmlStreamReader& xmlStre QString parameterValue; for ( const QXmlStreamAttribute& attr : xmlStream.attributes() ) { - if ( attr.name() == parameterName ) + if ( isTextEqual( attr.name(), parameterName ) ) { parameterValue = attr.value().toString(); } @@ -492,3 +524,22 @@ bool hasNegativeValues( std::vector xs ) { return xs[0] < -RigStimPlanFractureDefinition::THRESHOLD_VALUE; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigStimPlanFractureDefinition::Orientation mapTextToOrientation( const QString text ) +{ + if ( text.compare( "transverse", Qt::CaseInsensitive ) == 0 ) + { + return RigStimPlanFractureDefinition::Orientation::TRANSVERSE; + } + else if ( text.compare( "longitudinal", Qt::CaseInsensitive ) == 0 ) + { + return RigStimPlanFractureDefinition::Orientation::LONGITUDINAL; + } + else + { + return RigStimPlanFractureDefinition::Orientation::UNDEFINED; + } +} diff --git a/ApplicationLibCode/FileInterface/RifStimPlanXmlReader.h b/ApplicationLibCode/FileInterface/RifStimPlanXmlReader.h index cbcb3c3d61..e734223772 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanXmlReader.h +++ b/ApplicationLibCode/FileInterface/RifStimPlanXmlReader.h @@ -28,11 +28,12 @@ class RigStimPlanFractureDefinition; class QXmlStreamReader; +class QStringRef; class RifStimPlanXmlReader { public: - enum MirrorMode + enum class MirrorMode { MIRROR_OFF = 0, MIRROR_ON = 1, @@ -64,4 +65,6 @@ private: static double valueInRequiredUnitSystem( RiaDefines::EclipseUnitSystem sourceUnit, RiaDefines::EclipseUnitSystem requiredUnit, double value ); + + static bool isTextEqual( const QStringRef& text, const QString& compareText ); }; diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp index 1e681eb169..b8e0f83817 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp @@ -886,8 +886,10 @@ void RimFracture::setFractureTemplate( RimFractureTemplate* fractureTemplate ) RimStimPlanFractureTemplate* stimPlanFracTemplate = dynamic_cast( fractureTemplate ); if ( stimPlanFracTemplate ) { - m_stimPlanTimeIndexToPlot = stimPlanFracTemplate->activeTimeStepIndex(); - m_wellPathDepthAtFracture = stimPlanFracTemplate->wellPathDepthAtFracture(); + m_stimPlanTimeIndexToPlot = stimPlanFracTemplate->activeTimeStepIndex(); + m_wellPathDepthAtFracture = stimPlanFracTemplate->wellPathDepthAtFracture(); + double templateFormationDip = stimPlanFracTemplate->formationDip(); + if ( templateFormationDip != HUGE_VAL ) m_dip = templateFormationDip; } else { diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.cpp index 9d6333139b..311b7bcae1 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.cpp @@ -218,6 +218,15 @@ void RimStimPlanFractureTemplate::setDefaultsBasedOnXMLfile() else RiaLogging::info( QString( "Property for polygon calculation not set." ) ); + if ( m_stimPlanFractureDefinitionData->orientation() == RigStimPlanFractureDefinition::Orientation::TRANSVERSE ) + { + m_orientationType = TRANSVERSE_WELL_PATH; + } + else if ( m_stimPlanFractureDefinitionData->orientation() == RigStimPlanFractureDefinition::Orientation::LONGITUDINAL ) + { + m_orientationType = ALONG_WELL_PATH; + } + if ( !m_stimPlanFractureDefinitionData->conductivityResultNames().isEmpty() ) { m_conductivityResultNameOnFile = m_stimPlanFractureDefinitionData->conductivityResultNames().front(); @@ -264,11 +273,12 @@ void RimStimPlanFractureTemplate::loadDataAndUpdate() if ( m_readError ) return; - m_stimPlanFractureDefinitionData = RifStimPlanXmlReader::readStimPlanXMLFile( m_stimPlanFileName().path(), - m_conductivityScaleFactor(), - RifStimPlanXmlReader::MIRROR_AUTO, - fractureTemplateUnit(), - &errorMessage ); + m_stimPlanFractureDefinitionData = + RifStimPlanXmlReader::readStimPlanXMLFile( m_stimPlanFileName().path(), + m_conductivityScaleFactor(), + RifStimPlanXmlReader::MirrorMode::MIRROR_AUTO, + fractureTemplateUnit(), + &errorMessage ); if ( errorMessage.size() > 0 ) RiaLogging::error( errorMessage ); if ( m_stimPlanFractureDefinitionData.notNull() ) @@ -1121,3 +1131,13 @@ QString RimStimPlanFractureTemplate::wellPathDepthAtFractureUiName() const { return "Well/Fracture Intersection Depth"; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimStimPlanFractureTemplate::formationDip() const +{ + if ( m_stimPlanFractureDefinitionData.isNull() ) return HUGE_VAL; + + return m_stimPlanFractureDefinitionData->formationDip(); +} diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.h b/ApplicationLibCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.h index dfd5fe83ec..cf0289d901 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.h @@ -99,6 +99,8 @@ public: void convertToUnitSystem( RiaDefines::EclipseUnitSystem neededUnit ) override; + double formationDip() const; + protected: void initAfterRead() override; diff --git a/ApplicationLibCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp b/ApplicationLibCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp index 37f7c221f0..fa1b5d820d 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp @@ -52,6 +52,8 @@ RigStimPlanFractureDefinition::RigStimPlanFractureDefinition() , m_bottomPerfTvd( HUGE_VAL ) , m_topPerfMd( HUGE_VAL ) , m_bottomPerfMd( HUGE_VAL ) + , m_formationDip( HUGE_VAL ) + , m_orientation( Orientation::UNDEFINED ) { } @@ -733,3 +735,35 @@ size_t findMirrorXIndex( std::vector xs ) return mirrorIndex; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigStimPlanFractureDefinition::formationDip() const +{ + return m_formationDip; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStimPlanFractureDefinition::setFormationDip( double formationDip ) +{ + m_formationDip = formationDip; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigStimPlanFractureDefinition::Orientation RigStimPlanFractureDefinition::orientation() const +{ + return m_orientation; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStimPlanFractureDefinition::setOrientation( RigStimPlanFractureDefinition::Orientation orientation ) +{ + m_orientation = orientation; +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigStimPlanFractureDefinition.h b/ApplicationLibCode/ReservoirDataModel/RigStimPlanFractureDefinition.h index 0c2a0f4289..5c6d69043b 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigStimPlanFractureDefinition.h +++ b/ApplicationLibCode/ReservoirDataModel/RigStimPlanFractureDefinition.h @@ -56,6 +56,13 @@ class RigStimPlanFractureDefinition : public cvf::Object public: static const double THRESHOLD_VALUE; + enum class Orientation + { + UNDEFINED, + TRANSVERSE, + LONGITUDINAL + }; + RigStimPlanFractureDefinition(); ~RigStimPlanFractureDefinition() override; @@ -75,6 +82,12 @@ public: void setMdToTopPerf( double topPerfMd ); void setMdToBottomPerf( double bottomPerfMd ); + double formationDip() const; + void setFormationDip( double formationDip ); + + Orientation orientation() const; + void setOrientation( Orientation orientation ); + cvf::cref createFractureGrid( const QString& resultName, int activeTimeStepIndex, double xScaleFactor, @@ -148,4 +161,7 @@ private: double m_bottomPerfTvd; double m_topPerfMd; double m_bottomPerfMd; + + double m_formationDip; + Orientation m_orientation; }; diff --git a/ApplicationLibCode/UnitTests/RifStimPlanXmlReader-Test.cpp b/ApplicationLibCode/UnitTests/RifStimPlanXmlReader-Test.cpp index 61be3491eb..4a91e3f5f0 100644 --- a/ApplicationLibCode/UnitTests/RifStimPlanXmlReader-Test.cpp +++ b/ApplicationLibCode/UnitTests/RifStimPlanXmlReader-Test.cpp @@ -17,7 +17,7 @@ TEST( RifStimPlanXmlReaderTest, LoadFile ) double conductivityScaleFactor = 1.0; RiaDefines::EclipseUnitSystem unit = RiaDefines::EclipseUnitSystem::UNITS_METRIC; QString errorMessage; - RifStimPlanXmlReader::MirrorMode mode = RifStimPlanXmlReader::MIRROR_AUTO; + RifStimPlanXmlReader::MirrorMode mode = RifStimPlanXmlReader::MirrorMode::MIRROR_AUTO; cvf::ref fractureData; @@ -43,7 +43,7 @@ TEST( RifStimPlanXmlReaderTest, LoadFileNewFormat ) double conductivityScaleFactor = 1.0; RiaDefines::EclipseUnitSystem unit = RiaDefines::EclipseUnitSystem::UNITS_METRIC; QString errorMessage; - RifStimPlanXmlReader::MirrorMode mode = RifStimPlanXmlReader::MIRROR_AUTO; + RifStimPlanXmlReader::MirrorMode mode = RifStimPlanXmlReader::MirrorMode::MIRROR_AUTO; cvf::ref fractureData; @@ -63,3 +63,27 @@ TEST( RifStimPlanXmlReaderTest, LoadFileNewFormat ) EXPECT_DOUBLE_EQ( 2804.160, fractureData->topPerfMd() ); EXPECT_DOUBLE_EQ( 2804.770, fractureData->bottomPerfMd() ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RifStimPlanXmlReaderTest, LoadFileNewFormatExtraParameters ) +{ + QString fileName = CASE_REAL_TEST_DATA_DIRECTORY + "contour_with_extra_parameters.xml"; + + double conductivityScaleFactor = 1.0; + RiaDefines::EclipseUnitSystem unit = RiaDefines::EclipseUnitSystem::UNITS_METRIC; + QString errorMessage; + RifStimPlanXmlReader::MirrorMode mode = RifStimPlanXmlReader::MirrorMode::MIRROR_AUTO; + + cvf::ref fractureData; + + fractureData = + RifStimPlanXmlReader::readStimPlanXMLFile( fileName, conductivityScaleFactor, mode, unit, &errorMessage ); + + EXPECT_TRUE( errorMessage.isEmpty() ); + EXPECT_TRUE( fractureData.notNull() ); + + EXPECT_DOUBLE_EQ( 12.34, fractureData->formationDip() ); + EXPECT_EQ( fractureData->orientation(), RigStimPlanFractureDefinition::Orientation::TRANSVERSE ); +} diff --git a/ApplicationLibCode/UnitTests/TestData/RifStimPlanXmlReader/contour_with_extra_parameters.xml b/ApplicationLibCode/UnitTests/TestData/RifStimPlanXmlReader/contour_with_extra_parameters.xml new file mode 100644 index 0000000000..a1cbcd8f5c --- /dev/null +++ b/ApplicationLibCode/UnitTests/TestData/RifStimPlanXmlReader/contour_with_extra_parameters.xml @@ -0,0 +1,491 @@ + + + transverse + 12.34 + + [0.000 9.144 18.288 27.432 36.576 45.720 54.864 64.008 73.152 82.296 91.440 100.584 109.728 118.872 128.016 137.160 146.304 155.448 164.592 173.736 182.880 192.024 201.168 210.312 219.456 ] + [2858.516 2849.880 2841.244 2832.608 2823.972 2820.665 2817.358 2808.321 2799.283 2794.284 2789.286 2781.188 2773.091 2764.993 2760.345 2755.697 2751.277 2746.858 2738.323 2729.789 2721.254 2712.720 2704.186 ] + + + 2773.680 + 2773.680 + 2804.160 + 2804.770 + + + + + + + + + + + + + + [0.000 9.144 18.288 27.432 36.576 45.720 54.864 64.008 73.152 82.296 91.440 100.584 109.728 118.872 128.016 137.160 146.304 155.448 164.592 173.736 182.880 192.024 201.168 210.312 219.456 ] + [2858.516 2849.880 2841.244 2832.608 2823.972 2820.665 2817.358 2808.321 2799.283 2794.284 2789.286 2781.188 2773.091 2764.993 2760.345 2755.697 2751.277 2746.858 2738.323 2729.789 2721.254 2712.720 2704.186 ] + + + 2773.680 + 2773.680 + 2819.400 + 2820.010 + + + + + + + + + + + + + + [0.000 9.144 18.288 27.432 36.576 45.720 54.864 64.008 73.152 82.296 91.440 100.584 109.728 118.872 128.016 137.160 146.304 155.448 164.592 173.736 182.880 192.024 201.168 210.312 219.456 ] + [2858.516 2849.880 2841.244 2832.608 2823.972 2820.665 2817.358 2808.321 2799.283 2794.284 2789.286 2781.188 2773.091 2764.993 2760.345 2755.697 2751.277 2746.858 2738.323 2729.789 2721.254 2712.720 2704.186 ] + + + 2773.680 + 2773.680 + 2834.640 + 2835.250 + + + + + + + + + + + + +