2012-05-18 02:45:23 -05:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2013-03-22 10:58:44 -05:00
|
|
|
#include "RigSingleWellResultsData.h"
|
2012-05-18 02:45:23 -05:00
|
|
|
#include <map>
|
|
|
|
|
2013-02-13 07:50:37 -06:00
|
|
|
#include <QDebug>
|
2012-05-18 02:45:23 -05:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2013-03-22 09:43:42 -05:00
|
|
|
const RigWellResultFrame& RigSingleWellResultsData::wellResultFrame(size_t resultTimeStepIndex) const
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
|
|
|
CVF_ASSERT(resultTimeStepIndex < m_resultTimeStepIndexToWellTimeStepIndex.size());
|
|
|
|
|
|
|
|
size_t wellTimeStepIndex = m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex];
|
|
|
|
CVF_ASSERT(wellTimeStepIndex < m_wellCellsTimeSteps.size());
|
|
|
|
|
|
|
|
return m_wellCellsTimeSteps[wellTimeStepIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2013-03-22 09:43:42 -05:00
|
|
|
void RigSingleWellResultsData::computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector<QDateTime>& resultTimes)
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
|
|
|
m_resultTimeStepIndexToWellTimeStepIndex.clear();
|
|
|
|
if (m_wellCellsTimeSteps.size() == 0) return;
|
|
|
|
|
|
|
|
m_resultTimeStepIndexToWellTimeStepIndex.resize(resultTimes.size(), cvf::UNDEFINED_SIZE_T);
|
|
|
|
|
|
|
|
if (false)
|
|
|
|
{
|
|
|
|
qDebug() << "Well TimeStamps";
|
|
|
|
for (size_t i = 0; i < m_wellCellsTimeSteps.size(); i++)
|
|
|
|
{
|
|
|
|
qDebug() << m_wellCellsTimeSteps[i].m_timestamp.toString();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
qDebug() << "Result TimeStamps";
|
2013-03-20 00:11:45 -05:00
|
|
|
for (size_t i = 0; i < resultTimes.size(); i++)
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
|
|
|
qDebug() << resultTimes[i].toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int resultIdx = 0;
|
|
|
|
size_t wellIdx = 0;
|
|
|
|
size_t activeWellIdx = cvf::UNDEFINED_SIZE_T;
|
|
|
|
|
2013-03-20 00:11:45 -05:00
|
|
|
while (wellIdx <= m_wellCellsTimeSteps.size() && resultIdx < static_cast<int>(resultTimes.size()))
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
|
|
|
if (wellIdx < m_wellCellsTimeSteps.size() && m_wellCellsTimeSteps[wellIdx].m_timestamp <= resultTimes[resultIdx])
|
|
|
|
{
|
|
|
|
activeWellIdx = wellIdx;
|
|
|
|
wellIdx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
CVF_ASSERT(resultIdx < static_cast<int>(m_resultTimeStepIndexToWellTimeStepIndex.size()));
|
|
|
|
m_resultTimeStepIndexToWellTimeStepIndex[resultIdx] = activeWellIdx;
|
|
|
|
|
|
|
|
resultIdx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2013-03-22 09:43:42 -05:00
|
|
|
bool RigSingleWellResultsData::hasWellResult(size_t resultTimeStepIndex) const
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
|
|
|
size_t wellTimeStepIndex = m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex];
|
|
|
|
|
|
|
|
return wellTimeStepIndex != cvf::UNDEFINED_SIZE_T;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2013-03-22 09:43:42 -05:00
|
|
|
size_t RigSingleWellResultsData::firstResultTimeStep() const
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
|
|
|
size_t i = 0;
|
|
|
|
for(i = 0; i < m_resultTimeStepIndexToWellTimeStepIndex.size(); ++i)
|
|
|
|
{
|
|
|
|
if (m_resultTimeStepIndexToWellTimeStepIndex[i] != cvf::UNDEFINED_SIZE_T) return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cvf::UNDEFINED_SIZE_T;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2013-03-22 09:43:42 -05:00
|
|
|
void RigSingleWellResultsData::computeStaticWellCellPath()
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
|
|
|
if (m_wellCellsTimeSteps.size() == 0) return;
|
|
|
|
|
2013-08-26 07:03:01 -05:00
|
|
|
std::map < size_t, std::list< RigWellResultPoint > > staticWellBranches;
|
2012-05-18 02:45:23 -05:00
|
|
|
|
|
|
|
// Add ResultCell data from the first timestep to the final result.
|
|
|
|
|
|
|
|
for (size_t bIdx = 0; bIdx < m_wellCellsTimeSteps[0].m_wellResultBranches.size(); ++bIdx)
|
|
|
|
{
|
2013-08-26 06:56:42 -05:00
|
|
|
size_t branchNumber = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_branchIndex;
|
2013-08-26 07:03:01 -05:00
|
|
|
std::vector<RigWellResultPoint>& frameCells = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_branchResultPoints;
|
2012-06-26 09:10:41 -05:00
|
|
|
|
2013-08-26 07:03:01 -05:00
|
|
|
std::list< RigWellResultPoint >& branch = staticWellBranches[branchNumber];
|
2012-05-18 02:45:23 -05:00
|
|
|
|
|
|
|
for(size_t cIdx = 0; cIdx < frameCells.size(); ++cIdx)
|
|
|
|
{
|
2012-06-26 09:10:41 -05:00
|
|
|
branch.push_back(frameCells[cIdx]);
|
2012-05-18 02:45:23 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t tIdx = 1; tIdx < m_wellCellsTimeSteps.size(); ++tIdx)
|
|
|
|
{
|
|
|
|
// Merge well branches separately
|
|
|
|
|
|
|
|
for (size_t bIdx = 0; bIdx < m_wellCellsTimeSteps[tIdx].m_wellResultBranches.size(); ++bIdx)
|
|
|
|
{
|
2013-08-26 06:56:42 -05:00
|
|
|
size_t branchNumber = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_branchIndex;
|
2013-08-26 07:03:01 -05:00
|
|
|
std::vector<RigWellResultPoint>& resBranch = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_branchResultPoints;
|
2012-05-18 02:45:23 -05:00
|
|
|
|
2013-08-26 07:03:01 -05:00
|
|
|
std::list< RigWellResultPoint >& stBranch = staticWellBranches[branchNumber];
|
|
|
|
std::list< RigWellResultPoint >::iterator it;
|
|
|
|
std::list< RigWellResultPoint >::iterator sStartIt;
|
|
|
|
std::list< RigWellResultPoint >::iterator sEndIt;
|
2012-05-18 02:45:23 -05:00
|
|
|
size_t rStartIdx;
|
|
|
|
size_t rEndIdx;
|
|
|
|
|
|
|
|
|
|
|
|
size_t sGridIdx;
|
|
|
|
size_t sCellIdx;
|
|
|
|
size_t rGridIdx;
|
|
|
|
size_t rCellIdx;
|
|
|
|
|
|
|
|
// First detect if we have cells on the start of the result frame, that is not in the static frame
|
|
|
|
{
|
|
|
|
sEndIt = stBranch.begin();
|
|
|
|
bool found = false;
|
2012-06-26 09:10:41 -05:00
|
|
|
if (stBranch.size())
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
2012-06-26 09:10:41 -05:00
|
|
|
sGridIdx = sEndIt->m_gridIndex;
|
|
|
|
sCellIdx = sEndIt->m_gridCellIndex;
|
2012-05-18 02:45:23 -05:00
|
|
|
|
2012-06-26 09:10:41 -05:00
|
|
|
for (rEndIdx = 0; !found && rEndIdx < resBranch.size(); ++rEndIdx)
|
|
|
|
{
|
|
|
|
rGridIdx = resBranch[rEndIdx].m_gridIndex;
|
|
|
|
rCellIdx = resBranch[rEndIdx].m_gridCellIndex;
|
|
|
|
|
|
|
|
if (sGridIdx == rGridIdx && sCellIdx == rCellIdx) { found = true; break; }
|
|
|
|
}
|
2012-05-18 02:45:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (found)
|
|
|
|
{
|
|
|
|
if (rEndIdx > 0)
|
|
|
|
{
|
|
|
|
// Found cells in start, merge them in
|
|
|
|
for (size_t cIdx = 0; cIdx < rEndIdx; ++cIdx)
|
|
|
|
{
|
2012-06-26 09:10:41 -05:00
|
|
|
stBranch.insert(sEndIt, resBranch[cIdx]);
|
2012-05-18 02:45:23 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The result probably starts later in the well
|
|
|
|
rEndIdx = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
sStartIt = sEndIt;
|
|
|
|
rStartIdx = rEndIdx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now find all result cells in ranges between pairs in the static path
|
|
|
|
// If the result has items that "compete" with those in the static path,
|
|
|
|
// those items are inserted after the ones in the static path. This
|
|
|
|
// is not neccesarily correct. They could be in front, and also merged in
|
|
|
|
// strange ways. A geometric test could make this more robust, but we will
|
|
|
|
// not solve before we see that it actually ends up as a problem
|
|
|
|
|
2012-06-26 09:10:41 -05:00
|
|
|
if (sEndIt != stBranch.end()) ++sEndIt;
|
|
|
|
for ( ; sEndIt != stBranch.end() ; ++sEndIt)
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
2012-06-26 09:10:41 -05:00
|
|
|
sGridIdx = sEndIt->m_gridIndex;
|
|
|
|
sCellIdx = sEndIt->m_gridCellIndex;
|
2012-05-18 02:45:23 -05:00
|
|
|
|
|
|
|
bool found = false;
|
|
|
|
for (rEndIdx += 1; !found && rEndIdx < resBranch.size(); ++rEndIdx)
|
|
|
|
{
|
|
|
|
rGridIdx = resBranch[rEndIdx].m_gridIndex;
|
|
|
|
rCellIdx = resBranch[rEndIdx].m_gridCellIndex;
|
|
|
|
|
|
|
|
if (sGridIdx == rGridIdx && sCellIdx == rCellIdx) { found = true; break; }
|
|
|
|
}
|
|
|
|
|
|
|
|
if (found)
|
|
|
|
{
|
|
|
|
if (rEndIdx - rStartIdx > 1)
|
|
|
|
{
|
|
|
|
// Found cell range in result that we do not have in the static result, merge them in
|
|
|
|
for (size_t cIdx = rStartIdx + 1; cIdx < rEndIdx; ++cIdx)
|
|
|
|
{
|
2012-06-26 09:10:41 -05:00
|
|
|
stBranch.insert(sEndIt, resBranch[cIdx]);
|
2012-05-18 02:45:23 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The static path probably has some extra cells
|
|
|
|
rEndIdx = rStartIdx;
|
|
|
|
}
|
|
|
|
|
|
|
|
sStartIt = sEndIt;
|
|
|
|
rStartIdx = rEndIdx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Then add cells from the end of the resultpath not present in the static path
|
|
|
|
for (size_t cIdx = rEndIdx + 1; cIdx < resBranch.size(); ++cIdx)
|
|
|
|
{
|
2012-06-26 09:10:41 -05:00
|
|
|
stBranch.push_back(resBranch[cIdx]);
|
2012-05-18 02:45:23 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Populate the static well info
|
|
|
|
|
2013-08-26 07:03:01 -05:00
|
|
|
std::map < size_t, std::list< RigWellResultPoint > >::iterator bIt;
|
2012-05-18 02:45:23 -05:00
|
|
|
|
|
|
|
m_staticWellCells.m_wellResultBranches.clear();
|
|
|
|
m_staticWellCells.m_wellHead = m_wellCellsTimeSteps[0].m_wellHead;
|
|
|
|
|
2012-06-26 09:10:41 -05:00
|
|
|
for (bIt = staticWellBranches.begin(); bIt != staticWellBranches.end(); ++bIt)
|
2012-05-18 02:45:23 -05:00
|
|
|
{
|
2013-08-26 06:56:42 -05:00
|
|
|
if (bIt->first >= m_wellCellsTimeSteps[0].m_wellResultBranches.size())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy from first time step
|
|
|
|
RigWellResultBranch rigBranch = m_wellCellsTimeSteps[0].m_wellResultBranches[bIt->first];
|
|
|
|
rigBranch.m_branchIndex = bIt->first;
|
|
|
|
|
|
|
|
// Clear well cells, and insert the collection of well cells for the static situation
|
2013-08-26 07:03:01 -05:00
|
|
|
rigBranch.m_branchResultPoints.clear();
|
2012-05-18 02:45:23 -05:00
|
|
|
|
2013-08-26 07:03:01 -05:00
|
|
|
std::list< RigWellResultPoint >& branch = bIt->second;
|
|
|
|
std::list< RigWellResultPoint >::iterator cIt;
|
2012-05-18 02:45:23 -05:00
|
|
|
for (cIt = branch.begin(); cIt != branch.end(); ++cIt)
|
|
|
|
{
|
2013-08-26 07:03:01 -05:00
|
|
|
RigWellResultPoint rwc = *cIt;
|
2012-06-26 09:10:41 -05:00
|
|
|
rwc.m_isOpen = false; // Reset the dynamic property
|
2013-08-26 07:03:01 -05:00
|
|
|
rigBranch.m_branchResultPoints.push_back(*cIt);
|
2012-05-18 02:45:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
m_staticWellCells.m_wellResultBranches.push_back(rigBranch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-26 06:56:42 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RigSingleWellResultsData::setMultiSegmentWell(bool isMultiSegmentWell)
|
|
|
|
{
|
|
|
|
m_isMultiSegmentWell = isMultiSegmentWell;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
bool RigSingleWellResultsData::isMultiSegmentWell() const
|
|
|
|
{
|
|
|
|
return m_isMultiSegmentWell;
|
|
|
|
}
|
|
|
|
|