mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-26 03:00:17 -06:00
276 lines
8.4 KiB
C++
276 lines
8.4 KiB
C++
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
// vi: set et ts=4 sw=4 sts=4:
|
|
/*
|
|
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 2 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/>.
|
|
|
|
Consult the COPYING file in the top-level source directory of this
|
|
module for the precise wording of the license and the list of
|
|
copyright holders.
|
|
*/
|
|
/*!
|
|
* \file
|
|
* \copydoc Opm::Restart
|
|
*/
|
|
#ifndef EWOMS_RESTART_HH
|
|
#define EWOMS_RESTART_HH
|
|
|
|
#include <string>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
|
|
namespace Opm {
|
|
|
|
/*!
|
|
* \brief Load or save a state of a problem to/from the harddisk.
|
|
*/
|
|
class Restart
|
|
{
|
|
/*!
|
|
* \brief Create a magic cookie for restart files, so that it is
|
|
* unlikely to load a restart file for an incorrectly.
|
|
*/
|
|
template <class GridView>
|
|
static const std::string magicRestartCookie_(const GridView& gridView)
|
|
{
|
|
static const std::string gridName = "blubb"; // gridView.grid().name();
|
|
static const int dim = GridView::dimension;
|
|
|
|
int numVertices = gridView.size(dim);
|
|
int numElements = gridView.size(0);
|
|
int numEdges = gridView.size(dim - 1);
|
|
int numCPUs = gridView.comm().size();
|
|
int rank = gridView.comm().rank();
|
|
|
|
std::ostringstream oss;
|
|
oss << "eWoms restart file: "
|
|
<< "gridName='" << gridName << "' "
|
|
<< "numCPUs=" << numCPUs << " "
|
|
<< "myRank=" << rank << " "
|
|
<< "numElements=" << numElements << " "
|
|
<< "numEdges=" << numEdges << " "
|
|
<< "numVertices=" << numVertices;
|
|
return oss.str();
|
|
}
|
|
|
|
/*!
|
|
* \brief Return the restart file name.
|
|
*/
|
|
template <class GridView, class Scalar>
|
|
static const std::string restartFileName_(const GridView& gridView,
|
|
const std::string& outputDir,
|
|
const std::string& simName,
|
|
Scalar t)
|
|
{
|
|
std::string dir = outputDir;
|
|
if (dir == ".")
|
|
dir = "";
|
|
else if (!dir.empty() && dir.back() != '/')
|
|
dir += "/";
|
|
|
|
int rank = gridView.comm().rank();
|
|
std::ostringstream oss;
|
|
oss << dir << simName << "_time=" << t << "_rank=" << rank << ".ers";
|
|
return oss.str();
|
|
}
|
|
|
|
public:
|
|
/*!
|
|
* \brief Returns the name of the file which is (de-)serialized.
|
|
*/
|
|
const std::string& fileName() const
|
|
{ return fileName_; }
|
|
|
|
/*!
|
|
* \brief Write the current state of the model to disk.
|
|
*/
|
|
template <class Simulator>
|
|
void serializeBegin(Simulator& simulator)
|
|
{
|
|
const std::string magicCookie = magicRestartCookie_(simulator.gridView());
|
|
fileName_ = restartFileName_(simulator.gridView(),
|
|
simulator.problem().outputDir(),
|
|
simulator.problem().name(),
|
|
simulator.time());
|
|
|
|
// open output file and write magic cookie
|
|
outStream_.open(fileName_.c_str());
|
|
outStream_.precision(20);
|
|
|
|
serializeSectionBegin(magicCookie);
|
|
serializeSectionEnd();
|
|
}
|
|
|
|
/*!
|
|
* \brief The output stream to write the serialized data.
|
|
*/
|
|
std::ostream& serializeStream()
|
|
{ return outStream_; }
|
|
|
|
/*!
|
|
* \brief Start a new section in the serialized output.
|
|
*/
|
|
void serializeSectionBegin(const std::string& cookie)
|
|
{ outStream_ << cookie << "\n"; }
|
|
|
|
/*!
|
|
* \brief End of a section in the serialized output.
|
|
*/
|
|
void serializeSectionEnd()
|
|
{ outStream_ << "\n"; }
|
|
|
|
/*!
|
|
* \brief Serialize all leaf entities of a codim in a gridView.
|
|
*
|
|
* The actual work is done by Serializer::serialize(Entity)
|
|
*/
|
|
template <int codim, class Serializer, class GridView>
|
|
void serializeEntities(Serializer& serializer, const GridView& gridView)
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "Entities: Codim " << codim;
|
|
std::string cookie = oss.str();
|
|
serializeSectionBegin(cookie);
|
|
|
|
// write element data
|
|
using Iterator = typename GridView::template Codim<codim>::Iterator;
|
|
|
|
Iterator it = gridView.template begin<codim>();
|
|
const Iterator& endIt = gridView.template end<codim>();
|
|
for (; it != endIt; ++it) {
|
|
serializer.serializeEntity(outStream_, *it);
|
|
outStream_ << "\n";
|
|
}
|
|
|
|
serializeSectionEnd();
|
|
}
|
|
|
|
/*!
|
|
* \brief Finish the restart file.
|
|
*/
|
|
void serializeEnd()
|
|
{ outStream_.close(); }
|
|
|
|
/*!
|
|
* \brief Start reading a restart file at a certain simulated
|
|
* time.
|
|
*/
|
|
template <class Simulator, class Scalar>
|
|
void deserializeBegin(Simulator& simulator, Scalar t)
|
|
{
|
|
fileName_ = restartFileName_(simulator.gridView(), simulator.problem().outputDir(), simulator.problem().name(), t);
|
|
|
|
// open input file and read magic cookie
|
|
inStream_.open(fileName_.c_str());
|
|
if (!inStream_.good()) {
|
|
throw std::runtime_error("Restart file '"+fileName_+"' could not be opened properly");
|
|
}
|
|
|
|
// make sure that we don't open an empty file
|
|
inStream_.seekg(0, std::ios::end);
|
|
auto pos = inStream_.tellg();
|
|
if (pos == 0) {
|
|
throw std::runtime_error("Restart file '"+fileName_+"' is empty");
|
|
}
|
|
inStream_.seekg(0, std::ios::beg);
|
|
|
|
const std::string magicCookie = magicRestartCookie_(simulator.gridView());
|
|
|
|
deserializeSectionBegin(magicCookie);
|
|
deserializeSectionEnd();
|
|
}
|
|
|
|
/*!
|
|
* \brief The input stream to read the data which ought to be
|
|
* deserialized.
|
|
*/
|
|
std::istream& deserializeStream()
|
|
{ return inStream_; }
|
|
|
|
/*!
|
|
* \brief Start reading a new section of the restart file.
|
|
*/
|
|
void deserializeSectionBegin(const std::string& cookie)
|
|
{
|
|
if (!inStream_.good())
|
|
throw std::runtime_error("Encountered unexpected EOF in restart file.");
|
|
std::string buf;
|
|
std::getline(inStream_, buf);
|
|
if (buf != cookie)
|
|
throw std::runtime_error("Could not start section '"+cookie+"'");
|
|
}
|
|
|
|
/*!
|
|
* \brief End of a section in the serialized output.
|
|
*/
|
|
void deserializeSectionEnd()
|
|
{
|
|
std::string dummy;
|
|
std::getline(inStream_, dummy);
|
|
for (unsigned i = 0; i < dummy.length(); ++i) {
|
|
if (!std::isspace(dummy[i])) {
|
|
throw std::logic_error("Encountered unread values while deserializing");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Deserialize all leaf entities of a codim in a grid.
|
|
*
|
|
* The actual work is done by Deserializer::deserialize(Entity)
|
|
*/
|
|
template <int codim, class Deserializer, class GridView>
|
|
void deserializeEntities(Deserializer& deserializer, const GridView& gridView)
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "Entities: Codim " << codim;
|
|
std::string cookie = oss.str();
|
|
deserializeSectionBegin(cookie);
|
|
|
|
std::string curLine;
|
|
|
|
// read entity data
|
|
using Iterator = typename GridView::template Codim<codim>::Iterator;
|
|
Iterator it = gridView.template begin<codim>();
|
|
const Iterator& endIt = gridView.template end<codim>();
|
|
for (; it != endIt; ++it) {
|
|
if (!inStream_.good()) {
|
|
throw std::runtime_error("Restart file is corrupted");
|
|
}
|
|
|
|
std::getline(inStream_, curLine);
|
|
std::istringstream curLineStream(curLine);
|
|
deserializer.deserializeEntity(curLineStream, *it);
|
|
}
|
|
|
|
deserializeSectionEnd();
|
|
}
|
|
|
|
/*!
|
|
* \brief Stop reading the restart file.
|
|
*/
|
|
void deserializeEnd()
|
|
{ inStream_.close(); }
|
|
|
|
private:
|
|
std::string fileName_;
|
|
std::ifstream inStream_;
|
|
std::ofstream outStream_;
|
|
};
|
|
} // namespace Opm
|
|
|
|
#endif
|