/* Copyright 2013, 2014, 2015 SINTEF ICT, Applied Mathematics. Copyright 2014 Dr. Blatt - HPC-Simulation-Software & Services Copyright 2015 IRIS AS Copyright 2014 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 "opm/simulators/flow/BlackoilModelParameters.hpp" #include "opm/simulators/flow/FlowProblemParameters.hpp" #include "opm/simulators/flow/VtkTracerModule.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if HAVE_MPI #include #endif #include #include #include #include #include #include #include namespace Opm::detail { void mergeParallelLogFiles(std::string_view output_dir, std::string_view deckFilename, bool enableLoggingFalloutWarning) { namespace fs = ::std::filesystem; fs::path output_path(output_dir); fs::path deck_filename(deckFilename); std::string basename; // Strip extension "." and ".DATA" std::string extension = uppercase(deck_filename.extension().string()); if (extension == ".DATA" || extension == ".") { basename = uppercase(deck_filename.stem().string()); } else { basename = uppercase(deck_filename.filename().string()); } std::for_each(fs::directory_iterator(output_path), fs::directory_iterator(), detail::ParallelFileMerger(output_path, basename, enableLoggingFalloutWarning)); } void handleExtraConvergenceOutput(SimulatorReport& report, std::string_view option, std::string_view optionName, std::string_view output_dir, std::string_view base_name) { const auto extraConvOutput = ConvergenceOutputConfiguration { option, optionName }; if (extraConvOutput.want(ConvergenceOutputConfiguration::Option::Steps)) { namespace fs = ::std::filesystem; const auto infostep = fs::path{output_dir} / fs::path{base_name}.concat(".INFOSTEP"); std::ofstream os(infostep); report.fullReports(os); } } void checkAllMPIProcesses() { #if HAVE_MPI const auto& comm = FlowGenericVanguard::comm(); if (comm.size() > 1) { // we try to prevent the abort here. // For that we need a signal that each process is here. // Each process sends a message to rank 0. const int tag = 357912; if (comm.rank() == 0) { // wait for a message from all processes. std::vector requests(comm.size() - 1, MPI_REQUEST_NULL); std::vector data(comm.size()-1); for(decltype(comm.size()) i = 1; i < comm.size(); ++i) { if (auto error = MPI_Irecv(data.data() + (i - 1), 1, MPI_INT, i, tag, comm, requests.data() + (i - 1)); error != MPI_SUCCESS) { OpmLog::error(fmt::format("Error: Could not set up MPI receive (error code : {})", error)); MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } } std::size_t msgs = comm.size() - 1; for(std::size_t tries = 0; msgs >0 && tries < 3; ++tries) { sleep(3); int flag, idx; for(auto left_msgs = msgs; left_msgs > 0; --left_msgs) { if( auto error = MPI_Testany(comm.size()-1, requests.data(), &idx, &flag, MPI_STATUS_IGNORE); error != MPI_SUCCESS) { OpmLog::error(fmt::format("Error: Could not test for MPI message (error code : {})", error)); MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } if (flag) { --msgs; } } } if (msgs) { // seems like some processes are stuck. Abort just to be save MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } } else { int data= 3; MPI_Request request = MPI_REQUEST_NULL; if (auto error = MPI_Isend(&data, 1, MPI_INT, 0, tag, comm, &request); error != MPI_SUCCESS) { OpmLog::error(fmt::format("Error: Could send MPI message (error code : {})", error)); MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } bool completed = false; for(std::size_t tries = 0; !completed && tries < 3; tries++) { sleep(3); int flag; if( auto error = MPI_Test(&request, &flag, MPI_STATUS_IGNORE); error != MPI_SUCCESS) { OpmLog::error(fmt::format("Error: Could not test for MPI message (error code : {})", error)); MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } if (flag) { completed = true; } } if (!completed) { MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } } } #endif } template void hideUnusedParameters() { // hide the parameters unused by flow. TODO: this is a pain to maintain Parameters::Hide(); Parameters::Hide(); // this parameter is actually used in eWoms, but the flow well model // hard-codes the assumption that the intensive quantities cache is enabled, // so flow crashes. Let's hide the parameter for that reason. Parameters::Hide(); // thermodynamic hints are not implemented/required by the eWoms blackoil // model Parameters::Hide(); // in flow only the deck file determines the end time of the simulation Parameters::Hide>(); // time stepping is not done by the eWoms code in flow Parameters::Hide>(); Parameters::Hide(); Parameters::Hide>(); Parameters::Hide>(); Parameters::Hide(); // flow also does not use the eWoms Newton method Parameters::Hide>(); Parameters::Hide>(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); // the default eWoms checkpoint/restart mechanism does not work with flow Parameters::Hide>(); Parameters::Hide(); // hide all vtk related it is not currently possible to do this dependet on if the vtk writing is used //if(not(Parameters::Get())){ Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); //} Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); Parameters::Hide(); // hide average density option Parameters::Hide(); } template void hideUnusedParameters(); #if FLOW_INSTANTIATE_FLOAT template void hideUnusedParameters(); #endif } // namespace Opm::detail