InitialValues<dim> initial_values;
TimeStepping<dim> time_stepping;
SchlierenPostprocessor<dim> schlieren_postprocessor;
- DataOut<dim> data_out;
vector_type output_vector;
print_head(pcout, "set up time step");
time_stepping.prepare();
schlieren_postprocessor.prepare();
-
- data_out.attach_dof_handler(offline_data.dof_handler);
-
- constexpr auto problem_dimension =
- ProblemDescription<dim>::problem_dimension;
- const auto &component_names = ProblemDescription<dim>::component_names;
-
- for (unsigned int i = 0; i < problem_dimension; ++i)
- {
- output_vector[i].reinit(offline_data.partitioner);
- data_out.add_data_vector(output_vector[i], component_names[i]);
- }
-
- data_out.add_data_vector(schlieren_postprocessor.schlieren,
- "schlieren_plot");
}
// We will store the current time and state in the variable
// With either the initial state set up, or an interrupted state
// restored it is time to enter the main loop:
- output(U, base_name + "-solution", t, output_cycle++);
+ output(U, base_name, t, output_cycle++);
print_head(pcout, "enter main loop");
if (t > output_cycle * output_granularity)
{
- output(U, base_name + "-solution", t, output_cycle, true);
+ output(U, base_name, t, output_cycle, true);
++output_cycle;
}
}
// We wait for any remaining background output thread to finish before
// printing a summary and exiting.
if (background_thread_state.valid())
- {
- background_thread_state.wait();
- }
+ background_thread_state.wait();
computing_timer.print_summary();
pcout << timer_output.str() << std::endl;
ProblemDescription<dim>::problem_dimension;
// At this point we make a copy of the state vector, run the schlieren
- // postprocessor, and run DataOut<dim>::build_patches()
+ // postprocessor, and run DataOut<dim>::build_patches() The actual
+ // output code is standard: We create a DataOut instance, attach all
+ // data vectors we want to output and call
+ // DataOut<dim>::build_patches(). There is one twist, however. In order
+ // to perform asynchronous IO on a background thread we create the
+ // DataOut<dim> object as a shared pointer that we pass on to the
+ // worker thread to ensure that once we exit this function and the
+ // worker thread finishes the DataOut<dim> object gets destroyed again.
for (unsigned int i = 0; i < problem_dimension; ++i)
{
schlieren_postprocessor.compute_schlieren(output_vector);
- data_out.build_patches(discretization.mapping,
- discretization.finite_element.degree - 1);
+ auto data_out = std::make_shared<DataOut<dim>>();
+
+ data_out->attach_dof_handler(offline_data.dof_handler);
+
+ const auto &component_names = ProblemDescription<dim>::component_names;
+
+ for (unsigned int i = 0; i < problem_dimension; ++i)
+ data_out->add_data_vector(output_vector[i], component_names[i]);
+
+ data_out->add_data_vector(schlieren_postprocessor.schlieren,
+ "schlieren_plot");
+
+ data_out->build_patches(discretization.mapping,
+ discretization.finite_element.degree - 1);
// Next we create a lambda function for the background thread. We <a
// href="https://en.cppreference.com/w/cpp/language/lambda">capture</a>
// the output function by value so that we have access to them inside
// the lambda function.
- const auto output_worker = [this, name, t, cycle, checkpoint]() {
+ const auto output_worker = [this, name, t, cycle, checkpoint, data_out]() {
if (checkpoint)
{
// We checkpoint the current state by doing the precise inverse
const unsigned int i =
discretization.triangulation.locally_owned_subdomain();
- std::string name = base_name + "-checkpoint-" +
- Utilities::int_to_string(i, 4) + ".archive";
+ std::string filename =
+ name + "-checkpoint-" + Utilities::int_to_string(i, 4) + ".archive";
- std::ofstream file(name, std::ios::binary | std::ios::trunc);
+ std::ofstream file(filename, std::ios::binary | std::ios::trunc);
boost::archive::binary_oarchive oa(file);
oa << t << cycle;
cycle,
true,
DataOutBase::VtkFlags::best_speed);
- data_out.set_flags(flags);
+ data_out->set_flags(flags);
- data_out.write_vtu_with_pvtu_record("", name, cycle, mpi_communicator, 6);
+ data_out->write_vtu_with_pvtu_record(
+ "", name + "-solution", cycle, mpi_communicator, 6);
};
// If the asynchronous writeback option is set we launch a new