///////////////////////////////////////////////////////////////////////////////// // // 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimEclipseInputCase.h" #include "RiaPreferences.h" #include "RifEclipseInputFileTools.h" #include "RifReaderEclipseInput.h" #include "RifReaderInterface.h" #include "RifReaderMockModel.h" #include "RifReaderSettings.h" #include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigMainGrid.h" #include "RimDefines.h" #include "RimEclipseInputProperty.h" #include "RimEclipseInputPropertyCollection.h" #include "RimReservoirCellResultsStorage.h" #include "RimTools.h" #include "cafProgressInfo.h" #include CAF_PDM_SOURCE_INIT(RimEclipseInputCase, "RimInputReservoir"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimEclipseInputCase::RimEclipseInputCase() : RimEclipseCase() { CAF_PDM_InitObject("RimInputCase", ":/EclipseInput48x48.png", "", ""); CAF_PDM_InitField(&m_gridFileName, "GridFileName", QString(), "Case File Name", "", "" ,""); m_gridFileName.uiCapability()->setUiReadOnly(true); CAF_PDM_InitFieldNoDefault(&m_additionalFileNames, "AdditionalFileNames", "Additional files", "", "" ,""); m_additionalFileNames.uiCapability()->setUiReadOnly(true); CAF_PDM_InitFieldNoDefault(&m_inputPropertyCollection, "InputPropertyCollection", "", "", "", ""); m_inputPropertyCollection = new RimEclipseInputPropertyCollection; m_inputPropertyCollection->parentField()->uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimEclipseInputCase::~RimEclipseInputCase() { delete m_inputPropertyCollection; } //-------------------------------------------------------------------------------------------------- /// Open the supplied file set. If no grid data has been read, it will first find the possible /// grid data among the files then read all supported properties from the files matching the grid //-------------------------------------------------------------------------------------------------- void RimEclipseInputCase::openDataFileSet(const QStringList& fileNames) { if (fileNames.contains(RimDefines::mockModelBasicInputCase())) { cvf::ref readerInterface = this->createMockModel(fileNames[0]); results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); eclipseCaseData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->computeDerivedData(); eclipseCaseData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->computeDerivedData(); QFileInfo gridFileName(fileNames[0]); QString caseName = gridFileName.completeBaseName(); this->caseUserDescription = caseName; computeCachedData(); return; } if (this->eclipseCaseData() == NULL) { this->setReservoirData(new RigEclipseCaseData); } // First find and read the grid data if (this->eclipseCaseData()->mainGrid()->gridPointDimensions() == cvf::Vec3st(0,0,0)) { RiaPreferences* prefs = RiaApplication::instance()->preferences(); for (int i = 0; i < fileNames.size(); i++) { if (RifEclipseInputFileTools::openGridFile(fileNames[i], this->eclipseCaseData(), prefs->readerSettings->importFaults())) { m_gridFileName = fileNames[i]; QFileInfo gridFileName(fileNames[i]); QString caseName = gridFileName.completeBaseName(); this->caseUserDescription = caseName; this->eclipseCaseData()->mainGrid()->setFlipAxis(flipXAxis, flipYAxis); computeCachedData(); break; } } } if (this->eclipseCaseData()->mainGrid()->gridPointDimensions() == cvf::Vec3st(0,0,0)) { return ; // No grid present } // Then read the properties possibly in the grid file QStringList filesToRead; for (int i = 0; i < fileNames.size(); i++) { size_t j; bool exist = false; for (j = 0; j < m_additionalFileNames().size(); j++) { if (m_additionalFileNames()[j] == fileNames[i]) { exist = true; } } if (!exist) { filesToRead.push_back(fileNames[i]); } } for (int i = 0; i < filesToRead.size(); i++) { QString propertyFileName = filesToRead[i]; std::map readProperties = RifEclipseInputFileTools::readProperties(propertyFileName, this->eclipseCaseData()); std::map::iterator it; for (it = readProperties.begin(); it != readProperties.end(); ++it) { RimEclipseInputProperty* inputProperty = new RimEclipseInputProperty; inputProperty->resultName = it->first; inputProperty->eclipseKeyword = it->second; inputProperty->fileName = propertyFileName; inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED; m_inputPropertyCollection->inputProperties.push_back(inputProperty); } if (propertyFileName != m_gridFileName) { m_additionalFileNames.v().push_back(propertyFileName); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimEclipseInputCase::openEclipseGridFile() { // Early exit if reservoir data is created if (this->eclipseCaseData() == NULL) { cvf::ref readerInterface; if (m_gridFileName().contains(RimDefines::mockModelBasicInputCase())) { readerInterface = this->createMockModel(this->m_gridFileName()); } else { RiaPreferences* prefs = RiaApplication::instance()->preferences(); readerInterface = new RifReaderEclipseInput; readerInterface->setReaderSetting(prefs->readerSettings()); cvf::ref eclipseCase = new RigEclipseCaseData; if (!readerInterface->open(m_gridFileName, eclipseCase.p())) { return false; } this->setReservoirData( eclipseCase.p() ); } CVF_ASSERT(this->eclipseCaseData()); CVF_ASSERT(readerInterface.notNull()); results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); this->eclipseCaseData()->mainGrid()->setFlipAxis(flipXAxis, flipYAxis); computeCachedData(); loadAndSyncronizeInputProperties(); } RiaApplication* app = RiaApplication::instance(); if (app->preferences()->autocomputeDepthRelatedProperties) { RimReservoirCellResultsStorage* matrixResults = results(RifReaderInterface::MATRIX_RESULTS); RimReservoirCellResultsStorage* fractureResults = results(RifReaderInterface::FRACTURE_RESULTS); matrixResults->computeDepthRelatedResults(); fractureResults->computeDepthRelatedResults(); } return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimEclipseInputCase::reloadEclipseGridFile() { setReservoirData(nullptr); openReserviorCase(); } #define for_all(stdVector, indexName) for (size_t indexName = 0; indexName < stdVector.size(); ++indexName) //-------------------------------------------------------------------------------------------------- /// Loads input property data from the gridFile and additional files /// Creates new InputProperties if necessary, and flags the unused ones as obsolete //-------------------------------------------------------------------------------------------------- void RimEclipseInputCase::loadAndSyncronizeInputProperties() { // Make sure we actually have reservoir data CVF_ASSERT(this->eclipseCaseData()); CVF_ASSERT(this->eclipseCaseData()->mainGrid()->gridPointDimensions() != cvf::Vec3st(0,0,0)); // Then read the properties from all the files referenced by the InputReservoir std::vector filenames = m_additionalFileNames; filenames.push_back(m_gridFileName); size_t inputPropCount = this->m_inputPropertyCollection()->inputProperties.size(); caf::ProgressInfo progInfo(static_cast(filenames.size() * inputPropCount), "Reading Input properties" ); for_all(filenames, i) { int progress = static_cast(i*inputPropCount); // Find all the keywords present on the file progInfo.setProgressDescription(filenames[i]); QFileInfo fileNameInfo(filenames[i]); bool isExistingFile = fileNameInfo.exists(); std::set fileKeywordSet; if (isExistingFile) { std::vector< RifKeywordAndFilePos > fileKeywords; RifEclipseInputFileTools::findKeywordsOnFile(filenames[i], &fileKeywords); for_all(fileKeywords, fkIt) fileKeywordSet.insert(fileKeywords[fkIt].keyword); } // Find the input property objects referring to the file std::vector ipsUsingThisFile = this->m_inputPropertyCollection()->findInputProperties(filenames[i]); // Read property data for each inputProperty for_all(ipsUsingThisFile, ipIdx) { if (!isExistingFile) { ipsUsingThisFile[ipIdx]->resolvedState = RimEclipseInputProperty::FILE_MISSING; } else { QString kw = ipsUsingThisFile[ipIdx]->eclipseKeyword(); ipsUsingThisFile[ipIdx]->resolvedState = RimEclipseInputProperty::KEYWORD_NOT_IN_FILE; if (fileKeywordSet.count(kw)) { if (RifEclipseInputFileTools::readProperty(filenames[i], this->eclipseCaseData(), kw, ipsUsingThisFile[ipIdx]->resultName )) { ipsUsingThisFile[ipIdx]->resolvedState = RimEclipseInputProperty::RESOLVED; } } fileKeywordSet.erase(kw); } progInfo.setProgress(static_cast(progress + ipIdx) ); } progInfo.setProgress(static_cast(progress + inputPropCount)); // Check if there are more known property keywords left on file. If it is, read them and create inputProperty objects for (const QString fileKeyword : fileKeywordSet) { { QString resultName = this->eclipseCaseData()->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeyword); if (RifEclipseInputFileTools::readProperty(filenames[i], this->eclipseCaseData(), fileKeyword, resultName)) { RimEclipseInputProperty* inputProperty = new RimEclipseInputProperty; inputProperty->resultName = resultName; inputProperty->eclipseKeyword = fileKeyword; inputProperty->fileName = filenames[i]; inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED; m_inputPropertyCollection->inputProperties.push_back(inputProperty); } } progInfo.setProgress(static_cast(progress + inputPropCount)); } } for_all(m_inputPropertyCollection->inputProperties, i) { if (m_inputPropertyCollection->inputProperties[i]->resolvedState() == RimEclipseInputProperty::UNKNOWN) { m_inputPropertyCollection->inputProperties[i]->resolvedState = RimEclipseInputProperty::FILE_MISSING; } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::ref RimEclipseInputCase::createMockModel(QString modelName) { cvf::ref reservoir = new RigEclipseCaseData; cvf::ref mockFileInterface = new RifReaderMockModel; if (modelName == RimDefines::mockModelBasicInputCase()) { m_gridFileName = modelName; // Create the mock file interface and and RigSerervoir and set them up. mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20)); mockFileInterface->setGridPointDimensions(cvf::Vec3st(4, 5, 6)); mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 2, 2), cvf::Vec3st(0, 2, 2), cvf::Vec3st(3, 3, 3)); mockFileInterface->setResultInfo(3, 10); mockFileInterface->open("", reservoir.p()); { //size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); //TODO: Rewrite active cell info in mock models //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } { //size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); //TODO: Rewrite active cell info in mock models //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } // Add a property RimEclipseInputProperty* inputProperty = new RimEclipseInputProperty; inputProperty->resultName = "PORO"; inputProperty->eclipseKeyword = "PORO"; inputProperty->fileName = "PORO.prop"; m_inputPropertyCollection->inputProperties.push_back(inputProperty); } this->setReservoirData( reservoir.p() ); return mockFileInterface.p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimEclipseInputCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { uiOrdering.add(&caseUserDescription); uiOrdering.add(&caseId); uiOrdering.add(&m_gridFileName); uiOrdering.add(&m_additionalFileNames); auto group = uiOrdering.addNewGroup("Case Options"); group->add(&activeFormationNames); group->add(&flipXAxis); group->add(&flipYAxis); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimEclipseInputCase::locationOnDisc() const { if (m_gridFileName().isEmpty()) return QString(); QFileInfo fi(m_gridFileName); return fi.absolutePath(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimEclipseInputCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) { bool foundFile = false; std::vector searchedPaths; m_gridFileName = RimTools::relocateFile(m_gridFileName(), newProjectPath, oldProjectPath, &foundFile, &searchedPaths); for (size_t i = 0; i < m_additionalFileNames().size(); i++) { m_additionalFileNames.v()[i] = RimTools::relocateFile(m_additionalFileNames()[i], newProjectPath, oldProjectPath, &foundFile, &searchedPaths); } }