///////////////////////////////////////////////////////////////////////////////// // // 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 "RifEclipseOutputFileTools.h" #include "ert/ecl/ecl_file.h" #include "ert/ecl/ecl_grid.h" #include "ert/ecl/ecl_kw_magic.h" #include "cafProgressInfo.h" #include "cvfMath.h" #include #include #include #include //-------------------------------------------------------------------------------------------------- /// Constructor //-------------------------------------------------------------------------------------------------- RifEclipseOutputFileTools::RifEclipseOutputFileTools() { } //-------------------------------------------------------------------------------------------------- /// Destructor //-------------------------------------------------------------------------------------------------- RifEclipseOutputFileTools::~RifEclipseOutputFileTools() { } struct KeywordItemCounter { KeywordItemCounter(const std::string& keyword, size_t aggregatedItemCount) : m_keyword(keyword), m_aggregatedItemCount(aggregatedItemCount), m_reportStepCount(1) {} bool operator==(const std::string& rhs) const { return this->m_keyword == rhs; } std::string m_keyword; size_t m_aggregatedItemCount; size_t m_reportStepCount; }; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifEclipseOutputFileTools::findKeywordsAndItemCount(std::vector ecl_files, QStringList* resultNames, std::vector* resultDataItemCounts) { std::vector reportSteps; RifEclipseOutputFileTools::createReportStepsMetaData(ecl_files, &reportSteps); std::vector foundKeywords; for (auto reportStep : reportSteps) { for (auto keywordItemCount : reportStep.m_keywords.keywordsWithAggregatedItemCount()) { auto it = std::find(foundKeywords.begin(), foundKeywords.end(), keywordItemCount.first); if (it == foundKeywords.end()) { foundKeywords.push_back(KeywordItemCounter(keywordItemCount.first, keywordItemCount.second)); } else { it->m_aggregatedItemCount += keywordItemCount.second; it->m_reportStepCount++; } } } for (auto stdKeyword : foundKeywords) { resultNames->push_back(QString::fromStdString(stdKeyword.m_keyword)); resultDataItemCounts->push_back(stdKeyword.m_aggregatedItemCount); } } void getDayMonthYear(const ecl_kw_type* intehead_kw, int* day, int* month, int* year) { assert(day && month && year); *day = ecl_kw_iget_int(intehead_kw, INTEHEAD_DAY_INDEX); *month = ecl_kw_iget_int(intehead_kw, INTEHEAD_MONTH_INDEX); *year = ecl_kw_iget_int(intehead_kw, INTEHEAD_YEAR_INDEX); } //-------------------------------------------------------------------------------------------------- /// Get list of time step texts (dates) //-------------------------------------------------------------------------------------------------- void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector* timeSteps) { if (!ecl_file) return; CVF_ASSERT(timeSteps); // Get the number of occurrences of the INTEHEAD keyword int numINTEHEAD = ecl_file_get_num_named_kw(ecl_file, INTEHEAD_KW); // Get the number of occurrences of the DOUBHEAD keyword int numDOUBHEAD = ecl_file_get_num_named_kw(ecl_file, DOUBHEAD_KW); std::vector dayFractions(numINTEHEAD, 0.0); // Init fraction to zero // Read out fraction of day if number of keywords are identical if (numINTEHEAD == numDOUBHEAD) { for (int i = 0; i < numDOUBHEAD; i++) { ecl_kw_type* kwDOUBHEAD = ecl_file_iget_named_kw(ecl_file, DOUBHEAD_KW, i); if (kwDOUBHEAD) { double dayValue = ecl_kw_iget_double(kwDOUBHEAD, DOUBHEAD_DAYS_INDEX); double floorDayValue = cvf::Math::floor(dayValue); double dayDelta = dayValue - floorDayValue; dayFractions[i] = dayDelta; } } } for (int i = 0; i < numINTEHEAD; i++) { ecl_kw_type* kwINTEHEAD = ecl_file_iget_named_kw(ecl_file, INTEHEAD_KW, i); CVF_ASSERT(kwINTEHEAD); int day = 0; int month = 0; int year = 0; getDayMonthYear(kwINTEHEAD, &day, &month, &year); QDateTime reportDateTime(QDate(year, month, day)); CVF_ASSERT(reportDateTime.isValid()); double dayFraction = dayFractions[i]; int milliseconds = static_cast(dayFraction * 24.0 * 60.0 * 60.0 * 1000.0); int seconds = milliseconds % 1000; milliseconds -= seconds * 1000; QTime time(0, 0); time = time.addSecs(seconds); time = time.addMSecs(milliseconds); reportDateTime.setTime(time); if (std::find(timeSteps->begin(), timeSteps->end(), reportDateTime) == timeSteps->end()) { timeSteps->push_back(reportDateTime); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RifEclipseOutputFileTools::keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector* values) { ecl_kw_type* kwData = ecl_file_iget_named_kw(ecl_file, keyword.toAscii().data(), static_cast(fileKeywordOccurrence)); if (kwData) { size_t numValues = ecl_kw_get_size(kwData); std::vector doubleData; doubleData.resize(numValues); ecl_kw_get_data_as_double(kwData, doubleData.data()); values->insert(values->end(), doubleData.begin(), doubleData.end()); return true; } return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RifEclipseOutputFileTools::keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector* values) { ecl_kw_type* kwData = ecl_file_iget_named_kw(ecl_file, keyword.toAscii().data(), static_cast(fileKeywordOccurrence)); if (kwData) { size_t numValues = ecl_kw_get_size(kwData); std::vector integerData; integerData.resize(numValues); ecl_kw_get_memcpy_int_data(kwData, integerData.data()); values->insert(values->end(), integerData.begin(), integerData.end()); return true; } return false; } //-------------------------------------------------------------------------------------------------- /// Get first occurrence of file of given type in given list of filenames, as filename or NULL if not found //-------------------------------------------------------------------------------------------------- QString RifEclipseOutputFileTools::firstFileNameOfType(const QStringList& fileSet, ecl_file_enum fileType) { int i; for (i = 0; i < fileSet.count(); i++) { bool formatted = false; int reportNumber = -1; if (ecl_util_get_file_type(fileSet.at(i).toAscii().data(), &formatted, &reportNumber) == fileType) { return fileSet.at(i); } } return QString::null; } //-------------------------------------------------------------------------------------------------- /// Get all files of the given type from the provided list of filenames //-------------------------------------------------------------------------------------------------- QStringList RifEclipseOutputFileTools::filterFileNamesOfType(const QStringList& fileSet, ecl_file_enum fileType) { QStringList fileNames; int i; for (i = 0; i < fileSet.count(); i++) { bool formatted = false; int reportNumber = -1; if (ecl_util_get_file_type(fileSet.at(i).toAscii().data(), &formatted, &reportNumber) == fileType) { fileNames.append(fileSet.at(i)); } } return fileNames; } //-------------------------------------------------------------------------------------------------- /// Get set of Eclipse files based on an input file and its path //-------------------------------------------------------------------------------------------------- bool RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(const QString& fullPathFileName, QStringList* baseNameFiles) { CVF_ASSERT(baseNameFiles); baseNameFiles->clear(); QString filePath = QFileInfo(fullPathFileName).absoluteFilePath(); filePath = QFileInfo(filePath).path(); QString fileNameBase = QFileInfo(fullPathFileName).baseName(); stringlist_type* eclipseFiles = stringlist_alloc_new(); ecl_util_select_filelist(filePath.toAscii().data(), fileNameBase.toAscii().data(), ECL_OTHER_FILE, false, eclipseFiles); int i; for (i = 0; i < stringlist_get_size(eclipseFiles); i++) { baseNameFiles->append(stringlist_safe_iget(eclipseFiles, i)); } stringlist_free(eclipseFiles); return baseNameFiles->count() > 0; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifEclipseOutputFileTools::readGridDimensions(const QString& gridFileName, std::vector< std::vector >& gridDimensions) { ecl_grid_type * grid = ecl_grid_alloc(gridFileName.toAscii().data()); // bootstrap ecl_grid instance stringlist_type * lgr_names = ecl_grid_alloc_lgr_name_list( grid ); // get a list of all the lgr names. //printf("grid:%s has %d a total of %d lgr's \n", grid_filename , stringlist_get_size( lgr_names )); for (int lgr_nr = 0; lgr_nr < stringlist_get_size( lgr_names); lgr_nr++) { ecl_grid_type * lgr_grid = ecl_grid_get_lgr( grid , stringlist_iget( lgr_names , lgr_nr )); // get the ecl_grid instance of the lgr - by name. int nx,ny,nz,active_size; ecl_grid_get_dims( lgr_grid , &nx , &ny , &nz , &active_size); // get some size info from this lgr. std::vector values; values.push_back(nx); values.push_back(ny); values.push_back(nz); values.push_back(active_size); gridDimensions.push_back(values); } ecl_grid_free( grid ); stringlist_free( lgr_names ); } //-------------------------------------------------------------------------------------------------- /// Returns the following integer values from the first INTEHEAD keyword found /// 1 : METRIC /// 2 : FIELD /// 3 : LAB /// -1 : No INTEHEAD keyword found //-------------------------------------------------------------------------------------------------- int RifEclipseOutputFileTools::readUnitsType(ecl_file_type* ecl_file) { int unitsType = -1; if (ecl_file) { ecl_kw_type* kwINTEHEAD = ecl_file_iget_named_kw(ecl_file, INTEHEAD_KW, 0); if (kwINTEHEAD) { unitsType = ecl_kw_iget_int(kwINTEHEAD, INTEHEAD_UNIT_INDEX); } } return unitsType; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifEclipseOutputFileTools::createReportStepsMetaData(std::vector ecl_files, std::vector* reportSteps) { if (!reportSteps) return; for (auto ecl_file : ecl_files) { if (!ecl_file) continue; int reportStepCount = ecl_file_get_num_named_kw(ecl_file, INTEHEAD_KW); for (int reportStepIndex = 0; reportStepIndex < reportStepCount; reportStepIndex++) { ecl_file_view_type* rst_view = ecl_file_get_global_view(ecl_file); if (!rst_view) continue; ecl_rsthead_type* restart_header = ecl_rsthead_alloc(rst_view, reportStepIndex); if (restart_header) { ecl_file_push_block(ecl_file); { ecl_file_select_block(ecl_file, INTEHEAD_KW, reportStepIndex); RifRestartReportStep reportStep; // Set Date { QDateTime reportDateTime(QDate(restart_header->year, restart_header->month, restart_header->day)); reportStep.dateTime = reportDateTime; } // Find number of keywords withing this report step int numKeywords = ecl_file_get_num_distinct_kw(ecl_file); for (int iKey = 0; iKey < numKeywords; iKey++) { const char* kw = ecl_file_iget_distinct_kw(ecl_file, iKey); int namedKeywordCount = ecl_file_get_num_named_kw(ecl_file, kw); for (int iOcc = 0; iOcc < namedKeywordCount; iOcc++) { ecl_type_enum dataType = ecl_file_iget_named_type(ecl_file, kw, iOcc); if (dataType != ECL_DOUBLE_TYPE && dataType != ECL_FLOAT_TYPE && dataType != ECL_INT_TYPE) { continue; } int itemCount = ecl_file_iget_named_size(ecl_file, kw, iOcc); reportStep.m_keywords.appendKeyword(kw, itemCount, iOcc); } } reportSteps->push_back(reportStep); } ecl_file_pop_block(ecl_file); ecl_rsthead_free(restart_header); } } } }