#3474 LGR Export. Create temporary LGR. Take 1

This commit is contained in:
Bjørn Erik Jensen 2018-10-19 10:40:54 +02:00
parent 3edfd1dca6
commit 9d90f54d5f
19 changed files with 645 additions and 56 deletions

View File

@ -72,6 +72,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryGroupFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicConvertGroupToEnsembleFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicResampleDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicCreateTemporaryLgrFeature.h
)
@ -141,6 +142,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryGroupFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicConvertGroupToEnsembleFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicResampleDialog.cpp
${CMAKE_CURRENT_LIST_DIR}/RicCreateTemporaryLgrFeature.cpp
)

View File

@ -98,7 +98,7 @@ RicExportLgrUi* RicExportLgrFeature::openDialog(RimEclipseCase* defaultCase, int
featureUi->setTimeStep(defaultTimeStep);
caf::PdmUiPropertyViewDialog propertyDialog(nullptr, featureUi, "LGR Export", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
propertyDialog.resize(QSize(600, 300));
propertyDialog.resize(QSize(600, 275));
if (propertyDialog.exec() == QDialog::Accepted && !featureUi->exportFolder().isEmpty())
{
@ -167,9 +167,9 @@ void RicExportLgrFeature::exportLgrs(QTextStream& stream, const std::vector<LgrI
formatter.addOneBasedCellIndex(lgrInfo.mainGridEndCell.j());
formatter.addOneBasedCellIndex(lgrInfo.mainGridStartCell.k());
formatter.addOneBasedCellIndex(lgrInfo.mainGridEndCell.k());
formatter.add(lgrInfo.sizes.i());
formatter.add(lgrInfo.sizes.j());
formatter.add(lgrInfo.sizes.k());
formatter.add(lgrInfo.sizesPerMainGridCell().i());
formatter.add(lgrInfo.sizesPerMainGridCell().j());
formatter.add(lgrInfo.sizesPerMainGridCell().k());
formatter.rowCompleted();
formatter.tableCompleted("", false);
}
@ -194,7 +194,6 @@ std::vector<LgrInfo> RicExportLgrFeature::buildOneLgrPerMainCell(RimEclipseCase*
const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizes)
{
int lgrCount = 0;
std::vector<LgrInfo> lgrs;
eclipseCase->results(RiaDefines::MATRIX_MODEL)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "PORO");
@ -220,6 +219,7 @@ std::vector<LgrInfo> RicExportLgrFeature::buildOneLgrPerMainCell(RimEclipseCase*
}
}
int lgrId = firstAvailableLgrId(eclipseCase->mainGrid());
caf::VecIjk mainGridFirstCell(intersectingCell.localCellIndexI(),
intersectingCell.localCellIndexJ(),
intersectingCell.localCellIndexK());
@ -227,7 +227,7 @@ std::vector<LgrInfo> RicExportLgrFeature::buildOneLgrPerMainCell(RimEclipseCase*
intersectingCell.localCellIndexJ(),
intersectingCell.localCellIndexK());
LgrInfo lgrInfo(QString("LGR_%1").arg(++lgrCount), lgrSizes, mainGridFirstCell, mainGridEndCell);
LgrInfo lgrInfo(lgrId, QString("LGR_%1").arg(lgrId), lgrSizes, mainGridFirstCell, mainGridEndCell);
if(poroExists) lgrInfo.values = lgrValues;
lgrs.push_back(lgrInfo);
}
@ -240,7 +240,7 @@ std::vector<LgrInfo> RicExportLgrFeature::buildOneLgrPerMainCell(RimEclipseCase*
//--------------------------------------------------------------------------------------------------
std::vector<LgrInfo> RicExportLgrFeature::buildSingleLgr(RimEclipseCase* eclipseCase,
const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizes)
const caf::VecIjk& lgrSizesPerMainGridCell)
{
std::vector<LgrInfo> lgrs;
@ -276,11 +276,11 @@ std::vector<LgrInfo> RicExportLgrFeature::buildSingleLgr(RimEclipseCase* eclipse
double poro = poroExists ? poroAccessObject->cellScalarGlobIdx(globCellIndex) : std::numeric_limits<double>::infinity();
for (size_t k = 0; k < lgrSizes.k(); k++)
for (size_t k = 0; k < lgrSizesPerMainGridCell.k(); k++)
{
for (size_t j = 0; j < lgrSizes.j(); j++)
for (size_t j = 0; j < lgrSizesPerMainGridCell.j(); j++)
{
for (size_t i = 0; i < lgrSizes.i(); i++)
for (size_t i = 0; i < lgrSizesPerMainGridCell.i(); i++)
{
lgrValues.push_back(poro);
}
@ -291,10 +291,14 @@ std::vector<LgrInfo> RicExportLgrFeature::buildSingleLgr(RimEclipseCase* eclipse
}
}
int lgrId = firstAvailableLgrId(eclipseCase->mainGrid());
caf::VecIjk lgrSizes((iRange.second - iRange.first + 1) * lgrSizesPerMainGridCell.i(),
(jRange.second - jRange.first + 1) * lgrSizesPerMainGridCell.j(),
(kRange.second - kRange.first + 1) * lgrSizesPerMainGridCell.k());
caf::VecIjk mainGridStartCell(iRange.first, jRange.first, kRange.first);
caf::VecIjk mainGridEndCell(iRange.second, jRange.second, kRange.second);
LgrInfo lgrInfo(QString("LGR_1"), lgrSizes, mainGridStartCell, mainGridEndCell);
LgrInfo lgrInfo(lgrId, QString("LGR_%1").arg(lgrId), lgrSizes, mainGridStartCell, mainGridEndCell);
if(poroExists) lgrInfo.values = lgrValues;
lgrs.push_back(lgrInfo);
@ -343,14 +347,18 @@ void RicExportLgrFeature::onActionTriggered(bool isChecked)
QString dialogTitle = "LGR Export";
RimEclipseCase* defaultEclipseCase = nullptr;
int defaultTimeStep = 0;
auto activeView = dynamic_cast<RimEclipseView*>(RiaApplication::instance()->activeGridView());
if (activeView) defaultTimeStep = activeView->currentTimeStep();
if (activeView)
{
defaultEclipseCase = activeView->eclipseCase();
defaultTimeStep = activeView->currentTimeStep();
}
auto dialogData = openDialog(nullptr, defaultTimeStep);
auto dialogData = openDialog(defaultEclipseCase, defaultTimeStep);
if (dialogData)
{
auto eclipseCase = dialogData->caseToApply();
auto lgrCellCounts = dialogData->lgrCellCount();
size_t timeStep = dialogData->timeStep();
@ -425,3 +433,17 @@ bool RicExportLgrFeature::containsAnyNonMainGridCells(const std::vector<RigCompl
return !cell.isMainGridCell();
}) != cells.end();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RicExportLgrFeature::firstAvailableLgrId(const RigMainGrid* mainGrid)
{
int gridCount = (int)mainGrid->gridCount();
int lastUsedId = 0;
for (int i = 0; i < gridCount; i++)
{
lastUsedId = std::max(lastUsedId, mainGrid->gridByIndex(i)->gridId());
}
return lastUsedId + 1;
}

View File

@ -38,14 +38,33 @@ class QTextStream;
class LgrInfo
{
public:
LgrInfo(const QString&name,
LgrInfo(int id,
const QString&name,
const caf::VecIjk& sizes,
const caf::VecIjk& mainGridStartCell,
const caf::VecIjk& mainGridEndCell)
: name(name), sizes(sizes), mainGridStartCell(mainGridStartCell), mainGridEndCell(mainGridEndCell)
: id(id), name(name), sizes(sizes), mainGridStartCell(mainGridStartCell), mainGridEndCell(mainGridEndCell)
{
}
caf::VecIjk sizesPerMainGridCell() const
{
return caf::VecIjk(sizes.i() / (mainGridEndCell.i() - mainGridStartCell.i() + 1),
sizes.j() / (mainGridEndCell.j() - mainGridStartCell.j() + 1),
sizes.k() / (mainGridEndCell.k() - mainGridStartCell.k() + 1));
}
int cellCount() const
{
return (int)(sizes.i() * sizes.j() * sizes.k());
}
int cellCountPerMainGridCell() const
{
auto s = sizesPerMainGridCell();
return (int)(s.i() * s.j() * s.k());
}
int id;
QString name;
caf::VecIjk sizes;
std::vector<double> values;
@ -73,7 +92,7 @@ class RicExportLgrFeature : public caf::CmdFeature
const caf::VecIjk& lgrSizes);
static std::vector<LgrInfo> buildSingleLgr(RimEclipseCase* eclipseCase,
const std::vector<RigCompletionDataGridCell>& intersectingCells,
const caf::VecIjk& lgrSizes);
const caf::VecIjk& lgrSizesPerMainGridCell);
static std::vector<RigCompletionDataGridCell> cellsIntersectingCompletions(RimEclipseCase* eclipseCase,
const RimWellPath* wellPath,
@ -87,4 +106,5 @@ protected:
private:
static std::vector<RimWellPath*> selectedWellPaths();
static bool containsAnyNonMainGridCells(const std::vector<RigCompletionDataGridCell>& cells);
static int firstAvailableLgrId(const RigMainGrid* mainGrid);
};

View File

@ -0,0 +1,289 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RicCreateTemporaryLgrFeature.h"
#include "RiaApplication.h"
#include "RiaLogging.h"
#include "CompletionExportCommands/RicWellPathExportCompletionDataFeature.h"
#include "ExportCommands/RicExportLgrUi.h"
#include "ExportCommands/RicExportLgrFeature.h"
#include "RifEclipseDataTableFormatter.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigMainGrid.h"
#include "RigResultAccessor.h"
#include "RigResultAccessorFactory.h"
#include "RigVirtualPerforationTransmissibilities.h"
#include "RigCellGeometryTools.h"
#include "RimDialogData.h"
#include "RimEclipseCase.h"
#include "RimEclipseView.h"
#include "RimWellPath.h"
#include "RimProject.h"
#include "RimWellPathCollection.h"
#include "RimWellPathCompletions.h"
#include "RiuPlotMainWindow.h"
#include <QAction>
#include <QFileInfo>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <cafPdmUiPropertyViewDialog.h>
#include <cafSelectionManager.h>
#include <cafSelectionManagerTools.h>
#include <cafVecIjk.h>
#include <cafUtils.h>
#include <limits>
#include <algorithm>
CAF_CMD_SOURCE_INIT(RicCreateTemporaryLgrFeature, "RicCreateTemporaryLgrFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicCreateTemporaryLgrFeature::isCommandEnabled()
{
std::vector<RimWellPathCompletions*> completions = caf::selectedObjectsByTypeStrict<RimWellPathCompletions*>();
return !completions.empty();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicCreateTemporaryLgrFeature::onActionTriggered(bool isChecked)
{
std::vector<RimWellPath*> wellPaths = selectedWellPaths();
CVF_ASSERT(wellPaths.size() > 0);
std::vector<RimSimWellInView*> simWells;
QString dialogTitle = "Create Temporary LGR";
RimEclipseCase* defaultEclipseCase = nullptr;
int defaultTimeStep = 0;
auto activeView = dynamic_cast<RimEclipseView*>(RiaApplication::instance()->activeGridView());
if (activeView)
{
defaultEclipseCase = activeView->eclipseCase();
defaultTimeStep = activeView->currentTimeStep();
}
auto dialogData = RicExportLgrFeature::openDialog(defaultEclipseCase, defaultTimeStep);
if (dialogData)
{
auto eclipseCase = dialogData->caseToApply();
auto lgrCellCounts = dialogData->lgrCellCount();
size_t timeStep = dialogData->timeStep();
auto eclipseCaseData = eclipseCase->eclipseCaseData();
RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::MATRIX_MODEL);
RigActiveCellInfo* fractureActiveCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::FRACTURE_MODEL);
bool lgrIntersected = false;
for (const auto& wellPath : wellPaths)
{
auto intersectingCells = RicExportLgrFeature::cellsIntersectingCompletions(eclipseCase, wellPath, timeStep);
if (containsAnyNonMainGridCells(intersectingCells))
{
lgrIntersected = true;
continue;
}
eclipseCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->freeAllocatedResultsData();
std::vector<LgrInfo> lgrs;
if (dialogData->singleLgrSplit())
lgrs = RicExportLgrFeature::buildSingleLgr(eclipseCase, intersectingCells, lgrCellCounts);
else
lgrs = RicExportLgrFeature::buildOneLgrPerMainCell(eclipseCase, intersectingCells, lgrCellCounts);
auto mainGrid = eclipseCase->eclipseCaseData()->mainGrid();
//activeCellInfo->setGridCount(mainGrid->gridCount() + lgrs.size());
//fractureActiveCellInfo->setGridCount(mainGrid->gridCount() + lgrs.size());
for (auto lgr : lgrs)
{
int totalCellCountBeforLgr = (int)mainGrid->globalCellArray().size();
createLgr(lgr, eclipseCase->eclipseCaseData()->mainGrid());
int lgrCellCount = lgr.cellCount();
//activeCellInfo->setGridActiveCellCounts(lgr.id, lgrCellCount);
//fractureActiveCellInfo->setGridActiveCellCounts(lgr.id, lgrCellCount);
//activeCellInfo->computeDerivedData();
//fractureActiveCellInfo->computeDerivedData();
activeCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount);
fractureActiveCellInfo->addLgr(totalCellCountBeforLgr, lgrCellCount);
}
//activeCellInfo->setReservoirCellCount(mainGrid->globalCellArray().size());
//for (int i = 0; i < mainGrid->globalCellArray().size(); i++) activeCellInfo->setCellResultIndex(i, i);
mainGrid->calculateFaults(activeCellInfo, true);
}
eclipseCase->eclipseCaseData()->clearWellCellsInGridCache();
eclipseCase->eclipseCaseData()->mainGrid()->computeCachedData();
activeView->loadDataAndUpdate();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicCreateTemporaryLgrFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setText("Create Temporary LGR");
}
//--------------------------------------------------------------------------------------------------
/// Todo: Guarding, caching LGR corner nodes calculations
//--------------------------------------------------------------------------------------------------
void RicCreateTemporaryLgrFeature::createLgr(LgrInfo& lgrInfo, RigMainGrid* mainGrid)
{
auto app = RiaApplication::instance();
auto eclipseView = dynamic_cast<RimEclipseView*>(app->activeReservoirView());
if (!eclipseView) return;
int lgrId = lgrInfo.id;
size_t totalCellCount = mainGrid->globalCellArray().size();
size_t lgrCellCount = lgrInfo.cellCount();
// Create local grid and set properties
RigLocalGrid* localGrid = new RigLocalGrid(mainGrid);
localGrid->setAsTempGrid(true);
localGrid->setGridId(lgrId);
localGrid->setIndexToStartOfCells(totalCellCount);
localGrid->setGridName(lgrInfo.name.toStdString());
localGrid->setGridPointDimensions(cvf::Vec3st(lgrInfo.sizes.i() + 1, lgrInfo.sizes.j() + 1, lgrInfo.sizes.k() + 1));
mainGrid->addLocalGrid(localGrid);
size_t cellStartIndex = mainGrid->globalCellArray().size();
size_t nodeStartIndex = mainGrid->nodes().size();
// Resize global cell and node arrays
{
RigCell defaultCell;
defaultCell.setHostGrid(localGrid);
mainGrid->globalCellArray().resize(cellStartIndex + lgrCellCount, defaultCell);
mainGrid->nodes().resize(nodeStartIndex + lgrCellCount * 8, cvf::Vec3d(0, 0, 0));
}
auto lgrSizePerMainCell = lgrInfo.sizesPerMainGridCell();
size_t gridLocalCellIndex = 0;
// Loop through all new LGR cells
for (size_t lgrK = 0; lgrK < lgrInfo.sizes.k(); lgrK++)
{
size_t mainK = lgrInfo.mainGridStartCell.k() + lgrK / lgrSizePerMainCell.k();
for (size_t lgrJ = 0; lgrJ < lgrInfo.sizes.j(); lgrJ++)
{
size_t mainJ = lgrInfo.mainGridStartCell.j() + lgrJ / lgrSizePerMainCell.j();
for (size_t lgrI = 0; lgrI < lgrInfo.sizes.i(); lgrI++, gridLocalCellIndex++)
{
size_t mainI = lgrInfo.mainGridStartCell.i() + lgrI / lgrSizePerMainCell.i();
size_t mainCellIndex = mainGrid->cellIndexFromIJK(mainI, mainJ, mainK);
mainGrid->globalCellArray()[mainCellIndex].setSubGrid(localGrid);
RigCell& cell = mainGrid->globalCellArray()[cellStartIndex + gridLocalCellIndex];
cell.setGridLocalCellIndex(gridLocalCellIndex);
// Set parent cell
if (mainCellIndex == -1)
{
cell.setParentCellIndex(cvf::UNDEFINED_SIZE_T);
}
else
{
cell.setParentCellIndex(mainCellIndex);
}
// Corner coordinates
{
size_t cIdx;
std::array<cvf::Vec3d, 8> vertices;
mainGrid->cellCornerVertices(mainCellIndex, vertices.data());
auto cellCounts = lgrInfo.sizesPerMainGridCell();
auto lgrCoords =
RigCellGeometryTools::createHexCornerCoords(vertices, cellCounts.i(), cellCounts.j(), cellCounts.k());
size_t subI = lgrI % lgrSizePerMainCell.i();
size_t subJ = lgrJ % lgrSizePerMainCell.j();
size_t subK = lgrK % lgrSizePerMainCell.k();
size_t subIndex = subI + subJ * lgrSizePerMainCell.i() + subK * lgrSizePerMainCell.i() * lgrSizePerMainCell.j();
for (cIdx = 0; cIdx < 8; ++cIdx)
{
auto& node = mainGrid->nodes()[nodeStartIndex + gridLocalCellIndex * 8 + cIdx];
node.set(lgrCoords[subIndex * 8 + cIdx]);
cell.cornerIndices()[cIdx] = nodeStartIndex + gridLocalCellIndex * 8 + cIdx;
}
}
}
}
}
localGrid->setParentGrid(mainGrid);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellPath*> RicCreateTemporaryLgrFeature::selectedWellPaths()
{
std::vector<RimWellPathCompletions*> selectedCompletions = caf::selectedObjectsByTypeStrict<RimWellPathCompletions*>();
std::vector<RimWellPath*> wellPaths;
for (auto completion : selectedCompletions)
{
RimWellPath* parentWellPath;
completion->firstAncestorOrThisOfType(parentWellPath);
if (parentWellPath) wellPaths.push_back(parentWellPath);
}
return wellPaths;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicCreateTemporaryLgrFeature::containsAnyNonMainGridCells(const std::vector<RigCompletionDataGridCell>& cells)
{
return std::find_if(cells.begin(), cells.end(), [](const RigCompletionDataGridCell& cell)
{
return !cell.isMainGridCell();
}) != cells.end();
}

View File

@ -0,0 +1,54 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RigCompletionDataGridCell.h"
#include "cafCmdFeature.h"
#include <cafVecIjk.h>
#include <memory>
#include <limits>
class LgrInfo;
class RigMainGrid;
class RimEclipseCase;
class RimSimWellInView;
class RimWellPath;
class RicExportLgrUi;
class QFile;
class QTextStream;
//==================================================================================================
///
//==================================================================================================
class RicCreateTemporaryLgrFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
virtual bool isCommandEnabled() override;
virtual void onActionTriggered(bool isChecked) override;
virtual void setupActionLook(QAction* actionToSetup) override;
private:
static void createLgr(LgrInfo& lgrInfo, RigMainGrid* mainGrid);
static std::vector<RimWellPath*> selectedWellPaths();
static bool containsAnyNonMainGridCells(const std::vector<RigCompletionDataGridCell>& cells);
};

View File

@ -2203,6 +2203,8 @@ void RifReaderEclipseOutput::extractResultValuesBasedOnPorosityModel(RiaDefines:
for (size_t i = 0; i < m_eclipseCase->mainGrid()->gridCount(); i++)
{
if(m_eclipseCase->mainGrid()->gridByIndex(i)->isTempGrid()) continue;
size_t matrixActiveCellCount = 0;
size_t fractureActiveCellCount = 0;

View File

@ -769,6 +769,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
}
menuBuilder << "RicExportLgrFeature";
menuBuilder << "RicCreateTemporaryLgrFeature";
}
menuBuilder << "RicCreateMultipleFracturesFeature";

View File

@ -3,38 +3,36 @@
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 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>
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigActiveCellInfo.h"
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
RigActiveCellInfo::RigActiveCellInfo()
: m_reservoirActiveCellCount(0),
m_reservoirCellResultCount(0),
m_activeCellPositionMin(cvf::Vec3d::ZERO),
m_activeCellPositionMax(cvf::Vec3d::ZERO)
: m_reservoirActiveCellCount(0)
, m_reservoirCellResultCount(0)
, m_activeCellPositionMin(cvf::Vec3d::ZERO)
, m_activeCellPositionMax(cvf::Vec3d::ZERO)
{
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::setReservoirCellCount(size_t reservoirCellCount)
{
@ -58,7 +56,7 @@ size_t RigActiveCellInfo::reservoirCellResultCount() const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
bool RigActiveCellInfo::isActive(size_t reservoirCellIndex) const
{
@ -73,7 +71,7 @@ bool RigActiveCellInfo::isActive(size_t reservoirCellIndex) const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
size_t RigActiveCellInfo::cellResultIndex(size_t reservoirCellIndex) const
{
@ -88,7 +86,7 @@ size_t RigActiveCellInfo::cellResultIndex(size_t reservoirCellIndex) const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::setCellResultIndex(size_t reservoirCellIndex, size_t reservoirCellResultIndex)
{
@ -103,7 +101,7 @@ void RigActiveCellInfo::setCellResultIndex(size_t reservoirCellIndex, size_t res
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::setGridCount(size_t gridCount)
{
@ -111,7 +109,7 @@ void RigActiveCellInfo::setGridCount(size_t gridCount)
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::setGridActiveCellCounts(size_t gridIndex, size_t activeCellCount)
{
@ -121,7 +119,7 @@ void RigActiveCellInfo::setGridActiveCellCounts(size_t gridIndex, size_t activeC
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::computeDerivedData()
{
@ -134,7 +132,7 @@ void RigActiveCellInfo::computeDerivedData()
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
size_t RigActiveCellInfo::reservoirActiveCellCount() const
{
@ -142,7 +140,7 @@ size_t RigActiveCellInfo::reservoirActiveCellCount() const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::setIJKBoundingBox(const cvf::Vec3st& min, const cvf::Vec3st& max)
{
@ -151,7 +149,7 @@ void RigActiveCellInfo::setIJKBoundingBox(const cvf::Vec3st& min, const cvf::Vec
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::IJKBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const
{
@ -160,14 +158,14 @@ void RigActiveCellInfo::IJKBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::gridActiveCellCounts(size_t gridIndex, size_t& activeCellCount) const
{
activeCellCount = m_perGridActiveCellInfo[gridIndex].activeCellCount();
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
cvf::BoundingBox RigActiveCellInfo::geometryBoundingBox() const
{
@ -175,7 +173,7 @@ cvf::BoundingBox RigActiveCellInfo::geometryBoundingBox() const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::setGeometryBoundingBox(cvf::BoundingBox bb)
{
@ -183,20 +181,41 @@ void RigActiveCellInfo::setGeometryBoundingBox(cvf::BoundingBox bb)
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::clear()
{
m_perGridActiveCellInfo.clear();
m_cellIndexToResultIndex.clear();
m_reservoirActiveCellCount = 0;
m_activeCellPositionMin = cvf::Vec3st(0,0,0);
m_activeCellPositionMax = cvf::Vec3st(0,0,0);
m_activeCellPositionMin = cvf::Vec3st(0, 0, 0);
m_activeCellPositionMax = cvf::Vec3st(0, 0, 0);
m_activeCellsBoundingBox.reset();
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::addLgr(int lgrStartIndex, int cellCount)
{
GridActiveCellCounts count;
count.setActiveCellCount(cellCount);
m_perGridActiveCellInfo.push_back(count);
auto prevActiveCount = m_reservoirActiveCellCount;
auto newActiveCount = prevActiveCount + cellCount;
m_cellIndexToResultIndex.resize(lgrStartIndex + cellCount, cvf::UNDEFINED_SIZE_T);
m_reservoirActiveCellCount = newActiveCount;
m_reservoirCellResultCount = newActiveCount;
for (int i = 0; i < cellCount; i++)
{
m_cellIndexToResultIndex[lgrStartIndex + i] = prevActiveCount + i;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigActiveCellInfo::isCoarseningActive() const
{
@ -204,15 +223,15 @@ bool RigActiveCellInfo::isCoarseningActive() const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
RigActiveCellInfo::GridActiveCellCounts::GridActiveCellCounts()
: m_activeCellCount(0)
: m_activeCellCount(0)
{
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
size_t RigActiveCellInfo::GridActiveCellCounts::activeCellCount() const
{
@ -220,7 +239,7 @@ size_t RigActiveCellInfo::GridActiveCellCounts::activeCellCount() const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RigActiveCellInfo::GridActiveCellCounts::setActiveCellCount(size_t activeCellCount)
{

View File

@ -28,7 +28,6 @@
#include <vector>
class RigActiveCellInfo : public cvf::Object
{
public:
@ -57,6 +56,8 @@ public:
void clear();
void addLgr(int lgrStartIndex, int cellCount);
private:
class GridActiveCellCounts
{

View File

@ -1111,6 +1111,14 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType
bool resultLoadingSucess = true;
int tempGridCellCount = 0;
for (int i = 1; i < m_ownerMainGrid->gridCount(); i++)
{
auto grid = m_ownerMainGrid->gridByIndex(i);
if (grid->isTempGrid()) tempGridCellCount += grid->cellCount();
}
if (type == RiaDefines::DYNAMIC_NATIVE && timeStepCount > 0)
{
this->cellScalarResults(scalarResultIndex).resize(timeStepCount);
@ -1123,6 +1131,10 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType
{
resultLoadingSucess = false;
}
else
{
values.resize(values.size() + tempGridCellCount);
}
}
}
else if (type == RiaDefines::STATIC_NATIVE)
@ -1134,6 +1146,10 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType
{
resultLoadingSucess = false;
}
else
{
values.resize(values.size() + tempGridCellCount);
}
}
if (!resultLoadingSucess)

View File

@ -51,6 +51,7 @@ public:
RigLocalGrid* subGrid() const { return m_subGrid; }
void setSubGrid(RigLocalGrid* subGrid) { m_subGrid = subGrid; }
void removeSubGrid(RigLocalGrid* subGrid) { m_subGrid = nullptr; }
RigGridBase* hostGrid() const { return m_hostGrid; }
void setHostGrid(RigGridBase* hostGrid) { m_hostGrid = hostGrid; }

View File

@ -27,8 +27,36 @@
#include "clipper/clipper.hpp"
#include <vector>
#include <array>
//--------------------------------------------------------------------------------------------------
/// Internal functions
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
/// Splits a line in a number of equal parts
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> splitLine(cvf::Vec3d ptStart, cvf::Vec3d ptEnd, size_t partCount);
//--------------------------------------------------------------------------------------------------
/// Calculates all points on a face described by edge points from all four edges.
/// The result is a grid of points including the given edge points
///
/// edgeXPtsHigh
/// |-------------|
/// | |
/// edgeYPtsLow | | edgeYPtsHigh
/// | |
/// |-------------|
/// edgeXPtsLow
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>> calcFacePoints(const std::vector<cvf::Vec3d> edgeXPtsLow,
const std::vector<cvf::Vec3d> edgeXPtsHigh,
const std::vector<cvf::Vec3d> edgeYPtsLow,
const std::vector<cvf::Vec3d> edgeYPtsHigh);
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -545,6 +573,127 @@ std::vector<cvf::Vec3d> RigCellGeometryTools::unionOfPolygons(const std::vector<
return unionPolygon;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> splitLine(cvf::Vec3d ptStart, cvf::Vec3d ptEnd, size_t partCount)
{
std::vector<cvf::Vec3d> pts = { ptStart };
for (int i = 1; i < partCount; i++)
{
pts.push_back(cvf::Vec3d(ptStart.x() + (ptEnd.x() - ptStart.x()) * i / partCount,
ptStart.y() + (ptEnd.y() - ptStart.y()) * i / partCount,
ptStart.z() + (ptEnd.z() - ptStart.z()) * i / partCount));
}
pts.push_back(ptEnd);
return pts;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>>
calcFacePoints(const std::vector<cvf::Vec3d> edgeXPtsLow, const std::vector<cvf::Vec3d> edgeXPtsHigh,
const std::vector<cvf::Vec3d> edgeYPtsLow, const std::vector<cvf::Vec3d> edgeYPtsHigh)
{
CVF_ASSERT(edgeXPtsLow.size() == edgeXPtsHigh.size() && edgeYPtsLow.size() == edgeYPtsHigh.size());
size_t xSize = edgeXPtsLow.size();
size_t ySize = edgeYPtsLow.size();
std::vector<std::vector<cvf::Vec3d>> pts;
// Add low edge points
pts.push_back(edgeXPtsLow);
// Interior points
for (int y = 1; y < ySize - 1; y++)
{
//for (int x = 0; x < xSize; x++)
{
auto interiorPts = splitLine(edgeYPtsLow[y], edgeYPtsHigh[y], xSize - 1);
pts.push_back(interiorPts);
}
}
// Add low edge points
pts.push_back(edgeXPtsHigh);
return pts;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d>
RigCellGeometryTools::createHexCornerCoords(std::array<cvf::Vec3d, 8> mainCellCorners, size_t nx, size_t ny, size_t nz)
{
std::array<std::pair<size_t, size_t>, 12> edgeCorners =
{
std::make_pair(0, 1), std::make_pair(3, 2), std::make_pair(4, 5), std::make_pair(7, 6), // X
std::make_pair(0, 3), std::make_pair(4, 7), std::make_pair(1, 2), std::make_pair(5, 6), // Y
std::make_pair(0, 4), std::make_pair(1, 5), std::make_pair(3, 7), std::make_pair(2, 6), // Z
};
std::array<size_t, 3> nxyz = { nx, ny, nz };
std::array<std::vector<cvf::Vec3d>, 12> edgePoints;
for (int i = 0; i < 12; i++)
{
int partCountsIndex = i / 4;
edgePoints[i] = splitLine(mainCellCorners[edgeCorners[i].first], mainCellCorners[edgeCorners[i].second], nxyz[partCountsIndex]);
}
// lowIJ, highIJ, lowJK, highKJ,
std::vector<std::vector<std::vector<cvf::Vec3d>>> nodes;
nodes.reserve((nx + 1)*(ny + 1)*(nz + 1));
auto xyFacePtsLow = calcFacePoints(edgePoints[0], edgePoints[1], edgePoints[4], edgePoints[6]);
auto xyFacePtsHigh = calcFacePoints(edgePoints[2], edgePoints[3], edgePoints[5], edgePoints[7]);
auto yzFacePtsLow = calcFacePoints(edgePoints[4], edgePoints[5], edgePoints[8], edgePoints[10]);
auto yzFacePtsHigh = calcFacePoints(edgePoints[6], edgePoints[7], edgePoints[9], edgePoints[11]);
auto xzFacePtsLow = calcFacePoints(edgePoints[0], edgePoints[2], edgePoints[8], edgePoints[9]);
auto xzFacePtsHigh = calcFacePoints(edgePoints[1], edgePoints[3], edgePoints[10], edgePoints[11]);
nodes.push_back(xyFacePtsLow);
for (int z = 1; z < nz; z++)
{
auto xyFacePoints = calcFacePoints(xzFacePtsLow[z], xzFacePtsHigh[z], yzFacePtsLow[z], yzFacePtsHigh[z]);
nodes.push_back(xyFacePoints);
}
nodes.push_back(xyFacePtsHigh);
std::vector<cvf::Vec3d> coords;
coords.reserve(nx*ny*nz * 8);
for (int z = 1; z < nz + 1; z++)
{
for (int y = 1; y < ny + 1; y++)
{
for (int x = 1; x < nx + 1; x++)
{
std::array<cvf::Vec3d, 8> cs;
cs[0] = nodes[z - 1][y - 1][x - 1];
cs[1] = nodes[z - 1][y - 1][x];
cs[2] = nodes[z - 1][y][x];
cs[3] = nodes[z - 1][y][x - 1];
cs[4] = nodes[z][y - 1][x - 1];
cs[5] = nodes[z][y - 1][x];
cs[6] = nodes[z][y][x];
cs[7] = nodes[z][y][x - 1];
coords.insert(coords.end(), cs.begin(), cs.end());
}
}
}
return coords;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -57,6 +57,8 @@ public:
static std::vector<cvf::Vec3d> unionOfPolygons(const std::vector<std::vector<cvf::Vec3d>>& polygons);
static std::vector<cvf::Vec3d> createHexCornerCoords(std::array<cvf::Vec3d, 8> mainCellCorners, size_t nx, size_t ny, size_t nz);
private:
static std::vector<cvf::Vec3d> ajustPolygonToAvoidIntersectionsAtVertex(const std::vector<cvf::Vec3d>& polyLine,
const std::vector<cvf::Vec3d>& polygon);

View File

@ -115,6 +115,8 @@ public:
void setVirtualPerforationTransmissibilities(RigVirtualPerforationTransmissibilities* virtualPerforationTransmissibilities);
const RigVirtualPerforationTransmissibilities* virtualPerforationTransmissibilities() const;
void clearWellCellsInGridCache() { m_wellCellsInGrid.clear(); }
private:
void computeActiveCellIJKBBox();
void computeWellCellsPrGrid();

View File

@ -30,7 +30,8 @@
RigGridBase::RigGridBase(RigMainGrid* mainGrid):
m_gridPointDimensions(0,0,0),
m_indexToStartOfCells(0),
m_mainGrid(mainGrid)
m_mainGrid(mainGrid),
m_isTempGrid(false)
{
if (mainGrid == nullptr)
{

View File

@ -75,7 +75,6 @@ public:
cvf::BoundingBox boundingBox();
protected:
friend class RigMainGrid;//::initAllSubGridsParentGridPointer();
void initSubGridParentPointer();
@ -106,6 +105,10 @@ public:
bool isCellValid( size_t i, size_t j, size_t k ) const override;
bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex ) const override;
void setAsTempGrid(bool isTemp) { m_isTempGrid = isTemp; }
bool isTempGrid() const { return m_isTempGrid; }
private:
std::string m_gridName;
cvf::Vec3st m_gridPointDimensions;
@ -117,6 +120,7 @@ private:
std::vector<std::array<size_t, 6>> m_coarseningBoxInfo;
bool m_isTempGrid;
};

View File

@ -34,6 +34,5 @@ public:
private:
RigGridBase * m_parentGrid;
size_t m_positionInParentGrid;
};

View File

@ -340,14 +340,19 @@ bool RigMainGrid::hasFaultWithName(const QString& name) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo)
void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo, bool forceCalculation)
{
if (hasFaultWithName(RiaDefines::undefinedGridFaultName())
if (!forceCalculation &&
hasFaultWithName(RiaDefines::undefinedGridFaultName())
&& hasFaultWithName(RiaDefines::undefinedGridFaultWithInactiveName()))
{
//RiaLogging::debug(QString("Calculate faults already run for grid."));
return;
}
m_faults.clear();
m_faultsPrCellAcc = new RigFaultsPrCellAccumulator(m_cells.size());
// Spread fault idx'es on the cells from the faults

View File

@ -67,7 +67,7 @@ public:
RigNNCData* nncData();
void setFaults(const cvf::Collection<RigFault>& faults);
const cvf::Collection<RigFault>& faults() { return m_faults; }
void calculateFaults(const RigActiveCellInfo* activeCellInfo);
void calculateFaults(const RigActiveCellInfo* activeCellInfo, bool forceCalculation = false);
void distributeNNCsToFaults();