PRISMS-PF Manual
Loading...
Searching...
No Matches
solution_output.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2025 PRISMS Center at the University of Michigan
2// SPDX-License-Identifier: GNU Lesser General Public Version 2.1
3
4#pragma once
5
6#include <deal.II/base/data_out_base.h>
7#include <deal.II/base/exceptions.h>
8#include <deal.II/dofs/dof_handler.h>
9#include <deal.II/lac/la_parallel_vector.h>
10#include <deal.II/numerics/data_component_interpretation.h>
11#include <deal.II/numerics/data_out.h>
12
19
21
24
25#include <prismspf/config.h>
26
27#include <filesystem>
28#include <fstream>
29#include <iomanip>
30#include <mpi.h>
31#include <sstream>
32#include <string>
33#include <vector>
34
36
37template <unsigned int dim>
39
43template <unsigned int dim, unsigned int degree, typename number>
45{
46public:
48
52 SolutionOutput(const std::vector<FieldAttributes> &field_attributes,
53 const SolutionIndexer<dim, number> &solution_indexer,
54 const SimulationTimer &sim_timer,
55 const DoFManager<dim, degree> &dof_manager,
56 const std::string &file_prefix,
57 const UserInputParameters<dim> &user_inputs)
58 {
59 const OutputParameters &output_parameters = user_inputs.output_parameters;
60 // Some stuff to determine the actual name of the output file.
61 const auto n_trailing_digits = static_cast<unsigned int>(
62 std::floor(std::log10(user_inputs.temporal_discretization.num_increments)) + 1);
63
64 // Init data out
65 dealii::DataOut<dim> data_out;
66
67 // Add data vectors
68 for (unsigned int index = 0; index < field_attributes.size(); ++index)
69 {
70 const FieldAttributes &field = field_attributes[index];
71 auto &solution = solution_indexer.get_solution_vector(index);
72 solution.update_ghost_values();
73
74 // Mark field as Scalar/Vector
75 const unsigned int n_components =
76 (field.field_type == TensorRank::Scalar) ? 1 : dim;
77
78 const std::vector<
79 dealii::DataComponentInterpretation::DataComponentInterpretation>
81 (n_components == 1)
82 ? dealii::DataComponentInterpretation::component_is_scalar
83 : dealii::DataComponentInterpretation::component_is_part_of_vector);
84
85 const std::vector<std::string> names(n_components, field.name);
86
87 data_out.add_data_vector(dof_manager.get_field_dof_handler(index),
89 names,
90 data_type);
91
92 solution.zero_out_ghost_values();
93 }
94
95 // Build patches to linearly interpolate from higher order element degrees. Note that
96 // this essentially converts the element to an equal amount of subdivisions in the
97 // output. This does not make subdivisions and element degree equivalent in the
98 // simulation!
99 const unsigned int n_divisions = output_parameters.patch_subdivisions == 0
100 ? degree
101 : output_parameters.patch_subdivisions;
102 data_out.build_patches(n_divisions);
103
104 // Set some flags for data output
105 dealii::DataOutBase::VtkFlags flags;
106 flags.time = sim_timer.get_time();
107 flags.cycle = sim_timer.get_increment();
108 flags.print_date_and_time = true;
109#ifdef PRISMS_PF_WITH_ZLIB
110 flags.compression_level = dealii::DataOutBase::CompressionLevel::best_speed;
111#endif
112 data_out.set_flags(flags);
113
114 // Write to file based on the user input.
115 const unsigned int increment = sim_timer.get_increment();
116 const std::string &file_type = output_parameters.file_type;
117 if (file_type == "vtu")
118 {
119 std::ostringstream increment_stream;
121 << std::setfill('0') << increment;
122 const std::string filename = file_prefix + "_" + increment_stream.str() + ".vtu";
123 data_out.write_vtu_in_parallel(filename, MPI_COMM_WORLD);
124 }
125 else if (file_type == "pvtu")
126 {
127 std::filesystem::path output_path = file_prefix;
128 std::string filename = output_path.filename();
129 std::string directory = output_path.remove_filename();
130 data_out.write_vtu_with_pvtu_record(directory,
131 filename,
132 increment,
135 }
136 else if (file_type == "vtk")
137 {
138 std::ostringstream increment_stream;
140 << std::setfill('0') << increment;
141 const std::string filename = file_prefix + "_" + increment_stream.str() + ".vtk";
142 std::ofstream vtk_output(filename);
143 data_out.write_vtk(vtk_output);
144 }
145 else
146 {
148 }
149
150 // Update the ghost values again to allow for read access
151 for (unsigned int index = 0; index < field_attributes.size(); ++index)
152 {
153 solution_indexer.get_solution_vector(index).update_ghost_values();
154 }
155 }
156};
157
Class that manages the deal.II DoFHandlers.
Definition dof_manager.h:27
const dealii::DoFHandler< dim > & get_field_dof_handler(Types::Index field_index, unsigned int relative_level=0) const
Getter function for the DoFHandler (reference).
Definition dof_manager.h:63
Definition simulation_timer.h:13
unsigned int get_increment() const
Definition simulation_timer.h:22
double get_time() const
Definition simulation_timer.h:28
Class that provides access to solution vectors spread across different groups.
Definition solution_indexer.h:20
const SolutionVector< number > & get_solution_vector(unsigned int global_index, unsigned int relative_level=0) const
Get a solution vector of a given field index.
Definition solution_indexer.cc:31
Class that outputs a passed solution to vtu, vtk, or pvtu.
Definition solution_output.h:45
SolutionVector< number > VectorType
Definition solution_output.h:47
SolutionOutput(const std::vector< FieldAttributes > &field_attributes, const SolutionIndexer< dim, number > &solution_indexer, const SimulationTimer &sim_timer, const DoFManager< dim, degree > &dof_manager, const std::string &file_prefix, const UserInputParameters< dim > &user_inputs)
Outputs all fields in the solution set.
Definition solution_output.h:52
Definition user_input_parameters.h:32
OutputParameters output_parameters
Definition user_input_parameters.h:184
TemporalDiscretization temporal_discretization
Definition user_input_parameters.h:175
@ Value
Use value of the variable as a criterion for refinement.
Definition grid_refiner_criterion.h:31
BlockVector< number >::BlockType SolutionVector
Typedef for solution vector.
Definition group_solution_handler.h:35
Definition conditional_ostreams.cc:20
Structure to hold the attributes of a field. This includes things like the name, rank,...
Definition field_attributes.h:24
Struct that holds output parameters.
Definition output_parameters.h:27
unsigned int patch_subdivisions
Definition output_parameters.h:146
std::string file_type
Definition output_parameters.h:139
unsigned int num_increments
Definition temporal_discretization.h:52
@ Scalar
Definition type_enums.h:32