If you’re working with e.g. finite-difference approximations and similar lattice-based computations, often it is more flexible to use e.g. “ghost elements” (also called “ghost points”, “ghost cells”, “overlap regions”, “ghost zones”, …): you have an extra array element at each edge of the array that you update with whatever boundary condition you want as needed (e.g. at each time step). The motivation here is:
-
For typical lattice-based simulations, you only need to access elements adjacent to the boundaries. You don’t want to pay the price of a specialized
getindex(a, i) = a.a[i % n]
method for every array access just to be able to access one or two extra elements from each end. -
It is much more flexible. It becomes trivial to implement boundary conditions such as: periodic, Dirichlet, quasi/Bloch periodic (periodic × phase), mirror reflection or other symmetries, domain decomposition (boundary conditions that couple different arrays, e.g. on different processors), and so on.
(See e.g. the section on “overlap regions” in chapter 5 of Principles of Parallel Programming by Lin and Snyder.)