Loading [MathJax]/extensions/MathMenu.js
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, 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 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:135
std::vector< std::string > _mesh_names_for_output
Definition Output.h:126
OutputDataSpecification _output_data_specification
Definition Output.h:124
std::unique_ptr< OutputFormat > _output_format
Definition Output.h:120
bool _output_nonlinear_iteration_results
Definition Output.h:122

◆ 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:125

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:138

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

345{
346 if (isOutputStep(timestep, t))
347 {
348 doOutputAlways(process, process_id, timestep, t, iteration, converged,
349 xs);
350 }
351#ifdef OGS_USE_INSITU
352 // Note: last time step may be output twice: here and in
353 // doOutputLastTimestep() which throws a warning.
354 InSituLib::CoProcess(process.getMesh(), t, timestep, false,
355 _output_format->directory);
356#endif
357}
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
Definition Output.cpp:290
bool isOutputStep(int const timestep, NumLib::Time const &t) const
Tells if output will be written at the specified timestep/time.
Definition Output.cpp:424
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,
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 290 of file Output.cpp.

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

366{
367 if (!isOutputStep(timestep, t))
368 {
369 doOutputAlways(process, process_id, timestep, t, iteration, converged,
370 xs);
371 }
372#ifdef OGS_USE_INSITU
373 InSituLib::CoProcess(process.getMesh(), t, timestep, true,
374 _output_format->directory);
375#endif
376}

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

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

430{
431 auto construct_filename = ranges::views::transform(
432 [&](auto const& output_name) {
433 return _output_format->constructFilename(output_name, 0, 0, 0,
434 true);
435 });
436
437 return _mesh_names_for_output | construct_filename |
438 ranges::to<std::vector>;
439}

References _mesh_names_for_output, and _output_format.

◆ getFixedOutputTimes()

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

Definition at line 94 of file Output.h.

95 {
97 }
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 424 of file Output.cpp.

425{
426 return _output_data_specification.isOutputStep(timestep, t);
427}
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,
bool const converged,
std::vector< std::reference_wrapper< const MeshLib::Mesh > > const & meshes ) const
private

Definition at line 177 of file Output.cpp.

182{
184 {
185 // special case: no output properties specified => output all properties
186 for (auto const& mesh : meshes)
187 {
188 for (auto [name, property] : mesh.get().getProperties())
189 {
190 property->is_for_output = true;
191 }
192 }
193 }
194 else
195 {
196 for (auto const& mesh : meshes)
197 {
198 for (auto [name, property] : mesh.get().getProperties())
199 {
200 // special case: always output OGS_VERSION
201 if (name == "OGS_VERSION")
202 {
203 property->is_for_output = true;
204 continue;
205 }
206
207 property->is_for_output =
209 }
210 }
211 }
212 _output_format->outputMeshes(timestep, t, iteration, converged, meshes,
214}
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 216 of file Output.cpp.

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

456{
457 os << "Output::_output_data_specification:\t"
458 << output._output_data_specification;
459 os << "Output::_output_format:\t" << *(output._output_format);
460 return os;
461}

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 138 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 126 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 135 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 122 of file Output.h.

Referenced by doOutputNonlinearIteration().

◆ _output_processes

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

Definition at line 125 of file Output.h.

Referenced by addProcess(), and isOutputProcess().


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