///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2022 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimRftTopologyCurve.h" #include "RiaColorTables.h" #include "RiaColorTools.h" #include "RiaSummaryTools.h" #include "RifReaderOpmRft.h" #include "RigWellLogCurveData.h" #include "RimDepthTrackPlot.h" #include "RimProject.h" #include "RimRftTools.h" #include "RimSummaryCase.h" #include "RimWellLogPlot.h" #include "RiuPlotCurve.h" CAF_PDM_SOURCE_INIT( RimRftTopologyCurve, "RimRftTopologyCurve" ); namespace caf { template <> void caf::AppEnum::setUp() { addItem( RimRftTopologyCurve::CurveType::PACKER, "PACKER", "Packer" ); addItem( RimRftTopologyCurve::CurveType::TUBING, "TUBING", "Tubing" ); addItem( RimRftTopologyCurve::CurveType::ANNULUS, "ANNULUS", "Annulus" ); addItem( RimRftTopologyCurve::CurveType::DEVICE, "DEVICE", "Device" ); setDefault( RimRftTopologyCurve::CurveType::TUBING ); } } // End namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimRftTopologyCurve::RimRftTopologyCurve() { CAF_PDM_InitObject( "RFT Topology Curve" ); CAF_PDM_InitFieldNoDefault( &m_summaryCase, "SummaryCase", "Summary Case" ); m_summaryCase.uiCapability()->setUiTreeChildrenHidden( true ); CAF_PDM_InitFieldNoDefault( &m_timeStep, "TimeStep", "Time Step" ); CAF_PDM_InitFieldNoDefault( &m_wellName, "WellName", "Well Name" ); CAF_PDM_InitField( &m_segmentBranchIndex, "SegmentBranchIndex", -1, "Branch" ); CAF_PDM_InitFieldNoDefault( &m_segmentBranchType, "SegmentBranchType", "Completion" ); CAF_PDM_InitFieldNoDefault( &m_curveType, "CurveType", "Curve Type" ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimRftTopologyCurve* RimRftTopologyCurve::createPackerCurve( RimSummaryCase* summaryCase, const QDateTime& timeStep, const QString& wellName, int segmentBranchIndex ) { auto* curve = new RimRftTopologyCurve(); curve->setDataSource( summaryCase, timeStep, wellName, segmentBranchIndex ); curve->m_curveType = CurveType::PACKER; return curve; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimRftTopologyCurve* RimRftTopologyCurve::createTopologyCurve( RimSummaryCase* summaryCase, const QDateTime& timeStep, const QString& wellName, int segmentBranchIndex, RiaDefines::RftBranchType branchType ) { auto* curve = new RimRftTopologyCurve(); curve->setDataSource( summaryCase, timeStep, wellName, segmentBranchIndex ); switch ( branchType ) { case RiaDefines::RftBranchType::RFT_TUBING: curve->m_curveType = CurveType::TUBING; break; case RiaDefines::RftBranchType::RFT_DEVICE: curve->m_curveType = CurveType::DEVICE; break; case RiaDefines::RftBranchType::RFT_ANNULUS: curve->m_curveType = CurveType::ANNULUS; break; case RiaDefines::RftBranchType::RFT_UNKNOWN: break; default: break; } curve->m_segmentBranchType = branchType; return curve; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimRftTopologyCurve::setDataSource( RimSummaryCase* summaryCase, const QDateTime& timeStep, const QString& wellName, int segmentBranchIndex ) { m_summaryCase = summaryCase; m_timeStep = timeStep; m_wellName = wellName; m_segmentBranchIndex = segmentBranchIndex; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimRftTopologyCurve::wellName() const { return m_wellName; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimRftTopologyCurve::wellLogChannelUiName() const { return "Topology curve channel"; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimRftTopologyCurve::wellLogChannelUnits() const { return "Topology curve units"; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::Color3f RimRftTopologyCurve::colorForBranchType( CurveType curveType ) { switch ( curveType ) { case RimRftTopologyCurve::CurveType::PACKER: return RiaColorTools::fromQColorTo3f( QColor( "DarkGoldenRod" ) ); break; case RimRftTopologyCurve::CurveType::TUBING: return colorForRftBranchType( RiaDefines::RftBranchType::RFT_TUBING ); break; case RimRftTopologyCurve::CurveType::DEVICE: return colorForRftBranchType( RiaDefines::RftBranchType::RFT_DEVICE ); break; case RimRftTopologyCurve::CurveType::ANNULUS: return colorForRftBranchType( RiaDefines::RftBranchType::RFT_ANNULUS ); break; default: break; } return RiaColorTools::fromQColorTo3f( QColor( "LightBrown" ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::Color3f RimRftTopologyCurve::colorForRftBranchType( RiaDefines::RftBranchType branchType ) { switch ( branchType ) { case RiaDefines::RftBranchType::RFT_TUBING: return RiaColorTools::fromQColorTo3f( QColor( "ForestGreen" ) ); case RiaDefines::RftBranchType::RFT_DEVICE: return RiaColorTools::fromQColorTo3f( QColor( "IndianRed" ) ); case RiaDefines::RftBranchType::RFT_ANNULUS: return RiaColorTools::fromQColorTo3f( QColor( "DeepSkyBlue" ) ); case RiaDefines::RftBranchType::RFT_UNKNOWN: break; default: break; } return RiaColorTools::fromQColorTo3f( QColor( "LightBrown" ) ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimRftTopologyCurve::createCurveAutoName() { return m_curveType().uiText(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimRftTopologyCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { RimPlotCurve::updateFieldUiState(); caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Data Source" ); curveDataGroup->add( &m_summaryCase ); curveDataGroup->add( &m_wellName ); curveDataGroup->add( &m_timeStep ); curveDataGroup->add( &m_curveType ); curveDataGroup->add( &m_segmentBranchIndex ); curveDataGroup->add( &m_segmentBranchType ); RimStackablePlotCurve::defaultUiOrdering( uiOrdering ); uiOrdering.skipRemainingFields( true ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QList RimRftTopologyCurve::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) { if ( !m_summaryCase ) return {}; QList options = RimWellLogCurve::calculateValueOptions( fieldNeedingOptions ); auto reader = m_summaryCase->rftReader(); if ( fieldNeedingOptions == &m_summaryCase ) { options = RiaSummaryTools::optionsForSummaryCases( RimProject::current()->allSummaryCases() ); options.push_front( caf::PdmOptionItemInfo( "None", nullptr ) ); } else if ( fieldNeedingOptions == &m_wellName ) { options = RimRftTools::wellNameOptions( reader ); } else if ( fieldNeedingOptions == &m_timeStep ) { options = RimRftTools::segmentTimeStepOptions( reader, m_wellName ); } else if ( fieldNeedingOptions == &m_segmentBranchIndex ) { options = RimRftTools::segmentBranchIndexOptions( reader, m_wellName(), m_timeStep(), RiaDefines::RftBranchType::RFT_UNKNOWN ); } return options; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimRftTopologyCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) { RimWellLogCurve::fieldChangedByUi( changedField, oldValue, newValue ); this->loadDataAndUpdate( true ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimRftTopologyCurve::onLoadDataAndUpdate( bool updateParentPlot ) { this->RimPlotCurve::updateCurvePresentation( updateParentPlot ); if ( m_summaryCase ) { auto rftReader = dynamic_cast( m_summaryCase->rftReader() ); // Update well path attributes, packers and casing based on RFT data if ( rftReader ) { std::vector depths; std::vector propertyValues; std::vector seglenstValues = RimRftTools::seglenstValues( rftReader, m_wellName, m_timeStep, -1, RiaDefines::RftBranchType::RFT_UNKNOWN ); auto segment = rftReader->segmentForWell( m_wellName, m_timeStep ); auto segmentIndices = segment.segmentIndicesForBranchIndex( m_segmentBranchIndex(), m_segmentBranchType() ); if ( !segmentIndices.empty() ) { // Assign a static property value to each type of curve to make sure they all are separated and // easily visible double curveValue = 1.0; if ( m_segmentBranchType() == RiaDefines::RftBranchType::RFT_TUBING ) curveValue = 2.0; if ( m_segmentBranchType() == RiaDefines::RftBranchType::RFT_DEVICE ) curveValue = 3.0; if ( m_segmentBranchType() == RiaDefines::RftBranchType::RFT_ANNULUS ) curveValue = 4.0; if ( m_curveType() == CurveType::PACKER ) { curveValue = 4.0; } // Adjust the location of each branch if multiple branches are visible at the same time curveValue += m_segmentBranchIndex() * 0.2; if ( m_curveType() == RimRftTopologyCurve::CurveType::PACKER ) { auto packerSegmentIndices = segment.packerSegmentIndicesOnAnnulus( m_segmentBranchIndex() ); for ( auto segmentIndex : packerSegmentIndices ) { depths.push_back( seglenstValues[segmentIndex] ); propertyValues.push_back( curveValue ); } } else { for ( auto segmentIndex : segmentIndices ) { depths.push_back( seglenstValues[segmentIndex] ); propertyValues.push_back( curveValue ); } } } RimDepthTrackPlot* wellLogPlot; firstAncestorOrThisOfTypeAsserted( wellLogPlot ); RimWellLogPlot::DepthTypeEnum depthType = wellLogPlot->depthType(); RiaDefines::DepthUnitType displayUnit = wellLogPlot->depthUnit(); bool isExtractionCurve = false; bool useLogarithmicScale = false; setPropertyValuesAndDepths( propertyValues, depths, depthType, 0.0, displayUnit, isExtractionCurve, useLogarithmicScale ); // Assign curve values based on horizontal or vertical plot setPropertyAndDepthValuesToPlotCurve( propertyValues, depths ); if ( updateParentPlot ) { updateZoomInParentPlot(); } if ( m_parentPlot ) { m_parentPlot->replot(); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimRftTopologyCurve::setAdditionalDataSources( const std::vector& additionalDataSources ) { m_additionalDataSources.setValue( additionalDataSources ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimRftTopologyCurve::applyDefaultAppearance() { auto color = colorForBranchType( m_curveType() ); setColor( color ); if ( m_curveType() == RimRftTopologyCurve::CurveType::PACKER ) { int adjustedSymbolSize = symbolSize() * 2; setSymbolSize( adjustedSymbolSize ); setLineStyle( RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_NONE ); setSymbol( RiuPlotCurveSymbol::PointSymbolEnum::SYMBOL_RECT ); } else { if ( m_curveType() == RimRftTopologyCurve::CurveType::TUBING ) { setLineThickness( 5.0 ); } else if ( m_curveType() == RimRftTopologyCurve::CurveType::DEVICE ) { setSymbolEdgeColor( color ); setLineStyle( RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_NONE ); } else if ( m_curveType() == RimRftTopologyCurve::CurveType::ANNULUS ) { setSymbolEdgeColor( color ); setLineStyle( RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_NONE ); } int adjustedSymbolSize = symbolSize() * 1.5; setSymbolSize( adjustedSymbolSize ); setSymbol( RiuPlotCurveSymbol::PointSymbolEnum::SYMBOL_ELLIPSE ); } }