2012-05-18 09:45:23 +02:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
# pragma once
# include "RimDefines.h"
2012-06-26 16:10:41 +02:00
# include <QDateTime>
# include <vector>
2012-09-11 09:22:36 +02:00
# include <cmath>
2013-02-01 14:39:32 +01:00
# include "RifReaderInterface.h"
2012-05-18 09:45:23 +02:00
2012-06-26 16:10:41 +02:00
class RifReaderInterface ;
class RigMainGrid ;
2012-05-18 09:45:23 +02:00
//==================================================================================================
/// Class containing the results for the complete number of active cells. Both main grid and LGR's
//==================================================================================================
class RigReservoirCellResults : public cvf : : Object
{
public :
2012-06-26 16:10:41 +02:00
RigReservoirCellResults ( RigMainGrid * ownerGrid ) ;
2012-05-18 09:45:23 +02:00
2013-03-21 15:31:47 +01:00
void setMainGrid ( RigMainGrid * ownerGrid ) ;
2013-03-19 08:28:25 +01:00
2012-06-26 16:10:41 +02:00
// Max and min values of the results
2013-03-18 14:34:29 +01:00
void recalculateMinMax ( size_t scalarResultIndex ) ;
void minMaxCellScalarValues ( size_t scalarResultIndex , double & min , double & max ) ;
void minMaxCellScalarValues ( size_t scalarResultIndex , size_t timeStepIndex , double & min , double & max ) ;
const std : : vector < size_t > & cellScalarValuesHistogram ( size_t scalarResultIndex ) ;
void p10p90CellScalarValues ( size_t scalarResultIndex , double & p10 , double & p90 ) ;
void meanCellScalarValues ( size_t scalarResultIndex , double & meanValue ) ;
2012-05-18 09:45:23 +02:00
2012-06-26 16:10:41 +02:00
// Access meta-information about the results
2013-03-18 14:34:29 +01:00
size_t resultCount ( ) const ;
size_t timeStepCount ( size_t scalarResultIndex ) const ;
2013-03-19 08:14:35 +01:00
size_t maxTimeStepCount ( size_t * scalarResultIndex = NULL ) const ;
2013-03-18 14:34:29 +01:00
QStringList resultNames ( RimDefines : : ResultCatType type ) const ;
bool isUsingGlobalActiveIndex ( size_t scalarResultIndex ) const ;
2012-09-11 09:22:36 +02:00
2013-03-18 14:34:29 +01:00
QDateTime timeStepDate ( size_t scalarResultIndex , size_t timeStepIndex ) const ;
std : : vector < QDateTime > timeStepDates ( size_t scalarResultIndex ) const ;
void setTimeStepDates ( size_t scalarResultIndex , const std : : vector < QDateTime > & dates ) ;
2012-05-18 09:45:23 +02:00
2012-06-26 16:10:41 +02:00
// Find or create a slot for the results
2012-05-18 09:45:23 +02:00
2013-03-18 14:34:29 +01:00
size_t findScalarResultIndex ( RimDefines : : ResultCatType type , const QString & resultName ) const ;
size_t findScalarResultIndex ( const QString & resultName ) const ;
2013-03-21 15:31:47 +01:00
size_t addEmptyScalarResult ( RimDefines : : ResultCatType type , const QString & resultName , bool needsToBeStored ) ;
2013-03-18 14:34:29 +01:00
QString makeResultNameUnique ( const QString & resultNameProposal ) const ;
void removeResult ( const QString & resultName ) ;
void clearAllResults ( ) ;
2012-05-18 09:45:23 +02:00
2012-06-26 16:10:41 +02:00
// Access the results data
2013-03-21 15:31:47 +01:00
2013-03-18 14:34:29 +01:00
const std : : vector < std : : vector < double > > & cellScalarResults ( size_t scalarResultIndex ) const ;
std : : vector < std : : vector < double > > & cellScalarResults ( size_t scalarResultIndex ) ;
std : : vector < double > & cellScalarResults ( size_t scalarResultIndex , size_t timeStepIndex ) ;
double cellScalarResult ( size_t scalarResultIndex , size_t timeStepIndex , size_t resultValueIndex ) ;
2012-05-18 09:45:23 +02:00
2013-02-01 14:39:32 +01:00
static RifReaderInterface : : PorosityModelResultType convertFromProjectModelPorosityModel ( RimDefines : : PorosityModelType porosityModel ) ;
2012-05-18 09:45:23 +02:00
2013-03-18 11:40:39 +01:00
public :
2012-06-26 16:10:41 +02:00
class ResultInfo
{
public :
2013-03-21 15:31:47 +01:00
ResultInfo ( RimDefines : : ResultCatType resultType , bool needsToBeStored , QString resultName , size_t gridScalarResultIndex )
: m_resultType ( resultType ) , m_needsToBeStored ( needsToBeStored ) , m_resultName ( resultName ) , m_gridScalarResultIndex ( gridScalarResultIndex ) { }
2012-06-26 16:10:41 +02:00
public :
RimDefines : : ResultCatType m_resultType ;
2013-03-21 15:31:47 +01:00
bool m_needsToBeStored ;
2012-06-26 16:10:41 +02:00
QString m_resultName ;
size_t m_gridScalarResultIndex ;
2013-03-21 15:31:47 +01:00
std : : vector < QDateTime > m_timeStepDates ;
2012-06-26 16:10:41 +02:00
} ;
2013-03-18 11:40:39 +01:00
const std : : vector < ResultInfo > & infoForEachResultIndex ( ) { return m_resultInfos ; }
2013-03-18 14:34:29 +01:00
public :
size_t addStaticScalarResult ( RimDefines : : ResultCatType type ,
const QString & resultName ,
2013-03-21 15:31:47 +01:00
bool needsToBeStored ,
2013-03-18 14:34:29 +01:00
size_t resultValueCount ) ;
2013-03-18 11:40:39 +01:00
private :
std : : vector < std : : vector < std : : vector < double > > > m_cellScalarResults ; ///< Scalar results on the complete reservoir for each Result index (ResultVariable) and timestep
std : : vector < std : : pair < double , double > > m_maxMinValues ; ///< Max min values for each Result index
std : : vector < std : : vector < size_t > > m_histograms ; ///< Histogram for each Result Index
std : : vector < std : : pair < double , double > > m_p10p90 ; ///< P10 and p90 values for each Result Index
std : : vector < double > m_meanValues ; ///< Mean value for each Result Index
std : : vector < std : : vector < std : : pair < double , double > > > m_maxMinValuesPrTs ; ///< Max min values for each Result index and timestep
private :
2012-06-26 16:10:41 +02:00
std : : vector < ResultInfo > m_resultInfos ;
2013-03-18 14:34:29 +01:00
2012-06-26 16:10:41 +02:00
RigMainGrid * m_ownerMainGrid ;
2012-05-18 09:45:23 +02:00
} ;
2012-09-11 09:22:36 +02:00
class RigHistogramCalculator
{
public :
RigHistogramCalculator ( double min , double max , size_t nBins , std : : vector < size_t > * histogram )
{
CVF_ASSERT ( histogram ) ;
CVF_ASSERT ( nBins > 0 ) ;
if ( max = = min ) { nBins = 1 ; } // Avoid dividing on 0 range
m_histogram = histogram ;
m_min = min ;
m_observationCount = 0 ;
// Initialize bins
m_histogram - > resize ( nBins ) ;
for ( size_t i = 0 ; i < m_histogram - > size ( ) ; + + i ) ( * m_histogram ) [ i ] = 0 ;
m_range = max - min ;
maxIndex = nBins - 1 ;
}
void addData ( const std : : vector < double > & data )
{
CVF_ASSERT ( m_histogram ) ;
for ( size_t i = 0 ; i < data . size ( ) ; + + i )
{
2012-10-24 10:52:44 +02:00
if ( data [ i ] = = HUGE_VAL )
{
continue ;
}
2012-09-11 09:22:36 +02:00
size_t index = 0 ;
if ( maxIndex > 0 ) index = ( size_t ) ( maxIndex * ( data [ i ] - m_min ) / m_range ) ;
if ( index < m_histogram - > size ( ) ) // Just clip to the max min range (-index will overflow to positive )
{
( * m_histogram ) [ index ] + + ;
m_observationCount + + ;
}
}
}
/// Calculates the estimated percentile from the histogram.
/// the percentile is the domain value at which pVal of the observations are below it.
/// Will only consider observed values between min and max, as all other values are discarded from the histogram
double calculatePercentil ( double pVal )
{
CVF_ASSERT ( m_histogram ) ;
CVF_ASSERT ( m_histogram - > size ( ) ) ;
CVF_ASSERT ( 0.0 < = pVal & & pVal < = 1.0 ) ;
double pValObservationCount = pVal * m_observationCount ;
if ( pValObservationCount = = 0.0 ) return m_min ;
size_t accObsCount = 0 ;
double binWidth = m_range / m_histogram - > size ( ) ;
for ( size_t binIdx = 0 ; binIdx < m_histogram - > size ( ) ; + + binIdx )
{
size_t binObsCount = ( * m_histogram ) [ binIdx ] ;
accObsCount + = binObsCount ;
if ( accObsCount > = pValObservationCount )
{
double domainValueAtEndOfBin = m_min + ( binIdx + 1 ) * binWidth ;
double unusedFractionOfLastBin = ( double ) ( accObsCount - pValObservationCount ) / binObsCount ;
return domainValueAtEndOfBin - unusedFractionOfLastBin * binWidth ;
}
}
CVF_ASSERT ( false ) ;
return HUGE_VAL ;
}
private :
size_t maxIndex ;
double m_range ;
double m_min ;
size_t m_observationCount ;
std : : vector < size_t > * m_histogram ;
} ;