From 42ebaa045c27b3dcb28921996dc2c01c4f22a228 Mon Sep 17 00:00:00 2001 From: Elias Pipping <elias.pipping@fu-berlin.de> Date: Sun, 30 Apr 2017 20:34:15 +0200 Subject: [PATCH] [Output] Overhaul writer logic, rename writeVTK - The configuration parameter io.writeVTK is now io.vtk.write - The configuration parameters restarts.first and restarts.spacing were moved into the io namespace - Restarts are stored in a separate file - VTK data, restarts (in HDF5), and the other HDF5 data are now each controlled through a parameter: io.data.write, io.restarts.write, io.vtk.write In particular, it is thus now possible to write VTK data while opening the data and restart files in read-only mode (or not at all); This makes it possible to, by keeping the restarts file (and the binary!) around, quickly (re-)compute a a small segment from the history. The likeliest scenario: VTK files are huge and for a computation with tens of thousands of timesteps (e.g. 30000), we know already (from the data, or just expect it) that an event occurred during the last 500 timesteps. So we recompute them from a restart in the following mode: -io.restarts.first 29500 -io.restarts.write false -io.data.write false -io.vtk.write true Note that care needs to be taken to use a number for io.restarts.first which is compatible with the old io.restarts.spacing --- src/hdf5-writer.hh | 11 ++----- src/hdf5/restart-io.cc | 17 +++++----- src/hdf5/restart-io.hh | 4 +-- src/one-body-problem.cc | 68 ++++++++++++++++++++++++++-------------- src/one-body-problem.cfg | 11 +++---- 5 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/hdf5-writer.hh b/src/hdf5-writer.hh index 02de2b27..85a08e1e 100644 --- a/src/hdf5-writer.hh +++ b/src/hdf5-writer.hh @@ -8,7 +8,6 @@ #include "hdf5/frictionalboundary-writer.hh" #include "hdf5/iteration-writer.hh" #include "hdf5/patchinfo-writer.hh" -#include "hdf5/restart-io.hh" #include "hdf5/surface-writer.hh" #include "hdf5/time-writer.hh" @@ -32,8 +31,8 @@ class HDF5Writer { patchInfoWriter_(file_, vertexBasis, frictionalBoundary, weakPatch), #endif surfaceWriter_(file_, vertexCoordinates, surface), - frictionalBoundaryWriter_(file_, vertexCoordinates, frictionalBoundary), - restartWriter_(file_, vertexCoordinates.size()) { + frictionalBoundaryWriter_(file_, vertexCoordinates, + frictionalBoundary) { } template <class Friction> @@ -53,10 +52,6 @@ class HDF5Writer { iterationWriter_.write(programState.timeStep, iterationCount); } - void writeRestart(ProgramState const &programState) { - restartWriter_.write(programState); - } - private: HDF5::Grouplike &file_; @@ -67,7 +62,5 @@ class HDF5Writer { #endif SurfaceWriter<ProgramState, GridView> surfaceWriter_; FrictionalBoundaryWriter<ProgramState, GridView> frictionalBoundaryWriter_; - - RestartIO<ProgramState> restartWriter_; }; #endif diff --git a/src/hdf5/restart-io.cc b/src/hdf5/restart-io.cc index 8fe3c59a..5143947d 100644 --- a/src/hdf5/restart-io.cc +++ b/src/hdf5/restart-io.cc @@ -5,18 +5,17 @@ #include "restart-io.hh" template <class ProgramState> -RestartIO<ProgramState>::RestartIO(HDF5::Grouplike &file, size_t vertexCount) - : group_(file, "restarts"), - displacementWriter_(group_, "displacement", vertexCount, +RestartIO<ProgramState>::RestartIO(HDF5::Grouplike &group, size_t vertexCount) + : displacementWriter_(group, "displacement", vertexCount, Vector::block_type::dimension), - velocityWriter_(group_, "velocity", vertexCount, + velocityWriter_(group, "velocity", vertexCount, Vector::block_type::dimension), - accelerationWriter_(group_, "acceleration", vertexCount, + accelerationWriter_(group, "acceleration", vertexCount, Vector::block_type::dimension), - stateWriter_(group_, "state", vertexCount), - weightedNormalStressWriter_(group_, "weightedNormalStress", vertexCount), - relativeTimeWriter_(group_, "relativeTime"), - relativeTimeIncrementWriter_(group_, "relativeTimeIncrement") {} + stateWriter_(group, "state", vertexCount), + weightedNormalStressWriter_(group, "weightedNormalStress", vertexCount), + relativeTimeWriter_(group, "relativeTime"), + relativeTimeIncrementWriter_(group, "relativeTimeIncrement") {} template <class ProgramState> void RestartIO<ProgramState>::write(ProgramState const &programState) { diff --git a/src/hdf5/restart-io.hh b/src/hdf5/restart-io.hh index 94b60d67..f90b01a7 100644 --- a/src/hdf5/restart-io.hh +++ b/src/hdf5/restart-io.hh @@ -9,15 +9,13 @@ template <class ProgramState> class RestartIO { using Vector = typename ProgramState::Vector; public: - RestartIO(HDF5::Grouplike &file, size_t vertexCount); + RestartIO(HDF5::Grouplike &group, size_t vertexCount); void write(ProgramState const &programState); void read(size_t timeStep, ProgramState &programState); private: - HDF5::Group group_; - HDF5::SequenceIO<2> displacementWriter_; HDF5::SequenceIO<2> velocityWriter_; HDF5::SequenceIO<2> accelerationWriter_; diff --git a/src/one-body-problem.cc b/src/one-body-problem.cc index 14139f80..d4d5ed56 100644 --- a/src/one-body-problem.cc +++ b/src/one-body-problem.cc @@ -176,15 +176,29 @@ int main(int argc, char *argv[]) { _ell += gravityFunctional; }; - ProgramState<Vector, ScalarVector> programState(leafVertexCount); - auto const firstRestart = parset.get<size_t>("restarts.first"); - auto const restartSpacing = parset.get<size_t>("restarts.spacing"); - auto const restartTemplate = parset.get<std::string>("restarts.template"); - - HDF5::File ioFile("output.h5"); - if (firstRestart != 0) - RestartIO<ProgramState<Vector, ScalarVector>>(ioFile, leafVertexCount) - .read(firstRestart, programState); + using MyProgramState = ProgramState<Vector, ScalarVector>; + MyProgramState programState(leafVertexCount); + auto const firstRestart = parset.get<size_t>("io.restarts.first"); + auto const restartSpacing = parset.get<size_t>("io.restarts.spacing"); + auto const writeRestarts = parset.get<bool>("io.restarts.write"); + auto const writeData = parset.get<bool>("io.data.write"); + bool const handleRestarts = writeRestarts or firstRestart > 0; + + auto dataFile = + writeData ? std::make_unique<HDF5::File>("output.h5") : nullptr; + auto restartFile = handleRestarts + ? std::make_unique<HDF5::File>( + "restarts.h5", + writeRestarts ? HDF5::Access::READWRITE + : HDF5::Access::READONLY) + : nullptr; + auto restartIO = handleRestarts + ? std::make_unique<RestartIO<MyProgramState>>( + *restartFile, leafVertexCount) + : nullptr; + + if (firstRestart > 0) // automatically adjusts the time and timestep + restartIO->read(firstRestart, programState); else programState.setupInitialConditions(parset, computeExternalForces, matrices, myAssembler, dirichletNodes, @@ -205,24 +219,30 @@ int main(int argc, char *argv[]) { vertexCoordinates[vertexMapper.index(v)] = geoToPoint(v.geometry()); } - HDF5Writer<ProgramState<Vector, ScalarVector>, - typename MyAssembler::VertexBasis, GridView> - hdf5Writer(ioFile, vertexCoordinates, myAssembler.vertexBasis, surface, - frictionalBoundary, weakPatch); - MyVTKWriter<typename MyAssembler::VertexBasis, - typename MyAssembler::CellBasis> const - vtkWriter(myAssembler.cellBasis, myAssembler.vertexBasis, "obs"); + using MyVertexBasis = typename MyAssembler::VertexBasis; + auto dataWriter = + writeData ? std::make_unique< + HDF5Writer<MyProgramState, MyVertexBasis, GridView>>( + *dataFile, vertexCoordinates, myAssembler.vertexBasis, + surface, frictionalBoundary, weakPatch) + : nullptr; + MyVTKWriter<MyVertexBasis, typename MyAssembler::CellBasis> const vtkWriter( + myAssembler.cellBasis, myAssembler.vertexBasis, "obs"); IterationRegister iterationCount; auto const report = [&](bool initial = false) { - hdf5Writer.reportSolution(programState, *myGlobalFriction); - if (!initial) - hdf5Writer.reportIterations(programState, iterationCount); - - if (!initial and programState.timeStep % restartSpacing == 0) - hdf5Writer.writeRestart(programState); + if (writeData) { + dataWriter->reportSolution(programState, *myGlobalFriction); + if (!initial) + dataWriter->reportIterations(programState, iterationCount); + dataFile->flush(); + } - ioFile.flush(); + if (writeRestarts and !initial and + programState.timeStep % restartSpacing == 0) { + restartIO->write(programState); + restartFile->flush(); + } if (parset.get<bool>("io.printProgress")) std::cout << "timeStep = " << std::setw(6) << programState.timeStep @@ -230,7 +250,7 @@ int main(int argc, char *argv[]) { << ", tau = " << std::setw(12) << programState.relativeTau << std::endl; - if (parset.get<bool>("io.writeVTK")) { + if (parset.get<bool>("io.vtk.write")) { ScalarVector stress; myAssembler.assembleVonMisesStress(body.getYoungModulus(), body.getPoissonRatio(), diff --git a/src/one-body-problem.cfg b/src/one-body-problem.cfg index 21c7d5fc..d970f5e9 100644 --- a/src/one-body-problem.cfg +++ b/src/one-body-problem.cfg @@ -2,8 +2,12 @@ gravity = 9.81 # [m/s^2] [io] +data.write = true printProgress = false -writeVTK = false +restarts.first = 0 +restarts.spacing= 20 +restarts.write = true +vtk.write = false [problem] finalTime = 1000 # [s] @@ -35,11 +39,6 @@ b = 0.017 # [ ] a = 0.020 # [ ] b = 0.005 # [ ] -[restarts] -template = restart_%06d -first = 0 -spacing = 20 - [timeSteps] scheme = newmark -- GitLab