Skip to content

Round the grid origin to a whole pixel - #3333

Closed
smartalecH wants to merge 1 commit into
masterfrom
fix/geometry-center-whole-pixel
Closed

smartalecH wants to merge 1 commit into
masterfrom
fix/geometry-center-whole-pixel

Conversation

@smartalecH

Copy link
Copy Markdown
Collaborator

Alternative to #3298 for #1051, opened as a draft so we can decide which approach is right.

Root cause. grid_volume::set_origin(const vec&) rounds to the nearest half pixel, so any geometry_center that is not a whole number of pixels gives the grid an odd origin io (e.g. 0.1 at resolution 15 is 1.5 px). The Yee lattice assumes io is even — icenter() documents this and center_origin() enforces it — and loop_in_chunks (vec2diel_floor) and grid_volume::interpolate place each component on absolute ivec parities. With an odd io those disagree with where fields and materials are actually stored, so:

  • sources are deposited half a pixel from where they are evaluated (materials are not affected),
  • get_field_point, DFT monitors and other loop_in_chunks readouts are likewise half a pixel off,
  • source deposition depends on the chunk layout, because the chunk-owned ranges no longer tile the source's interpolation lattice.

Fix. Round the origin to a whole pixel, as center_origin() already does, and round Simulation.geometry_center the same way in Python so the two agree. The rounding is documented.

Evidence (2D/3D, all six components; point, line, plane and boundary-straddling sources on/off chunk splits; random non-pixel geometry_center):

master master, geometry_center pre-rounded this PR
split vs. unsplit, 80 random configs 23/80 differ 0/80 0/80
-np 3/-np 4 vs -np 1, 40 configs — — bit-identical
#1051 script vs. translated reference 0.9916 vs 0.753 — 0.741437 vs 0.741436

The middle column is the key point: master's existing source-deposition code is already chunk-independent once io is even, so none of #3298's loop_in_chunks / fix_boundary_sources changes are needed.

Behavior change. A non-pixel geometry_center now snaps to the nearest pixel instead of the nearest half pixel. Such runs previously misplaced sources and monitors relative to the structure.

Tests: the chunk-boundary tests from #3298 (unchanged), plus test_geometry_center_rounded_to_pixel.

🤖 Generated with Claude Code

geometry_center was rounded to the nearest half pixel, so a non-integer
number of pixels gave the grid an odd origin. The Yee lattice assumes an
even origin (see grid_volume::icenter), so sources and monitors were
placed half a pixel from the fields and materials, and source deposition
depended on the chunk layout.

Fixes #1051.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@smartalecH

Copy link
Copy Markdown
Collaborator Author

Folded into #3298, which now contains this change (approved in review there).

@smartalecH smartalecH closed this Oct 9, 2026
@smartalecH
smartalecH deleted the fix/geometry-center-whole-pixel branch October 9, 2026 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant