Files
ResInsight/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp
Jacob Støren 4be58edf78 MSW code reverted. Regrettfully the work has to be reconsidered.
Both ERT and the resinsight code is rolled back to before MSW was introduced as refined.
p4#: 21999
2013-06-25 15:53:19 +02:00

272 lines
10 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigSingleWellResultsData.h"
#include <map>
#include <QDebug>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigWellResultFrame& RigSingleWellResultsData::wellResultFrame(size_t resultTimeStepIndex) const
{
CVF_ASSERT(resultTimeStepIndex < m_resultTimeStepIndexToWellTimeStepIndex.size());
size_t wellTimeStepIndex = m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex];
CVF_ASSERT(wellTimeStepIndex < m_wellCellsTimeSteps.size());
return m_wellCellsTimeSteps[wellTimeStepIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigSingleWellResultsData::computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector<QDateTime>& resultTimes)
{
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";
for (size_t i = 0; i < resultTimes.size(); i++)
{
qDebug() << resultTimes[i].toString();
}
}
int resultIdx = 0;
size_t wellIdx = 0;
size_t activeWellIdx = cvf::UNDEFINED_SIZE_T;
while (wellIdx <= m_wellCellsTimeSteps.size() && resultIdx < static_cast<int>(resultTimes.size()))
{
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++;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigSingleWellResultsData::hasWellResult(size_t resultTimeStepIndex) const
{
size_t wellTimeStepIndex = m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex];
return wellTimeStepIndex != cvf::UNDEFINED_SIZE_T;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigSingleWellResultsData::firstResultTimeStep() const
{
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigSingleWellResultsData::computeStaticWellCellPath()
{
if (m_wellCellsTimeSteps.size() == 0) return;
std::map < size_t, std::list< RigWellResultCell > > staticWellBranches;
// Add ResultCell data from the first timestep to the final result.
for (size_t bIdx = 0; bIdx < m_wellCellsTimeSteps[0].m_wellResultBranches.size(); ++bIdx)
{
size_t branchNumber = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_branchNumber;
std::vector<RigWellResultCell>& frameCells = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_wellCells;
std::list< RigWellResultCell >& branch = staticWellBranches[branchNumber];
for(size_t cIdx = 0; cIdx < frameCells.size(); ++cIdx)
{
branch.push_back(frameCells[cIdx]);
}
}
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)
{
size_t branchNumber = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_branchNumber;
std::vector<RigWellResultCell>& resBranch = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_wellCells;
std::list< RigWellResultCell >& stBranch = staticWellBranches[branchNumber];
std::list< RigWellResultCell >::iterator it;
std::list< RigWellResultCell >::iterator sStartIt;
std::list< RigWellResultCell >::iterator sEndIt;
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;
if (stBranch.size())
{
sGridIdx = sEndIt->m_gridIndex;
sCellIdx = sEndIt->m_gridCellIndex;
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; }
}
}
if (found)
{
if (rEndIdx > 0)
{
// Found cells in start, merge them in
for (size_t cIdx = 0; cIdx < rEndIdx; ++cIdx)
{
stBranch.insert(sEndIt, resBranch[cIdx]);
}
}
}
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
if (sEndIt != stBranch.end()) ++sEndIt;
for ( ; sEndIt != stBranch.end() ; ++sEndIt)
{
sGridIdx = sEndIt->m_gridIndex;
sCellIdx = sEndIt->m_gridCellIndex;
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)
{
stBranch.insert(sEndIt, resBranch[cIdx]);
}
}
}
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)
{
stBranch.push_back(resBranch[cIdx]);
}
}
}
// Populate the static well info
std::map < size_t, std::list< RigWellResultCell > >::iterator bIt;
m_staticWellCells.m_wellResultBranches.clear();
m_staticWellCells.m_wellHead = m_wellCellsTimeSteps[0].m_wellHead;
for (bIt = staticWellBranches.begin(); bIt != staticWellBranches.end(); ++bIt)
{
RigWellResultBranch rigBranch;
rigBranch.m_branchNumber = bIt->first;
std::list< RigWellResultCell >& branch = bIt->second;
std::list< RigWellResultCell >::iterator cIt;
for (cIt = branch.begin(); cIt != branch.end(); ++cIt)
{
RigWellResultCell rwc = *cIt;
rwc.m_isOpen = false; // Reset the dynamic property
rigBranch.m_wellCells.push_back(*cIt);
}
m_staticWellCells.m_wellResultBranches.push_back(rigBranch);
}
}