mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 14:40:26 -05:00
Rename and move Rig files
This commit is contained in:
1 parent
a88fecdaa4
commit
ab1f053449
8 files changed
+41
-40
No files matched your search
@@ -1,8 +1,13 @@
|
||||
set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RigMswTableRows.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigMswTableData.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigMswDataFormatter.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigMswUnifiedData.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RigMswTableData.cpp)
|
||||
set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RigMswTableData.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigMswDataFormatter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigMswUnifiedData.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})
|
||||
@@ -0,0 +1,402 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 "RigMswDataFormatter.h"
|
||||
|
||||
#include "RifTextDataTableFormatter.h"
|
||||
|
||||
#include "RigMswTableData.h"
|
||||
#include "RigMswUnifiedData.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to format WELSEGS segment data rows
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename RowContainer>
|
||||
void formatWelsegsRows( RifTextDataTableFormatter& formatter, const RowContainer& rows )
|
||||
{
|
||||
for ( const auto& row : rows )
|
||||
{
|
||||
formatter.add( row.segmentNumber );
|
||||
formatter.add( row.segmentNumber );
|
||||
formatter.add( row.branchNumber );
|
||||
formatter.add( row.outletSegmentNumber );
|
||||
formatter.add( row.length );
|
||||
|
||||
formatter.addOptionalValue( row.depth );
|
||||
formatter.addOptionalValue( row.diameter );
|
||||
formatter.addOptionalValue( row.roughness );
|
||||
|
||||
formatter.addOptionalComment( QString::fromStdString( row.description ) );
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to format COMPSEGS data rows
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename RowContainer>
|
||||
void formatCompsegsRows( RifTextDataTableFormatter& formatter, const RowContainer& rows, bool isLgrData )
|
||||
{
|
||||
for ( const auto& row : rows )
|
||||
{
|
||||
if ( isLgrData )
|
||||
{
|
||||
formatter.addStdString( row.gridName );
|
||||
}
|
||||
|
||||
formatter.add( row.cellI );
|
||||
formatter.add( row.cellJ );
|
||||
formatter.add( row.cellK );
|
||||
formatter.add( row.branchNumber );
|
||||
formatter.add( row.startLength );
|
||||
formatter.add( row.endLength );
|
||||
|
||||
formatter.addOptionalValue( row.direction );
|
||||
formatter.addOptionalValue( row.endRange );
|
||||
formatter.addOptionalValue( row.connectionDepth );
|
||||
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to format WSEGVALV data rows
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename RowContainer>
|
||||
void formatWsegvalvRows( RifTextDataTableFormatter& formatter, const RowContainer& rows )
|
||||
{
|
||||
for ( const auto& row : rows )
|
||||
{
|
||||
formatter.addStdString( row.wellName );
|
||||
formatter.add( row.segmentNumber );
|
||||
formatter.add( row.flowCoefficient );
|
||||
formatter.addOptionalValue( row.area );
|
||||
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to format WSEGAICD data rows
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename RowContainer>
|
||||
void formatWsegaicdRows( RifTextDataTableFormatter& formatter, const RowContainer& rows )
|
||||
{
|
||||
for ( const auto& row : rows )
|
||||
{
|
||||
formatter.addStdString( row.wellName );
|
||||
formatter.add( row.segmentNumber );
|
||||
formatter.add( row.flowCoefficient );
|
||||
formatter.addOptionalValue( row.area );
|
||||
formatter.addOptionalValue( row.oilViscosityParameter );
|
||||
formatter.addOptionalValue( row.waterViscosityParameter );
|
||||
formatter.addOptionalValue( row.gasViscosityParameter );
|
||||
formatter.addStdString( row.deviceType );
|
||||
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to create COMPSEGS headers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifTextDataTableColumn> createCompsegsHeader( bool isLgrData )
|
||||
{
|
||||
if ( isLgrData )
|
||||
{
|
||||
return { RifTextDataTableColumn( "Grid" ),
|
||||
RifTextDataTableColumn( "I" ),
|
||||
RifTextDataTableColumn( "J" ),
|
||||
RifTextDataTableColumn( "K" ),
|
||||
RifTextDataTableColumn( "Branch no" ),
|
||||
RifTextDataTableColumn( "Start Length" ),
|
||||
RifTextDataTableColumn( "End Length" ),
|
||||
RifTextDataTableColumn( "Dir Pen" ),
|
||||
RifTextDataTableColumn( "End Range" ),
|
||||
RifTextDataTableColumn( "Connection Depth" ) };
|
||||
}
|
||||
else
|
||||
{
|
||||
return { RifTextDataTableColumn( "I" ),
|
||||
RifTextDataTableColumn( "J" ),
|
||||
RifTextDataTableColumn( "K" ),
|
||||
RifTextDataTableColumn( "Branch no" ),
|
||||
RifTextDataTableColumn( "Start Length" ),
|
||||
RifTextDataTableColumn( "End Length" ),
|
||||
RifTextDataTableColumn( "Dir Pen" ),
|
||||
RifTextDataTableColumn( "End Range" ),
|
||||
RifTextDataTableColumn( "Connection Depth" ) };
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to create WSEGVALV headers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifTextDataTableColumn> createWsegvalvHeader()
|
||||
{
|
||||
return { RifTextDataTableColumn( "Well" ),
|
||||
RifTextDataTableColumn( "Seg No" ),
|
||||
RifTextDataTableColumn( "Cv" ),
|
||||
RifTextDataTableColumn( "Ac", RifTextDataTableDoubleFormatting( RIF_CONSISE, 4 ) ) };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to create WSEGAICD headers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifTextDataTableColumn> createWsegaicdHeader()
|
||||
{
|
||||
return { RifTextDataTableColumn( "Well" ),
|
||||
RifTextDataTableColumn( "Seg No" ),
|
||||
RifTextDataTableColumn( "Flow Coeff" ),
|
||||
RifTextDataTableColumn( "Area" ),
|
||||
RifTextDataTableColumn( "Oil Visc" ),
|
||||
RifTextDataTableColumn( "Water Visc" ),
|
||||
RifTextDataTableColumn( "Gas Visc" ),
|
||||
RifTextDataTableColumn( "Device Type" ) };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Helper function to create WELSEGS segment headers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifTextDataTableColumn> createWelsegsSegmentHeader()
|
||||
{
|
||||
return { RifTextDataTableColumn( "First Seg" ),
|
||||
RifTextDataTableColumn( "Last Seg" ),
|
||||
RifTextDataTableColumn( "Branch No" ),
|
||||
RifTextDataTableColumn( "Outlet Seg" ),
|
||||
RifTextDataTableColumn( "Length" ),
|
||||
RifTextDataTableColumn( "Depth Change" ),
|
||||
RifTextDataTableColumn( "Diam" ),
|
||||
RifTextDataTableColumn( "Rough", RifTextDataTableDoubleFormatting( RIF_FLOAT, 7 ) ) };
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format WELSEGS table for a single well
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatWelsegsTable( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData )
|
||||
{
|
||||
if ( !tableData.hasWelsegsData() ) return;
|
||||
|
||||
const auto& welsegsHeader = tableData.welsegsHeader();
|
||||
formatter.keyword( "WELSEGS" );
|
||||
std::vector<RifTextDataTableColumn> tableHeader = {
|
||||
RifTextDataTableColumn( "Well" ),
|
||||
RifTextDataTableColumn( "Dep 1" ),
|
||||
RifTextDataTableColumn( "Tlen 1" ),
|
||||
RifTextDataTableColumn( "Vol 1" ),
|
||||
RifTextDataTableColumn( "Len&Dep" ),
|
||||
RifTextDataTableColumn( "PresDrop" ),
|
||||
};
|
||||
formatter.header( tableHeader );
|
||||
|
||||
// Write header row
|
||||
formatter.addStdString( welsegsHeader.wellName );
|
||||
formatter.add( welsegsHeader.topTVD );
|
||||
formatter.add( welsegsHeader.topMD );
|
||||
formatter.addOptionalValue( welsegsHeader.volume );
|
||||
formatter.addStdString( welsegsHeader.lengthAndDepthText );
|
||||
formatter.addStdString( welsegsHeader.pressureDropText );
|
||||
formatter.rowCompleted();
|
||||
|
||||
// Column headers for segment data
|
||||
auto segmentHeader = createWelsegsSegmentHeader();
|
||||
formatter.header( segmentHeader );
|
||||
|
||||
// Write segment data using helper function
|
||||
formatWelsegsRows( formatter, tableData.welsegsData() );
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format COMPSEGS table for a single well
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatCompsegsTable( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData, bool isLgrData )
|
||||
{
|
||||
std::vector<CompsegsRow> rows;
|
||||
if ( isLgrData )
|
||||
{
|
||||
rows = tableData.lgrCompsegsData();
|
||||
}
|
||||
else
|
||||
{
|
||||
rows = tableData.mainGridCompsegsData();
|
||||
}
|
||||
|
||||
if ( rows.empty() ) return;
|
||||
|
||||
formatter.keyword( "COMPSEGS" );
|
||||
|
||||
// Add well name
|
||||
{
|
||||
std::vector<RifTextDataTableColumn> header = { RifTextDataTableColumn( "Name" ) };
|
||||
formatter.header( header );
|
||||
formatter.addStdString( tableData.wellName() );
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
auto header = createCompsegsHeader( isLgrData );
|
||||
formatter.header( header );
|
||||
|
||||
formatCompsegsRows( formatter, rows, isLgrData );
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format WSEGVALV table for a single well
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatWsegvalvTable( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData )
|
||||
{
|
||||
if ( !tableData.hasWsegvalvData() ) return;
|
||||
|
||||
formatter.keyword( "WSEGVALV" );
|
||||
auto header = createWsegvalvHeader();
|
||||
formatter.header( header );
|
||||
|
||||
formatWsegvalvRows( formatter, tableData.wsegvalvData() );
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format WSEGAICD table for a single well
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatWsegaicdTable( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData )
|
||||
{
|
||||
if ( !tableData.hasWsegaicdData() ) return;
|
||||
|
||||
formatter.keyword( "WSEGAICD" );
|
||||
auto header = createWsegaicdHeader();
|
||||
formatter.header( header );
|
||||
|
||||
formatWsegaicdRows( formatter, tableData.wsegaicdData() );
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format WELSEGS table for unified data (multiple wells)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatWelsegsTable( RifTextDataTableFormatter& formatter, const RigMswUnifiedDataWIP& unifiedData )
|
||||
{
|
||||
if ( unifiedData.isEmpty() ) return;
|
||||
|
||||
auto headers = unifiedData.getAllWelsegsHeaders();
|
||||
auto rows = unifiedData.getAllWelsegsRows();
|
||||
|
||||
if ( headers.empty() && rows.empty() ) return;
|
||||
|
||||
formatter.keyword( "WELSEGS" );
|
||||
std::vector<RifTextDataTableColumn> unifiedWelsegsHeader = { RifTextDataTableColumn( "Well" ),
|
||||
RifTextDataTableColumn( "Dep 1" ),
|
||||
RifTextDataTableColumn( "Tlen 1" ),
|
||||
RifTextDataTableColumn( "Vol 1" ),
|
||||
RifTextDataTableColumn( "Len&Dep" ),
|
||||
RifTextDataTableColumn( "PresDrop" ) };
|
||||
formatter.header( unifiedWelsegsHeader );
|
||||
|
||||
// Write headers for all wells
|
||||
for ( const auto& header : headers )
|
||||
{
|
||||
formatter.addStdString( header.wellName );
|
||||
formatter.add( header.topTVD );
|
||||
formatter.add( header.topMD );
|
||||
formatter.addOptionalValue( header.volume );
|
||||
formatter.addStdString( header.lengthAndDepthText );
|
||||
formatter.addStdString( header.pressureDropText );
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
|
||||
// Column headers for segment data
|
||||
auto segmentHeader = createWelsegsSegmentHeader();
|
||||
formatter.header( segmentHeader );
|
||||
|
||||
// Write all segment data using helper function
|
||||
formatWelsegsRows( formatter, rows );
|
||||
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format WSEGVALV table for unified data (multiple wells)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatWsegvalvTable( RifTextDataTableFormatter& formatter, const RigMswUnifiedDataWIP& unifiedData )
|
||||
{
|
||||
auto rows = unifiedData.getAllWsegvalvRows();
|
||||
if ( rows.empty() ) return;
|
||||
|
||||
formatter.keyword( "WSEGVALV" );
|
||||
auto header = createWsegvalvHeader();
|
||||
formatter.header( header );
|
||||
|
||||
formatWsegvalvRows( formatter, rows );
|
||||
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format WSEGAICD table for unified data (multiple wells)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatWsegaicdTable( RifTextDataTableFormatter& formatter, const RigMswUnifiedDataWIP& unifiedData )
|
||||
{
|
||||
auto rows = unifiedData.getAllWsegaicdRows();
|
||||
if ( rows.empty() ) return;
|
||||
|
||||
formatter.keyword( "WSEGAICD" );
|
||||
auto header = createWsegaicdHeader();
|
||||
formatter.header( header );
|
||||
|
||||
formatWsegaicdRows( formatter, rows );
|
||||
|
||||
formatter.tableCompleted();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format all MSW tables for a single well
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatMswTables( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData )
|
||||
{
|
||||
formatWelsegsTable( formatter, tableData );
|
||||
formatCompsegsTable( formatter, tableData, false ); // Main grid
|
||||
|
||||
if ( tableData.hasLgrData() )
|
||||
{
|
||||
formatCompsegsTable( formatter, tableData, true ); // LGR data
|
||||
}
|
||||
|
||||
formatWsegvalvTable( formatter, tableData );
|
||||
formatWsegaicdTable( formatter, tableData );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Format all MSW tables for unified data (multiple wells)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswDataFormatter::formatMswTables( RifTextDataTableFormatter& formatter, const RigMswUnifiedDataWIP& unifiedData )
|
||||
{
|
||||
formatWelsegsTable( formatter, unifiedData );
|
||||
|
||||
for ( const auto& wellData : unifiedData.wellDataList() )
|
||||
{
|
||||
bool isLgrData = false;
|
||||
formatCompsegsTable( formatter, wellData, isLgrData ); // Main grid, LGR is handeled separately
|
||||
}
|
||||
|
||||
formatWsegvalvTable( formatter, unifiedData );
|
||||
formatWsegaicdTable( formatter, unifiedData );
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
class RifTextDataTableFormatter;
|
||||
class RigMswTableData;
|
||||
class RigMswUnifiedDataWIP;
|
||||
|
||||
//==================================================================================================
|
||||
/// Formatter functions that convert MSW data structures to file output using RifTextDataTableFormatter
|
||||
//==================================================================================================
|
||||
namespace RigMswDataFormatter
|
||||
{
|
||||
// Consolidated data formatting - works with any compatible data source
|
||||
void formatCompsegsTable( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData, bool isLgrData = false );
|
||||
void formatWsegvalvTable( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData );
|
||||
void formatWsegvalvTable( RifTextDataTableFormatter& formatter, const RigMswUnifiedDataWIP& unifiedData );
|
||||
void formatWsegaicdTable( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData );
|
||||
void formatWsegaicdTable( RifTextDataTableFormatter& formatter, const RigMswUnifiedDataWIP& unifiedData );
|
||||
void formatWelsegsTable( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData );
|
||||
void formatWelsegsTable( RifTextDataTableFormatter& formatter, const RigMswUnifiedDataWIP& unifiedData );
|
||||
|
||||
// Complete MSW export
|
||||
void formatMswTables( RifTextDataTableFormatter& formatter, const RigMswTableData& tableData );
|
||||
void formatMswTables( RifTextDataTableFormatter& formatter, const RigMswUnifiedDataWIP& unifiedData );
|
||||
} // namespace RigMswDataFormatter
|
||||
@@ -0,0 +1,240 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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 "RigMswUnifiedData.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswUnifiedDataWIP::addWellData( RigMswTableData wellData )
|
||||
{
|
||||
// Check if well name already exists
|
||||
const std::string& wellName = wellData.wellName();
|
||||
auto it = std::find_if( m_wellDataList.begin(),
|
||||
m_wellDataList.end(),
|
||||
[&wellName]( const RigMswTableData& data ) { return data.wellName() == wellName; } );
|
||||
|
||||
if ( it != m_wellDataList.end() )
|
||||
{
|
||||
// Replace existing data
|
||||
*it = std::move( wellData );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add new data
|
||||
m_wellDataList.push_back( std::move( wellData ) );
|
||||
}
|
||||
|
||||
updateIndex();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswUnifiedDataWIP::clear()
|
||||
{
|
||||
m_wellDataList.clear();
|
||||
m_wellNameToIndex.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RigMswTableData* RigMswUnifiedDataWIP::getWellData( const std::string& wellName ) const
|
||||
{
|
||||
auto it = m_wellNameToIndex.find( wellName );
|
||||
if ( it != m_wellNameToIndex.end() && it->second < m_wellDataList.size() )
|
||||
{
|
||||
return &m_wellDataList[it->second];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<WelsegsHeader> RigMswUnifiedDataWIP::getAllWelsegsHeaders() const
|
||||
{
|
||||
std::vector<WelsegsHeader> allHeaders;
|
||||
|
||||
for ( const auto& wellData : m_wellDataList )
|
||||
{
|
||||
allHeaders.push_back( wellData.welsegsHeader() );
|
||||
}
|
||||
|
||||
return allHeaders;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<WelsegsRow> RigMswUnifiedDataWIP::getAllWelsegsRows() const
|
||||
{
|
||||
std::vector<WelsegsRow> allRows;
|
||||
|
||||
for ( const auto& wellData : m_wellDataList )
|
||||
{
|
||||
const auto& wellRows = wellData.welsegsData();
|
||||
allRows.insert( allRows.end(), wellRows.begin(), wellRows.end() );
|
||||
}
|
||||
|
||||
return allRows;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<CompsegsRow> RigMswUnifiedDataWIP::getAllCompsegsRows( bool lgrOnly ) const
|
||||
{
|
||||
std::vector<CompsegsRow> allRows;
|
||||
|
||||
for ( const auto& wellData : m_wellDataList )
|
||||
{
|
||||
std::vector<CompsegsRow> wellRows;
|
||||
|
||||
if ( lgrOnly )
|
||||
{
|
||||
wellRows = wellData.lgrCompsegsData();
|
||||
}
|
||||
else
|
||||
{
|
||||
wellRows = wellData.mainGridCompsegsData();
|
||||
}
|
||||
|
||||
allRows.insert( allRows.end(), wellRows.begin(), wellRows.end() );
|
||||
}
|
||||
|
||||
return allRows;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<WsegvalvRow> RigMswUnifiedDataWIP::getAllWsegvalvRows() const
|
||||
{
|
||||
std::vector<WsegvalvRow> allRows;
|
||||
|
||||
for ( const auto& wellData : m_wellDataList )
|
||||
{
|
||||
const auto& wellRows = wellData.wsegvalvData();
|
||||
allRows.insert( allRows.end(), wellRows.begin(), wellRows.end() );
|
||||
}
|
||||
|
||||
return allRows;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<WsegaicdRow> RigMswUnifiedDataWIP::getAllWsegaicdRows() const
|
||||
{
|
||||
std::vector<WsegaicdRow> allRows;
|
||||
|
||||
for ( const auto& wellData : m_wellDataList )
|
||||
{
|
||||
const auto& wellRows = wellData.wsegaicdData();
|
||||
allRows.insert( allRows.end(), wellRows.begin(), wellRows.end() );
|
||||
}
|
||||
|
||||
return allRows;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigMswUnifiedDataWIP::hasAnyLgrData() const
|
||||
{
|
||||
return std::any_of( m_wellDataList.begin(), m_wellDataList.end(), []( const RigMswTableData& wellData ) { return wellData.hasLgrData(); } );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::string> RigMswUnifiedDataWIP::wellNames() const
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
names.reserve( m_wellDataList.size() );
|
||||
|
||||
std::transform( m_wellDataList.begin(),
|
||||
m_wellDataList.end(),
|
||||
std::back_inserter( names ),
|
||||
[]( const RigMswTableData& wellData ) { return wellData.wellName(); } );
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigMswUnifiedDataWIP::isValid() const
|
||||
{
|
||||
return validationErrors().empty();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString> RigMswUnifiedDataWIP::validationErrors() const
|
||||
{
|
||||
std::vector<QString> errors;
|
||||
|
||||
if ( m_wellDataList.empty() )
|
||||
{
|
||||
errors.push_back( "No well data available" );
|
||||
return errors;
|
||||
}
|
||||
|
||||
// Check each well's data validity
|
||||
for ( const auto& wellData : m_wellDataList )
|
||||
{
|
||||
if ( !wellData.isValid() )
|
||||
{
|
||||
auto wellErrors = wellData.validationErrors();
|
||||
for ( const auto& error : wellErrors )
|
||||
{
|
||||
errors.push_back( QString( "%1: %2" ).arg( QString::fromStdString( wellData.wellName() ), error ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for duplicate well names
|
||||
std::vector<std::string> names = wellNames();
|
||||
std::sort( names.begin(), names.end() );
|
||||
auto it = std::adjacent_find( names.begin(), names.end() );
|
||||
if ( it != names.end() )
|
||||
{
|
||||
errors.push_back( QString( "Duplicate well name: %1" ).arg( QString::fromStdString( *it ) ) );
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigMswUnifiedDataWIP::updateIndex()
|
||||
{
|
||||
m_wellNameToIndex.clear();
|
||||
|
||||
for ( size_t i = 0; i < m_wellDataList.size(); ++i )
|
||||
{
|
||||
m_wellNameToIndex[m_wellDataList[i].wellName()] = i;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2025 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CompletionsMsw/RigMswTableData.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
//==================================================================================================
|
||||
/// Container class for unified MSW table data from multiple wells
|
||||
//==================================================================================================
|
||||
class RigMswUnifiedDataWIP
|
||||
{
|
||||
public:
|
||||
RigMswUnifiedDataWIP() = default;
|
||||
|
||||
// Data modification
|
||||
void addWellData( RigMswTableData wellData );
|
||||
void clear();
|
||||
|
||||
// Data access
|
||||
const std::vector<RigMswTableData>& wellDataList() const { return m_wellDataList; }
|
||||
const RigMswTableData* getWellData( const std::string& wellName ) const;
|
||||
|
||||
// Aggregated data access - combines data from all wells
|
||||
std::vector<WelsegsHeader> getAllWelsegsHeaders() const;
|
||||
std::vector<WelsegsRow> getAllWelsegsRows() const;
|
||||
std::vector<CompsegsRow> getAllCompsegsRows( bool lgrOnly = false ) const;
|
||||
std::vector<WsegvalvRow> getAllWsegvalvRows() const;
|
||||
std::vector<WsegaicdRow> getAllWsegaicdRows() const;
|
||||
|
||||
// Metadata and analysis
|
||||
bool isEmpty() const { return m_wellDataList.empty(); }
|
||||
bool hasAnyLgrData() const;
|
||||
size_t wellCount() const { return m_wellDataList.size(); }
|
||||
std::vector<std::string> wellNames() const;
|
||||
|
||||
// Data validation
|
||||
bool isValid() const;
|
||||
std::vector<QString> validationErrors() const;
|
||||
|
||||
// Iterator support for range-based loops
|
||||
auto begin() const { return m_wellDataList.begin(); }
|
||||
auto end() const { return m_wellDataList.end(); }
|
||||
auto begin() { return m_wellDataList.begin(); }
|
||||
auto end() { return m_wellDataList.end(); }
|
||||
|
||||
private:
|
||||
std::vector<RigMswTableData> m_wellDataList;
|
||||
std::map<std::string, size_t> m_wellNameToIndex;
|
||||
|
||||
void updateIndex();
|
||||
};
|
||||
Reference in new issue
Block a user