Files
ResInsight/ApplicationLibCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp
T
Magne Sjaastad 93bd0b9c9d Refactor well log track settings into modular classes
* Refactor well log track settings into modular classes

Major refactoring of RimWellLogTrack to delegate property axis, formation, region annotation, and well path attribute settings to dedicated settings classes. Introduces RimWellLogPropertyAxisSettings, RimWellLogFormationSettings, RimWellLogRegionAnnotationSettings, and RimWellLogWellPathAttributeSettings, each encapsulating related fields, UI logic, and option handling. Old fields are retained for migration and backward compatibility. Updates enums and signatures for consistency.
2026-02-09 15:33:18 +01:00

297 lines
10 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RimWellFlowRateCurve.h"
#include "WellLogCommands/RicWellLogPlotCurveFeatureImpl.h"
#include "Well/RigWellLogCurveData.h"
#include "RimWellAllocationPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RiuQwtPlotCurve.h"
#include "RiaColorTools.h"
#include "qwt_plot.h"
#include <QPen>
#include <cmath>
//==================================================================================================
///
///
//==================================================================================================
CAF_PDM_SOURCE_INIT( RimWellFlowRateCurve, "WellFlowRateCurve" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellFlowRateCurve::RimWellFlowRateCurve()
{
CAF_PDM_InitObject( "Flow Rate Curve" );
m_groupId = 0;
m_doFillCurve = true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellFlowRateCurve::~RimWellFlowRateCurve()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseResultCase* RimWellFlowRateCurve::rimCase()
{
RimWellAllocationPlot* wap = wellAllocationPlot();
if ( wap )
{
return wap->rimCase();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimWellFlowRateCurve::timeStep()
{
RimWellAllocationPlot* wap = wellAllocationPlot();
if ( wap )
{
return wap->timeStep();
}
return -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellFlowRateCurve::wellName() const
{
QString name;
RimWellAllocationPlot* wap = wellAllocationPlot();
if ( wap )
{
name = wap->wellName();
}
else
{
name = "Undefined";
}
return name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellFlowRateCurve::wellLogChannelUiName() const
{
return "AccumulatedFlowRate";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellFlowRateCurve::wellLogChannelUnits() const
{
return RiaWellLogUnitTools<double>::noUnitString();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFlowRateCurve::setGroupId( int groupId )
{
m_groupId = groupId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimWellFlowRateCurve::groupId() const
{
return m_groupId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFlowRateCurve::setDoFillCurve( bool doFill )
{
m_doFillCurve = doFill;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellFlowRateCurve::createCurveAutoName()
{
return m_curveAutoName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFlowRateCurve::onLoadDataAndUpdate( bool updateParentPlot )
{
RimPlotCurve::updateCurvePresentation( updateParentPlot );
m_plotCurve->setTitle( createCurveAutoName() );
if ( updateParentPlot )
{
auto track = firstAncestorOrThisOfTypeAsserted<RimWellLogTrack>();
track->updateStackedCurveData();
updateZoomInParentPlot();
}
if ( hasParentPlot() ) m_parentPlot->replot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFlowRateCurve::updateCurveAppearance()
{
RimWellLogCurve::updateCurveAppearance();
bool isLastCurveInGroup = false;
{
auto wellLogTrack = firstAncestorOrThisOfTypeAsserted<RimWellLogTrack>();
std::map<int, std::vector<RimWellLogCurve*>> stackedCurveGroups = wellLogTrack->visibleStackedCurves();
const std::vector<RimWellLogCurve*>& curveGroup = stackedCurveGroups[m_groupId];
if ( !curveGroup.empty() )
{
isLastCurveInGroup = ( curveGroup.back() == this );
}
}
QwtPlotCurve* qwtPlotCurve = dynamic_cast<QwtPlotCurve*>( m_plotCurve );
if ( isUsingConnectionNumberDepthType() && qwtPlotCurve )
{
// Steps style only for Qwt.
qwtPlotCurve->setStyle( QwtPlotCurve::Steps );
}
if ( m_doFillCurve || isLastCurveInGroup ) // Fill the last curve in group with a transparent color to "tie" the
// group together
{
QColor curveQColor = RiaColorTools::toQColor( m_curveAppearance->color() );
QColor fillColor = curveQColor;
QColor lineColor = curveQColor.darker();
if ( !m_doFillCurve && isLastCurveInGroup )
{
fillColor = QColor( 24, 16, 10, 50 );
lineColor = curveQColor;
}
QLinearGradient gradient;
gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
gradient.setColorAt( 0, fillColor.darker( 110 ) );
gradient.setColorAt( 0.15, fillColor );
gradient.setColorAt( 0.25, fillColor );
gradient.setColorAt( 0.4, fillColor.darker( 110 ) );
gradient.setColorAt( 0.6, fillColor );
gradient.setColorAt( 0.8, fillColor.darker( 110 ) );
gradient.setColorAt( 1, fillColor );
m_plotCurve->setBrush( gradient );
if ( qwtPlotCurve )
{
// Baseline and orientation only available for Qwt.
QPen curvePen = qwtPlotCurve->pen();
curvePen.setColor( lineColor );
qwtPlotCurve->setPen( curvePen );
qwtPlotCurve->setOrientation( Qt::Horizontal );
qwtPlotCurve->setBaseline( 0.0 );
qwtPlotCurve->setCurveAttribute( QwtPlotCurve::Inverted, true );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFlowRateCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_curveName );
m_curveName.uiCapability()->setUiReadOnly( true );
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFlowRateCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
if ( changedField == &m_showCurve )
{
loadDataAndUpdate( true );
}
RimWellLogCurve::fieldChangedByUi( changedField, oldValue, newValue );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellFlowRateCurve::isUsingConnectionNumberDepthType() const
{
auto wellLogPlot = firstAncestorOrThisOfType<RimWellLogPlot>();
return wellLogPlot && wellLogPlot->depthType() == RiaDefines::DepthType::CONNECTION_NUMBER;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellAllocationPlot* RimWellFlowRateCurve::wellAllocationPlot() const
{
return firstAncestorOrThisOfType<RimWellAllocationPlot>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFlowRateCurve::setFlowValuesPrDepthValue( const QString& curveName,
RiaDefines::DepthType depthType,
const std::vector<double>& depthValues,
const std::vector<double>& flowRates )
{
bool useLogarithmicScale = false;
setPropertyValuesAndDepths( flowRates, depthValues, depthType, 0.0, RiaDefines::DepthUnitType::UNIT_NONE, false, useLogarithmicScale );
m_curveAutoName = curveName;
}