mirror of
				https://github.com/OPM/ResInsight.git
				synced 2025-02-25 18:55:39 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			433 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			433 lines
		
	
	
		
			15 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.
 | 
						|
//
 | 
						|
/////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#include "RigWellPathFormations.h"
 | 
						|
 | 
						|
#include "QStringList"
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
RigWellPathFormations::RigWellPathFormations(const std::vector<RigWellPathFormation>& formations, const QString& filePath,
 | 
						|
                                             const QString& key)
 | 
						|
{
 | 
						|
    m_filePath  = filePath;
 | 
						|
    m_keyInFile = key;
 | 
						|
 | 
						|
    for (const RigWellPathFormation& formation : formations)
 | 
						|
    {
 | 
						|
        if (isFluid(formation.formationName))
 | 
						|
        {
 | 
						|
            m_fluids.push_back(formation);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            FormationLevel level             = detectLevel(formation.formationName);
 | 
						|
            m_formationsLevelsPresent[level] = true;
 | 
						|
 | 
						|
            m_formations.push_back(std::pair<RigWellPathFormation, FormationLevel>(formation, level));
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigWellPathFormations::depthAndFormationNamesWithoutDuplicatesOnDepth(std::vector<QString>* names,
 | 
						|
                                                                           std::vector<double>*  measuredDepths,
 | 
						|
                                                                           RimWellLogPlot::DepthTypeEnum depthType) const
 | 
						|
{
 | 
						|
    std::map<double, bool, DepthComp> tempMakeVectorUniqueOnMeasuredDepth;
 | 
						|
 | 
						|
    if (depthType == RimWellLogPlot::MEASURED_DEPTH)
 | 
						|
    {
 | 
						|
        for (const std::pair<RigWellPathFormation, FormationLevel>& formation : m_formations)
 | 
						|
        {
 | 
						|
            if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.mdTop))
 | 
						|
            {
 | 
						|
                measuredDepths->push_back(formation.first.mdTop);
 | 
						|
                names->push_back(formation.first.formationName + " Top");
 | 
						|
                tempMakeVectorUniqueOnMeasuredDepth[formation.first.mdTop] = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        for (const std::pair<RigWellPathFormation, FormationLevel>& formation : m_formations)
 | 
						|
        {
 | 
						|
            if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.mdBase))
 | 
						|
            {
 | 
						|
                measuredDepths->push_back(formation.first.mdBase);
 | 
						|
                names->push_back(formation.first.formationName + " Base");
 | 
						|
                tempMakeVectorUniqueOnMeasuredDepth[formation.first.mdBase] = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH)
 | 
						|
    {
 | 
						|
        for (const std::pair<RigWellPathFormation, FormationLevel>& formation : m_formations)
 | 
						|
        {
 | 
						|
            if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.tvdTop))
 | 
						|
            {
 | 
						|
                measuredDepths->push_back(formation.first.tvdTop);
 | 
						|
                names->push_back(formation.first.formationName + " Top");
 | 
						|
                tempMakeVectorUniqueOnMeasuredDepth[formation.first.tvdTop] = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        for (const std::pair<RigWellPathFormation, FormationLevel>& formation : m_formations)
 | 
						|
        {
 | 
						|
            if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.tvdBase))
 | 
						|
            {
 | 
						|
                measuredDepths->push_back(formation.first.tvdBase);
 | 
						|
                names->push_back(formation.first.formationName + " Base");
 | 
						|
                tempMakeVectorUniqueOnMeasuredDepth[formation.first.tvdBase] = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    for (const std::pair<RigWellPathFormation, FormationLevel>& formation : m_formations)
 | 
						|
    {
 | 
						|
        if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.mdTop))
 | 
						|
        {
 | 
						|
            double depth;
 | 
						|
            if (depthType == RimWellLogPlot::MEASURED_DEPTH)
 | 
						|
            {
 | 
						|
                depth = formation.first.mdTop;
 | 
						|
            }
 | 
						|
            else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH)
 | 
						|
            {
 | 
						|
                depth = formation.first.tvdTop;
 | 
						|
            }
 | 
						|
            else return;
 | 
						|
 | 
						|
            measuredDepths->push_back(depth);
 | 
						|
            names->push_back(formation.first.formationName + " Top");
 | 
						|
            tempMakeVectorUniqueOnMeasuredDepth[depth] = true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    for (const std::pair<RigWellPathFormation, FormationLevel>& formation : m_formations)
 | 
						|
    {
 | 
						|
        double depth;
 | 
						|
        if (depthType == RimWellLogPlot::MEASURED_DEPTH)
 | 
						|
        {
 | 
						|
            depth = formation.first.mdBase;
 | 
						|
        }
 | 
						|
        else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH)
 | 
						|
        {
 | 
						|
            depth = formation.first.tvdBase;
 | 
						|
        }
 | 
						|
        else return;
 | 
						|
 | 
						|
        if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.mdBase))
 | 
						|
        {
 | 
						|
            measuredDepths->push_back(depth);
 | 
						|
            names->push_back(formation.first.formationName + " Base");
 | 
						|
            tempMakeVectorUniqueOnMeasuredDepth[depth] = true;
 | 
						|
        }
 | 
						|
    }*/
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigWellPathFormations::evaluateFormationsForOnePosition(
 | 
						|
    const std::vector<std::pair<RigWellPathFormation, FormationLevel>>& formations,
 | 
						|
    const FormationLevel& maxLevel, const PickPosition& position,
 | 
						|
    std::map<double, LevelAndName, DepthComp>* uniqueListMaker, RimWellLogPlot::DepthTypeEnum depthType) const
 | 
						|
{
 | 
						|
    QString postFix;
 | 
						|
 | 
						|
    if (position == TOP)
 | 
						|
    {
 | 
						|
        postFix = " Top";
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        postFix = " Base";
 | 
						|
    }
 | 
						|
 | 
						|
    for (const std::pair<RigWellPathFormation, FormationLevel>& formation : formations)
 | 
						|
    {
 | 
						|
        double depth;
 | 
						|
 | 
						|
        if (depthType == RimWellLogPlot::MEASURED_DEPTH)
 | 
						|
        {
 | 
						|
            if (position == TOP)
 | 
						|
            {
 | 
						|
                depth = formation.first.mdTop;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                depth = formation.first.mdBase;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH)
 | 
						|
        {
 | 
						|
            if (position == TOP)
 | 
						|
            {
 | 
						|
                depth = formation.first.tvdTop;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                depth = formation.first.tvdBase;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else return;
 | 
						|
 | 
						|
        if (formation.second > maxLevel) continue;
 | 
						|
 | 
						|
        if (!uniqueListMaker->count(depth) || uniqueListMaker->at(depth).level < formation.second)
 | 
						|
        {
 | 
						|
            (*uniqueListMaker)[depth] = LevelAndName(formation.second, formation.first.formationName + postFix);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigWellPathFormations::evaluateFormations(const std::vector<std::pair<RigWellPathFormation, FormationLevel>>& formations,
 | 
						|
                                               const FormationLevel& maxLevel, std::vector<QString>* names,
 | 
						|
                                               std::vector<double>* depths, RimWellLogPlot::DepthTypeEnum depthType) const
 | 
						|
{
 | 
						|
    std::map<double, LevelAndName, DepthComp> tempMakeVectorUniqueOnDepth;
 | 
						|
 | 
						|
    evaluateFormationsForOnePosition(formations, maxLevel, PickPosition::TOP, &tempMakeVectorUniqueOnDepth, depthType);
 | 
						|
    evaluateFormationsForOnePosition(formations, maxLevel, PickPosition::BASE, &tempMakeVectorUniqueOnDepth, depthType);
 | 
						|
 | 
						|
    for (const std::pair<double, LevelAndName>& uniqueDepth : tempMakeVectorUniqueOnDepth)
 | 
						|
    {
 | 
						|
        depths->push_back(uniqueDepth.first);
 | 
						|
        names->push_back(uniqueDepth.second.name);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigWellPathFormations::evaluateFluids(const std::vector<RigWellPathFormation>& fluidFormations, std::vector<QString>* names,
 | 
						|
                                           std::vector<double>* depths, RimWellLogPlot::DepthTypeEnum depthType) const
 | 
						|
{
 | 
						|
    std::map<double, QString, DepthComp> uniqueListMaker;
 | 
						|
 | 
						|
    for (const RigWellPathFormation& formation : fluidFormations)
 | 
						|
    {
 | 
						|
        double depthBase;
 | 
						|
        if (depthType == RimWellLogPlot::MEASURED_DEPTH)
 | 
						|
        {
 | 
						|
            depthBase = formation.mdBase;
 | 
						|
        }
 | 
						|
        else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH)
 | 
						|
        {
 | 
						|
            depthBase = formation.tvdBase;
 | 
						|
        }
 | 
						|
        else return;
 | 
						|
 | 
						|
        uniqueListMaker[depthBase] = formation.formationName + " Base";
 | 
						|
    }
 | 
						|
 | 
						|
    for (const RigWellPathFormation& formation : fluidFormations)
 | 
						|
    {
 | 
						|
        double depthTop;
 | 
						|
        if (depthType == RimWellLogPlot::MEASURED_DEPTH)
 | 
						|
        {
 | 
						|
            depthTop = formation.mdTop;
 | 
						|
        }
 | 
						|
        else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH)
 | 
						|
        {
 | 
						|
            depthTop = formation.tvdTop;
 | 
						|
        }
 | 
						|
        else return;
 | 
						|
 | 
						|
        uniqueListMaker[depthTop] = formation.formationName + " Top";
 | 
						|
    }
 | 
						|
 | 
						|
    for (const std::pair<double, QString>& depthAndFormation : uniqueListMaker)
 | 
						|
    {
 | 
						|
        depths->push_back(depthAndFormation.first);
 | 
						|
        names->push_back(depthAndFormation.second);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigWellPathFormations::depthAndFormationNamesUpToLevel(FormationLevel level, std::vector<QString>* names, std::vector<double>* depths,
 | 
						|
                                                            bool includeFluids, RimWellLogPlot::DepthTypeEnum depthType) const
 | 
						|
{
 | 
						|
    names->clear();
 | 
						|
    depths->clear();
 | 
						|
 | 
						|
    if (includeFluids)
 | 
						|
    {
 | 
						|
        evaluateFluids(m_fluids, names, depths, depthType);
 | 
						|
    }
 | 
						|
 | 
						|
    if (level == RigWellPathFormations::NONE)
 | 
						|
    {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    else if (level == RigWellPathFormations::ALL)
 | 
						|
    {
 | 
						|
        depthAndFormationNamesWithoutDuplicatesOnDepth(names, depths, depthType);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        evaluateFormations(m_formations, level, names, depths, depthType);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
std::vector<RigWellPathFormations::FormationLevel> RigWellPathFormations::formationsLevelsPresent() const
 | 
						|
{
 | 
						|
    std::vector<RigWellPathFormations::FormationLevel> formationLevels;
 | 
						|
 | 
						|
    for (const std::pair<RigWellPathFormations::FormationLevel, bool>& formationLevel : m_formationsLevelsPresent)
 | 
						|
    {
 | 
						|
        formationLevels.push_back(formationLevel.first);
 | 
						|
    }
 | 
						|
    return formationLevels;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
QString RigWellPathFormations::filePath() const
 | 
						|
{
 | 
						|
    return m_filePath;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
QString RigWellPathFormations::keyInFile() const
 | 
						|
{
 | 
						|
    return m_keyInFile;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
size_t RigWellPathFormations::formationNamesCount() const
 | 
						|
{
 | 
						|
    return m_formations.size() + m_fluids.size();
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
bool RigWellPathFormations::isFluid(QString formationName)
 | 
						|
{
 | 
						|
    formationName = formationName.trimmed();
 | 
						|
 | 
						|
    if (formationName == "OIL" || formationName == "GAS" || formationName == "WATER")
 | 
						|
    {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
///
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
RigWellPathFormations::FormationLevel RigWellPathFormations::detectLevel(QString formationName)
 | 
						|
{
 | 
						|
    formationName = formationName.trimmed();
 | 
						|
 | 
						|
    bool isGroupName = true;
 | 
						|
    for (QChar c : formationName)
 | 
						|
    {
 | 
						|
        if (c.isLower())
 | 
						|
        {
 | 
						|
            isGroupName = false;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (isGroupName)
 | 
						|
    {
 | 
						|
        return RigWellPathFormations::GROUP;
 | 
						|
    }
 | 
						|
 | 
						|
    QStringList formationNameSplitted = formationName.split(" ");
 | 
						|
 | 
						|
    std::vector<QString> levelDesctiptorCandidates;
 | 
						|
 | 
						|
    for (QString word : formationNameSplitted)
 | 
						|
    {
 | 
						|
        for (const QChar& c : word)
 | 
						|
        {
 | 
						|
            if (c.isDigit())
 | 
						|
            {
 | 
						|
                levelDesctiptorCandidates.push_back(word);
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (levelDesctiptorCandidates.empty())
 | 
						|
    {
 | 
						|
        return RigWellPathFormations::LEVEL0;
 | 
						|
    }
 | 
						|
 | 
						|
    if (levelDesctiptorCandidates.size() > 1)
 | 
						|
    {
 | 
						|
        for (auto it = levelDesctiptorCandidates.begin(); it != levelDesctiptorCandidates.end(); it++)
 | 
						|
        {
 | 
						|
            for (const QChar& c : *it)
 | 
						|
            {
 | 
						|
                if (c.isLetter())
 | 
						|
                {
 | 
						|
                    levelDesctiptorCandidates.erase(it);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (levelDesctiptorCandidates.size() != 1) return RigWellPathFormations::UNKNOWN;
 | 
						|
 | 
						|
    QString levelDescriptor = levelDesctiptorCandidates[0];
 | 
						|
 | 
						|
    QStringList joinedLevel = levelDescriptor.split('+');
 | 
						|
    if (joinedLevel.size() > 1)
 | 
						|
    {
 | 
						|
        levelDescriptor = joinedLevel[0];
 | 
						|
    }
 | 
						|
 | 
						|
    int dotCount = levelDescriptor.count('.');
 | 
						|
 | 
						|
    switch (dotCount)
 | 
						|
    {
 | 
						|
        case 0: return RigWellPathFormations::LEVEL1;
 | 
						|
        case 1: return RigWellPathFormations::LEVEL2;
 | 
						|
        case 2: return RigWellPathFormations::LEVEL3;
 | 
						|
        case 3: return RigWellPathFormations::LEVEL4;
 | 
						|
        case 4: return RigWellPathFormations::LEVEL5;
 | 
						|
        case 5: return RigWellPathFormations::LEVEL6;
 | 
						|
        case 6: return RigWellPathFormations::LEVEL7;
 | 
						|
        case 7: return RigWellPathFormations::LEVEL8;
 | 
						|
        case 8: return RigWellPathFormations::LEVEL9;
 | 
						|
        case 9: return RigWellPathFormations::LEVEL10;
 | 
						|
        default: break;
 | 
						|
    }
 | 
						|
    return RigWellPathFormations::UNKNOWN;
 | 
						|
}
 |