OGS
ProcessLib::Output Class Reference

Detailed Description

Manages writing the solution of processes to disk.

This class decides at which timesteps output is written and initiates the writing process.

Definition at line 29 of file ProcessLib/Output/Output.h.

#include <Output.h>

Collaboration diagram for ProcessLib::Output:
[legend]

Public Member Functions

 Output (std::unique_ptr< OutputFormat > &&output_format, bool const output_nonlinear_iteration_results, OutputDataSpecification &&output_data_specification, std::vector< std::string > &&mesh_names_for_output, std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
 Output (Output const &other)=delete
 Output (Output &&other)=default
Outputoperator= (Output const &src)=delete
Outputoperator= (Output &&src)=default
 ~Output ()=default
void addProcess (ProcessLib::Process const &process)
 TODO doc. Opens a PVD file for each process.
void doNotProjectFromBulkMeshToSubmeshes (std::string const &property_name, MeshLib::MeshItemType const mesh_item_type)
void doOutput (Process const &process, const int process_id, int const timestep, const NumLib::Time &t, int const iteration, bool const converged, std::vector< GlobalVector * > const &xs) const
void doOutputLastTimestep (Process const &process, const int process_id, int const timestep, const NumLib::Time &t, int const iteration, bool const converged, std::vector< GlobalVector * > const &xs) const
void doOutputAlways (Process const &process, const int process_id, int const timestep, const NumLib::Time &t, int const iteration, bool const converged, std::vector< GlobalVector * > const &xs) const
void doOutputNonlinearIteration (Process const &process, const int process_id, int const timestep, const NumLib::Time &t, const int iteration, bool const converged, std::vector< GlobalVector * > const &xs) const
bool isOutputStep (int const timestep, NumLib::Time const &t) const
 Tells if output will be written at the specified timestep/time.
std::vector< double > const & getFixedOutputTimes () const
std::vector< std::string > getFileNamesForOutput () const

Private Member Functions

bool isOutputProcess (int const process_id, Process const &process) const
void outputMeshes (int const timestep, const double t, int const iteration, bool const converged, std::vector< std::reference_wrapper< const MeshLib::Mesh > > const &meshes) const
MeshLib::Mesh const & prepareSubmesh (std::string const &submesh_output_name, Process const &process, const int process_id, NumLib::Time const &t, std::vector< GlobalVector * > const &xs) const

Private Attributes

std::unique_ptr< OutputFormat_output_format
bool _output_nonlinear_iteration_results
OutputDataSpecification _output_data_specification
std::vector< std::reference_wrapper< Process const > > _output_processes
std::vector< std::string > _mesh_names_for_output
std::reference_wrapper< std::vector< std::unique_ptr< MeshLib::Mesh > > const > _meshes
std::set< std::pair< std::string, MeshLib::MeshItemType > > _do_not_project_from_bulk_mesh_to_submeshes

Friends

std::ostream & operator<< (std::ostream &os, Output const &output)

Constructor & Destructor Documentation

◆ Output() [1/3]

ProcessLib::Output::Output ( std::unique_ptr< OutputFormat > && output_format,
bool const output_nonlinear_iteration_results,
OutputDataSpecification && output_data_specification,
std::vector< std::string > && mesh_names_for_output,
std::vector< std::unique_ptr< MeshLib::Mesh > > const & meshes )

Definition at line 140 of file ProcessLib/Output/Output.cpp.

145 : _output_format(std::move(output_format)),
146 _output_nonlinear_iteration_results(output_nonlinear_iteration_results),
147 _output_data_specification(std::move(output_data_specification)),
148 _mesh_names_for_output(std::move(mesh_names_for_output)),
149 _meshes(meshes)
150{
151}
std::reference_wrapper< std::vector< std::unique_ptr< MeshLib::Mesh > > const > _meshes
std::vector< std::string > _mesh_names_for_output
OutputDataSpecification _output_data_specification
std::unique_ptr< OutputFormat > _output_format

References _mesh_names_for_output, _meshes, _output_data_specification, _output_format, and _output_nonlinear_iteration_results.

Referenced by Output(), Output(), operator<<, operator=(), and operator=().

◆ Output() [2/3]

ProcessLib::Output::Output ( Output const & other)
delete

References Output().

◆ Output() [3/3]

ProcessLib::Output::Output ( Output && other)
default

References Output().

◆ ~Output()

ProcessLib::Output::~Output ( )
default

Member Function Documentation

◆ addProcess()

void ProcessLib::Output::addProcess ( ProcessLib::Process const & process)

TODO doc. Opens a PVD file for each process.

Definition at line 153 of file ProcessLib/Output/Output.cpp.

154{
155 _output_processes.push_back(process);
156 if (_mesh_names_for_output.empty())
157 {
158 _mesh_names_for_output.push_back(process.getMesh().getName());
159 }
160}
std::vector< std::reference_wrapper< Process const > > _output_processes

References _mesh_names_for_output, _output_processes, ProcessLib::Process::getMesh(), and MeshLib::Mesh::getName().

◆ doNotProjectFromBulkMeshToSubmeshes()

void ProcessLib::Output::doNotProjectFromBulkMeshToSubmeshes ( std::string const & property_name,
MeshLib::MeshItemType const mesh_item_type )

Declare that the specified mesh property should not be projected from the bulk mesh to submeshes during submesh output.

Definition at line 162 of file ProcessLib/Output/Output.cpp.

165{
167 mesh_item_type);
168}
std::set< std::pair< std::string, MeshLib::MeshItemType > > _do_not_project_from_bulk_mesh_to_submeshes

References _do_not_project_from_bulk_mesh_to_submeshes.

◆ doOutput()

void ProcessLib::Output::doOutput ( Process const & process,
const int process_id,
int const timestep,
const NumLib::Time & t,
int const iteration,
bool const converged,
std::vector< GlobalVector * > const & xs ) const

Writes output for the given process if it should be written in the given timestep.

Definition at line 331 of file ProcessLib/Output/Output.cpp.

338{
339 if (isOutputStep(timestep, t))
340 {
341 doOutputAlways(process, process_id, timestep, t, iteration, converged,
342 xs);
343 }
344#ifdef OGS_USE_INSITU
345 // Note: last time step may be output twice: here and in
346 // doOutputLastTimestep() which throws a warning.
347 InSituLib::CoProcess(process.getMesh(), t, timestep, false,
348 _output_format->directory);
349#endif
350}
void doOutputAlways(Process const &process, const int process_id, int const timestep, const NumLib::Time &t, int const iteration, bool const converged, std::vector< GlobalVector * > const &xs) const
bool isOutputStep(int const timestep, NumLib::Time const &t) const
Tells if output will be written at the specified timestep/time.
void CoProcess(MeshLib::Mesh const &mesh, double const time, unsigned int const timeStep, bool const lastTimeStep, std::string output_directory)
Definition Adaptor.cpp:63

References _output_format, InSituLib::CoProcess(), doOutputAlways(), ProcessLib::Process::getMesh(), and isOutputStep().

Referenced by ProcessLib::TimeLoop::calculateNextTimeStep(), and ProcessLib::TimeLoop::initialize().

◆ doOutputAlways()

void ProcessLib::Output::doOutputAlways ( Process const & process,
const int process_id,
int const timestep,
const NumLib::Time & t,
int const iteration,
bool const converged,
std::vector< GlobalVector * > const & xs ) const

Writes output for the given process. This method will always write. It is intended to write output in error handling routines.

Definition at line 283 of file ProcessLib/Output/Output.cpp.

290{
291 BaseLib::RunTime time_output;
292 time_output.start();
293
294 bool const output_secondary_variables = true;
295 auto const process_output_data =
296 createProcessOutputData(process, xs.size(), process.getMesh());
297
298 // Need to add variables of process to mesh even if no output takes place.
299 addProcessDataToMesh(t, xs, process_id, process_output_data,
300 output_secondary_variables,
302
303 if (!isOutputProcess(process_id, process))
304 {
305 return;
306 }
307
308 std::vector<std::reference_wrapper<const MeshLib::Mesh>> output_meshes;
309 for (auto const& mesh_output_name : _mesh_names_for_output)
310 {
311 if (process.getMesh().getName() == mesh_output_name)
312 {
313 // process related output
314 output_meshes.emplace_back(process.getMesh());
315 }
316 else
317 {
318 // mesh related output
319 auto const& submesh =
320 prepareSubmesh(mesh_output_name, process, process_id, t, xs);
321 output_meshes.emplace_back(submesh);
322 }
323 }
324
325 outputMeshes(timestep, t(), iteration, converged, std::move(output_meshes));
326
327 INFO("[time] Output of timestep {:d} took {:g} s.", timestep,
328 time_output.elapsed());
329}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:31
void start()
Start the timer.
Definition RunTime.h:21
void outputMeshes(int const timestep, const double t, int const iteration, bool const converged, std::vector< std::reference_wrapper< const MeshLib::Mesh > > const &meshes) const
MeshLib::Mesh const & prepareSubmesh(std::string const &submesh_output_name, Process const &process, const int process_id, NumLib::Time const &t, std::vector< GlobalVector * > const &xs) const
bool isOutputProcess(int const process_id, Process const &process) const
void addProcessDataToMesh(NumLib::Time const &t, std::vector< GlobalVector * > const &xs, int const process_id, ProcessOutputData const &process_output_data, bool const output_secondary_variables, OutputDataSpecification const &process_output)
ProcessOutputData createProcessOutputData(Process const &process, std::size_t const n_processes, MeshLib::Mesh &output_mesh)
Extracts data necessary for output from the given process.

References _mesh_names_for_output, _output_data_specification, ProcessLib::addProcessDataToMesh(), ProcessLib::createProcessOutputData(), BaseLib::RunTime::elapsed(), ProcessLib::Process::getMesh(), MeshLib::Mesh::getName(), INFO(), isOutputProcess(), outputMeshes(), prepareSubmesh(), and BaseLib::RunTime::start().

Referenced by doOutput(), and doOutputLastTimestep().

◆ doOutputLastTimestep()

void ProcessLib::Output::doOutputLastTimestep ( Process const & process,
const int process_id,
int const timestep,
const NumLib::Time & t,
int const iteration,
bool const converged,
std::vector< GlobalVector * > const & xs ) const

Writes output for the given process if it has not been written yet. This method is intended for doing output after the last timestep in order to make sure that its results are written.

Definition at line 352 of file ProcessLib/Output/Output.cpp.

359{
360 if (!isOutputStep(timestep, t))
361 {
362 doOutputAlways(process, process_id, timestep, t, iteration, converged,
363 xs);
364 }
365#ifdef OGS_USE_INSITU
366 InSituLib::CoProcess(process.getMesh(), t, timestep, true,
367 _output_format->directory);
368#endif
369}

References _output_format, InSituLib::CoProcess(), doOutputAlways(), ProcessLib::Process::getMesh(), and isOutputStep().

Referenced by ProcessLib::TimeLoop::outputLastTimeStep().

◆ doOutputNonlinearIteration()

void ProcessLib::Output::doOutputNonlinearIteration ( Process const & process,
const int process_id,
int const timestep,
const NumLib::Time & t,
const int iteration,
bool const converged,
std::vector< GlobalVector * > const & xs ) const

Writes output for the given process. To be used for debug output after an iteration of the nonlinear solver.

Definition at line 371 of file ProcessLib/Output/Output.cpp.

375{
377 {
378 return;
379 }
380
381 BaseLib::RunTime time_output;
382 time_output.start();
383
384 bool const output_secondary_variable = true;
385 auto const process_output_data =
386 createProcessOutputData(process, xs.size(), process.getMesh());
387
388 addProcessDataToMesh(t, xs, process_id, process_output_data,
389 output_secondary_variable, _output_data_specification);
390
391 if (!isOutputProcess(process_id, process))
392 {
393 return;
394 }
395
396 std::string const output_file_name = _output_format->constructFilename(
397 process.getMesh().getName(), timestep, t(), iteration, converged);
398
399 std::string const output_file_path =
400 BaseLib::joinPaths(_output_format->directory, output_file_name);
401
402 DBUG("output iteration results to {:s}", output_file_path);
403
404 if (dynamic_cast<OutputVTKFormat*>(_output_format.get()))
405 {
407 output_file_path, process.getMesh(), _output_format->compression,
408 dynamic_cast<OutputVTKFormat*>(_output_format.get())->data_mode);
409 }
410 else
411 {
412 DBUG("non-linear iterations can only written in Vtk/VTU format.");
413 }
414 INFO("[time] Output took {:g} s.", time_output.elapsed());
415}
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
std::string joinPaths(std::string const &pathA, std::string const &pathB)
void outputMeshVtk(std::string const &file_name, MeshLib::Mesh const &mesh, bool const compress_output, int const data_mode)

References _output_data_specification, _output_format, _output_nonlinear_iteration_results, ProcessLib::addProcessDataToMesh(), ProcessLib::createProcessOutputData(), ProcessLib::OutputVTKFormat::data_mode, DBUG(), BaseLib::RunTime::elapsed(), ProcessLib::Process::getMesh(), MeshLib::Mesh::getName(), INFO(), isOutputProcess(), BaseLib::joinPaths(), ProcessLib::outputMeshVtk(), and BaseLib::RunTime::start().

◆ getFileNamesForOutput()

std::vector< std::string > ProcessLib::Output::getFileNamesForOutput ( ) const

Definition at line 422 of file ProcessLib/Output/Output.cpp.

423{
424 auto construct_filename = ranges::views::transform(
425 [&](auto const& output_name) {
426 return _output_format->constructFilename(output_name, 0, 0, 0,
427 true);
428 });
429
430 return _mesh_names_for_output | construct_filename |
431 ranges::to<std::vector>;
432}

References _mesh_names_for_output, and _output_format.

◆ getFixedOutputTimes()

std::vector< double > const & ProcessLib::Output::getFixedOutputTimes ( ) const
inline

Definition at line 87 of file ProcessLib/Output/Output.h.

88 {
89 return _output_data_specification.fixed_output_times;
90 }

References _output_data_specification.

◆ isOutputProcess()

bool ProcessLib::Output::isOutputProcess ( int const process_id,
Process const & process ) const
private

Determines if output should be written for the given process.

With staggered coupling not every process writes output.

Definition at line 128 of file ProcessLib/Output/Output.cpp.

129{
130 auto const is_last_process =
131 process_id == static_cast<int>(_output_processes.size()) - 1;
132
133 return process.isMonolithicSchemeUsed()
134 // For the staggered scheme for the coupling, only the last
135 // process, which gives the latest solution within a coupling
136 // loop, is allowed to make output.
137 || is_last_process;
138}

References _output_processes, and ProcessLib::Process::isMonolithicSchemeUsed().

Referenced by doOutputAlways(), and doOutputNonlinearIteration().

◆ isOutputStep()

bool ProcessLib::Output::isOutputStep ( int const timestep,
NumLib::Time const & t ) const

Tells if output will be written at the specified timestep/time.

Definition at line 417 of file ProcessLib/Output/Output.cpp.

418{
419 return _output_data_specification.isOutputStep(timestep, t);
420}

References _output_data_specification.

Referenced by doOutput(), and doOutputLastTimestep().

◆ operator=() [1/2]

Output & ProcessLib::Output::operator= ( Output && src)
default

References Output().

◆ operator=() [2/2]

Output & ProcessLib::Output::operator= ( Output const & src)
delete

References Output().

◆ outputMeshes()

void ProcessLib::Output::outputMeshes ( int const timestep,
const double t,
int const iteration,
bool const converged,
std::vector< std::reference_wrapper< const MeshLib::Mesh > > const & meshes ) const
private

Definition at line 170 of file ProcessLib/Output/Output.cpp.

175{
176 if (_output_data_specification.output_variables.empty())
177 {
178 // special case: no output properties specified => output all properties
179 for (auto const& mesh : meshes)
180 {
181 for (auto [name, property] : mesh.get().getProperties())
182 {
183 property->is_for_output = true;
184 }
185 }
186 }
187 else
188 {
189 for (auto const& mesh : meshes)
190 {
191 for (auto [name, property] : mesh.get().getProperties())
192 {
193 // special case: always output OGS_VERSION
194 if (name == "OGS_VERSION")
195 {
196 property->is_for_output = true;
197 continue;
198 }
199
200 property->is_for_output =
201 _output_data_specification.output_variables.contains(name);
202 }
203 }
204 }
205 _output_format->outputMeshes(timestep, t, iteration, converged, meshes,
206 _output_data_specification.output_variables);
207}

References _output_data_specification, and _output_format.

Referenced by doOutputAlways().

◆ prepareSubmesh()

MeshLib::Mesh const & ProcessLib::Output::prepareSubmesh ( std::string const & submesh_output_name,
Process const & process,
const int process_id,
NumLib::Time const & t,
std::vector< GlobalVector * > const & xs ) const
private

Definition at line 209 of file ProcessLib/Output/Output.cpp.

213{
214 auto& submesh = MeshLib::findMeshByName(_meshes.get(), submesh_output_name);
215
216 DBUG("Found {:d} nodes for output at mesh '{:s}'.",
217 submesh.getNumberOfNodes(), submesh.getName());
218
219 bool const output_secondary_variables = false;
220
221 // TODO Under the assumption that xs.size() and submesh do not change during
222 // the simulation, process output data should not be recreated every time,
223 // but should rather be computed only once and stored for later reuse.
224 auto const process_output_data =
225 createProcessOutputData(process, xs.size(), submesh);
226
227 addProcessDataToMesh(t, xs, process_id, process_output_data,
228 output_secondary_variables,
230
231 auto const& bulk_mesh = process.getMesh();
232 auto const& property_names =
233 bulk_mesh.getProperties().getPropertyVectorNames();
234
235 // TODO Once all processes have been refactored to use the new residuum
236 // assembly logic, the functionality of this lambda should be refactored.
237 // Currently (Jan '23) there is a difference between the logic using this
238 // lambda and doNotProjectFromBulkMeshToSubmeshes(): The latter is
239 // considered regardless of submesh dimension.
240 auto is_residuum_field = [](std::string const& name) -> bool
241 {
242 using namespace std::literals::string_view_literals;
243 static constexpr std::string_view endings[] = {
244 "FlowRate"sv, "heat_flux"sv, "MaterialForces"sv, "NodalForces"sv,
245 "NodalForcesJump"sv};
246 auto ends_with = [&](std::string_view const& ending)
247 { return name.ends_with(ending); };
248 return std::find_if(std::begin(endings), std::end(endings),
249 ends_with) != std::end(endings);
250 };
251
252 for (auto const& name : property_names)
253 {
255 {name, MeshLib::MeshItemType::Node}))
256 {
257 // the projection is disabled regardless of mesh and submesh
258 // dimension
259 continue;
260 }
261
262 if (bulk_mesh.getDimension() == submesh.getDimension())
263 {
264 // omit the 'simple' transfer of the properties in the if condition
265 // on submeshes with equal dimension to the bulk mesh
266 // for those data extra assembly is required
267 if (is_residuum_field(name))
268 {
269 continue;
270 }
271 addBulkMeshPropertyToSubMesh(bulk_mesh, submesh, name);
272 }
273 else
274 {
275 // For residuum based properties it is assumed that the lower
276 // dimensional mesh is a boundary mesh!
277 addBulkMeshPropertyToSubMesh(bulk_mesh, submesh, name);
278 }
279 }
280 return submesh;
281}
Mesh & findMeshByName(std::vector< std::unique_ptr< Mesh > > const &meshes, std::string_view const name)
Definition Mesh.cpp:354
void addBulkMeshPropertyToSubMesh(MeshLib::Mesh const &bulk_mesh, MeshLib::Mesh &sub_mesh, std::string const &property_name)

References _do_not_project_from_bulk_mesh_to_submeshes, _meshes, _output_data_specification, ProcessLib::addBulkMeshPropertyToSubMesh(), ProcessLib::addProcessDataToMesh(), ProcessLib::createProcessOutputData(), DBUG(), MeshLib::findMeshByName(), ProcessLib::Process::getMesh(), MeshLib::Mesh::getProperties(), and MeshLib::Properties::getPropertyVectorNames().

Referenced by doOutputAlways().

◆ operator<<

std::ostream & operator<< ( std::ostream & os,
Output const & output )
friend

Definition at line 448 of file ProcessLib/Output/Output.cpp.

449{
450 os << "Output::_output_data_specification:\t"
451 << output._output_data_specification;
452 os << "Output::_output_format:\t" << *(output._output_format);
453 return os;
454}

References Output(), _output_data_specification, and _output_format.

Member Data Documentation

◆ _do_not_project_from_bulk_mesh_to_submeshes

std::set<std::pair<std::string, MeshLib::MeshItemType> > ProcessLib::Output::_do_not_project_from_bulk_mesh_to_submeshes
private

◆ _mesh_names_for_output

std::vector<std::string> ProcessLib::Output::_mesh_names_for_output
private

◆ _meshes

std::reference_wrapper<std::vector<std::unique_ptr<MeshLib::Mesh> > const> ProcessLib::Output::_meshes
private

Definition at line 128 of file ProcessLib/Output/Output.h.

Referenced by Output(), and prepareSubmesh().

◆ _output_data_specification

OutputDataSpecification ProcessLib::Output::_output_data_specification
private

◆ _output_format

std::unique_ptr<OutputFormat> ProcessLib::Output::_output_format
private

◆ _output_nonlinear_iteration_results

bool ProcessLib::Output::_output_nonlinear_iteration_results
private

Definition at line 115 of file ProcessLib/Output/Output.h.

Referenced by Output(), and doOutputNonlinearIteration().

◆ _output_processes

std::vector<std::reference_wrapper<Process const> > ProcessLib::Output::_output_processes
private

Definition at line 118 of file ProcessLib/Output/Output.h.

Referenced by addProcess(), and isOutputProcess().


The documentation for this class was generated from the following files: