Geometry / Read the grid

Let the compiler read the geometry

Predict the coordinates before you run the code.

Download runnable lesson (.zip)

Includes the model, inputs, required headers and a short run guide.

An origin and a spacing are both triples of real numbers, but swapping them changes the physics. OpenPFC gives them separate types so the function signature can express what each triple means.

Put meaning into the arguments

pfc::Domain make_domain(pfc::GridSize size, pfc::PhysicalOrigin origin,
                        pfc::GridSpacing spacing) {
  return pfc::domain::create(size, origin, spacing);
}
static_assert(std::is_invocable_v<decltype(&make_domain), pfc::GridSize,
                                  pfc::PhysicalOrigin, pfc::GridSpacing>);
static_assert(!std::is_invocable_v<decltype(&make_domain), pfc::GridSize,
                                   pfc::GridSpacing, pfc::PhysicalOrigin>);

The first assertion verifies the intended call. The second verifies that the compiler rejects the same arguments with origin and spacing exchanged. This is a small compile-time check of an API property, not an intentional build failure hidden in a comment.

const auto grid =
    make_domain(pfc::GridSize{{8, 4, 2}}, pfc::PhysicalOrigin{{-1, -2, 0}},
                pfc::GridSpacing{{.25, 1, 2}});
const auto center = pfc::domain::center(grid);
std::cout << "points,cx,cy,cz\n"
          << pfc::domain::get_total_size(grid) << ',' << center[0] << ','
          << center[1] << ',' << center[2] << '\n';

The grid has 64 samples. Its fully periodic extent is \((2,4,4)\), so its geometric centre is \((0,0,2)\). That centre is a point in physical space; it need not coincide with a stored sample on an arbitrary grid.

Change the geometry confidently

openpfc run model.cpp input.json --launcher=none

The empty input is unused; this lesson invites edits to the C++ expression. Change the origin and predict the centre’s translation. Change the spacing and predict the extent. The runtime check verifies the concrete count and centre, while the static assertions verify the argument-order property.

These wrappers distinguish roles, not physical units. GridSpacing does not know whether a number is in metres or micrometres, and a correctly typed value can still describe the wrong experiment. Use consistent units in the model equations and inputs. See the strong type definitions and continue with anisotropic coordinates.

The complete C++ model and starting input are available with this lesson.