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 330 of file ProcessLib/Output/Output.cpp.

337{
338 if (isOutputStep(timestep, t))
339 {
340 doOutputAlways(process, process_id, timestep, t, iteration, converged,
341 xs);
342 }
343#ifdef OGS_USE_INSITU
344 // Note: last time step may be output twice: here and in
345 // doOutputLastTimestep() which throws a warning.
346 InSituLib::CoProcess(process.getMesh(), t, timestep, false,
347 _output_format->directory);
348#endif
349}
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 282 of file ProcessLib/Output/Output.cpp.

289{
290 BaseLib::RunTime time_output;
291 time_output.start();
292
293 bool const output_secondary_variables = true;
294 auto const process_output_data =
295 createProcessOutputData(process, xs.size(), process.getMesh());
296
297 // Need to add variables of process to mesh even if no output takes place.
298 addProcessDataToMesh(t, xs, process_id, process_output_data,
299 output_secondary_variables,
301
302 if (!isOutputProcess(process_id, process))
303 {
304 return;
305 }
306
307 std::vector<std::reference_wrapper<const MeshLib::Mesh>> output_meshes;
308 for (auto const& mesh_output_name : _mesh_names_for_output)
309 {
310 if (process.getMesh().getName() == mesh_output_name)
311 {
312 // process related output
313 output_meshes.emplace_back(process.getMesh());
314 }
315 else
316 {
317 // mesh related output
318 auto const& submesh =
319 prepareSubmesh(mesh_output_name, process, process_id, t, xs);
320 output_meshes.emplace_back(submesh);
321 }
322 }
323
324 outputMeshes(timestep, t(), iteration, converged, std::move(output_meshes));
325
326 INFO("[time] Output of timestep {:d} took {:g} s.", timestep,
327 time_output.elapsed());
328}
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 351 of file ProcessLib/Output/Output.cpp.

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

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 370 of file ProcessLib/Output/Output.cpp.

374{
376 {
377 return;
378 }
379
380 BaseLib::RunTime time_output;
381 time_output.start();
382
383 bool const output_secondary_variable = true;
384 auto const process_output_data =
385 createProcessOutputData(process, xs.size(), process.getMesh());
386
387 addProcessDataToMesh(t, xs, process_id, process_output_data,
388 output_secondary_variable, _output_data_specification);
389
390 if (!isOutputProcess(process_id, process))
391 {
392 return;
393 }
394
395 std::string const output_file_name = _output_format->constructFilename(
396 process.getMesh().getName(), timestep, t(), iteration, converged);
397
398 std::string const output_file_path =
399 BaseLib::joinPaths(_output_format->directory, output_file_name);
400
401 DBUG("output iteration results to {:s}", output_file_path);
402
403 if (dynamic_cast<OutputVTKFormat*>(_output_format.get()))
404 {
406 output_file_path, process.getMesh(),
407 _output_data_specification.output_variables,
408 _output_format->compression,
409 dynamic_cast<OutputVTKFormat*>(_output_format.get())->data_mode);
410 }
411 else
412 {
413 DBUG("non-linear iterations can only written in Vtk/VTU format.");
414 }
415 INFO("[time] Output took {:g} s.", time_output.elapsed());
416}
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, std::set< std::string > const &output_variables, 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 423 of file ProcessLib/Output/Output.cpp.

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

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 418 of file ProcessLib/Output/Output.cpp.

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

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

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 208 of file ProcessLib/Output/Output.cpp.

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

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

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: