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 36 of file 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, 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, 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, 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, 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, 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 147 of file Output.cpp.

152 : _output_format(std::move(output_format)),
153 _output_nonlinear_iteration_results(output_nonlinear_iteration_results),
154 _output_data_specification(std::move(output_data_specification)),
155 _mesh_names_for_output(std::move(mesh_names_for_output)),
156 _meshes(meshes)
157{
158}
std::reference_wrapper< std::vector< std::unique_ptr< MeshLib::Mesh > > const > _meshes
Definition Output.h:133
std::vector< std::string > _mesh_names_for_output
Definition Output.h:124
OutputDataSpecification _output_data_specification
Definition Output.h:122
std::unique_ptr< OutputFormat > _output_format
Definition Output.h:118
bool _output_nonlinear_iteration_results
Definition Output.h:120

◆ Output() [2/3]

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

◆ Output() [3/3]

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

◆ ~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 160 of file Output.cpp.

161{
162 _output_processes.push_back(process);
163 if (_mesh_names_for_output.empty())
164 {
165 _mesh_names_for_output.push_back(process.getMesh().getName());
166 }
167}
std::vector< std::reference_wrapper< Process const > > _output_processes
Definition Output.h:123

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 169 of file Output.cpp.

172{
174 mesh_item_type);
175}
std::set< std::pair< std::string, MeshLib::MeshItemType > > _do_not_project_from_bulk_mesh_to_submeshes
Definition Output.h:136

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,
std::vector< GlobalVector * > const & xs ) const

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

Definition at line 336 of file Output.cpp.

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

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,
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 289 of file Output.cpp.

295{
296 BaseLib::RunTime time_output;
297 time_output.start();
298
299 bool const output_secondary_variables = true;
300 auto const process_output_data =
301 createProcessOutputData(process, xs.size(), process.getMesh());
302
303 // Need to add variables of process to mesh even if no output takes place.
304 addProcessDataToMesh(t, xs, process_id, process_output_data,
305 output_secondary_variables,
307
308 if (!isOutputProcess(process_id, process))
309 {
310 return;
311 }
312
313 std::vector<std::reference_wrapper<const MeshLib::Mesh>> output_meshes;
314 for (auto const& mesh_output_name : _mesh_names_for_output)
315 {
316 if (process.getMesh().getName() == mesh_output_name)
317 {
318 // process related output
319 output_meshes.emplace_back(process.getMesh());
320 }
321 else
322 {
323 // mesh related output
324 auto const& submesh =
325 prepareSubmesh(mesh_output_name, process, process_id, t, xs);
326 output_meshes.emplace_back(submesh);
327 }
328 }
329
330 outputMeshes(timestep, t(), iteration, std::move(output_meshes));
331
332 INFO("[time] Output of timestep {:d} took {:g} s.", timestep,
333 time_output.elapsed());
334}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
Count the running time.
Definition RunTime.h:29
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:42
void start()
Start the timer.
Definition RunTime.h:32
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
Definition Output.cpp:215
bool isOutputProcess(int const process_id, Process const &process) const
Definition Output.cpp:135
void outputMeshes(int const timestep, const double t, int const iteration, std::vector< std::reference_wrapper< const MeshLib::Mesh > > const &meshes) const
Definition Output.cpp:177
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,
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 355 of file Output.cpp.

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

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,
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 372 of file Output.cpp.

376{
378 {
379 return;
380 }
381
382 BaseLib::RunTime time_output;
383 time_output.start();
384
385 bool const output_secondary_variable = true;
386 auto const process_output_data =
387 createProcessOutputData(process, xs.size(), process.getMesh());
388
389 addProcessDataToMesh(t, xs, process_id, process_output_data,
390 output_secondary_variable, _output_data_specification);
391
392 if (!isOutputProcess(process_id, process))
393 {
394 return;
395 }
396
397 std::string const output_file_name = _output_format->constructFilename(
398 process.getMesh().getName(), timestep, t(), iteration);
399
400 std::string const output_file_path =
401 BaseLib::joinPaths(_output_format->directory, output_file_name);
402
403 DBUG("output iteration results to {:s}", output_file_path);
404
405 if (dynamic_cast<OutputVTKFormat*>(_output_format.get()))
406 {
408 output_file_path, process.getMesh(), _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:30
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 423 of file Output.cpp.

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

References _mesh_names_for_output, and _output_format.

◆ getFixedOutputTimes()

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

Definition at line 93 of file Output.h.

94 {
96 }
std::vector< double > fixed_output_times
Given times that steps have to reach.

References _output_data_specification, and ProcessLib::OutputDataSpecification::fixed_output_times.

◆ 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 135 of file Output.cpp.

136{
137 auto const is_last_process =
138 process_id == static_cast<int>(_output_processes.size()) - 1;
139
140 return process.isMonolithicSchemeUsed()
141 // For the staggered scheme for the coupling, only the last
142 // process, which gives the latest solution within a coupling
143 // loop, is allowed to make output.
144 || is_last_process;
145}

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 Output.cpp.

419{
420 return _output_data_specification.isOutputStep(timestep, t);
421}
bool isOutputStep(int timestep, NumLib::Time const &time) const

References _output_data_specification, and ProcessLib::OutputDataSpecification::isOutputStep().

Referenced by doOutput(), and doOutputLastTimestep().

◆ operator=() [1/2]

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

◆ operator=() [2/2]

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

◆ outputMeshes()

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

Definition at line 177 of file Output.cpp.

181{
183 {
184 // special case: no output properties specified => output all properties
185 for (auto const& mesh : meshes)
186 {
187 for (auto [name, property] : mesh.get().getProperties())
188 {
189 property->is_for_output = true;
190 }
191 }
192 }
193 else
194 {
195 for (auto const& mesh : meshes)
196 {
197 for (auto [name, property] : mesh.get().getProperties())
198 {
199 // special case: always output OGS_VERSION
200 if (name == "OGS_VERSION")
201 {
202 property->is_for_output = true;
203 continue;
204 }
205
206 property->is_for_output =
208 }
209 }
210 }
211 _output_format->outputMeshes(timestep, t, iteration, meshes,
213}
std::set< std::string > output_variables
All variables that shall be output.

References _output_data_specification, _output_format, and ProcessLib::OutputDataSpecification::output_variables.

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 215 of file Output.cpp.

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

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().

Friends And Related Symbol Documentation

◆ operator<<

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

Definition at line 447 of file Output.cpp.

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

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

Definition at line 136 of file Output.h.

Referenced by doNotProjectFromBulkMeshToSubmeshes(), and prepareSubmesh().

◆ _mesh_names_for_output

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

Definition at line 124 of file Output.h.

Referenced by addProcess(), doOutputAlways(), and getFileNamesForOutput().

◆ _meshes

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

Definition at line 133 of file Output.h.

Referenced by 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 120 of file Output.h.

Referenced by doOutputNonlinearIteration().

◆ _output_processes

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

Definition at line 123 of file Output.h.

Referenced by addProcess(), and isOutputProcess().


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