mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-03 12:10:57 -06:00
1c6c82af85
Needs to copy the cached wellpaths on save. Split the cached filePath and the uncached filePath to only list the external well paths in the global path list, and to be able to copy the cached files on save.
822 lines
28 KiB
C++
822 lines
28 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2018- 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 <http://www.gnu.org/licenses/gpl.html>
|
|
// for more details.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "RicWellPathFractureTextReportFeatureImpl.h"
|
|
|
|
#include "RiaApplication.h"
|
|
#include "RiaRegressionTestRunner.h"
|
|
|
|
#include "RicExportFractureCompletionsImpl.h"
|
|
#include "RicWellPathFractureReportItem.h"
|
|
|
|
#include "RifTextDataTableFormatter.h"
|
|
|
|
#include "RigCompletionData.h"
|
|
#include "RigTransmissibilityEquations.h"
|
|
|
|
#include "RimEclipseCase.h"
|
|
#include "RimEllipseFractureTemplate.h"
|
|
#include "RimFileWellPath.h"
|
|
#include "RimFractureContainment.h"
|
|
#include "RimFractureTemplate.h"
|
|
#include "RimFractureTemplateCollection.h"
|
|
#include "RimOilField.h"
|
|
#include "RimProject.h"
|
|
#include "RimStimPlanFractureTemplate.h"
|
|
#include "RimTools.h"
|
|
#include "RimWellPath.h"
|
|
#include "RimWellPathCollection.h"
|
|
#include "RimWellPathFracture.h"
|
|
#include "RimWellPathFractureCollection.h"
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString orientationText( RimFractureTemplate::FracOrientationEnum orientation )
|
|
{
|
|
return caf::AppEnum<RimFractureTemplate::FracOrientationEnum>::uiText( orientation );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RifTextDataTableColumn floatNumberColumn( const QString& text )
|
|
{
|
|
return RifTextDataTableColumn( text, RifTextDataTableDoubleFormatting( RIF_FLOAT, 3 ), RIGHT );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::wellPathFractureReport(
|
|
RimEclipseCase* sourceCase,
|
|
const std::vector<RimWellPath*>& wellPaths,
|
|
const std::vector<RicWellPathFractureReportItem>& wellPathFractureReportItems ) const
|
|
{
|
|
QString lineStart = "--";
|
|
|
|
QString text;
|
|
QTextStream textStream( &text );
|
|
|
|
textStream
|
|
<< lineStart
|
|
<< "========================================================================================================\n";
|
|
|
|
textStream << lineStart << " RESINSIGHT DATA\n";
|
|
|
|
textStream << lineStart << "\n";
|
|
|
|
std::vector<RimStimPlanFractureTemplate*> stimPlanTemplates;
|
|
std::vector<RimEllipseFractureTemplate*> ellipseTemplates;
|
|
|
|
{
|
|
auto proj = RiaApplication::instance()->project();
|
|
auto fractureTemplates = proj->activeOilField()->fractureDefinitionCollection()->fractureTemplates();
|
|
|
|
std::set<QString> usedFractureTemplateNames;
|
|
for ( const auto& item : wellPathFractureReportItems )
|
|
{
|
|
usedFractureTemplateNames.insert( item.fractureTemplateName() );
|
|
}
|
|
|
|
for ( const auto fracTemplate : fractureTemplates )
|
|
{
|
|
if ( usedFractureTemplateNames.find( fracTemplate->name() ) == usedFractureTemplateNames.end() )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
auto stimPlanTemplate = dynamic_cast<RimStimPlanFractureTemplate*>( fracTemplate );
|
|
if ( stimPlanTemplate )
|
|
{
|
|
stimPlanTemplates.push_back( stimPlanTemplate );
|
|
}
|
|
|
|
auto ellipseTemplate = dynamic_cast<RimEllipseFractureTemplate*>( fracTemplate );
|
|
if ( ellipseTemplate )
|
|
{
|
|
ellipseTemplates.push_back( ellipseTemplate );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !RiaRegressionTestRunner::instance()->isRunningRegressionTests() )
|
|
{
|
|
if ( sourceCase )
|
|
{
|
|
textStream << lineStart << " Grid Model:\n";
|
|
textStream << lineStart << " " << sourceCase->gridFileName() << "\n";
|
|
textStream << lineStart << "\n";
|
|
}
|
|
|
|
{
|
|
QString tableText = createWellFileLocationText( wellPaths );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
|
|
{
|
|
QString tableText = createStimPlanFileLocationText( stimPlanTemplates );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
}
|
|
|
|
{
|
|
QString tableText = createEllipseFractureText( ellipseTemplates );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
|
|
{
|
|
QString tableText = createStimPlanFractureText( stimPlanTemplates );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
|
|
{
|
|
std::vector<RimFractureTemplate*> fracTemplates;
|
|
fracTemplates.insert( fracTemplates.end(), ellipseTemplates.begin(), ellipseTemplates.end() );
|
|
fracTemplates.insert( fracTemplates.end(), stimPlanTemplates.begin(), stimPlanTemplates.end() );
|
|
|
|
QString tableText = createFractureText( fracTemplates );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
|
|
{
|
|
std::vector<RimWellPathFracture*> wellPathFractures;
|
|
for ( const auto& w : wellPaths )
|
|
{
|
|
for ( const auto& frac : w->fractureCollection()->activeFractures() )
|
|
{
|
|
wellPathFractures.push_back( frac );
|
|
}
|
|
}
|
|
|
|
std::sort( wellPathFractures.begin(), wellPathFractures.end(), RimWellPathFracture::compareByWellPathNameAndMD );
|
|
|
|
{
|
|
QString tableText = createFractureInstancesText( wellPathFractures );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
|
|
{
|
|
QString tableText = createFractureCompletionSummaryText( wellPathFractureReportItems );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
|
|
{
|
|
QString tableText = createFracturePressureDepletionSummaryText( wellPathFractureReportItems );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
|
|
{
|
|
textStream << lineStart << " Maximum number of connections per well\n";
|
|
textStream << lineStart << "\n";
|
|
|
|
QString tableText = createConnectionsPerWellText( wellPathFractureReportItems );
|
|
textStream << tableText;
|
|
textStream << lineStart << "\n";
|
|
}
|
|
}
|
|
|
|
return text;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<RimWellPath*> RicWellPathFractureTextReportFeatureImpl::wellPathsWithActiveFractures()
|
|
{
|
|
std::vector<RimWellPath*> wellPaths;
|
|
|
|
auto* wellPathColl = RimTools::wellPathCollection();
|
|
if ( wellPathColl )
|
|
{
|
|
for ( const auto& wellPath : wellPathColl->wellPaths() )
|
|
{
|
|
if ( !wellPath->fractureCollection()->activeFractures().empty() )
|
|
{
|
|
wellPaths.push_back( wellPath );
|
|
}
|
|
}
|
|
}
|
|
|
|
return wellPaths;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createWellFileLocationText( const std::vector<RimWellPath*>& wellPaths ) const
|
|
{
|
|
if ( wellPaths.empty() ) return "";
|
|
|
|
QString tableText;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
std::vector<RifTextDataTableColumn> header = {
|
|
RifTextDataTableColumn( "Well" ),
|
|
RifTextDataTableColumn( "Location" ),
|
|
};
|
|
|
|
formatter.header( header );
|
|
|
|
formatter.addHorizontalLine( '-' );
|
|
|
|
if ( !wellPaths.empty() )
|
|
{
|
|
for ( const auto& wellPath : wellPaths )
|
|
{
|
|
auto fileWellPath = dynamic_cast<RimFileWellPath*>( wellPath );
|
|
if ( fileWellPath )
|
|
{
|
|
formatter.add( wellPath->name() );
|
|
formatter.add( fileWellPath->filePath() );
|
|
formatter.rowCompleted();
|
|
}
|
|
}
|
|
}
|
|
|
|
formatter.tableCompleted();
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createStimPlanFileLocationText(
|
|
const std::vector<RimStimPlanFractureTemplate*>& stimPlanTemplates ) const
|
|
{
|
|
if ( stimPlanTemplates.empty() ) return "";
|
|
|
|
QString tableText;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
std::vector<RifTextDataTableColumn> header = {
|
|
RifTextDataTableColumn( "StimPlan Name" ),
|
|
RifTextDataTableColumn( "Location" ),
|
|
};
|
|
|
|
formatter.header( header );
|
|
|
|
formatter.addHorizontalLine( '-' );
|
|
|
|
if ( !stimPlanTemplates.empty() )
|
|
{
|
|
for ( const auto& stimPlanTemplate : stimPlanTemplates )
|
|
{
|
|
formatter.add( stimPlanTemplate->name() );
|
|
formatter.add( stimPlanTemplate->fileName() );
|
|
formatter.rowCompleted();
|
|
}
|
|
}
|
|
|
|
formatter.tableCompleted();
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createStimPlanFractureText(
|
|
const std::vector<RimStimPlanFractureTemplate*>& stimPlanTemplates ) const
|
|
{
|
|
if ( stimPlanTemplates.empty() ) return "";
|
|
|
|
QString tableText;
|
|
|
|
RiaEclipseUnitTools::UnitSystem unitSystem = stimPlanTemplates.front()->fractureTemplateUnit();
|
|
bool isFieldUnits = unitSystem == RiaEclipseUnitTools::UNITS_FIELD;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
std::vector<RifTextDataTableColumn> header = {
|
|
RifTextDataTableColumn( "StimPlan" ),
|
|
RifTextDataTableColumn( " " ),
|
|
floatNumberColumn( "WDiam" ),
|
|
floatNumberColumn( "Skin" ),
|
|
};
|
|
|
|
formatter.header( header );
|
|
|
|
// Second header line
|
|
{
|
|
formatter.add( "Template" ); // Template
|
|
formatter.add( "Orientation" ); // Orientation
|
|
formatter.add( isFieldUnits ? "[in]" : "[m]" ); // WDiam
|
|
formatter.add( "[] " ); // Skin
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.addHorizontalLine( '-' );
|
|
|
|
for ( const auto& stimPlanTemplate : stimPlanTemplates )
|
|
{
|
|
formatter.add( stimPlanTemplate->name() );
|
|
formatter.add( orientationText( stimPlanTemplate->orientationType() ) );
|
|
formatter.add( stimPlanTemplate->wellDiameter() );
|
|
formatter.add( stimPlanTemplate->skinFactor() );
|
|
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.tableCompleted();
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createEllipseFractureText(
|
|
const std::vector<RimEllipseFractureTemplate*>& ellipseTemplates ) const
|
|
{
|
|
if ( ellipseTemplates.empty() ) return "";
|
|
|
|
QString tableText;
|
|
|
|
RiaEclipseUnitTools::UnitSystem unitSystem = ellipseTemplates.front()->fractureTemplateUnit();
|
|
bool isFieldUnits = unitSystem == RiaEclipseUnitTools::UNITS_FIELD;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
std::vector<RifTextDataTableColumn> header = {
|
|
RifTextDataTableColumn( "Ellipse" ),
|
|
RifTextDataTableColumn( " " ),
|
|
floatNumberColumn( "Xf" ),
|
|
floatNumberColumn( "Height" ),
|
|
floatNumberColumn( "Kf" ),
|
|
floatNumberColumn( "Wf" ),
|
|
floatNumberColumn( "WDiam" ),
|
|
floatNumberColumn( "Skin" ),
|
|
};
|
|
|
|
formatter.header( header );
|
|
|
|
// Second header line
|
|
{
|
|
formatter.add( "Template" ); // Template
|
|
formatter.add( "Orientation" ); // Orientation
|
|
formatter.add( isFieldUnits ? "[ft]" : "[m]" ); // Xf
|
|
formatter.add( isFieldUnits ? "[ft]" : "[m]" ); // Height
|
|
formatter.add( "[mD]" ); // Kf
|
|
formatter.add( isFieldUnits ? "[in]" : "[m]" ); // Wf
|
|
formatter.add( isFieldUnits ? "[ft]" : "[m]" ); // WDiam
|
|
formatter.add( "[] " ); // Skin
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.addHorizontalLine( '-' );
|
|
|
|
for ( const auto& ellipseTemplate : ellipseTemplates )
|
|
{
|
|
formatter.add( ellipseTemplate->name() );
|
|
formatter.add( orientationText( ellipseTemplate->orientationType() ) );
|
|
|
|
formatter.add( ellipseTemplate->halfLength() );
|
|
formatter.add( ellipseTemplate->height() );
|
|
|
|
formatter.add(
|
|
RigTransmissibilityEquations::permeability( ellipseTemplate->conductivity(), ellipseTemplate->width() ) );
|
|
formatter.add( ellipseTemplate->width() );
|
|
|
|
formatter.add( ellipseTemplate->wellDiameter() );
|
|
formatter.add( ellipseTemplate->skinFactor() );
|
|
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.tableCompleted();
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createFractureText(
|
|
const std::vector<RimFractureTemplate*>& fractureTemplates ) const
|
|
{
|
|
if ( fractureTemplates.empty() ) return "";
|
|
|
|
QString tableText;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
std::vector<RifTextDataTableColumn> header = {
|
|
RifTextDataTableColumn( " " ),
|
|
floatNumberColumn( "Top" ),
|
|
floatNumberColumn( "Bot" ),
|
|
floatNumberColumn( "Fault" ),
|
|
floatNumberColumn( "Height" ),
|
|
floatNumberColumn( "Half Length" ),
|
|
floatNumberColumn( "DFac" ),
|
|
floatNumberColumn( "Conductivity" ),
|
|
};
|
|
|
|
formatter.header( header );
|
|
|
|
// Second header line
|
|
{
|
|
formatter.add( "Template" );
|
|
formatter.add( "Cont" );
|
|
formatter.add( "Cont" );
|
|
formatter.add( "Truncation" );
|
|
formatter.add( "Scale" );
|
|
formatter.add( "Scale" );
|
|
formatter.add( "Scale" );
|
|
formatter.add( "Scale" );
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.addHorizontalLine( '-' );
|
|
|
|
for ( const auto& fracTemplate : fractureTemplates )
|
|
{
|
|
formatter.add( fracTemplate->name() );
|
|
|
|
if ( fracTemplate->fractureContainment()->isEnabled() )
|
|
{
|
|
formatter.add( fracTemplate->fractureContainment()->topKLayer() );
|
|
formatter.add( fracTemplate->fractureContainment()->baseKLayer() );
|
|
}
|
|
else
|
|
{
|
|
formatter.add( "N/A" );
|
|
formatter.add( "N/A" );
|
|
}
|
|
|
|
if ( fracTemplate->fractureContainment()->minimumFaultThrow() >= 0.0 )
|
|
{
|
|
formatter.add( fracTemplate->fractureContainment()->minimumFaultThrow() );
|
|
}
|
|
else
|
|
{
|
|
formatter.add( "N/A" );
|
|
}
|
|
|
|
double halfLengthScale, heightScale, dfactorScale, conductivityScale;
|
|
fracTemplate->scaleFactors( &halfLengthScale, &heightScale, &dfactorScale, &conductivityScale );
|
|
formatter.add( heightScale );
|
|
formatter.add( halfLengthScale );
|
|
formatter.add( dfactorScale );
|
|
formatter.add( conductivityScale );
|
|
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.tableCompleted();
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createFractureInstancesText(
|
|
const std::vector<RimWellPathFracture*>& fractures ) const
|
|
{
|
|
if ( fractures.empty() ) return "";
|
|
|
|
RiaEclipseUnitTools::UnitSystem unitSystem = fractures.front()->fractureUnit(); // Fix
|
|
bool isFieldUnits = unitSystem == RiaEclipseUnitTools::UNITS_FIELD;
|
|
|
|
QString tableText;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
std::vector<RifTextDataTableColumn> header = {
|
|
RifTextDataTableColumn( "" ),
|
|
RifTextDataTableColumn( "" ),
|
|
RifTextDataTableColumn( "" ),
|
|
floatNumberColumn( "MD" ),
|
|
floatNumberColumn( "Dip" ),
|
|
floatNumberColumn( "Tilt" ),
|
|
floatNumberColumn( "LPerf" ),
|
|
floatNumberColumn( "PerfEff" ),
|
|
floatNumberColumn( "Wdia" ),
|
|
RifTextDataTableColumn( "Dfac",
|
|
RifTextDataTableDoubleFormatting( RifTextDataTableDoubleFormat::RIF_SCIENTIFIC ),
|
|
RIGHT ),
|
|
};
|
|
|
|
formatter.header( header );
|
|
|
|
// Second header line
|
|
{
|
|
formatter.add( "Well" );
|
|
formatter.add( "Fracture" );
|
|
formatter.add( "Template" );
|
|
formatter.add( "" ); // MD
|
|
formatter.add( "" ); // Dip
|
|
formatter.add( "" ); // Tilt
|
|
formatter.add( isFieldUnits ? "[ft]" : "[m]" ); // LPerf
|
|
formatter.add( "[]" ); // PerfEff
|
|
formatter.add( isFieldUnits ? "[ft]" : "[m]" ); // WDia
|
|
formatter.add( "[...]" ); // Dfac
|
|
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.addHorizontalLine( '-' );
|
|
|
|
for ( const auto& fracture : fractures )
|
|
{
|
|
fracture->ensureValidNonDarcyProperties();
|
|
|
|
QString wellName;
|
|
|
|
RimWellPath* wellPath = nullptr;
|
|
fracture->firstAncestorOrThisOfType( wellPath );
|
|
if ( wellPath )
|
|
{
|
|
wellName = wellPath->name();
|
|
}
|
|
|
|
formatter.add( wellName );
|
|
formatter.add( fracture->name() );
|
|
|
|
if ( fracture->fractureTemplate() )
|
|
{
|
|
formatter.add( fracture->fractureTemplate()->name() );
|
|
}
|
|
else
|
|
{
|
|
formatter.add( "N/A" );
|
|
}
|
|
|
|
formatter.add( fracture->fractureMD() );
|
|
formatter.add( fracture->dip() );
|
|
formatter.add( fracture->tilt() );
|
|
|
|
if ( fracture->fractureTemplate() &&
|
|
fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH )
|
|
{
|
|
formatter.add( fracture->perforationLength() );
|
|
}
|
|
else
|
|
{
|
|
formatter.add( "N/A" );
|
|
}
|
|
|
|
formatter.add( fracture->perforationEfficiency() );
|
|
formatter.add( fracture->wellRadius() * 2.0 );
|
|
|
|
if ( fracture->fractureTemplate() && fracture->fractureTemplate()->isNonDarcyFlowEnabled() )
|
|
{
|
|
formatter.add( fracture->nonDarcyProperties().dFactor );
|
|
}
|
|
else
|
|
{
|
|
formatter.add( "N/A" );
|
|
}
|
|
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.tableCompleted();
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createFractureCompletionSummaryText(
|
|
const std::vector<RicWellPathFractureReportItem>& wellPathFractureReportItems ) const
|
|
{
|
|
QString tableText;
|
|
|
|
RiaEclipseUnitTools::UnitSystem unitSystem = wellPathFractureReportItems.front().unitSystem();
|
|
bool isFieldUnits = unitSystem == RiaEclipseUnitTools::UNITS_FIELD;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
const QString meanText = "Mean";
|
|
|
|
std::vector<RifTextDataTableColumn> header = {
|
|
RifTextDataTableColumn( "" ), // Well
|
|
RifTextDataTableColumn( "" ), // Fracture
|
|
RifTextDataTableColumn( "" ), // Template
|
|
floatNumberColumn( "" ), // Tr
|
|
floatNumberColumn( "" ), //#con
|
|
floatNumberColumn( "" ), // Fcd
|
|
RifTextDataTableColumn( "", RifTextDataTableDoubleFormatting( RIF_FLOAT, 1 ), RIGHT ), // Area
|
|
RifTextDataTableColumn( meanText, RifTextDataTableDoubleFormatting( RIF_FLOAT, 1 ), RIGHT ), // KfWf
|
|
RifTextDataTableColumn( meanText, RifTextDataTableDoubleFormatting( RIF_FLOAT, 1 ), RIGHT ), // Kf
|
|
floatNumberColumn( meanText ), // wf
|
|
RifTextDataTableColumn( meanText, RifTextDataTableDoubleFormatting( RIF_FLOAT, 1 ), RIGHT ), // xf
|
|
RifTextDataTableColumn( meanText, RifTextDataTableDoubleFormatting( RIF_FLOAT, 1 ), RIGHT ), // H
|
|
floatNumberColumn( meanText ), // Km
|
|
};
|
|
|
|
formatter.header( header );
|
|
|
|
// Second header line
|
|
{
|
|
formatter.add( "" );
|
|
formatter.add( "" );
|
|
formatter.add( "" );
|
|
formatter.add( "Tr" ); // Tr
|
|
formatter.add( "#con" ); // #con
|
|
formatter.add( "Fcd" ); // Fcd
|
|
formatter.add( "Area" ); // Area
|
|
formatter.add( "KfWf" ); // KfWf
|
|
formatter.add( "Kf" ); // Kf
|
|
formatter.add( "wf" ); // wf
|
|
formatter.add( "Xf" ); // Xf
|
|
formatter.add( "H" ); // H
|
|
formatter.add( "Km" ); // Km
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
// Third header line
|
|
{
|
|
formatter.add( "Well" );
|
|
formatter.add( "Fracture" );
|
|
formatter.add( "Template" );
|
|
formatter.add( isFieldUnits ? "[cP.rb/day/psi]" : "[cP.rm3/day/bars]" ); // Tr
|
|
formatter.add( "" ); // #con
|
|
formatter.add( "[]" ); // Fcd
|
|
formatter.add( isFieldUnits ? "[ft2]" : "[m2]" ); // Area
|
|
formatter.add( isFieldUnits ? "[mDft]" : "[mDm]" ); // KfWf
|
|
formatter.add( "[mD]" ); // Kf
|
|
formatter.add( isFieldUnits ? "[ft]" : "[m]" ); // wf
|
|
formatter.add( isFieldUnits ? "[ft]" : "[m]" ); // Xf
|
|
formatter.add( isFieldUnits ? "[ft]" : "[m]" ); // H
|
|
formatter.add( "[mD]" ); // Km
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.addHorizontalLine( '-' );
|
|
|
|
for ( const auto& reportItem : wellPathFractureReportItems )
|
|
{
|
|
formatter.add( reportItem.wellPathNameForExport() );
|
|
formatter.add( reportItem.fractureName() );
|
|
formatter.add( reportItem.fractureTemplateName() );
|
|
|
|
formatter.add( reportItem.transmissibility() );
|
|
formatter.add( reportItem.connectionCount() );
|
|
formatter.add( reportItem.fcd() );
|
|
formatter.add( reportItem.area() );
|
|
|
|
formatter.add( reportItem.kfwf() ); // KfWf
|
|
formatter.add( reportItem.kf() ); // Kf
|
|
formatter.add( reportItem.wf() ); // wf
|
|
|
|
formatter.add( reportItem.xf() ); // Xf
|
|
formatter.add( reportItem.h() ); // H
|
|
formatter.add( reportItem.km() ); // Km
|
|
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.tableCompleted();
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createFracturePressureDepletionSummaryText(
|
|
const std::vector<RicWellPathFractureReportItem>& wellPathFractureReportItems ) const
|
|
{
|
|
QString tableText;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
std::vector<RifTextDataTableColumn> header = {RifTextDataTableColumn( "Well" ),
|
|
RifTextDataTableColumn( "Fracture" ),
|
|
RifTextDataTableColumn( "Actual WBHP" ),
|
|
RifTextDataTableColumn( "Min Pressure Drop" ),
|
|
RifTextDataTableColumn( "Max Pressure Drop" )};
|
|
|
|
bool createdTable = false;
|
|
|
|
for ( const auto& reportItem : wellPathFractureReportItems )
|
|
{
|
|
if ( reportItem.performPressureDepletionScaling() )
|
|
{
|
|
if ( !createdTable )
|
|
{
|
|
formatter.comment(
|
|
QString( "Pressure Depletion Time step: %1" ).arg( reportItem.pressureDepletionTimeStepString() ) );
|
|
formatter.comment( QString( "WBHP Source: %1" ).arg( reportItem.pressureDepletionWBHPString() ) );
|
|
formatter.comment( QString( "User Defined WBHP: %1" ).arg( reportItem.pressureDepletionUserWBHP() ) );
|
|
|
|
formatter.header( header );
|
|
formatter.addHorizontalLine( '-' );
|
|
createdTable = true;
|
|
}
|
|
formatter.add( reportItem.wellPathNameForExport() );
|
|
formatter.add( reportItem.fractureName() );
|
|
formatter.add( reportItem.pressureDepletionActualWBHP() );
|
|
formatter.add( reportItem.pressureDepletionMinPressureDrop() );
|
|
formatter.add( reportItem.pressureDepletionMaxPressureDrop() );
|
|
formatter.rowCompleted();
|
|
}
|
|
}
|
|
if ( createdTable )
|
|
{
|
|
formatter.tableCompleted();
|
|
}
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RicWellPathFractureTextReportFeatureImpl::createConnectionsPerWellText(
|
|
const std::vector<RicWellPathFractureReportItem>& wellPathFractureReportItems ) const
|
|
{
|
|
QString tableText;
|
|
|
|
QTextStream stream( &tableText );
|
|
RifTextDataTableFormatter formatter( stream );
|
|
configureFormatter( &formatter );
|
|
|
|
std::vector<RifTextDataTableColumn> header = {RifTextDataTableColumn( "Well" ), floatNumberColumn( "ConnCount" )};
|
|
|
|
formatter.header( header );
|
|
formatter.addHorizontalLine( '-' );
|
|
|
|
std::map<QString /*Well*/, size_t> wellConnectionCounts;
|
|
for ( const auto& reportItem : wellPathFractureReportItems )
|
|
{
|
|
QString wellPathName = reportItem.wellPathNameForExport();
|
|
if ( wellConnectionCounts.find( wellPathName ) == wellConnectionCounts.end() )
|
|
{
|
|
wellConnectionCounts.insert( std::make_pair( wellPathName, 0 ) );
|
|
}
|
|
|
|
wellConnectionCounts[wellPathName] += reportItem.connectionCount();
|
|
}
|
|
|
|
for ( const auto& connCount : wellConnectionCounts )
|
|
{
|
|
formatter.add( connCount.first );
|
|
formatter.add( connCount.second );
|
|
|
|
formatter.rowCompleted();
|
|
}
|
|
|
|
formatter.tableCompleted();
|
|
|
|
return tableText;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RicWellPathFractureTextReportFeatureImpl::configureFormatter( RifTextDataTableFormatter* formatter ) const
|
|
{
|
|
if ( !formatter ) return;
|
|
|
|
formatter->setColumnSpacing( 3 );
|
|
formatter->setTableRowPrependText( "-- " );
|
|
formatter->setTableRowLineAppendText( "" );
|
|
}
|