/* Copyright 2015 Statoil ASA. This file is part of the Open Porous Media project (OPM). OPM 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. OPM 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 for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include namespace Opm { IOConfig::IOConfig(const std::string& input_path): m_write_INIT_file(false), m_write_EGRID_file(true), m_write_initial_RST_file(false), m_UNIFIN(false), m_UNIFOUT(false), m_FMTIN(false), m_FMTOUT(false), m_eclipse_input_path(input_path), m_ignore_RPTSCHED_RESTART(false){ } bool IOConfig::getWriteEGRIDFile() const { return m_write_EGRID_file; } bool IOConfig::getWriteINITFile() const { return m_write_INIT_file; } bool IOConfig::getWriteRestartFile(size_t timestep) const { bool write_restart_ts = false; if (0 == timestep) { write_restart_ts = m_write_initial_RST_file; } else if (m_restart_output_config) { restartConfig ts_restart_config = m_restart_output_config->get(timestep); //Look at rptsched restart setting if (ts_restart_config.rptsched_restart_set) { if (ts_restart_config.rptsched_restart > 0) { write_restart_ts = true; } } else { //Look at rptrst basic setting switch (ts_restart_config.basic) { case 0: //Do not write restart files write_restart_ts = false; break; case 1: //Write restart file every report time write_restart_ts = true; break; case 2: //Write restart file every report time write_restart_ts = true; break; case 3: //Every n'th report time write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency); break; case 4: //First reportstep of every year, or if n > 1, n'th years write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency, true); break; case 5: //First reportstep of every month, or if n > 1, n'th months write_restart_ts = getWriteRestartFileFrequency(timestep, ts_restart_config.timestep, ts_restart_config.frequency, false, true); break; default: // do nothing break; } } } return write_restart_ts; } bool IOConfig::getWriteRestartFileFrequency(size_t timestep, size_t start_timestep, size_t frequency, bool years, bool months) const { bool write_restart_file = false; if ((!years && !months) && (timestep >= start_timestep)) { write_restart_file = ((timestep % frequency) == 0) ? true : false; } else { write_restart_file = m_timemap->isTimestepInFirstOfMonthsYearsSequence(timestep, years, start_timestep, frequency); } return write_restart_file; } void IOConfig::handleRPTRSTBasic(TimeMapConstPtr timemap, size_t timestep, size_t basic, size_t frequency, bool update_default, bool reset_global) { if (6 == basic ) { throw std::runtime_error("OPM does not support the RPTRST BASIC=6 setting (write restart file every timestep)"); } if (basic > 2) { m_ignore_RPTSCHED_RESTART = true; } else { m_ignore_RPTSCHED_RESTART = false; } assertTimeMap( timemap ); { restartConfig rs; rs.timestep = timestep; rs.basic = basic; rs.frequency = frequency; rs.rptsched_restart_set = false; rs.rptsched_restart = 0; if (update_default) { m_restart_output_config->updateInitial(rs); } else if (reset_global) { m_restart_output_config->globalReset(rs); } else { m_restart_output_config->update(timestep, rs); } } } void IOConfig::handleRPTSCHEDRestart(TimeMapConstPtr timemap, size_t timestep, size_t restart) { if (6 == restart ) { throw std::runtime_error("OPM does not support the RPTSCHED RESTART=6 setting (write restart file every timestep)"); } if (m_ignore_RPTSCHED_RESTART) { //If previously RPTRST BASIC has been set >2, ignore RPTSCHED RESTART return; } assertTimeMap( timemap ); { restartConfig rs; rs.timestep = 0; rs.basic = 0; rs.frequency = 0; rs.rptsched_restart = restart; rs.rptsched_restart_set = true; m_restart_output_config->update(timestep, rs); } } void IOConfig::assertTimeMap(TimeMapConstPtr timemap) { if (!m_timemap) { restartConfig rs; rs.timestep = 0; rs.basic = 0; rs.frequency = 1; rs.rptsched_restart_set = false; rs.rptsched_restart = 0; m_timemap = timemap; m_restart_output_config = std::make_shared>(timemap, rs); } } void IOConfig::handleSolutionSection(TimeMapConstPtr timemap, std::shared_ptr solutionSection) { if (solutionSection->hasKeyword("RPTRST")) { const auto& rptrstkeyword = solutionSection->getKeyword("RPTRST"); const auto& record = rptrstkeyword.getRecord(0); const auto& item = record.getItem(0); bool handleRptrstBasic = false; size_t basic = 0; size_t freq = 0; for (size_t index = 0; index < item.size(); ++index) { if (item.hasValue(index)) { std::string mnemonics = item.get< std::string >(index); std::size_t found_basic = mnemonics.find("BASIC="); if (found_basic != std::string::npos) { std::string basic_no = mnemonics.substr(found_basic+6, found_basic+7); basic = atoi(basic_no.c_str()); handleRptrstBasic = true; } std::size_t found_freq = mnemonics.find("FREQ="); if (found_freq != std::string::npos) { std::string freq_no = mnemonics.substr(found_freq+5, found_freq+6); freq = atoi(freq_no.c_str()); } } } if (handleRptrstBasic) { size_t currentStep = 0; handleRPTRSTBasic(timemap, currentStep, basic, freq, true); } setWriteInitialRestartFile(true); // Guessing on eclipse rules for write of initial RESTART file (at time 0): // Write of initial restart file is (due to the eclipse reference manual) // governed by RPTSOL RESTART in solution section, // if RPTSOL RESTART > 1 initial restart file is written. // but - due to initial restart file written from Eclipse // for data where RPTSOL RESTART not set - guessing that // when RPTRST is set in SOLUTION (no basic though...) -> write inital restart. } //RPTRST if (solutionSection->hasKeyword("RPTSOL") && (timemap->size() > 0)) { handleRPTSOL(solutionSection->getKeyword("RPTSOL")); } //RPTSOL } void IOConfig::handleGridSection(std::shared_ptr gridSection) { m_write_INIT_file = gridSection->hasKeyword("INIT"); if (gridSection->hasKeyword("GRIDFILE")) { const auto& gridfilekeyword = gridSection->getKeyword("GRIDFILE"); if (gridfilekeyword.size() > 0) { const auto& rec = gridfilekeyword.getRecord(0); const auto& item1 = rec.getItem(0); if ((item1.hasValue(0)) && (item1.get< int >(0) != 0)) { std::cerr << "IOConfig: Reading GRIDFILE keyword from GRID section: Output of GRID file is not supported" << std::endl; } if (rec.size() > 1) { const auto& item2 = rec.getItem(1); if ((item2.hasValue(0)) && (item2.get< int >(0) == 0)) { m_write_EGRID_file = false; } } } } if (gridSection->hasKeyword("NOGGF")) { m_write_EGRID_file = false; } } void IOConfig::handleRunspecSection(std::shared_ptr runspecSection) { m_FMTIN = runspecSection->hasKeyword("FMTIN"); //Input files are formatted m_FMTOUT = runspecSection->hasKeyword("FMTOUT"); //Output files are to be formatted m_UNIFIN = runspecSection->hasKeyword("UNIFIN"); //Input files are unified m_UNIFOUT = runspecSection->hasKeyword("UNIFOUT"); //Output files are to be unified } void IOConfig::overrideRestartWriteInterval(size_t interval) { if (interval > 0) { size_t basic = 3; size_t timestep = 0; handleRPTRSTBasic(m_timemap, timestep, basic, interval, false, true); setWriteInitialRestartFile(true); } else { size_t basic = 0; size_t timestep = 0; handleRPTRSTBasic(m_timemap, timestep, basic, interval, false, true); setWriteInitialRestartFile(false); } } bool IOConfig::getUNIFIN() const { return m_UNIFIN; } bool IOConfig::getUNIFOUT() const { return m_UNIFOUT; } bool IOConfig::getFMTIN() const { return m_FMTIN; } bool IOConfig::getFMTOUT() const { return m_FMTOUT; } const std::string& IOConfig::getEclipseInputPath() const { return m_eclipse_input_path; } void IOConfig::setWriteInitialRestartFile(bool writeInitialRestartFile) { m_write_initial_RST_file = writeInitialRestartFile; } void IOConfig::handleRPTSOL( const DeckKeyword& keyword) { const auto& record = keyword.getRecord(0); size_t restart = 0; size_t found_mnemonic_RESTART = 0; bool handle_RPTSOL_RESTART = false; const auto& item = record.getItem(0); for (size_t index = 0; index < item.size(); ++index) { const std::string& mnemonic = item.get< std::string >(index); found_mnemonic_RESTART = mnemonic.find("RESTART="); if (found_mnemonic_RESTART != std::string::npos) { std::string restart_no = mnemonic.substr(found_mnemonic_RESTART+8, mnemonic.size()); restart = boost::lexical_cast(restart_no); handle_RPTSOL_RESTART = true; } } /* If no RESTART mnemonic is found, either it is not present or we might have an old data set containing integer controls instead of mnemonics. Restart integer switch is integer control nr 7 */ if (found_mnemonic_RESTART == std::string::npos) { if (item.size() >= 7) { const std::string& integer_control = item.get< std::string >(6); try { restart = boost::lexical_cast(integer_control); handle_RPTSOL_RESTART = true; } catch (boost::bad_lexical_cast &) { //do nothing } } } if (handle_RPTSOL_RESTART) { if (restart > 1) { setWriteInitialRestartFile(true); } else { setWriteInitialRestartFile(false); } } } boost::gregorian::date IOConfig::getTimestepDate(size_t reportStep) const { auto time = (*m_timemap)[reportStep]; return time.date(); } void IOConfig::dumpRestartConfig() const { for (size_t reportStep = 0; reportStep < m_timemap->size(); reportStep++) { if (getWriteRestartFile(reportStep)) { auto time = (*m_timemap)[reportStep]; boost::gregorian::date date = time.date(); printf("%04zu : %02hu/%02hu/%hu \n" , reportStep , date.day().as_number() , date.month().as_number() , static_cast(date.year())); } } } std::string IOConfig::getRestartFileName(const std::string& restart_base, int report_step, bool output) const { bool unified = output ? getUNIFOUT() : getUNIFIN(); bool fmt_file = output ? getFMTOUT() : getFMTIN(); ecl_file_enum file_type = (unified) ? ECL_UNIFIED_RESTART_FILE : ECL_RESTART_FILE; char * c_str = ecl_util_alloc_filename( NULL , restart_base.c_str() , file_type, fmt_file , report_step); std::string restart_filename = c_str; free( c_str ); return restart_filename; } } //namespace Opm