Files
ResInsight/ApplicationLibCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h
T
Kristian Bendiksen 409f175467 COMPLUMP: Choose completion number by largest overlap in cell
When several perforation intervals cut the same cell, the completion number
was taken from the first contribution, which depended on the order events
were applied. Unrelated event changes (e.g. group tree members) could then
change COMPLUMP numbers on boundary cells.

Pick the number with the largest summed MD overlap in the cell, with ties
going to the lowest number. Also use stable_sort for same-date events so
they keep file order.
2026-10-21 14:43:07 +02:00

147 lines
8.5 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigCompletionData.h"
#include "RicExportCompletionDataSettingsUi.h"
#include "cvfVector2.h"
#include "cvfVector3.h"
#include <QDateTime>
#include <QFile>
#include <memory>
#include <optional>
#include <vector>
class RigCell;
class RigEclipseCaseData;
class RigMainGrid;
class RimEclipseCase;
class RimFishbones;
class RimPerforationInterval;
class RimWellPath;
class RimWellPathValve;
class RimWellPathFracture;
class RimNonDarcyPerforationParameters;
class RifTextDataTableFormatter;
class RigVirtualPerforationTransmissibilities;
class SubSegmentIntersectionInfo;
//==================================================================================================
///
//==================================================================================================
using QFilePtr = std::shared_ptr<QFile>;
//==================================================================================================
///
//==================================================================================================
class RicWellPathExportCompletionDataFeatureImpl
{
public:
static void exportCompletions( const std::vector<RimWellPath*>& wellPaths, const RicExportCompletionDataSettingsUi& exportSettings );
static std::vector<RigCompletionData> computeStaticCompletionsForWellPath( RimWellPath* wellPath, RimEclipseCase* eclipseCase );
static std::vector<RigCompletionData>
computeDynamicCompletionsForWellPath( RimWellPath* wellPath, RimEclipseCase* eclipseCase, size_t timeStepIndex );
static std::vector<RigCompletionData>
completionDataForWellPath( RimWellPath* wellPath, RimEclipseCase* eCase, const std::optional<QDateTime>& exportDate = std::nullopt );
// Completion data for several well paths (including their laterals), combined per cell into one connection.
// Connections are ordered with each well path's mainbore connections first, followed by each lateral's
// (depth-first), matching ResInsight's internal completion ordering (see
// https://github.com/OPM/ResInsight/issues/14963).
static std::vector<RigCompletionData> completionDataForWellPaths( const std::vector<RimWellPath*>& wellPaths,
RimEclipseCase* eCase,
const std::optional<QDateTime>& exportDate = std::nullopt );
static std::pair<double, cvf::Vec2i>
wellPathUpperGridIntersectionIJ( const RimEclipseCase* gridCase, const RimWellPath* wellPath, const QString& gridName = "" );
static std::optional<QDateTime> exportDateForTimeStep( const RimEclipseCase* eclipseCase, size_t timeStepIndex );
// Completion number for a cell with several contributions: the number with the largest summed MD overlap
// (endMD - startMD) wins, ties go to the lowest number. Independent of contribution order.
static std::optional<int> completionNumberForCell( const std::vector<RigCompletionData>& completions );
private:
static std::vector<RigCompletionData> generatePerforationsCompdatValues( const RimWellPath* wellPath,
const std::vector<const RimPerforationInterval*>& intervals,
const RicExportCompletionDataSettingsUi& settings,
const std::optional<QDateTime>& exportDate = std::nullopt );
static RigCompletionData combineEclipseCellCompletions( const std::vector<RigCompletionData>& completions,
const RicExportCompletionDataSettingsUi& settings );
static std::vector<RigCompletionData> mainGridCompletions( const std::vector<RigCompletionData>& allCompletions );
static std::map<QString, std::vector<RigCompletionData>> subGridsCompletions( const std::vector<RigCompletionData>& allCompletions );
static void exportWellPathFractureReport( RimEclipseCase* sourceCase,
QFilePtr exportFile,
const std::vector<RicWellPathFractureReportItem>& wellPathFractureReportItems );
static void exportWelspecsToFile( RimEclipseCase* gridCase,
QFilePtr exportFile,
const std::vector<RigCompletionData>& completions,
bool exportDataSourceAsComment );
static void exportWelspeclToFile( RimEclipseCase* gridCase,
QFilePtr exportFile,
const std::map<QString, std::vector<RigCompletionData>>& completions );
static void sortAndExportCompletionsToFile( RimEclipseCase* eclipseCase,
const QString& exportFolder,
const QString& fileName,
const std::vector<RigCompletionData>& completions,
const std::vector<RicWellPathFractureReportItem>& wellPathFractureReportItems,
RicExportCompletionDataSettingsUi::CompdatExportType exportType,
bool exportDataSourceAsComment,
bool exportWelspec );
static void exportCompdatAndWpimultTables( RimEclipseCase* sourceCase,
QFilePtr exportFile,
const std::map<QString, std::vector<RigCompletionData>>& completionsPerGrid,
RicExportCompletionDataSettingsUi::CompdatExportType exportType,
bool exportDataSourceAsComment );
static void exportCompdatTableUsingFormatter( RifTextDataTableFormatter& formatter,
const QString& gridName,
const std::vector<RigCompletionData>& completionData );
static void exportComplumpTableUsingFormatter( RifTextDataTableFormatter& formatter,
const QString& gridName,
const std::vector<RigCompletionData>& completionData );
static void exportWpimultTableUsingFormatter( RifTextDataTableFormatter& formatter,
const QString& gridName,
const std::vector<RigCompletionData>& completionData );
static void appendCompletionData( std::map<size_t, std::vector<RigCompletionData>>* completionData,
const std::vector<RigCompletionData>& data );
static void exportCarfinForTemporaryLgrs( const RimEclipseCase* sourceCase, const QString& folder );
static RimWellPath* topLevelWellPath( const RigCompletionData& completion );
};