diff --git a/ProcessLib/Output/CreateOutput.cpp b/ProcessLib/Output/CreateOutput.cpp index 2c11d520a0e8023be32fd47bbc111d520ec96627..119df26d4a0dc8ad631cd94ceb6b141cbd244f33 100644 --- a/ProcessLib/Output/CreateOutput.cpp +++ b/ProcessLib/Output/CreateOutput.cpp @@ -48,14 +48,29 @@ int convertVtkDataMode(std::string const& data_mode) namespace ProcessLib { std::unique_ptr<OutputFile> createOutputFile( - std::string&& output_directory, OutputType const output_type, - std::string&& prefix, std::string&& suffix, bool const compress_output, - unsigned int const number_of_files, std::string const& data_mode) + std::string const& output_directory, OutputType const output_type, + std::string&& prefix, std::string&& suffix, std::string const& data_mode, + bool const compress_output, unsigned int const number_of_files) { - return std::make_unique<OutputFile>( - std::move(output_directory), output_type, std::move(prefix), - std::move(suffix), convertVtkDataMode(data_mode), compress_output, - number_of_files); + if (output_type == OutputType::vtk) + { + return std::make_unique<OutputVtkFormat>( + output_directory, std::move(prefix), std::move(suffix), + convertVtkDataMode(data_mode), compress_output, number_of_files); + } + if (output_type == OutputType::xdmf) + { + return std::make_unique<OutputXDMFHDF5Format>( + output_directory, std::move(prefix), std::move(suffix), + convertVtkDataMode(data_mode), compress_output, number_of_files); + } + else + { + OGS_FATAL( + "No supported file type provided. Read `{:s}' from <output><type> \ + in prj File. Supported: VTK, XDMF.", + output_type); + } } std::unique_ptr<Output> createOutput( @@ -207,9 +222,9 @@ std::unique_ptr<Output> createOutput( //! \ogs_file_param{prj__time_loop__output__output_iteration_results} config.getConfigParameter<bool>("output_iteration_results", false); - OutputFile output_file(output_directory, output_type, prefix, suffix, - convertVtkDataMode(data_mode), compress_output, - number_of_files); + auto output_file = createOutputFile( + output_directory, output_type, std::move(prefix), std::move(suffix), + data_mode, compress_output, number_of_files); return std::make_unique<Output>(std::move(output_file), output_iteration_results, diff --git a/ProcessLib/Output/Output.cpp b/ProcessLib/Output/Output.cpp index 22d4af43be7921d7bd1a4063b1c26163429eb0c0..727b23be82045fd174b22742df38d7bc8ab37c5e 100644 --- a/ProcessLib/Output/Output.cpp +++ b/ProcessLib/Output/Output.cpp @@ -149,7 +149,7 @@ bool Output::isOutputProcess(const int process_id, const Process& process) const || is_last_process; } -Output::Output(OutputFile&& output_file, +Output::Output(std::unique_ptr<OutputFile> output_file, bool const output_nonlinear_iteration_results, OutputDataSpecification&& output_data_specification, std::vector<std::string>&& mesh_names_for_output, @@ -171,7 +171,7 @@ void Output::addProcess(ProcessLib::Process const& process) for (auto const& mesh_output_name : _mesh_names_for_output) { - auto const filename = output_file.constructPVDName(mesh_output_name); + auto const filename = output_file->constructPVDName(mesh_output_name); _process_to_pvd_file.emplace(std::piecewise_construct, std::forward_as_tuple(&process), std::forward_as_tuple(filename)); @@ -183,21 +183,22 @@ void Output::outputMeshes( const double t, const int iteration, std::vector<std::reference_wrapper<const MeshLib::Mesh>> meshes) { - if (output_file.type == ProcessLib::OutputType::vtk) + if (output_file->type == ProcessLib::OutputType::vtk) { for (auto const& mesh : meshes) { auto const filename = - output_file.constructPVDName(mesh.get().getName()); + output_file->constructPVDName(mesh.get().getName()); auto& pvd_file = findPVDFile(process, process_id, filename, _process_to_pvd_file); - outputMeshVtk(output_file, pvd_file, mesh, t, timestep, iteration); + outputMeshVtk(*output_file.get(), pvd_file, mesh, t, timestep, + iteration); } } - else if (output_file.type == ProcessLib::OutputType::xdmf) + else if (output_file->type == ProcessLib::OutputType::xdmf) { - output_file.outputMeshXdmf(_output_data_specification.output_variables, - std::move(meshes), timestep, t, iteration); + output_file->outputMeshXdmf(_output_data_specification.output_variables, + std::move(meshes), timestep, t, iteration); } } @@ -301,7 +302,7 @@ void Output::doOutput(Process const& process, // Note: last time step may be output twice: here and in // doOutputLastTimestep() which throws a warning. InSituLib::CoProcess(process.getMesh(), t, timestep, false, - output_file.directory); + output_file->directory); #endif } @@ -318,7 +319,7 @@ void Output::doOutputLastTimestep(Process const& process, } #ifdef USE_INSITU InSituLib::CoProcess(process.getMesh(), t, timestep, true, - output_file.directory); + output_file->directory); #endif } @@ -348,15 +349,15 @@ void Output::doOutputNonlinearIteration(Process const& process, return; } - std::string const output_file_name = output_file.constructFilename( + std::string const output_file_name = output_file->constructFilename( process.getMesh().getName(), timestep, t, iteration); std::string const output_file_path = - BaseLib::joinPaths(output_file.directory, output_file_name); + BaseLib::joinPaths(output_file->directory, output_file_name); DBUG("output iteration results to {:s}", output_file_path); - outputMeshVtk(output_file_path, process.getMesh(), output_file.compression, - output_file.data_mode); + outputMeshVtk(output_file_path, process.getMesh(), output_file->compression, + output_file->data_mode); INFO("[time] Output took {:g} s.", time_output.elapsed()); } } // namespace ProcessLib diff --git a/ProcessLib/Output/Output.h b/ProcessLib/Output/Output.h index 748828c47cf1dd5ba3b850fd5394332816526531..211a01ffc159b57a521b4ccab17c000494db8c2b 100644 --- a/ProcessLib/Output/Output.h +++ b/ProcessLib/Output/Output.h @@ -32,7 +32,7 @@ class Process; class Output { public: - Output(OutputFile&& output_file, + Output(std::unique_ptr<OutputFile> output_file, bool const output_nonlinear_iteration_results, OutputDataSpecification&& output_data_specification, std::vector<std::string>&& mesh_names_for_output, @@ -93,7 +93,7 @@ private: const int process_id, double const t, std::vector<GlobalVector*> const& xs) const; - OutputFile output_file; + std::unique_ptr<OutputFile> output_file; bool const _output_nonlinear_iteration_results; diff --git a/ProcessLib/Output/OutputFile.cpp b/ProcessLib/Output/OutputFile.cpp index 4cfb64b79b572c11ed2fcdfb115f3cf0e1234164..24dffcf8105efb3253b535ca66f1272b07e9d8c9 100644 --- a/ProcessLib/Output/OutputFile.cpp +++ b/ProcessLib/Output/OutputFile.cpp @@ -83,30 +83,26 @@ OutputFile::OutputFile(std::string const& directory, OutputType const type, { } -std::string OutputFile::constructFilename(std::string mesh_name, - int const timestep, - double const t, - int const iteration) const +std::string OutputVtkFormat::constructFilename(std::string mesh_name, + int const timestep, + double const t, + int const iteration) const { - std::map<OutputType, std::string> filetype_to_extension = { - {OutputType::vtk, "vtu"}, {OutputType::xdmf, "xdmf"}}; + return BaseLib::constructFormattedFileName(prefix, mesh_name, timestep, t, + iteration) + + BaseLib::constructFormattedFileName(suffix, mesh_name, timestep, t, + iteration) + + ".vtu"; +} - try - { - std::string extension = filetype_to_extension.at(type); - return BaseLib::constructFormattedFileName(prefix, mesh_name, timestep, - t, iteration) + - BaseLib::constructFormattedFileName(suffix, mesh_name, timestep, - t, iteration) + - "." + extension; - } - catch (std::out_of_range&) - { - OGS_FATAL( - "No supported file type provided. Read `{:s}' from <output><type> \ - in prj file. Supported: VTK, XDMF.", - type); - } +std::string OutputXDMFHDF5Format::constructFilename(std::string mesh_name, + int const timestep, + double const t, + int const iteration) const +{ + return BaseLib::constructFormattedFileName(prefix, mesh_name, timestep, t, + iteration) + + ".xdmf"; } void OutputFile::outputMeshXdmf( diff --git a/ProcessLib/Output/OutputFile.h b/ProcessLib/Output/OutputFile.h index bc74d335675083f93d3ff321701672bdbb3ea4d4..bcf49c479dc29997d1ced36cc539fc60fe873504 100644 --- a/ProcessLib/Output/OutputFile.h +++ b/ProcessLib/Output/OutputFile.h @@ -29,6 +29,7 @@ struct OutputFile std::string const& prefix, std::string const& suffix, int const data_mode_, bool const compression_, unsigned int const n_files); + virtual ~OutputFile() = default; std::string directory; std::string prefix; @@ -48,8 +49,9 @@ struct OutputFile //! Specifies the number of hdf5 output files. unsigned int const n_files; - std::string constructFilename(std::string mesh_name, int const timestep, - double const t, int const iteration) const; + virtual std::string constructFilename(std::string mesh_name, + int const timestep, double const t, + int const iteration) const = 0; void outputMeshXdmf( std::set<std::string> const& output_variables, @@ -59,6 +61,48 @@ struct OutputFile std::string constructPVDName(std::string const& mesh_name) const; }; +struct OutputVtkFormat final : public OutputFile +{ + OutputVtkFormat(std::string const& directory, std::string const& prefix, + std::string const& suffix, int const data_mode, + bool const compression, const int number_of_files) + : OutputFile(directory, OutputType::vtk, prefix, suffix, data_mode, + compression, number_of_files) + { + } + + //! Chooses vtk's data mode for output following the enumeration given + /// in the vtkXMLWriter: {Ascii, Binary, Appended}. See vtkXMLWriter + /// documentation + /// http://www.vtk.org/doc/nightly/html/classvtkXMLWriter.html + // int const data_mode; + + //! Enables or disables zlib-compression of the output files. + // bool const compression; + + std::string constructFilename(std::string mesh_name, int const timestep, + double const t, + int const iteration) const override; + + // std::string constructPVDName(std::string const& mesh_name) const; +}; + +struct OutputXDMFHDF5Format final : public OutputFile +{ + OutputXDMFHDF5Format(std::string const& directory, + std::string const& prefix, std::string const& suffix, + int const data_mode, bool const compression, + unsigned int const n_files) + : OutputFile(directory, OutputType::xdmf, prefix, suffix, data_mode, + compression, n_files) + { + } + + std::string constructFilename(std::string mesh_name, int const timestep, + double const t, + int const iteration) const override; +}; + void outputMeshVtk(std::string const& file_name, MeshLib::Mesh const& mesh, bool const compress_output, int const data_mode); } // namespace ProcessLib