Construct a new Model object.
Construct a new Model objectConstructs a Model with the given FFT backend and simulation domain. The FFT object must outlive the Model instance.
#ifndef PFC_MODEL_HPP
#define PFC_MODEL_HPP
#include "types.hpp"
#include <algorithm>
#include <iostream>
#include <memory>
#include <numeric>
#include <string_view>
#include <vector>
namespace pfc {
class Model {
private:
RealFieldSet m_real_fields;
ComplexFieldSet m_complex_fields;
const World &m_world;
bool m_rank0 = false;
public:
Model(FFT &fft, const World &world)
: m_fft(fft), m_world(world),
domain(
to_heffte_box(world)),
m_rank0(mpi::get_rank() == 0) {}
Model(const Model &) = delete;
inline bool is_rank0()
const noexcept {
return m_rank0; }
const World &
get_world()
const noexcept {
return m_world; }
[[nodiscard]] FFT &get_fft() noexcept { return m_fft; }
virtual void step(double t) = 0;
virtual void initialize(double dt) = 0;
virtual size_t get_allocated_memory_bytes() const { return 0; }
[[nodiscard]]
bool has_real_field(std::string_view field_name)
const noexcept {
return m_real_fields.count(std::string(field_name)) > 0;
}
void add_real_field(std::string_view name, RealField &field) {
m_real_fields.emplace(std::string(name), field);
}
[[nodiscard]] bool has_complex_field(std::string_view field_name) const noexcept {
return m_complex_fields.count(std::string(field_name)) > 0;
}
void add_complex_field(std::string_view name, ComplexField &field) {
m_complex_fields.emplace(std::string(name), field);
}
[[nodiscard]] RealField &get_real_field(std::string_view name) {
auto it = m_real_fields.find(std::string(name));
if (it == m_real_fields.end()) {
throw std::out_of_range("Real field '" + std::string(name) +
"' not found. "
"Available fields: " +
list_field_names());
}
return it->second;
}
[[nodiscard]] const RealField &get_real_field(std::string_view name) const {
auto it = m_real_fields.find(std::string(name));
if (it == m_real_fields.end()) {
throw std::out_of_range("Real field '" + std::string(name) +
"' not found. "
"Available fields: " +
list_field_names());
}
return it->second;
}
[[nodiscard]] ComplexField &get_complex_field(std::string_view name) {
auto it = m_complex_fields.find(std::string(name));
if (it == m_complex_fields.end()) {
throw std::out_of_range("Complex field '" + std::string(name) +
"' not found. "
"Available fields: " +
list_field_names());
}
return it->second;
}
[[nodiscard]] const ComplexField &get_complex_field(std::string_view name) const {
auto it = m_complex_fields.find(std::string(name));
if (it == m_complex_fields.end()) {
throw std::out_of_range("Complex field '" + std::string(name) +
"' not found. "
"Available fields: " +
list_field_names());
}
return it->second;
}
void add_field(
const std::string &name, RealField &field) {
add_real_field(name, field);
}
void add_field(
const std::string &name, ComplexField &field) {
add_complex_field(name, field);
}
[[nodiscard]] bool has_field(std::string_view field_name) const noexcept {
}
throw std::runtime_error("'default' field is not defined.");
}
return get_real_field("default");
};
private:
std::string list_field_names() const {
std::vector<std::string> names;
for (const auto &[name, _] : m_real_fields) {
names.push_back(name);
}
for (const auto &[name, _] : m_complex_fields) {
names.push_back(name);
}
if (names.empty()) {
return "(none)";
}
return std::accumulate(
std::next(names.begin()), names.end(), names[0],
[](const std::string &a, const std::string &b) { return a + ", " + b; });
}
};
}
#endif
~Model()
Destroy the Model object.
Definition model.hpp:119
bool is_rank0() const noexcept
Check if current MPI rank is 0.
Definition model.hpp:175
void add_field(const std::string &name, RealField &field)
Add a field to the model.
Definition model.hpp:604
Model & operator=(const Model &)=delete
Disable copy assignment operator.
bool has_real_field(std::string_view field_name) const noexcept
Check if the model has a real-valued field with the given name.
Definition model.hpp:370
const World & get_world() const noexcept
Get the decomposition object associated with the model.
Definition model.hpp:191
virtual Field & get_field()
Get a reference to the default primary unknown field.
Definition model.hpp:662
Domain decomposition for parallel MPI simulations.
Fast Fourier Transform interface for spectral methods.
Adapter functions for HeFFTe library integration.
MPI utilities and wrappers.
World(const Int3 &lower, const Int3 &upper, const CoordinateSystem< T > &cs)
Constructs a World object.
World class definition and unified interface.