OpenPFC  0.1.4
Phase Field Crystal simulation framework
Loading...
Searching...
No Matches
model.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 VTT Technical Research Centre of Finland Ltd
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
60#ifndef PFC_MODEL_HPP
61#define PFC_MODEL_HPP
62
64#include "core/world.hpp"
65#include "fft.hpp"
66#include "mpi.hpp"
68#include "types.hpp"
69#include <algorithm>
70#include <iostream>
71#include <memory>
72#include <numeric>
73#include <string_view>
74#include <vector>
75
76namespace pfc {
77
95class Model {
96private:
106 FFT &m_fft;
107 RealFieldSet m_real_fields;
109 ComplexFieldSet m_complex_fields;
111 const World &m_world;
112 heffte::box3d<int> domain;
113 bool m_rank0 = false;
114
115public:
120
145 Model(FFT &fft, const World &world)
146 : m_fft(fft), m_world(world),
147 domain(to_heffte_box(world)), // Use to_heffte_box
148 m_rank0(mpi::get_rank() == 0) {}
149
153 Model(const Model &) = delete;
154
158 Model &operator=(const Model &) = delete;
159
175 inline bool is_rank0() const noexcept { return m_rank0; }
176
182 /*
183 const Decomposition &get_decomposition() { return get_fft().get_decomposition(); }
184 */
185
191 const World &get_world() const noexcept { return m_world; }
192
233 [[nodiscard]] FFT &get_fft() noexcept { return m_fft; }
234
280 virtual void step(double t) = 0;
281
334 virtual void initialize(double dt) = 0;
335
362 virtual size_t get_allocated_memory_bytes() const { return 0; }
363
370 [[nodiscard]] bool has_real_field(std::string_view field_name) const noexcept {
371 return m_real_fields.count(std::string(field_name)) > 0;
372 }
373
395 void add_real_field(std::string_view name, RealField &field) {
396 m_real_fields.emplace(std::string(name), field);
397 }
398
425 [[nodiscard]] bool has_complex_field(std::string_view field_name) const noexcept {
426 return m_complex_fields.count(std::string(field_name)) > 0;
427 }
428
463 void add_complex_field(std::string_view name, ComplexField &field) {
464 m_complex_fields.emplace(std::string(name), field);
465 }
466
491 [[nodiscard]] RealField &get_real_field(std::string_view name) {
492 auto it = m_real_fields.find(std::string(name));
493 if (it == m_real_fields.end()) {
494 throw std::out_of_range("Real field '" + std::string(name) +
495 "' not found. "
496 "Available fields: " +
497 list_field_names());
498 }
499 return it->second;
500 }
501
514 [[nodiscard]] const RealField &get_real_field(std::string_view name) const {
515 auto it = m_real_fields.find(std::string(name));
516 if (it == m_real_fields.end()) {
517 throw std::out_of_range("Real field '" + std::string(name) +
518 "' not found. "
519 "Available fields: " +
520 list_field_names());
521 }
522 return it->second;
523 }
524
564 [[nodiscard]] ComplexField &get_complex_field(std::string_view name) {
565 auto it = m_complex_fields.find(std::string(name));
566 if (it == m_complex_fields.end()) {
567 throw std::out_of_range("Complex field '" + std::string(name) +
568 "' not found. "
569 "Available fields: " +
570 list_field_names());
571 }
572 return it->second;
573 }
574
587 [[nodiscard]] const ComplexField &get_complex_field(std::string_view name) const {
588 auto it = m_complex_fields.find(std::string(name));
589 if (it == m_complex_fields.end()) {
590 throw std::out_of_range("Complex field '" + std::string(name) +
591 "' not found. "
592 "Available fields: " +
593 list_field_names());
594 }
595 return it->second;
596 }
597
604 void add_field(const std::string &name, RealField &field) {
605 add_real_field(name, field);
606 }
607
614 void add_field(const std::string &name, ComplexField &field) {
615 add_complex_field(name, field);
616 }
617
651 [[nodiscard]] bool has_field(std::string_view field_name) const noexcept {
652 return has_real_field(field_name) || has_complex_field(field_name);
653 }
654
662 virtual Field &get_field() {
663 if (!has_real_field("default")) {
664 throw std::runtime_error("'default' field is not defined.");
665 }
666 return get_real_field("default");
667 };
668
669private:
678 std::string list_field_names() const {
679 std::vector<std::string> names;
680 for (const auto &[name, _] : m_real_fields) {
681 names.push_back(name);
682 }
683 for (const auto &[name, _] : m_complex_fields) {
684 names.push_back(name);
685 }
686 if (names.empty()) {
687 return "(none)";
688 }
689 return std::accumulate(
690 std::next(names.begin()), names.end(), names[0],
691 [](const std::string &a, const std::string &b) { return a + ", " + b; });
692 }
693};
694
695} // namespace pfc
696
697#endif
The Model class represents the physics model for simulations in OpenPFC.
Definition model.hpp:95
~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
void add_field(const std::string &name, ComplexField &field)
Add a field to the model.
Definition model.hpp:614
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
Model(const Model &)=delete
Disable copy constructor.
const RealField & get_real_field(std::string_view name) const
Retrieve a registered real-valued field by name (const version)
Definition model.hpp:514
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
const ComplexField & get_complex_field(std::string_view name) const
Retrieve a registered complex-valued field by name (const version)
Definition model.hpp:587
Domain decomposition for parallel MPI simulations.
Fast Fourier Transform interface for spectral methods.
Adapter functions for HeFFTe library integration.
heffte::box3d< int > to_heffte_box(const World &world)
Converts a World object to heffte::box3d<int>.
Definition heffte_adapter.hpp:51
MPI utilities and wrappers.
FFT class for distributed-memory parallel Fourier transforms.
Definition fft.hpp:248
Represents the global simulation domain (the "world").
Definition world.hpp:91
World(const Int3 &lower, const Int3 &upper, const CoordinateSystem< T > &cs)
Constructs a World object.
Common type aliases used throughout OpenPFC.
World class definition and unified interface.