diff --git a/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.cpp b/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.cpp index bfb4e14d1..e2c8df1b7 100644 --- a/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.cpp +++ b/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.cpp @@ -22,11 +22,14 @@ #include #include +#include + #include #include #include +#include #include #include @@ -61,4 +64,74 @@ void outputTimestampFIP(const SimulatorTimer& timer, OpmLog::note(ss.str()); } +void checkSerializedCmdLine(const std::string& current, + const std::string& stored) +{ + auto filter_strings = [](const std::vector& input) + { + std::vector output; + output.reserve(input.size()); + std::copy_if(input.begin(), input.end(), std::back_inserter(output), + [](const std::string& line) + { + return line.compare(0, 11, "EclDeckFile") != 0 && + line.compare(0, 8, "LoadStep") != 0 && + line.compare(0, 8, "SaveFile") != 0 && + line.compare(0, 8, "SaveStep") != 0; + }); + return output; + }; + + auto curr_strings = split_string(current, '\n'); + auto stored_strings = split_string(stored, '\n'); + std::sort(curr_strings.begin(), curr_strings.end()); + std::sort(stored_strings.begin(), stored_strings.end()); + curr_strings = filter_strings(curr_strings); + stored_strings = filter_strings(stored_strings); + + std::vector difference; + std::set_symmetric_difference(stored_strings.begin(), stored_strings.end(), + curr_strings.begin(), curr_strings.end(), + std::back_inserter(difference)); + + std::vector only_stored, only_curr; + if (!difference.empty()) { + for (size_t i = 0; i < difference.size(); ) { + auto stored_it = std::find(stored_strings.begin(), + stored_strings.end(), difference[i]); + auto pos = difference[i].find_first_of('='); + if (i < difference.size() - 1 && + difference[i].compare(0, pos, difference[i+1], 0, pos) == 0) { + if (stored_it == stored_strings.end()) { + std::swap(difference[i], difference[i+1]); + } + i += 2; + } else { + if (stored_it == stored_strings.end()) { + only_curr.push_back(difference[i]); + } else { + only_stored.push_back(difference[i]); + } + difference.erase(difference.begin() + i); + } + } + std::stringstream str; + str << "Differences:\n"; + for (std::size_t i = 0; i < difference.size(); ++i) { + str << '\t' << (i % 2 == 0 ? '-' : '+') << difference[i] << '\n'; + } + if (!only_stored.empty()) { + str << "Only in serialized parameters:\n"; + for (const std::string& line : only_stored) + str << '\t' << line << '\n'; + } + if (!only_curr.empty()) { + str << "Only in current parameters:\n"; + for (const std::string& line : only_curr) + str << '\t' << line << '\n'; + } + OpmLog::warning("Command line parameters mismatch:\n" + str.str()); + } +} + } // namespace Opm diff --git a/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp b/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp index 631ddd95c..162f57e21 100644 --- a/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp +++ b/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp @@ -135,6 +135,8 @@ void outputReportStep(const SimulatorTimer& timer); void outputTimestampFIP(const SimulatorTimer& timer, const std::string& title, const std::string& version); +void checkSerializedCmdLine(const std::string& current, + const std::string& stored); /// a simulator for the blackoil model template @@ -644,16 +646,33 @@ protected: const std::string groupName = "/report_step/" + std::to_string(loadStep_); reader.read(timer, groupName, "simulator_timer", HDF5File::DataSetMode::ROOT_ONLY); + std::tuple,int> header; + reader.read(header, "/", "simulator_info", HDF5File::DataSetMode::ROOT_ONLY); + const auto& [strings, procs] = header; + + if (EclGenericVanguard::comm().size() != procs) { + throw std::runtime_error("Number of processes (procs=" + + std::to_string(EclGenericVanguard::comm().size()) + + ") does not match .OPMRST file (procs=" + + std::to_string(procs) + ")"); + } + if (EclGenericVanguard::comm().size() > 1) { std::size_t stored_hash; reader.read(stored_hash, "/", "grid_checksum"); const auto& cellMapping = ebosSimulator_.vanguard().globalCell(); std::size_t hash = Dune::hash_range(cellMapping.begin(), cellMapping.end()); if (hash != stored_hash) { - throw std::runtime_error("Grid hash mismatch, .SAVE file cannot be used"); + throw std::runtime_error("Grid hash mismatch, .OPMRST file cannot be used"); } } + if (EclGenericVanguard::comm().rank() == 0) { + std::ostringstream str; + Parameters::printValues(str); + checkSerializedCmdLine(str.str(), strings[4]); + } + OPM_END_PARALLEL_TRY_CATCH("Error loading serialized state: ", EclGenericVanguard::comm()); #endif