OpenPFC  0.1.4
Phase Field Crystal simulation framework
Loading...
Searching...
No Matches
world.cpp

Overview

This tutorial-style example introduces the World object, which plays a foundational role in OpenPFC. It represents the global simulation domain ( \Omega ), encoding the size, lower and upper bounds, spacing, coordinate system, and periodicity.

The core purpose of World is to provide a geometric abstraction of the domain used in simulations. It does not perform computational steps, but rather serves as a foundational definition of the simulation space, essential for defining fields, applying boundary conditions, and performing discretization.

In the most common case of Cartesian grids, the relation between grid indices and physical coordinates is defined as:

[ x(i) = x_0 + i \cdot \Delta x, \quad i = 0, 1, \dots, L_x - 1 ]

This maps each grid point (i, j, k) to a point in physical space (x, y, z).

In this set of examples, we explore several different ways of constructing World objects and using their features, showcasing the flexibility and design philosophy of the OpenPFC framework.

// SPDX-FileCopyrightText: 2025 VTT Technical Research Centre of Finland Ltd
// SPDX-License-Identifier: AGPL-3.0-or-later
#include <iostream>
void example1_basic_cartesian_world() {
cout << "=== Example 1: Basic Cartesian World ===\n";
std::array<int, 3> dimensions = {10, 20, 30};
std::array<double, 3> origin = {0.0, 0.0, 0.0};
std::array<double, 3> discretization = {0.1, 0.1, 0.1};
pfc::World w = pfc::world::create(dimensions, origin, discretization);
std::cout << "World created:\n" << w << endl;
std::cout << "Size: " << get_size(w)[0] << ", " << get_size(w)[1] << ", "
<< get_size(w)[2] << endl;
std::cout << "Origin: (" << get_origin(w)[0] << ", " << get_origin(w)[1] << ", "
<< get_origin(w)[2] << ")\n";
std::cout << "Spacing: " << get_spacing(w)[0] << ", " << get_spacing(w)[1] << ", "
<< get_spacing(w)[2] << endl;
std::cout << "Coordinate System: " << static_cast<int>(get_coordinate_system(w))
<< endl;
std::cout << "Periodicity in dimensions (x, y, z):\n";
for (int i = 0; i < 3; ++i) {
std::cout << " Dimension " << i << ": "
<< (is_periodic(w, i) ? "true" : "false") << std::endl;
}
}
void example2_minimal_world() {
cout << "\n=== Example 2: Minimal Definition ===\n";
World w = world::create({64, 64, 64});
cout << w << endl;
}
void example3_strong_typedef_construction() {
cout << "\n=== Example 3: Strong Typedefs ===\n";
using namespace world;
Size3 size({16, 16, 1});
LowerBounds3 lower({-1.0, -1.0, 0.0});
UpperBounds3 upper({1.0, 1.0, 0.0});
Spacing3 spacing({0.125, 0.125, 1.0});
Periodic3 periodic({true, true, false});
World w = world::create(size, lower, upper, spacing, periodic,
CoordinateSystemTag::Plane);
cout << w << endl;
}
void example4_coordinate_conversion() {
cout << "\n=== Example 4: Grid ↔ Coordinates ===\n";
World w = world::create({10, 10, 1});
Int3 idx = {3, 7, 0};
Real3 coords = to_coords(w, idx);
cout << "Grid index: (" << idx[0] << ", " << idx[1] << ", " << idx[2]
<< ") maps to: ";
cout << "(" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")\n";
Int3 roundtrip = to_indices(w, coords);
cout << "Back to index: (" << roundtrip[0] << ", " << roundtrip[1] << ", "
<< roundtrip[2] << ")\n";
}
int main() {
example1_basic_cartesian_world();
example2_minimal_world();
example3_strong_typedef_construction();
example4_coordinate_conversion();
return 0;
}
const Real3 to_coords(const CartesianCS &cs, const Int3 &idx) noexcept
Convert grid indices to physical coordinates.
Definition csys.hpp:291
auto create(const World< T > &world, const heffte::box3d< int > &box)
Construct a new World object from an existing one and a box.
Definition decomposition.hpp:62
Represents the global simulation domain (the "world").
Definition world.hpp:91
World class definition and unified interface.