2016-12-16 14:17:56 +01:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016- 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 "RigFlowDiagSolverInterface.h"
2016-12-20 11:41:05 +01:00
2017-11-30 10:47:02 +01:00
#include "RiaLogging.h"
2016-12-20 11:41:05 +01:00
#include "RifEclipseOutputFileTools.h"
2017-01-09 19:14:07 +01:00
#include "RifReaderInterface.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
2017-01-10 09:51:39 +01:00
#include "RigEclipseCaseData.h"
2017-03-13 11:03:34 +01:00
2017-01-09 19:14:07 +01:00
#include "RigFlowDiagInterfaceTools.h"
2017-03-13 11:03:34 +01:00
#include "opm/flowdiagnostics/DerivedQuantities.hpp"
2017-01-09 19:14:07 +01:00
2017-12-04 19:47:08 +01:00
#include "opm/utility/ECLPropertyUnitConversion.hpp"
2017-10-27 09:38:24 +02:00
#include "opm/utility/ECLSaturationFunc.hpp"
#include "opm/utility/ECLPvtCurveCollection.hpp"
2016-12-20 11:41:05 +01:00
#include "RimEclipseCase.h"
2017-01-09 19:14:07 +01:00
#include "RimEclipseResultCase.h"
#include "RimFlowDiagSolution.h"
2016-12-20 11:41:05 +01:00
#include <QMessageBox>
2017-01-12 16:36:48 +01:00
#include "cafProgressInfo.h"
2016-12-16 14:17:56 +01:00
2017-11-27 09:08:09 +01:00
#include "cvfTrace.h"
2016-12-16 14:17:56 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagTimeStepResult :: RigFlowDiagTimeStepResult ( size_t activeCellCount )
2017-08-09 14:10:39 +02:00
: m_activeCellCount ( activeCellCount )
2016-12-20 11:41:05 +01:00
{
}
2016-12-16 14:17:56 +01:00
2016-12-20 11:41:05 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-08-10 15:08:30 +02:00
void RigFlowDiagTimeStepResult :: setTracerTOF ( const std :: string & tracerName ,
RigFlowDiagResultAddress :: PhaseSelection phaseSelection ,
const std :: map < int , double >& cellValues )
2016-12-20 11:41:05 +01:00
{
std :: set < std :: string > tracers ;
tracers . insert ( tracerName );
2017-01-06 15:12:13 +01:00
2017-08-10 15:08:30 +02:00
RigFlowDiagResultAddress resAddr ( RIG_FLD_TOF_RESNAME , phaseSelection , tracers );
2016-12-20 11:41:05 +01:00
2017-01-06 15:12:13 +01:00
this -> addResult ( resAddr , cellValues );
2016-12-20 11:41:05 +01:00
2017-01-06 15:12:13 +01:00
std :: vector < double >& activeCellValues = m_nativeResults [ resAddr ];
for ( double & val : activeCellValues )
{
val = val * 1.15741e-5 ; // days pr second. Converting to days
}
2016-12-20 11:41:05 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-08-10 15:08:30 +02:00
void RigFlowDiagTimeStepResult :: setTracerFraction ( const std :: string & tracerName ,
RigFlowDiagResultAddress :: PhaseSelection phaseSelection ,
const std :: map < int , double >& cellValues )
2016-12-20 11:41:05 +01:00
{
std :: set < std :: string > tracers ;
tracers . insert ( tracerName );
2017-08-10 15:08:30 +02:00
this -> addResult ( RigFlowDiagResultAddress ( RIG_FLD_CELL_FRACTION_RESNAME , phaseSelection , tracers ), cellValues );
2016-12-20 11:41:05 +01:00
}
2016-12-16 14:17:56 +01:00
2017-03-13 11:03:34 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFlowDiagTimeStepResult :: setInjProdWellPairFlux ( const std :: string & injectorTracerName ,
const std :: string & producerTracerName ,
const std :: pair < double , double >& injProdFluxes )
{
m_injProdWellPairFluxes [ std :: make_pair ( injectorTracerName , producerTracerName )] = injProdFluxes ;
}
2016-12-16 14:17:56 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-12-20 11:41:05 +01:00
void RigFlowDiagTimeStepResult :: addResult ( const RigFlowDiagResultAddress & resAddr , const std :: map < int , double >& cellValues )
2016-12-16 14:17:56 +01:00
{
2016-12-20 11:41:05 +01:00
std :: vector < double >& activeCellValues = m_nativeResults [ resAddr ];
2017-03-22 14:04:13 +01:00
CVF_ASSERT ( activeCellValues . empty ());
2016-12-20 11:41:05 +01:00
activeCellValues . resize ( m_activeCellCount , HUGE_VAL );
2016-12-16 14:17:56 +01:00
2016-12-20 11:41:05 +01:00
for ( const auto & pairIt : cellValues )
{
activeCellValues [ pairIt . first ] = pairIt . second ;
}
}
2017-01-06 14:41:00 +01:00
2017-05-12 12:22:50 +02:00
class RigOpmFlowDiagStaticData : public cvf :: Object
2017-01-06 14:41:00 +01:00
{
public :
2017-12-05 14:17:42 +01:00
RigOpmFlowDiagStaticData ( const std :: string & grid , const std :: string & init , RiaEclipseUnitTools :: UnitSystem caseUnitSystem )
2017-03-24 15:10:39 +01:00
{
2017-05-12 12:22:50 +02:00
Opm :: ECLInitFileData initData ( init );
m_eclGraph . reset ( new Opm :: ECLGraph ( Opm :: ECLGraph :: load ( grid , initData )));
m_hasUnifiedRestartFile = false ;
m_poreVolume = m_eclGraph -> poreVolume ();
2017-10-27 09:38:24 +02:00
2018-01-05 11:00:23 +01:00
try
{
m_eclSaturationFunc . reset ( new Opm :: ECLSaturationFunc ( * m_eclGraph , initData , true , Opm :: ECLSaturationFunc :: InvalidEPBehaviour :: IgnorePoint ));
}
catch (...)
{
RiaLogging :: warning ( "Exception during initialization of relative permeability plotting functionality. Functionality will not be available." );
}
2017-11-27 09:08:09 +01:00
try
{
m_eclPvtCurveCollection . reset ( new Opm :: ECLPVT :: ECLPvtCurveCollection ( * m_eclGraph , initData ));
}
catch (...)
{
2017-11-30 10:47:02 +01:00
RiaLogging :: warning ( "Unsupported PVT table format. Could not initialize PVT plotting functionality." );
2017-11-27 09:08:09 +01:00
}
2017-12-11 11:45:32 +01:00
// Try and set output unit system to the same system as the eclipse case system
std :: unique_ptr < const Opm :: ECLUnits :: UnitSystem > eclUnitSystem ;
if ( caseUnitSystem == RiaEclipseUnitTools :: UNITS_METRIC ) eclUnitSystem = Opm :: ECLUnits :: metricUnitConventions ();
else if ( caseUnitSystem == RiaEclipseUnitTools :: UNITS_FIELD ) eclUnitSystem = Opm :: ECLUnits :: fieldUnitConventions ();
else if ( caseUnitSystem == RiaEclipseUnitTools :: UNITS_LAB ) eclUnitSystem = Opm :: ECLUnits :: labUnitConventions ();
if ( eclUnitSystem )
{
if ( m_eclSaturationFunc )
{
m_eclSaturationFunc -> setOutputUnits ( eclUnitSystem -> clone ());
}
if ( m_eclPvtCurveCollection )
{
m_eclPvtCurveCollection -> setOutputUnits ( eclUnitSystem -> clone ());
}
}
2017-03-24 15:10:39 +01:00
}
2017-01-06 14:41:00 +01:00
2017-12-05 14:17:42 +01:00
public :
2017-05-12 12:22:50 +02:00
std :: unique_ptr < Opm :: ECLGraph > m_eclGraph ;
2017-03-24 15:10:39 +01:00
std :: vector < double > m_poreVolume ;
std :: unique_ptr < Opm :: FlowDiagnostics :: Toolbox > m_fldToolbox ;
bool m_hasUnifiedRestartFile ;
2017-05-12 12:22:50 +02:00
std :: vector < Opm :: ECLRestartData > m_singleRestartDataTimeSteps ;
std :: unique_ptr < Opm :: ECLRestartData > m_unifiedRestartData ;
2017-10-27 09:38:24 +02:00
std :: unique_ptr < Opm :: ECLSaturationFunc > m_eclSaturationFunc ;
2017-11-27 09:08:09 +01:00
std :: unique_ptr < Opm :: ECLPVT :: ECLPvtCurveCollection > m_eclPvtCurveCollection ;
2017-01-06 14:41:00 +01:00
};
2016-12-20 11:41:05 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface :: RigFlowDiagSolverInterface ( RimEclipseResultCase * eclipseCase )
2018-01-19 15:21:17 +01:00
: m_eclipseCase ( eclipseCase ),
m_pvtCurveErrorCount ( 0 ),
m_relpermCurveErrorCount ( 0 )
2016-12-20 11:41:05 +01:00
{
2016-12-16 14:17:56 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface ::~ RigFlowDiagSolverInterface ()
{
}
2017-10-11 18:02:00 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: string removeCrossFlowEnding ( std :: string tracerName )
{
return RimFlowDiagSolution :: removeCrossFlowEnding ( QString :: fromStdString ( tracerName )). toStdString ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool hasCrossFlowEnding ( std :: string tracerName )
{
return RimFlowDiagSolution :: hasCrossFlowEnding ( QString :: fromStdString ( tracerName ));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: string addCrossFlowEnding ( std :: string tracerName )
{
return RimFlowDiagSolution :: addCrossFlowEnding ( QString :: fromStdString ( tracerName )). toStdString ();
}
2017-01-06 14:41:00 +01:00
2016-12-16 14:17:56 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-12-20 11:41:05 +01:00
RigFlowDiagTimeStepResult RigFlowDiagSolverInterface :: calculate ( size_t timeStepIndex ,
2017-08-10 15:08:30 +02:00
RigFlowDiagResultAddress :: PhaseSelection phaseSelection ,
2016-12-20 11:41:05 +01:00
std :: map < std :: string , std :: vector < int > > injectorTracers ,
std :: map < std :: string , std :: vector < int > > producerTracers )
2016-12-16 14:17:56 +01:00
{
2016-12-20 11:41:05 +01:00
using namespace Opm :: FlowDiagnostics ;
2017-08-11 14:05:59 +02:00
RigFlowDiagTimeStepResult result ( m_eclipseCase -> eclipseCaseData () -> activeCellInfo ( RiaDefines :: MATRIX_MODEL ) -> reservoirActiveCellCount ());
2016-12-20 11:41:05 +01:00
2017-03-13 11:03:34 +01:00
caf :: ProgressInfo progressInfo ( 8 , "Calculating Flow Diagnostics" );
2017-01-12 16:36:48 +01:00
2018-01-19 12:46:53 +01:00
try
2017-01-06 14:41:00 +01:00
{
2017-01-12 16:36:48 +01:00
progressInfo . setProgressDescription ( "Grid access" );
2017-10-27 09:38:24 +02:00
if ( ! ensureStaticDataObjectInstanceCreated ())
{
return result ;
}
2016-12-20 11:41:05 +01:00
2017-01-12 16:36:48 +01:00
progressInfo . incrementProgress ();
progressInfo . setProgressDescription ( "Calculating Connectivities" );
2017-10-27 09:38:24 +02:00
CVF_ASSERT ( m_opmFlowDiagStaticData . notNull ());
2017-01-06 14:41:00 +01:00
const Opm :: FlowDiagnostics :: ConnectivityGraph connGraph =
2017-05-12 12:22:50 +02:00
Opm :: FlowDiagnostics :: ConnectivityGraph { static_cast < int > ( m_opmFlowDiagStaticData -> m_eclGraph -> numCells ()),
m_opmFlowDiagStaticData -> m_eclGraph -> neighbours () };
2016-12-20 11:41:05 +01:00
2017-01-12 16:36:48 +01:00
progressInfo . incrementProgress ();
progressInfo . setProgressDescription ( "Initialize Solver" );
2017-01-06 14:41:00 +01:00
// Create the Toolbox.
2016-12-20 11:41:05 +01:00
2017-05-12 12:22:50 +02:00
m_opmFlowDiagStaticData -> m_fldToolbox . reset ( new Opm :: FlowDiagnostics :: Toolbox { connGraph });
2016-12-20 15:33:39 +01:00
2017-01-06 14:41:00 +01:00
// Look for unified restart file
2017-08-10 10:09:01 +02:00
QStringList m_filesWithSameBaseName ;
2017-10-27 09:38:24 +02:00
QString gridFileName = m_eclipseCase -> gridFileName ();
2017-08-10 10:09:01 +02:00
if ( ! RifEclipseOutputFileTools :: findSiblingFilesWithSameBaseName ( gridFileName , & m_filesWithSameBaseName ) ) return result ;
2016-12-20 15:33:39 +01:00
2017-01-06 14:41:00 +01:00
QString restartFileName = RifEclipseOutputFileTools :: firstFileNameOfType ( m_filesWithSameBaseName , ECL_UNIFIED_RESTART_FILE );
if ( ! restartFileName . isEmpty () )
{
2017-05-12 12:22:50 +02:00
m_opmFlowDiagStaticData -> m_unifiedRestartData . reset ( new Opm :: ECLRestartData ( Opm :: ECLRestartData ( restartFileName . toStdString ())));
m_opmFlowDiagStaticData -> m_hasUnifiedRestartFile = true ;
2017-01-06 14:41:00 +01:00
}
else
2016-12-20 11:41:05 +01:00
{
2017-05-12 12:22:50 +02:00
QStringList restartFileNames = RifEclipseOutputFileTools :: filterFileNamesOfType ( m_filesWithSameBaseName , ECL_RESTART_FILE );
2017-01-06 14:41:00 +01:00
2017-05-12 12:22:50 +02:00
size_t restartFileCount = static_cast < size_t > ( restartFileNames . size ());
2017-08-11 14:05:59 +02:00
size_t maxTimeStepCount = m_eclipseCase -> eclipseCaseData () -> results ( RiaDefines :: MATRIX_MODEL ) -> maxTimeStepCount ();
2017-01-06 14:41:00 +01:00
2017-05-12 12:22:50 +02:00
if ( restartFileCount <= timeStepIndex && restartFileCount != maxTimeStepCount )
2017-01-06 14:41:00 +01:00
{
QMessageBox :: critical ( nullptr , "ResInsight" , "Flow Diagnostics: Could not find all the restart files. Results will not be loaded." );
return result ;
}
2017-05-12 12:22:50 +02:00
restartFileNames . sort (); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file.
m_opmFlowDiagStaticData -> m_hasUnifiedRestartFile = false ;
for ( auto restartFileName : restartFileNames )
{
m_opmFlowDiagStaticData -> m_singleRestartDataTimeSteps . push_back ( Opm :: ECLRestartData ( restartFileName . toStdString ()));
}
2016-12-20 11:41:05 +01:00
}
2017-01-06 14:41:00 +01:00
}
2018-01-19 12:46:53 +01:00
catch ( const std :: exception & e )
{
QMessageBox :: critical ( nullptr , "ResInsight" , "Flow Diagnostics Exception: " + QString ( e . what ()));
return result ;
}
2017-01-06 14:41:00 +01:00
2017-01-12 16:36:48 +01:00
progressInfo . setProgress ( 3 );
progressInfo . setProgressDescription ( "Assigning Flux Field" );
2016-12-20 11:41:05 +01:00
2018-01-02 14:44:02 +01:00
assignPhaseCorrecedPORV ( phaseSelection , timeStepIndex );
2017-05-12 12:22:50 +02:00
Opm :: ECLRestartData * currentRestartData = nullptr ;
if ( ! m_opmFlowDiagStaticData -> m_hasUnifiedRestartFile )
2017-01-06 14:41:00 +01:00
{
2017-05-12 12:22:50 +02:00
currentRestartData = & ( m_opmFlowDiagStaticData -> m_singleRestartDataTimeSteps [ timeStepIndex ]);
}
else
{
currentRestartData = m_opmFlowDiagStaticData -> m_unifiedRestartData . get ();
2016-12-20 11:41:05 +01:00
}
2017-05-12 12:22:50 +02:00
CVF_ASSERT ( currentRestartData );
2017-01-12 12:04:54 +01:00
size_t resultIndexWithMaxTimeSteps = cvf :: UNDEFINED_SIZE_T ;
2017-08-11 14:05:59 +02:00
m_eclipseCase -> eclipseCaseData () -> results ( RiaDefines :: MATRIX_MODEL ) -> maxTimeStepCount ( & resultIndexWithMaxTimeSteps );
2016-12-20 11:41:05 +01:00
2017-08-11 14:05:59 +02:00
int reportStepNumber = m_eclipseCase -> eclipseCaseData () -> results ( RiaDefines :: MATRIX_MODEL ) -> reportStepNumber ( resultIndexWithMaxTimeSteps , timeStepIndex );
2017-01-12 12:04:54 +01:00
2017-05-12 12:22:50 +02:00
if ( ! currentRestartData -> selectReportStep ( reportStepNumber ) )
2016-12-20 11:41:05 +01:00
{
QMessageBox :: critical ( nullptr , "ResInsight" , "Flow Diagnostics: Could not find the requested timestep in the result file. Results will not be loaded." );
return result ;
}
2017-01-06 14:41:00 +01:00
// Set up flow Toolbox with timestep data
2017-10-11 18:02:00 +02:00
std :: map < Opm :: FlowDiagnostics :: CellSetID , Opm :: FlowDiagnostics :: CellSetValues > WellInFluxPrCell ;
2017-03-13 11:03:34 +01:00
2018-01-19 12:46:53 +01:00
try
2016-12-20 11:41:05 +01:00
{
2017-08-11 14:05:59 +02:00
if ( m_eclipseCase -> eclipseCaseData () -> results ( RiaDefines :: MATRIX_MODEL ) -> hasFlowDiagUsableFluxes ())
2017-08-10 10:09:01 +02:00
{
Opm :: FlowDiagnostics :: ConnectionValues connectionsVals = RigFlowDiagInterfaceTools :: extractFluxFieldFromRestartFile ( * ( m_opmFlowDiagStaticData -> m_eclGraph ),
2017-08-10 15:08:30 +02:00
* currentRestartData ,
phaseSelection );
2017-08-10 10:09:01 +02:00
m_opmFlowDiagStaticData -> m_fldToolbox -> assignConnectionFlux ( connectionsVals );
}
else
{
2018-01-19 12:46:53 +01:00
Opm :: ECLInitFileData init ( getInitFileName ());
Opm :: FlowDiagnostics :: ConnectionValues connectionVals = RigFlowDiagInterfaceTools :: calculateFluxField (( * m_opmFlowDiagStaticData -> m_eclGraph ),
init ,
* currentRestartData ,
phaseSelection );
m_opmFlowDiagStaticData -> m_fldToolbox -> assignConnectionFlux ( connectionVals );
2017-08-10 10:09:01 +02:00
}
2016-12-20 11:41:05 +01:00
2017-01-12 16:36:48 +01:00
progressInfo . incrementProgress ();
2017-02-28 16:03:43 +01:00
Opm :: ECLWellSolution wsol = Opm :: ECLWellSolution { - 1.0 , false };
2017-01-06 14:41:00 +01:00
2017-05-12 12:22:50 +02:00
std :: vector < std :: string > gridNames = m_opmFlowDiagStaticData -> m_eclGraph -> activeGrids ();
const std :: vector < Opm :: ECLWellSolution :: WellData > well_fluxes = wsol . solution ( * currentRestartData , gridNames );
2017-01-06 14:41:00 +01:00
2017-10-11 18:02:00 +02:00
WellInFluxPrCell = RigFlowDiagInterfaceTools :: extractWellFlows ( * ( m_opmFlowDiagStaticData -> m_eclGraph ), well_fluxes );
2017-03-09 16:05:48 +01:00
2017-10-11 18:02:00 +02:00
m_opmFlowDiagStaticData -> m_fldToolbox -> assignInflowFlux ( WellInFluxPrCell );
2017-03-09 16:05:48 +01:00
2017-01-06 14:41:00 +01:00
}
2018-01-19 12:46:53 +01:00
catch ( const std :: exception & e )
{
QMessageBox :: critical ( nullptr , "ResInsight" , "Flow Diagnostics Exception: " + QString ( e . what ()));
return result ;
}
2017-01-06 14:41:00 +01:00
2017-01-12 16:36:48 +01:00
progressInfo . incrementProgress ();
progressInfo . setProgressDescription ( "Injector Solution" );
2018-01-19 12:46:53 +01:00
try
2017-01-06 14:41:00 +01:00
{
2017-03-13 11:03:34 +01:00
// Injection Solution
2017-10-11 18:02:00 +02:00
std :: set < std :: string > injectorCrossFlowTracers ;
2017-03-13 11:03:34 +01:00
std :: vector < CellSet > injectorCellSets ;
std :: unique_ptr < Toolbox :: Forward > injectorSolution ;
2016-12-20 11:41:05 +01:00
{
2017-10-11 18:02:00 +02:00
for ( const auto & tIt : injectorTracers )
{
std :: string tracerName = tIt . first ;
if ( hasCrossFlowEnding ( tracerName ))
{
tracerName = removeCrossFlowEnding ( tracerName );
injectorCrossFlowTracers . insert ( tracerName );
}
injectorCellSets . push_back ( CellSet ( CellSetID ( tracerName ), tIt . second ));
}
2018-01-19 12:46:53 +01:00
injectorSolution . reset ( new Toolbox :: Forward ( m_opmFlowDiagStaticData -> m_fldToolbox -> computeInjectionDiagnostics ( injectorCellSets )));
2017-10-11 18:02:00 +02:00
for ( const CellSetID & tracerId : injectorSolution -> fd . startPoints () )
{
std :: string tracername = tracerId . to_string ();
if ( injectorCrossFlowTracers . count ( tracername )) tracername = addCrossFlowEnding ( tracername );
CellSetValues tofVals = injectorSolution -> fd . timeOfFlight ( tracerId );
result . setTracerTOF ( tracername , phaseSelection , tofVals );
CellSetValues fracVals = injectorSolution -> fd . concentration ( tracerId );
result . setTracerFraction ( tracername , phaseSelection , fracVals );
}
2017-03-13 11:03:34 +01:00
}
2017-01-12 16:36:48 +01:00
2017-03-13 11:03:34 +01:00
progressInfo . incrementProgress ();
progressInfo . setProgressDescription ( "Producer Solution" );
// Producer Solution
2017-10-11 18:02:00 +02:00
std :: set < std :: string > producerCrossFlowTracers ;
2017-03-13 11:03:34 +01:00
std :: vector < CellSet > prodjCellSets ;
std :: unique_ptr < Toolbox :: Reverse > producerSolution ;
2017-03-06 16:33:29 +01:00
{
2017-10-11 18:02:00 +02:00
for ( const auto & tIt : producerTracers )
{
std :: string tracerName = tIt . first ;
if ( hasCrossFlowEnding ( tracerName ))
{
tracerName = removeCrossFlowEnding ( tracerName );
producerCrossFlowTracers . insert ( tracerName );
}
prodjCellSets . push_back ( CellSet ( CellSetID ( tracerName ), tIt . second ));
}
2017-03-13 11:03:34 +01:00
2018-01-19 12:46:53 +01:00
producerSolution . reset ( new Toolbox :: Reverse ( m_opmFlowDiagStaticData -> m_fldToolbox -> computeProductionDiagnostics ( prodjCellSets )));
2017-10-11 18:02:00 +02:00
for ( const CellSetID & tracerId : producerSolution -> fd . startPoints () )
{
std :: string tracername = tracerId . to_string ();
if ( producerCrossFlowTracers . count ( tracername )) tracername = addCrossFlowEnding ( tracername );
CellSetValues tofVals = producerSolution -> fd . timeOfFlight ( tracerId );
result . setTracerTOF ( tracername , phaseSelection , tofVals );
CellSetValues fracVals = producerSolution -> fd . concentration ( tracerId );
result . setTracerFraction ( tracername , phaseSelection , fracVals );
}
2017-03-13 11:03:34 +01:00
}
progressInfo . incrementProgress ();
progressInfo . setProgressDescription ( "Well pair fluxes" );
int producerTracerCount = static_cast < int > ( prodjCellSets . size ());
#pragma omp parallel for
for ( int pIdx = 0 ; pIdx < producerTracerCount ; ++ pIdx )
{
const auto & prodCellSet = prodjCellSets [ pIdx ];
2017-10-11 18:02:00 +02:00
std :: string prodTracerName = prodCellSet . id (). to_string ();
CellSetID prodID ( prodTracerName );
std :: string uiProducerTracerName = prodTracerName ;
if ( producerCrossFlowTracers . count ( prodTracerName ))
{
uiProducerTracerName = addCrossFlowEnding ( prodTracerName );
}
2017-03-13 11:03:34 +01:00
for ( const auto & injCellSet : injectorCellSets )
{
2017-10-11 18:02:00 +02:00
std :: string injTracerName = injCellSet . id (). to_string ();
CellSetID injID ( injTracerName );
2017-03-13 11:03:34 +01:00
std :: pair < double , double > fluxPair = injectorProducerPairFlux ( * ( injectorSolution . get ()),
* ( producerSolution . get ()),
2017-10-11 18:02:00 +02:00
injID ,
prodID ,
WellInFluxPrCell );
std :: string uiInjectorTracerName = injTracerName ;
if ( injectorCrossFlowTracers . count ( injTracerName ))
{
uiInjectorTracerName = addCrossFlowEnding ( injTracerName );
}
2017-03-13 11:03:34 +01:00
#pragma omp critical
{
2017-10-11 18:02:00 +02:00
result . setInjProdWellPairFlux ( uiInjectorTracerName ,
uiProducerTracerName ,
2017-03-13 11:03:34 +01:00
fluxPair );
}
}
}
2017-01-06 14:41:00 +01:00
}
2018-01-19 12:46:53 +01:00
catch ( const std :: exception & e )
{
QMessageBox :: critical ( nullptr , "ResInsight" , "Flow Diagnostics Exception: " + QString ( e . what ()));
return result ;
}
2016-12-17 10:46:57 +01:00
2016-12-20 11:41:05 +01:00
return result ; // Relying on implicit move constructor
2016-12-16 14:17:56 +01:00
}
2017-10-27 09:38:24 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFlowDiagSolverInterface :: ensureStaticDataObjectInstanceCreated ()
{
if ( m_opmFlowDiagStaticData . isNull ())
{
// Get set of files
QString gridFileName = m_eclipseCase -> gridFileName ();
std :: string initFileName = getInitFileName ();
if ( initFileName . empty ()) return false ;
2017-12-05 14:17:42 +01:00
const RigEclipseCaseData * eclipseCaseData = m_eclipseCase -> eclipseCaseData ();
2018-01-29 14:41:07 +01:00
if ( eclipseCaseData -> hasFractureResults ())
{
return false ;
}
RiaEclipseUnitTools :: UnitSystem caseUnitSystem = eclipseCaseData ? eclipseCaseData -> unitsType () : RiaEclipseUnitTools :: UNITS_UNKNOWN ;
2017-12-05 14:17:42 +01:00
m_opmFlowDiagStaticData = new RigOpmFlowDiagStaticData ( gridFileName . toStdString (), initFileName , caseUnitSystem );
2017-10-27 09:38:24 +02:00
}
return m_opmFlowDiagStaticData . notNull () ? true : false ;
}
2018-01-02 14:44:02 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFlowDiagSolverInterface :: assignPhaseCorrecedPORV ( RigFlowDiagResultAddress :: PhaseSelection phaseSelection ,
size_t timeStepIdx )
{
RigEclipseCaseData * eclipseCaseData = m_eclipseCase -> eclipseCaseData ();
const std :: vector < double >* phaseSaturation = nullptr ;
switch ( phaseSelection )
{
case RigFlowDiagResultAddress :: PHASE_OIL :
phaseSaturation = eclipseCaseData -> resultValues ( RiaDefines :: MATRIX_MODEL , RiaDefines :: DYNAMIC_NATIVE , "SOIL" , timeStepIdx );
break ;
case RigFlowDiagResultAddress :: PHASE_GAS :
phaseSaturation = eclipseCaseData -> resultValues ( RiaDefines :: MATRIX_MODEL , RiaDefines :: DYNAMIC_NATIVE , "SGAS" , timeStepIdx );
break ;
case RigFlowDiagResultAddress :: PHASE_WAT :
phaseSaturation = eclipseCaseData -> resultValues ( RiaDefines :: MATRIX_MODEL , RiaDefines :: DYNAMIC_NATIVE , "SWAT" , timeStepIdx );
break ;
default :
m_opmFlowDiagStaticData -> m_fldToolbox -> assignPoreVolume ( m_opmFlowDiagStaticData -> m_poreVolume );
break ;
}
if ( phaseSaturation )
{
std :: vector < double > porvAdjusted = m_opmFlowDiagStaticData -> m_poreVolume ;
CAF_ASSERT ( porvAdjusted . size () == phaseSaturation -> size ());
for ( size_t idx = 0 ; idx < porvAdjusted . size (); ++ idx )
{
porvAdjusted [ idx ] *= phaseSaturation -> at ( idx );
}
m_opmFlowDiagStaticData -> m_fldToolbox -> assignPoreVolume ( porvAdjusted );
}
else
{
m_opmFlowDiagStaticData -> m_fldToolbox -> assignPoreVolume ( m_opmFlowDiagStaticData -> m_poreVolume );
}
}
2018-01-19 15:21:17 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFlowDiagSolverInterface :: reportRelPermCurveError ( const QString & message )
{
if ( m_relpermCurveErrorCount == 0 )
{
QMessageBox :: critical ( nullptr , "ResInsight" , "RelPerm curve problems: \n " + message );
}
m_relpermCurveErrorCount ++ ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFlowDiagSolverInterface :: reportPvtCurveError ( const QString & message )
{
if ( m_pvtCurveErrorCount == 0 )
{
QMessageBox :: critical ( nullptr , "ResInsight" , "PVT curve problems: \n " + message );
}
m_pvtCurveErrorCount ++ ;
}
2017-08-09 14:10:39 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-08-10 10:09:01 +02:00
RigFlowDiagSolverInterface :: FlowCharacteristicsResultFrame RigFlowDiagSolverInterface :: calculateFlowCharacteristics ( const std :: vector < double >* injector_tof ,
const std :: vector < double >* producer_tof ,
2017-08-17 11:24:51 +02:00
const std :: vector < size_t >& selected_cell_indices ,
2017-08-09 14:10:39 +02:00
double max_pv_fraction )
{
using namespace Opm :: FlowDiagnostics ;
RigFlowDiagSolverInterface :: FlowCharacteristicsResultFrame result ;
2017-08-10 10:09:01 +02:00
if ( injector_tof == nullptr || producer_tof == nullptr )
{
return result ;
}
2017-08-17 11:24:51 +02:00
std :: vector < double > poreVolume ;
for ( size_t cellIndex : selected_cell_indices )
{
poreVolume . push_back ( m_opmFlowDiagStaticData -> m_poreVolume [ cellIndex ]);
}
2017-08-10 10:09:01 +02:00
2017-08-09 14:10:39 +02:00
try
{
2017-08-10 10:09:01 +02:00
Graph flowCapStorCapCurve = flowCapacityStorageCapacityCurve ( * injector_tof ,
* producer_tof ,
2017-08-17 11:24:51 +02:00
poreVolume ,
2017-08-09 14:10:39 +02:00
max_pv_fraction );
result . m_flowCapStorageCapCurve = flowCapStorCapCurve ;
result . m_lorenzCoefficient = lorenzCoefficient ( flowCapStorCapCurve );
result . m_sweepEfficiencyCurve = sweepEfficiency ( flowCapStorCapCurve );
}
catch ( const std :: exception & e )
{
QMessageBox :: critical ( nullptr , "ResInsight" , "Flow Diagnostics: " + QString ( e . what ()));
}
return result ;
}
2017-10-27 09:38:24 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-12-05 14:17:42 +01:00
std :: vector < RigFlowDiagSolverInterface :: RelPermCurve > RigFlowDiagSolverInterface :: calculateRelPermCurves ( size_t activeCellIndex )
2017-10-27 09:38:24 +02:00
{
std :: vector < RelPermCurve > retCurveArr ;
if ( ! ensureStaticDataObjectInstanceCreated ())
{
return retCurveArr ;
}
CVF_ASSERT ( m_opmFlowDiagStaticData . notNull ());
2018-01-05 11:00:23 +01:00
if ( ! m_opmFlowDiagStaticData -> m_eclSaturationFunc )
{
return retCurveArr ;
}
2017-10-27 09:38:24 +02:00
2017-11-22 16:14:04 +01:00
const Opm :: ECLSaturationFunc :: RawCurve krw { Opm :: ECLSaturationFunc :: RawCurve :: Function :: RelPerm , Opm :: ECLSaturationFunc :: RawCurve :: SubSystem :: OilWater , Opm :: ECLPhaseIndex :: Aqua }; // water rel-perm in oil-water system
const Opm :: ECLSaturationFunc :: RawCurve krg { Opm :: ECLSaturationFunc :: RawCurve :: Function :: RelPerm , Opm :: ECLSaturationFunc :: RawCurve :: SubSystem :: OilGas , Opm :: ECLPhaseIndex :: Vapour }; // gas rel-perm in oil-gas system
const Opm :: ECLSaturationFunc :: RawCurve krow { Opm :: ECLSaturationFunc :: RawCurve :: Function :: RelPerm , Opm :: ECLSaturationFunc :: RawCurve :: SubSystem :: OilWater , Opm :: ECLPhaseIndex :: Liquid }; // oil rel-perm in oil-water system
const Opm :: ECLSaturationFunc :: RawCurve krog { Opm :: ECLSaturationFunc :: RawCurve :: Function :: RelPerm , Opm :: ECLSaturationFunc :: RawCurve :: SubSystem :: OilGas , Opm :: ECLPhaseIndex :: Liquid }; // oil rel-perm in oil-gas system
const Opm :: ECLSaturationFunc :: RawCurve pcgo { Opm :: ECLSaturationFunc :: RawCurve :: Function :: CapPress , Opm :: ECLSaturationFunc :: RawCurve :: SubSystem :: OilGas , Opm :: ECLPhaseIndex :: Vapour }; // gas/oil capillary pressure (Pg-Po) in G/O system
const Opm :: ECLSaturationFunc :: RawCurve pcow { Opm :: ECLSaturationFunc :: RawCurve :: Function :: CapPress , Opm :: ECLSaturationFunc :: RawCurve :: SubSystem :: OilWater , Opm :: ECLPhaseIndex :: Aqua }; // oil/water capillary pressure (Po-Pw) in O/W system
2017-10-27 09:38:24 +02:00
std :: vector < std :: pair < RelPermCurve :: Ident , std :: string >> curveIdentNameArr ;
std :: vector < Opm :: ECLSaturationFunc :: RawCurve > satFuncRequests ;
curveIdentNameArr . push_back ( std :: make_pair ( RelPermCurve :: KRW , "KRW" )); satFuncRequests . push_back ( krw );
curveIdentNameArr . push_back ( std :: make_pair ( RelPermCurve :: KRG , "KRG" )); satFuncRequests . push_back ( krg );
curveIdentNameArr . push_back ( std :: make_pair ( RelPermCurve :: KROW , "KROW" )); satFuncRequests . push_back ( krow );
curveIdentNameArr . push_back ( std :: make_pair ( RelPermCurve :: KROG , "KROG" )); satFuncRequests . push_back ( krog );
2017-11-22 16:14:04 +01:00
curveIdentNameArr . push_back ( std :: make_pair ( RelPermCurve :: PCOG , "PCOG" )); satFuncRequests . push_back ( pcgo );
curveIdentNameArr . push_back ( std :: make_pair ( RelPermCurve :: PCOW , "PCOW" )); satFuncRequests . push_back ( pcow );
2017-10-27 09:38:24 +02:00
2018-01-19 15:21:17 +01:00
try {
2017-11-23 11:51:24 +01:00
// Calculate and return curves both with and without endpoint scaling and tag them accordingly
// Must use two calls to achieve this
2018-02-23 22:39:29 +01:00
const std :: array < RelPermCurve :: EpsMode , 2 > epsModeArr = { { RelPermCurve :: EPS_ON , RelPermCurve :: EPS_OFF } };
2017-11-23 11:51:24 +01:00
for ( RelPermCurve :: EpsMode epsMode : epsModeArr )
2017-10-27 09:38:24 +02:00
{
2017-11-23 11:51:24 +01:00
const bool useEps = epsMode == RelPermCurve :: EPS_ON ? true : false ;
std :: vector < Opm :: FlowDiagnostics :: Graph > graphArr = m_opmFlowDiagStaticData -> m_eclSaturationFunc -> getSatFuncCurve ( satFuncRequests , static_cast < int > ( activeCellIndex ), useEps );
for ( size_t i = 0 ; i < graphArr . size (); i ++ )
2017-10-27 09:38:24 +02:00
{
2017-11-23 11:51:24 +01:00
const RelPermCurve :: Ident curveIdent = curveIdentNameArr [ i ]. first ;
const std :: string curveName = curveIdentNameArr [ i ]. second ;
const Opm :: FlowDiagnostics :: Graph & srcGraph = graphArr [ i ];
if ( srcGraph . first . size () > 0 )
{
const std :: vector < double >& xVals = srcGraph . first ;
const std :: vector < double >& yVals = srcGraph . second ;
retCurveArr . push_back ({ curveIdent , curveName , epsMode , xVals , yVals });
}
2017-10-27 09:38:24 +02:00
}
}
2018-01-19 15:21:17 +01:00
}
catch ( const std :: exception & e )
{
reportRelPermCurveError ( QString ( e . what ()));
return retCurveArr ;
}
2017-10-27 09:38:24 +02:00
return retCurveArr ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-12-05 14:17:42 +01:00
std :: vector < RigFlowDiagSolverInterface :: PvtCurve > RigFlowDiagSolverInterface :: calculatePvtCurves ( PvtCurveType pvtCurveType , size_t activeCellIndex )
2017-10-27 09:38:24 +02:00
{
std :: vector < PvtCurve > retCurveArr ;
2018-01-19 15:21:17 +01:00
try {
2017-10-27 09:38:24 +02:00
if ( ! ensureStaticDataObjectInstanceCreated ())
{
return retCurveArr ;
}
2017-11-27 09:08:09 +01:00
CVF_ASSERT ( m_opmFlowDiagStaticData . notNull ());
if ( ! m_opmFlowDiagStaticData -> m_eclPvtCurveCollection )
{
return retCurveArr ;
}
// Requesting FVF or Viscosity
2017-12-11 16:00:56 +01:00
if ( pvtCurveType == PvtCurveType :: PVT_CT_FVF )
{
// Bo
{
std :: vector < Opm :: ECLPVT :: PVTGraph > graphArr = m_opmFlowDiagStaticData -> m_eclPvtCurveCollection -> getPvtCurve ( Opm :: ECLPVT :: RawCurve :: FVF , Opm :: ECLPhaseIndex :: Liquid , static_cast < int > ( activeCellIndex ));
for ( Opm :: ECLPVT :: PVTGraph srcGraph : graphArr )
{
if ( srcGraph . press . size () > 0 )
{
2017-12-12 22:40:17 +01:00
retCurveArr . push_back ({ PvtCurve :: Bo , PvtCurve :: OIL , srcGraph . press , srcGraph . value , srcGraph . mixRat });
2017-12-11 16:00:56 +01:00
}
}
}
2017-11-27 09:08:09 +01:00
2017-12-11 16:00:56 +01:00
// Bg
{
std :: vector < Opm :: ECLPVT :: PVTGraph > graphArr = m_opmFlowDiagStaticData -> m_eclPvtCurveCollection -> getPvtCurve ( Opm :: ECLPVT :: RawCurve :: FVF , Opm :: ECLPhaseIndex :: Vapour , static_cast < int > ( activeCellIndex ));
for ( Opm :: ECLPVT :: PVTGraph srcGraph : graphArr )
{
if ( srcGraph . press . size () > 0 )
{
2017-12-12 22:40:17 +01:00
retCurveArr . push_back ({ PvtCurve :: Bg , PvtCurve :: GAS , srcGraph . press , srcGraph . value , srcGraph . mixRat });
2017-12-11 16:00:56 +01:00
}
}
}
}
2017-11-27 09:08:09 +01:00
2017-12-11 16:00:56 +01:00
else if ( pvtCurveType == PvtCurveType :: PVT_CT_VISCOSITY )
2017-11-27 09:08:09 +01:00
{
2017-12-11 16:00:56 +01:00
// Visc_o / mu_o
{
std :: vector < Opm :: ECLPVT :: PVTGraph > graphArr = m_opmFlowDiagStaticData -> m_eclPvtCurveCollection -> getPvtCurve ( Opm :: ECLPVT :: RawCurve :: Viscosity , Opm :: ECLPhaseIndex :: Liquid , static_cast < int > ( activeCellIndex ));
for ( Opm :: ECLPVT :: PVTGraph srcGraph : graphArr )
{
if ( srcGraph . press . size () > 0 )
{
2017-12-12 22:40:17 +01:00
retCurveArr . push_back ({ PvtCurve :: Visc_o , PvtCurve :: OIL , srcGraph . press , srcGraph . value , srcGraph . mixRat });
2017-12-11 16:00:56 +01:00
}
}
}
2017-11-27 09:08:09 +01:00
2017-12-11 16:00:56 +01:00
// Visc_g / mu_g
2017-11-27 09:08:09 +01:00
{
2017-12-11 16:00:56 +01:00
std :: vector < Opm :: ECLPVT :: PVTGraph > graphArr = m_opmFlowDiagStaticData -> m_eclPvtCurveCollection -> getPvtCurve ( Opm :: ECLPVT :: RawCurve :: Viscosity , Opm :: ECLPhaseIndex :: Vapour , static_cast < int > ( activeCellIndex ));
for ( Opm :: ECLPVT :: PVTGraph srcGraph : graphArr )
2017-11-27 09:08:09 +01:00
{
2017-12-11 16:00:56 +01:00
if ( srcGraph . press . size () > 0 )
{
2017-12-12 22:40:17 +01:00
retCurveArr . push_back ({ PvtCurve :: Visc_g , PvtCurve :: GAS , srcGraph . press , srcGraph . value , srcGraph . mixRat });
2017-12-11 16:00:56 +01:00
}
2017-11-27 09:08:09 +01:00
}
}
}
2017-10-27 09:38:24 +02:00
2018-01-19 15:21:17 +01:00
}
catch ( const std :: exception & e )
{
reportPvtCurveError ( QString ( e . what ()));
return retCurveArr ;
}
2017-10-27 09:38:24 +02:00
return retCurveArr ;
}
2017-12-05 14:17:42 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFlowDiagSolverInterface :: calculatePvtDynamicPropertiesFvf ( size_t activeCellIndex , double pressure , double rs , double rv , double * bo , double * bg )
{
if ( bo ) * bo = HUGE_VAL ;
if ( bg ) * bg = HUGE_VAL ;
if ( ! ensureStaticDataObjectInstanceCreated ())
{
return false ;
}
2017-12-05 16:16:58 +01:00
CVF_ASSERT ( m_opmFlowDiagStaticData . notNull ());
if ( ! m_opmFlowDiagStaticData -> m_eclPvtCurveCollection )
{
return false ;
}
2018-01-19 15:21:17 +01:00
try {
2017-12-05 14:17:42 +01:00
// Bo
{
std :: vector < double > phasePress = { pressure };
std :: vector < double > mixRatio = { rs };
std :: vector < double > valArr = m_opmFlowDiagStaticData -> m_eclPvtCurveCollection -> getDynamicPropertyNative ( Opm :: ECLPVT :: RawCurve :: FVF , Opm :: ECLPhaseIndex :: Liquid , static_cast < int > ( activeCellIndex ), phasePress , mixRatio );
if ( valArr . size () > 0 )
{
* bo = valArr [ 0 ];
}
}
// Bg
{
std :: vector < double > phasePress = { pressure };
std :: vector < double > mixRatio = { rv };
std :: vector < double > valArr = m_opmFlowDiagStaticData -> m_eclPvtCurveCollection -> getDynamicPropertyNative ( Opm :: ECLPVT :: RawCurve :: FVF , Opm :: ECLPhaseIndex :: Vapour , static_cast < int > ( activeCellIndex ), phasePress , mixRatio );
if ( valArr . size () > 0 )
{
* bg = valArr [ 0 ];
}
}
2018-01-19 15:21:17 +01:00
}
catch ( const std :: exception & e )
{
reportPvtCurveError ( QString ( e . what ()));
return false ;
}
2017-12-05 14:17:42 +01:00
return true ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigFlowDiagSolverInterface :: calculatePvtDynamicPropertiesViscosity ( size_t activeCellIndex , double pressure , double rs , double rv , double * mu_o , double * mu_g )
{
if ( mu_o ) * mu_o = HUGE_VAL ;
if ( mu_g ) * mu_g = HUGE_VAL ;
if ( ! ensureStaticDataObjectInstanceCreated ())
{
return false ;
}
2017-12-05 16:16:58 +01:00
CVF_ASSERT ( m_opmFlowDiagStaticData . notNull ());
if ( ! m_opmFlowDiagStaticData -> m_eclPvtCurveCollection )
{
return false ;
}
2018-01-19 15:21:17 +01:00
try {
2017-12-05 14:17:42 +01:00
// mu_o
{
std :: vector < double > phasePress = { pressure };
std :: vector < double > mixRatio = { rs };
std :: vector < double > valArr = m_opmFlowDiagStaticData -> m_eclPvtCurveCollection -> getDynamicPropertyNative ( Opm :: ECLPVT :: RawCurve :: Viscosity , Opm :: ECLPhaseIndex :: Liquid , static_cast < int > ( activeCellIndex ), phasePress , mixRatio );
if ( valArr . size () > 0 )
{
* mu_o = valArr [ 0 ];
}
}
// mu_o
{
std :: vector < double > phasePress = { pressure };
std :: vector < double > mixRatio = { rv };
std :: vector < double > valArr = m_opmFlowDiagStaticData -> m_eclPvtCurveCollection -> getDynamicPropertyNative ( Opm :: ECLPVT :: RawCurve :: Viscosity , Opm :: ECLPhaseIndex :: Vapour , static_cast < int > ( activeCellIndex ), phasePress , mixRatio );
if ( valArr . size () > 0 )
{
* mu_g = valArr [ 0 ];
}
}
2018-01-19 15:21:17 +01:00
}
catch ( const std :: exception & e )
{
reportPvtCurveError ( QString ( e . what ()));
return false ;
}
2017-12-05 14:17:42 +01:00
return true ;
}
2017-08-10 10:09:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: string RigFlowDiagSolverInterface :: getInitFileName () const
{
QString gridFileName = m_eclipseCase -> gridFileName ();
QStringList m_filesWithSameBaseName ;
if ( ! RifEclipseOutputFileTools :: findSiblingFilesWithSameBaseName ( gridFileName , & m_filesWithSameBaseName )) return std :: string ();
QString initFileName = RifEclipseOutputFileTools :: firstFileNameOfType ( m_filesWithSameBaseName , ECL_INIT_FILE );
return initFileName . toStdString ();
}
2017-08-09 14:10:39 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFlowDiagSolverInterface :: FlowCharacteristicsResultFrame :: FlowCharacteristicsResultFrame ()
: m_lorenzCoefficient ( HUGE_VAL )
{
}