mirror of
				https://github.com/OPM/ResInsight.git
				synced 2025-02-25 18:55:39 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			191 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
//  Copyright (C) 2015-     Statoil ASA
 | 
						|
//  Copyright (C) 2015-     Ceetron Solutions 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 "RigCaseToCaseCellMapper.h"
 | 
						|
#include "RigCaseToCaseCellMapperTools.h"
 | 
						|
 | 
						|
#include "RigFemPart.h"
 | 
						|
#include "RigMainGrid.h"
 | 
						|
#include "RigFemPartGrid.h"
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
RigCaseToCaseCellMapper::RigCaseToCaseCellMapper(RigMainGrid* masterEclGrid, RigMainGrid* dependentEclGrid)
 | 
						|
    : m_masterGrid(masterEclGrid),
 | 
						|
      m_dependentGrid(dependentEclGrid),
 | 
						|
      m_masterFemPart(nullptr),
 | 
						|
      m_dependentFemPart(nullptr)
 | 
						|
{
 | 
						|
    m_masterCellOrIntervalIndex.resize(dependentEclGrid->globalCellArray().size(), cvf::UNDEFINED_INT);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
RigCaseToCaseCellMapper::RigCaseToCaseCellMapper(RigFemPart* masterFemPart, RigMainGrid* dependentEclGrid)
 | 
						|
    : m_masterGrid(nullptr),
 | 
						|
      m_dependentGrid(dependentEclGrid),
 | 
						|
      m_masterFemPart(masterFemPart),
 | 
						|
      m_dependentFemPart(nullptr)
 | 
						|
{
 | 
						|
    m_masterCellOrIntervalIndex.resize(dependentEclGrid->globalCellArray().size(), cvf::UNDEFINED_INT);
 | 
						|
    this->calculateEclToGeomCellMapping(dependentEclGrid, masterFemPart, false);
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
RigCaseToCaseCellMapper::RigCaseToCaseCellMapper(RigFemPart* masterFemPart, RigFemPart* dependentFemPart)
 | 
						|
    : m_masterGrid(nullptr),
 | 
						|
      m_dependentGrid(nullptr),
 | 
						|
      m_masterFemPart(masterFemPart),
 | 
						|
      m_dependentFemPart(dependentFemPart)
 | 
						|
{
 | 
						|
    m_masterCellOrIntervalIndex.resize(dependentFemPart->elementCount(), cvf::UNDEFINED_INT);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
RigCaseToCaseCellMapper::RigCaseToCaseCellMapper(RigMainGrid* masterEclGrid, RigFemPart* dependentFemPart)
 | 
						|
    : m_masterGrid(masterEclGrid),
 | 
						|
      m_dependentGrid(nullptr),
 | 
						|
      m_masterFemPart(dependentFemPart),
 | 
						|
      m_dependentFemPart(nullptr)
 | 
						|
{
 | 
						|
    m_masterCellOrIntervalIndex.resize(dependentFemPart->elementCount(), cvf::UNDEFINED_INT);
 | 
						|
    this->calculateEclToGeomCellMapping(masterEclGrid, dependentFemPart, true);
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
const int * RigCaseToCaseCellMapper::masterCaseCellIndices(int dependentCaseReservoirCellIndex, int* masterCaseCellIndexCount) const
 | 
						|
{
 | 
						|
    int seriesIndex = m_masterCellOrIntervalIndex[dependentCaseReservoirCellIndex];
 | 
						|
 | 
						|
    if (seriesIndex == cvf::UNDEFINED_INT)
 | 
						|
    {
 | 
						|
        (*masterCaseCellIndexCount) = 0;
 | 
						|
        return nullptr;
 | 
						|
    }
 | 
						|
 | 
						|
    if (seriesIndex < 0)
 | 
						|
    {
 | 
						|
        (*masterCaseCellIndexCount) = static_cast<int>(m_masterCellIndexSeries[-seriesIndex].size());
 | 
						|
        return &(m_masterCellIndexSeries[-seriesIndex][0]);    
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        (*masterCaseCellIndexCount) = 1;
 | 
						|
        return &(m_masterCellOrIntervalIndex[dependentCaseReservoirCellIndex]);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigCaseToCaseCellMapper::addMapping(int depCaseCellIdx, int masterCaseMatchingCell)
 | 
						|
{
 | 
						|
    int mcOrSeriesIdx = m_masterCellOrIntervalIndex[depCaseCellIdx];
 | 
						|
    if (mcOrSeriesIdx == cvf::UNDEFINED_INT)
 | 
						|
    {
 | 
						|
        m_masterCellOrIntervalIndex[depCaseCellIdx] = masterCaseMatchingCell;
 | 
						|
    }
 | 
						|
    else if (mcOrSeriesIdx >= 0)
 | 
						|
    {
 | 
						|
        int newSeriesIdx = static_cast<int>(m_masterCellIndexSeries.size());
 | 
						|
        m_masterCellIndexSeries.push_back(std::vector<int>());
 | 
						|
        m_masterCellIndexSeries.back().push_back(mcOrSeriesIdx);
 | 
						|
        m_masterCellIndexSeries.back().push_back(masterCaseMatchingCell);
 | 
						|
        m_masterCellOrIntervalIndex[depCaseCellIdx] = -newSeriesIdx;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        m_masterCellIndexSeries[-mcOrSeriesIdx].push_back(masterCaseMatchingCell);
 | 
						|
    }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigCaseToCaseCellMapper::calculateEclToGeomCellMapping(RigMainGrid* masterEclGrid, RigFemPart* dependentFemPart, bool eclipseIsMaster)
 | 
						|
{
 | 
						|
    // Find tolerance
 | 
						|
 | 
						|
    double cellSizeI, cellSizeJ, cellSizeK;
 | 
						|
    masterEclGrid->characteristicCellSizes(&cellSizeI, &cellSizeJ, &cellSizeK);
 | 
						|
    
 | 
						|
    double xyTolerance  = cellSizeI* 0.4;
 | 
						|
    double zTolerance   = cellSizeK* 0.4;
 | 
						|
 | 
						|
    bool isEclFaceNormalsOutwards = masterEclGrid->isFaceNormalsOutwards();
 | 
						|
 | 
						|
    cvf::Vec3d elmCorners[8];
 | 
						|
 | 
						|
    size_t cellCount =  masterEclGrid->cellCount();
 | 
						|
 | 
						|
    for (size_t cellIdx = 0; cellIdx < cellCount; ++cellIdx)
 | 
						|
    {
 | 
						|
        #ifdef _DEBUG
 | 
						|
        { 
 | 
						|
            // For debugging 
 | 
						|
            size_t i, j, k;
 | 
						|
            masterEclGrid->ijkFromCellIndex(cellIdx, &i, &j, &k); // Will not work when LGR present
 | 
						|
        }
 | 
						|
        #endif  
 | 
						|
 | 
						|
        cvf::Vec3d geoMechConvertedEclCell[8];
 | 
						|
        RigCaseToCaseCellMapperTools::estimatedFemCellFromEclCell(masterEclGrid, cellIdx, geoMechConvertedEclCell);
 | 
						|
 | 
						|
        cvf::BoundingBox elmBBox;
 | 
						|
        for (int i = 0; i < 8 ; ++i) elmBBox.add(geoMechConvertedEclCell[i]);
 | 
						|
 | 
						|
        std::vector<size_t> closeElements;
 | 
						|
        dependentFemPart->findIntersectingCells(elmBBox, &closeElements);
 | 
						|
 | 
						|
        for (size_t ccIdx = 0; ccIdx < closeElements.size(); ++ccIdx)
 | 
						|
        {
 | 
						|
            int elmIdx = static_cast<int>(closeElements[ccIdx]);
 | 
						|
 | 
						|
            RigCaseToCaseCellMapperTools::elementCorners(dependentFemPart, elmIdx, elmCorners);
 | 
						|
 | 
						|
            RigCaseToCaseCellMapperTools::rotateCellTopologicallyToMatchBaseCell(geoMechConvertedEclCell, isEclFaceNormalsOutwards , elmCorners);
 | 
						|
 | 
						|
            bool isMatching = RigCaseToCaseCellMapperTools::isEclFemCellsMatching(geoMechConvertedEclCell, elmCorners, 
 | 
						|
                                                    xyTolerance, zTolerance);
 | 
						|
 | 
						|
            if (isMatching)
 | 
						|
            {
 | 
						|
                if (eclipseIsMaster)
 | 
						|
                    addMapping(elmIdx, static_cast<int>(cellIdx));
 | 
						|
                else
 | 
						|
                    addMapping(static_cast<int>(cellIdx), elmIdx);
 | 
						|
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |