OutputStream::Restart: Pull File Creation Into Constructor

Then we don't have to store copies of the 'formatted' and 'unified'
flags, and are also able to remove the 'prepareStep()' function.  We
will reintroduce these features if we decide to add support for
keeping the output stream open between separate restart output
requests (i.e., between calls to EclipseIO::writeTimeStep()).
This commit is contained in:
Bård Skaflestad 2019-05-27 18:03:11 +02:00
parent df1a011b78
commit a2ec7d7f6d
3 changed files with 87 additions and 371 deletions

View File

@ -52,12 +52,23 @@ namespace Opm { namespace ecl { namespace OutputStream {
public:
/// Constructor.
///
/// Opens file stream pertaining to restart of particular report
/// step and also outputs a SEQNUM record in the case of a unified
/// output stream.
///
/// Must be called before accessing the stream object through the
/// stream() member function.
///
/// \param[in] rset Output directory and base name of output stream.
///
/// \param[in] seqnum Sequence number of new report. One-based
/// report step ID.
///
/// \param[in] fmt Whether or not to create formatted output files.
///
/// \param[in] unif Whether or not to create unified output files.
explicit Restart(ResultSet rset,
explicit Restart(const ResultSet& rset,
const int seqnum,
const Formatted& fmt,
const Unified& unif);
@ -69,32 +80,6 @@ namespace Opm { namespace ecl { namespace OutputStream {
Restart& operator=(const Restart& rhs) = delete;
Restart& operator=(Restart&& rhs);
/// Opens file stream pertaining to restart of particular report
/// step and also outputs a SEQNUM record in the case of a unified
/// output stream.
///
/// Must be called before accessing the stream object through the
/// stream() member function.
///
/// \param[in] seqnum Sequence number of new report. One-based
/// report step ID.
void prepareStep(const int seqnum);
const ResultSet& resultSetDescriptor() const
{
return this->rset_;
}
bool formatted() const
{
return this->formatted_;
}
bool unified() const
{
return this->unified_;
}
/// Generate a message string (keyword type 'MESS') in underlying
/// output stream.
///
@ -156,10 +141,6 @@ namespace Opm { namespace ecl { namespace OutputStream {
const std::vector<std::string>& data);
private:
ResultSet rset_;
bool formatted_;
bool unified_;
/// Restart output stream.
std::unique_ptr<EclOutput> stream_;
@ -170,9 +151,13 @@ namespace Opm { namespace ecl { namespace OutputStream {
///
/// \param[in] fname Filename of output stream.
///
/// \param[in] formatted Whether or not to create a
/// formatted output file.
///
/// \param[in] seqnum Sequence number of new report. One-based
/// report step ID.
void openUnified(const std::string& fname,
const bool formatted,
const int seqnum);
/// Open new output stream.
@ -181,7 +166,11 @@ namespace Opm { namespace ecl { namespace OutputStream {
/// that does not already exist. Writes to \c stream_.
///
/// \param[in] fname Filename of new output stream.
void openNew(const std::string& fname);
///
/// \param[in] formatted Whether or not to create a
/// formatted output file.
void openNew(const std::string& fname,
const bool formatted);
/// Open existing output file and place stream's output indicator
/// in appropriate location.
@ -194,6 +183,7 @@ namespace Opm { namespace ecl { namespace OutputStream {
/// indicator. Use \code streampos{ streamoff{-1} } \endcode to
/// place output indicator at end of file (i.e, simple append).
void openExisting(const std::string& fname,
const bool formatted,
const std::streampos writePos);
/// Access writable output stream.
@ -223,19 +213,6 @@ namespace Opm { namespace ecl { namespace OutputStream {
std::string outputFileName(const ResultSet& rsetDescriptor,
const std::string& ext);
/// Derive filename of restart output stream.
///
/// Knows the rules for formatted vs. unformatted, and separate vs.
/// unified output files.
///
/// \param[in] rst Previously configured restart stream.
///
/// \param[in] seqnum Sequence number (1-based report step ID).
///
/// \return Filename corresponding to stream's configuration.
std::string outputFileName(const Restart& rst,
const int seqnum);
}}} // namespace Opm::ecl::OutputStream
#endif // OPM_IO_OUTPUTSTREAM_HPP_INCLUDED

View File

@ -113,40 +113,19 @@ namespace {
} // Anonymous namespace
Opm::ecl::OutputStream::Restart::
Restart(ResultSet rset,
Restart(const ResultSet& rset,
const int seqnum,
const Formatted& fmt,
const Unified& unif)
: rset_ (std::move(rset))
, formatted_{fmt.set}
, unified_ {unif.set}
{}
Opm::ecl::OutputStream::Restart::~Restart()
{}
Opm::ecl::OutputStream::Restart::Restart(Restart&& rhs)
: rset_ (std::move(rhs.rset_))
, formatted_{rhs.formatted_}
, unified_ {rhs.unified_}
{}
Opm::ecl::OutputStream::Restart&
Opm::ecl::OutputStream::Restart::operator=(Restart&& rhs)
{
this->rset_ = std::move(rhs.rset_);
this->formatted_ = rhs.formatted_;
this->unified_ = rhs.unified_;
const auto ext = FileExtension::
restart(seqnum, fmt.set, unif.set);
return *this;
}
const auto fname = outputFileName(rset, ext);
void Opm::ecl::OutputStream::Restart::prepareStep(const int seqnum)
{
const auto fname = outputFileName(*this, seqnum);
if (this->unified_) {
if (unif.set) {
// Run uses unified restart files.
this->openUnified(fname, seqnum);
this->openUnified(fname, fmt.set, seqnum);
// Write SEQNUM value to stream to start new output sequence.
this->stream_->write("SEQNUM", std::vector<int>{ seqnum });
@ -154,10 +133,25 @@ void Opm::ecl::OutputStream::Restart::prepareStep(const int seqnum)
else {
// Run uses separate, not unified, restart files. Create a
// new output file and open an output stream on it.
this->openNew(fname);
this->openNew(fname, fmt.set);
}
}
Opm::ecl::OutputStream::Restart::~Restart()
{}
Opm::ecl::OutputStream::Restart::Restart(Restart&& rhs)
: stream_{ std::move(rhs.stream_) }
{}
Opm::ecl::OutputStream::Restart&
Opm::ecl::OutputStream::Restart::operator=(Restart&& rhs)
{
this->stream_ = std::move(rhs.stream_);
return *this;
}
void Opm::ecl::OutputStream::Restart::message(const std::string& msg)
{
this->stream().message(msg);
@ -201,6 +195,7 @@ write(const std::string& kw, const std::vector<std::string>& data)
void
Opm::ecl::OutputStream::Restart::
openUnified(const std::string& fname,
const bool formatted,
const int seqnum)
{
// Determine if we're creating a new output/restart file or
@ -210,7 +205,7 @@ openUnified(const std::string& fname,
if (rst == nullptr) {
// No such unified restart file exists. Create new file.
this->openNew(fname);
this->openNew(fname, formatted);
}
else if (! rst->hasKey("SEQNUM")) {
// File with correct filename exists but does not appear
@ -225,23 +220,26 @@ openUnified(const std::string& fname,
// Restart file exists and appears to be a unified restart
// resource. Open writable restart stream backed by the
// specific file.
this->openExisting(fname, rst->restartStepWritePosition(seqnum));
this->openExisting(fname, formatted,
rst->restartStepWritePosition(seqnum));
}
}
void
Opm::ecl::OutputStream::Restart::openNew(const std::string& fname)
Opm::ecl::OutputStream::Restart::
openNew(const std::string& fname,
const bool formatted)
{
this->stream_ = Open::Restart::writeNew(fname, this->formatted_);
this->stream_ = Open::Restart::writeNew(fname, formatted);
}
void
Opm::ecl::OutputStream::Restart::
openExisting(const std::string& fname,
const bool formatted,
const std::streampos writePos)
{
this->stream_ = Open::Restart::
writeExisting(fname, this->formatted_);
this->stream_ = Open::Restart::writeExisting(fname, formatted);
if (writePos == std::streampos(-1)) {
// No specified initial write position. Typically the case if
@ -307,13 +305,3 @@ Opm::ecl::OutputStream::outputFileName(const ResultSet& rsetDescriptor,
return (fs::path { rsetDescriptor.outputDir } / fname)
.generic().string();
}
std::string
Opm::ecl::OutputStream::outputFileName(const Restart& rst,
const int seqnum)
{
const auto ext = FileExtension::
restart(seqnum, rst.formatted(), rst.unified());
return outputFileName(rst.resultSetDescriptor(), ext);
}

View File

@ -125,262 +125,6 @@ BOOST_AUTO_TEST_CASE(ResultSetDescriptor)
}
}
BOOST_AUTO_TEST_CASE(Formatted_Separate)
{
const auto odir = std::string{"/x/y/z///"};
const auto seqnum = 123;
const auto fmt = ::Opm::ecl::OutputStream::Formatted{ true };
const auto unif = ::Opm::ecl::OutputStream::Unified { false };
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE"
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.F0123");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE." // CASE DOT
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.F0123");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE.01"
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.01.F0123");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE.01." // CASE.01 DOT
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.01.F0123");
}
}
BOOST_AUTO_TEST_CASE(Formatted_Unified)
{
const auto odir = std::string{"/x/y/z///"};
const auto seqnum = 123;
const auto fmt = ::Opm::ecl::OutputStream::Formatted{ true };
const auto unif = ::Opm::ecl::OutputStream::Unified { true };
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE"
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.FUNRST");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE." // CASE DOT
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.FUNRST");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE.01"
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.01.FUNRST");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE.01." // CASE.01 DOT
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.01.FUNRST");
}
}
BOOST_AUTO_TEST_CASE(Unformatted_Separate)
{
const auto odir = std::string{"/x/y/z///"};
const auto seqnum = 123;
const auto fmt = ::Opm::ecl::OutputStream::Formatted{ false };
const auto unif = ::Opm::ecl::OutputStream::Unified { false };
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE"
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.X0123");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE." // CASE DOT
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.X0123");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE.01"
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.01.X0123");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE.01." // CASE.01 DOT
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.01.X0123");
}
}
BOOST_AUTO_TEST_CASE(Unformatted_Unified)
{
const auto odir = std::string{"/x/y/z///"};
const auto seqnum = 123;
const auto fmt = ::Opm::ecl::OutputStream::Formatted{ false };
const auto unif = ::Opm::ecl::OutputStream::Unified { true };
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE"
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.UNRST");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE." // CASE DOT
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.UNRST");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE.01"
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.01.UNRST");
}
{
const auto rset = ::Opm::ecl::OutputStream::ResultSet {
odir, "CASE.01." // CASE.01 DOT
};
const auto rst = ::Opm::ecl::OutputStream::Restart {
rset, fmt, unif
};
const auto fname = outputFileName(rst, seqnum);
BOOST_CHECK_EQUAL(fname, odir + "CASE.01.UNRST");
}
}
BOOST_AUTO_TEST_SUITE_END() // FileName
// ==========================================================================
@ -420,9 +164,10 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified)
const auto unif = ::Opm::ecl::OutputStream::Unified { true };
{
auto rst = ::Opm::ecl::OutputStream::Restart{ rset, fmt, unif };
rst.prepareStep(1);
const auto seqnum = 1;
auto rst = ::Opm::ecl::OutputStream::Restart {
rset, seqnum, fmt, unif
};
rst.write("I", std::vector<int> {1, 7, 2, 9});
rst.write("L", std::vector<bool> {true, false, false, true});
@ -432,9 +177,10 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified)
}
{
auto rst = ::Opm::ecl::OutputStream::Restart{ rset, fmt, unif };
rst.prepareStep(13);
const auto seqnum = 13;
auto rst = ::Opm::ecl::OutputStream::Restart {
rset, seqnum, fmt, unif
};
rst.write("I", std::vector<int> {35, 51, 13});
rst.write("L", std::vector<bool> {true, true, true, false});
@ -529,9 +275,10 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified)
}
{
auto rst = ::Opm::ecl::OutputStream::Restart{ rset, fmt, unif };
rst.prepareStep(5); // Before 13. Should overwrite 13
const auto seqnum = 5; // Before 13. Should overwrite 13
auto rst = ::Opm::ecl::OutputStream::Restart {
rset, seqnum, fmt, unif
};
rst.write("I", std::vector<int> {1, 2, 3, 4});
rst.write("L", std::vector<bool> {false, false, false, true});
@ -627,9 +374,10 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified)
}
{
auto rst = ::Opm::ecl::OutputStream::Restart{ rset, fmt, unif };
rst.prepareStep(13);
const auto seqnum = 13;
auto rst = ::Opm::ecl::OutputStream::Restart {
rset, seqnum, fmt, unif
};
rst.write("I", std::vector<int> {35, 51, 13});
rst.write("L", std::vector<bool> {true, true, true, false});
@ -723,7 +471,6 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified)
expect_Z.end());
}
}
}
BOOST_AUTO_TEST_CASE(Formatted_Separate)
@ -733,9 +480,10 @@ BOOST_AUTO_TEST_CASE(Formatted_Separate)
const auto unif = ::Opm::ecl::OutputStream::Unified { false };
{
auto rst = ::Opm::ecl::OutputStream::Restart{ rset, fmt, unif };
rst.prepareStep(1);
const auto seqnum = 1;
auto rst = ::Opm::ecl::OutputStream::Restart {
rset, seqnum, fmt, unif
};
rst.write("I", std::vector<int> {1, 7, 2, 9});
rst.write("L", std::vector<bool> {true, false, false, true});
@ -745,9 +493,10 @@ BOOST_AUTO_TEST_CASE(Formatted_Separate)
}
{
auto rst = ::Opm::ecl::OutputStream::Restart{ rset, fmt, unif };
rst.prepareStep(13);
const auto seqnum = 13;
auto rst = ::Opm::ecl::OutputStream::Restart {
rset, seqnum, fmt, unif
};
rst.write("I", std::vector<int> {35, 51, 13});
rst.write("L", std::vector<bool> {true, true, true, false});
@ -760,7 +509,7 @@ BOOST_AUTO_TEST_CASE(Formatted_Separate)
using ::Opm::ecl::OutputStream::Restart;
const auto fname = ::Opm::ecl::OutputStream::
outputFileName(Restart{rset, fmt, unif}, 13);
outputFileName(rset, "F0013");
auto rst = ::Opm::ecl::EclFile{fname};
@ -832,9 +581,11 @@ BOOST_AUTO_TEST_CASE(Formatted_Separate)
}
{
auto rst = ::Opm::ecl::OutputStream::Restart{ rset, fmt, unif };
rst.prepareStep(5); // Separate output. Step 13 should be unaffected.
// Separate output. Step 13 should be unaffected.
const auto seqnum = 5;
auto rst = ::Opm::ecl::OutputStream::Restart {
rset, seqnum, fmt, unif
};
rst.write("I", std::vector<int> {1, 2, 3, 4});
rst.write("L", std::vector<bool> {false, false, false, true});
@ -847,7 +598,7 @@ BOOST_AUTO_TEST_CASE(Formatted_Separate)
using ::Opm::ecl::OutputStream::Restart;
const auto fname = ::Opm::ecl::OutputStream::
outputFileName(Restart{rset, fmt, unif}, 5);
outputFileName(rset, "F0005");
auto rst = ::Opm::ecl::EclFile{fname};
@ -926,7 +677,7 @@ BOOST_AUTO_TEST_CASE(Formatted_Separate)
using ::Opm::ecl::OutputStream::Restart;
const auto fname = ::Opm::ecl::OutputStream::
outputFileName(Restart{rset, fmt, unif}, 13);
outputFileName(rset, "F0013");
auto rst = ::Opm::ecl::EclFile{fname};