OpenPFC  0.1.4
Phase Field Crystal simulation framework
Loading...
Searching...
No Matches
/home/runner/work/OpenPFC/OpenPFC/include/openpfc/results_writer.hpp

Abstract base class for writing simulation results to various formats.

Abstract base class for writing simulation results to various formatsResultsWriter provides a unified interface for outputting simulation data to different file formats (binary, VTK, HDF5, etc.). It handles parallel I/O via MPI, allowing each rank to write its local subdomain data to a collective output file.

Key Responsibilities

Design Philosophy

ResultsWriter follows OpenPFC's principles:

Usage Pattern

using namespace pfc;
// 1. Create writer (filename pattern)
auto writer = std::make_unique<BinaryWriter>(\"output_%04d.bin\");
// 2. Set domain configuration (once)
writer->set_domain(global_size, local_size, local_offset);
// 3. Write at each time step
for (int step = 0; step < num_steps; ++step) {
writer->write(step, field); // Creates output_0000.bin, output_0001.bin, ...
}
Represents the global simulation domain (the "world").
Definition world.hpp:91

Subclasses

Basic Binary Output

using namespace pfc;
// Create decomposed domain
auto world = world::create({256, 256, 256}, {1.0, 1.0, 1.0});
auto decomp = decomposition::create(world, mpi_size);
auto local_world = decomposition::get_subworld(decomp, mpi_rank);
// Create field and writer
auto writer = std::make_unique<BinaryWriter>(\"results_%04d.bin\");
// Configure writer
auto global_size = world::get_size(world);
auto local_size = world::get_size(local_world);
auto local_offset = compute_offset(local_world); // Relative to global origin
writer->set_domain(global_size, local_size, local_offset);
// Write field at step 0
writer->write(0, field); // Creates results_0000.bin
// SPDX-FileCopyrightText: 2025 VTT Technical Research Centre of Finland Ltd
// SPDX-License-Identifier: AGPL-3.0-or-later
#ifndef PFC_RESULTS_WRITER_HPP
#define PFC_RESULTS_WRITER_HPP
#include "types.hpp"
#include "utils.hpp"
#include <array>
#include <iostream>
#include <mpi.h>
#include <vector>
namespace pfc {
class ResultsWriter {
public:
ResultsWriter(const std::string &filename) { m_filename = filename; }
virtual ~ResultsWriter() = default;
virtual void set_domain(const std::array<int, 3> &arr_global,
const std::array<int, 3> &arr_local,
const std::array<int, 3> &arr_offset) = 0;
virtual MPI_Status write(int increment, const RealField &data) = 0;
virtual MPI_Status write(int increment, const ComplexField &data) = 0;
template <typename T> MPI_Status write(const std::vector<T> &data) {
return write(0, data);
}
protected:
std::string m_filename;
};
class BinaryWriter : public ResultsWriter {
using ResultsWriter::ResultsWriter;
private:
MPI_Datatype m_filetype;
static MPI_Datatype get_type(RealField) { return MPI_DOUBLE; }
static MPI_Datatype get_type(ComplexField) { return MPI_DOUBLE_COMPLEX; }
public:
void set_domain(const std::array<int, 3> &arr_global,
const std::array<int, 3> &arr_local,
const std::array<int, 3> &arr_offset) {
MPI_Type_create_subarray(3, arr_global.data(), arr_local.data(),
arr_offset.data(), MPI_ORDER_FORTRAN, MPI_DOUBLE,
&m_filetype);
MPI_Type_commit(&m_filetype);
};
MPI_Status write(int increment, const RealField &data) {
return write_(increment, data);
}
MPI_Status write(int increment, const ComplexField &data) {
return write_(increment, data);
}
template <typename T>
MPI_Status write_(int increment, const std::vector<T> &data) {
MPI_File fh;
std::string filename2 = utils::format_with_number(m_filename, increment);
MPI_File_open(MPI_COMM_WORLD, filename2.c_str(),
MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
MPI_Offset filesize = 0;
MPI_Status status;
const unsigned int disp = 0;
MPI_Datatype type = get_type(data);
MPI_File_set_size(fh, filesize); // force overwriting existing data
MPI_File_set_view(fh, disp, type, m_filetype, "native", MPI_INFO_NULL);
MPI_File_write_all(fh, data.data(), data.size(), type, &status);
MPI_File_close(&fh);
return status;
}
};
} // namespace pfc
#endif // PFC_RESULTS_WRITER_HPP
General utility functions.