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 31 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 double t, int const iteration, std::vector< GlobalVector * > const &xs) const
 
void doOutputLastTimestep (Process const &process, const int process_id, int const timestep, const double t, int const iteration, std::vector< GlobalVector * > const &xs) const
 
void doOutputAlways (Process const &process, const int process_id, int const timestep, const double t, int const iteration, std::vector< GlobalVector * > const &xs) const
 
void doOutputNonlinearIteration (Process const &process, const int process_id, int const timestep, const double t, const int iteration, std::vector< GlobalVector * > const &xs) const
 
bool isOutputStep (int const timestep, double 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, double 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 145 of file Output.cpp.

150 : _output_format(std::move(output_format)),
151 _output_nonlinear_iteration_results(output_nonlinear_iteration_results),
152 _output_data_specification(std::move(output_data_specification)),
153 _mesh_names_for_output(std::move(mesh_names_for_output)),
154 _meshes(meshes)
155{
156}
std::reference_wrapper< std::vector< std::unique_ptr< MeshLib::Mesh > > const > _meshes
Definition: Output.h:126
std::vector< std::string > _mesh_names_for_output
Definition: Output.h:117
OutputDataSpecification _output_data_specification
Definition: Output.h:115
std::unique_ptr< OutputFormat > _output_format
Definition: Output.h:111
bool _output_nonlinear_iteration_results
Definition: Output.h:113

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

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

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

170{
172 mesh_item_type);
173}
std::set< std::pair< std::string, MeshLib::MeshItemType > > _do_not_project_from_bulk_mesh_to_submeshes
Definition: Output.h:129

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

344{
345 if (isOutputStep(timestep, t))
346 {
347 doOutputAlways(process, process_id, timestep, t, iteration, xs);
348 }
349#ifdef OGS_USE_INSITU
350 // Note: last time step may be output twice: here and in
351 // doOutputLastTimestep() which throws a warning.
352 InSituLib::CoProcess(process.getMesh(), t, timestep, false,
353 _output_format->directory);
354#endif
355}
bool isOutputStep(int const timestep, double const t) const
Tells if output will be written at the specified timestep/time.
Definition: Output.cpp:420
void doOutputAlways(Process const &process, const int process_id, int const timestep, const double t, int const iteration, std::vector< GlobalVector * > const &xs) const
Definition: Output.cpp:291
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 double  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 291 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, 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
MeshLib::Mesh const & prepareSubmesh(std::string const &submesh_output_name, Process const &process, const int process_id, double const t, std::vector< GlobalVector * > const &xs) const
Definition: Output.cpp:213
bool isOutputProcess(int const process_id, Process const &process) const
Definition: Output.cpp:133
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:175
void addProcessDataToMesh(const double 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 double  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 357 of file Output.cpp.

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

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

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

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

References _mesh_names_for_output, and _output_format.

◆ getFixedOutputTimes()

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

Definition at line 86 of file Output.h.

87 {
89 }
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 133 of file Output.cpp.

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

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

Referenced by doOutputAlways(), and doOutputNonlinearIteration().

◆ isOutputStep()

bool ProcessLib::Output::isOutputStep ( int const  timestep,
double const  t 
) const

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

Definition at line 420 of file Output.cpp.

421{
422 return _output_data_specification.isOutputStep(timestep, t);
423}
bool isOutputStep(int timestep, double 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 175 of file Output.cpp.

179{
181 {
182 // special case: no output properties specified => output all properties
183 for (auto const& mesh : meshes)
184 {
185 for (auto [name, property] : mesh.get().getProperties())
186 {
187 property->is_for_output = true;
188 }
189 }
190 }
191 else
192 {
193 for (auto const& mesh : meshes)
194 {
195 for (auto [name, property] : mesh.get().getProperties())
196 {
197 // special case: always output OGS_VERSION
198 if (name == "OGS_VERSION")
199 {
200 property->is_for_output = true;
201 continue;
202 }
203
204 property->is_for_output =
206 }
207 }
208 }
209 _output_format->outputMeshes(timestep, t, iteration, meshes,
211}
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,
double const  t,
std::vector< GlobalVector * > const &  xs 
) const
private

Definition at line 213 of file Output.cpp.

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

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

Referenced by doOutputAlways().

Friends And Related Function Documentation

◆ operator<<

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

Definition at line 449 of file Output.cpp.

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

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 129 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 117 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 126 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 113 of file Output.h.

Referenced by doOutputNonlinearIteration().

◆ _output_processes

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

Definition at line 116 of file Output.h.

Referenced by addProcess(), and isOutputProcess().


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