144 lines
5.2 KiB
C++
144 lines
5.2 KiB
C++
/*
|
|
Copyright 2013, 2020 Equinor 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <chrono>
|
|
#include <sstream>
|
|
|
|
#include <opm/input/eclipse/Deck/Deck.hpp>
|
|
|
|
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
|
|
|
#include <opm/input/eclipse/Parser/ErrorGuard.hpp>
|
|
#include <opm/input/eclipse/Parser/InputErrorAction.hpp>
|
|
#include <opm/input/eclipse/Parser/Parser.hpp>
|
|
#include <opm/input/eclipse/Parser/ParseContext.hpp>
|
|
|
|
#include <opm/input/eclipse/Python/Python.hpp>
|
|
|
|
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
|
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
|
|
|
|
#include <opm/common/OpmLog/OpmLog.hpp>
|
|
#include <opm/common/OpmLog/StreamLog.hpp>
|
|
#include <opm/common/OpmLog/LogUtil.hpp>
|
|
|
|
|
|
inline void createDot(const Opm::Schedule& schedule, const std::string& casename)
|
|
{
|
|
std::cout << "Writing " << casename << ".gv .... "; std::cout.flush();
|
|
std::ofstream os(casename + ".gv");
|
|
os << "// This file was written by the 'wellgraph' utility from OPM.\n";
|
|
os << "// Find the source code at github.com/OPM.\n";
|
|
os << "// Convert output to PDF with 'dot -Tpdf " << casename << ".gv > " << casename << ".pdf'\n";
|
|
os << "strict digraph \"" << casename << "\"\n{\n";
|
|
const auto groupnames = schedule.groupNames();
|
|
const std::size_t last = schedule.size() - 1;
|
|
// Group -> Group relations.
|
|
for (const auto& gn : groupnames) {
|
|
const auto& g = schedule.getGroup(gn, last);
|
|
const auto& children = g.groups();
|
|
if (!children.empty()) {
|
|
os << " \"" << gn << "\" -> {";
|
|
for (const auto& child : children) {
|
|
os << " \"" << child << '"';
|
|
}
|
|
os << " }\n";
|
|
}
|
|
}
|
|
// Group -> Well relations.
|
|
os << " node [shape=box]\n";
|
|
for (const auto& gn : groupnames) {
|
|
const auto& g = schedule.getGroup(gn, last);
|
|
const auto& children = g.wells();
|
|
if (!children.empty()) {
|
|
os << " \"" << gn << "\" -> {";
|
|
for (const auto& child : children) {
|
|
os << " \"" << child << '"';
|
|
}
|
|
os << " }\n";
|
|
}
|
|
}
|
|
// Color wells by injector or producer.
|
|
for (const auto& w : schedule.getWellsatEnd()) {
|
|
os << " \"" << w.name() << '"';
|
|
if (w.isProducer() && w.isInjector()) {
|
|
os << " [color=purple]\n";
|
|
} else if (w.isProducer()) {
|
|
os << " [color=red]\n";
|
|
} else {
|
|
os << " [color=blue]\n";
|
|
}
|
|
}
|
|
os << "}\n";
|
|
std::cout << "complete." << std::endl;
|
|
std::cout << "Convert output to PDF with 'dot -Tpdf " << casename << ".gv > " << casename << ".pdf'\n" << std::endl;
|
|
}
|
|
|
|
|
|
inline Opm::Schedule loadSchedule(const std::string& deck_file)
|
|
{
|
|
Opm::ParseContext parseContext({{Opm::ParseContext::PARSE_RANDOM_SLASH, Opm::InputErrorAction::IGNORE},
|
|
{Opm::ParseContext::PARSE_MISSING_DIMS_KEYWORD, Opm::InputErrorAction::WARN},
|
|
{Opm::ParseContext::SUMMARY_UNKNOWN_WELL, Opm::InputErrorAction::WARN},
|
|
{Opm::ParseContext::SUMMARY_UNKNOWN_GROUP, Opm::InputErrorAction::WARN}});
|
|
Opm::ErrorGuard errors;
|
|
Opm::Parser parser;
|
|
auto python = std::make_shared<Opm::Python>();
|
|
|
|
std::cout << "Loading and parsing deck: " << deck_file << " ..... "; std::cout.flush();
|
|
auto deck = parser.parseFile(deck_file, parseContext, errors);
|
|
std::cout << "complete.\n";
|
|
|
|
std::cout << "Creating EclipseState .... "; std::cout.flush();
|
|
Opm::EclipseState state( deck );
|
|
std::cout << "complete.\n";
|
|
|
|
std::cout << "Creating Schedule .... "; std::cout.flush();
|
|
Opm::Schedule schedule( deck, state, python);
|
|
std::cout << "complete." << std::endl;
|
|
|
|
return schedule;
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
std::ostringstream os;
|
|
std::shared_ptr<Opm::StreamLog> string_log = std::make_shared<Opm::StreamLog>(os, Opm::Log::DefaultMessageTypes);
|
|
Opm::OpmLog::addBackend( "STRING" , string_log);
|
|
try {
|
|
for (int iarg = 1; iarg < argc; iarg++) {
|
|
const std::string filename = argv[iarg];
|
|
const auto sched = loadSchedule(filename);
|
|
const auto casename = std::filesystem::path(filename).stem();
|
|
createDot(sched, casename);
|
|
}
|
|
} catch (const std::exception& e) {
|
|
std::cout << "\n\n***** Caught an exception: " << e.what() << std::endl;
|
|
std::cout << "\n\n***** Printing log: "<< std::endl;
|
|
std::cout << os.str();
|
|
std::cout << "\n\n***** Exiting due to errors." << std::endl;
|
|
}
|
|
}
|
|
|