Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Path Forward

This page is a running log, not a tutorial. It records forward-looking notes as they come up — open questions, scale targets, directions worth exploring — dated as they're written. Nothing here is implemented yet unless the note says so.

2026-08-11

North star. DIC at real finite-element-mesh scale eventually means at least a billion correlations. Realistically, tens of billions. The working assumption is that this stays under a trillion — that's the ceiling to design for, not a target to reach.

Four directions worth exploring, in the order we'll likely take them:

  1. GPU implementations. Parallelization only covers CPU-bound threads and processes so far. GPU work is still explicitly deferred until a documented CPU bottleneck exists (see the parallelism roadmap referenced there) — this note doesn't change that. It's on the list for when that bottleneck shows up.
  2. Dynamic search-window sizing. Every worked example so far uses a fixed, generously-sized search area per point. Parallelization's own measurements found that per-correlation size, not point count alone, is the dominant cost lever. A search window only as large as it needs to be — sized from a prior displacement estimate rather than a fixed worst-case margin — shrinks that per-correlation cost directly, for every point in a mesh, not just the parallelizable part of the problem.
  3. Pure rotation. Rigid Body Motion and the polar decomposition (, see Continuum Mechanics) already separate rotation from stretch: a pure rotation carries zero strain by construction. Two things worth testing empirically, not just assuming from the closed-form math: how large a rigid-body rotation angle dictk's own correlation-based tracking can actually recover before it breaks down — a large enough rotation distorts a kernel's own content beyond what a translation-only search can still match — and confirming a correctly-tracked pure rotation reports zero strain end to end, not just in theory.
  4. Synthetic dataset comparison to XCorrel and VIC-2D. Run the same synthetic datasets this book already uses through both tools, and compare their reported displacements and strain against dictk's own. A synthetic dataset has a known, exact ground truth — the same trick every worked example in this book already relies on — so this is a direct, numeric check against established DIC software, not just a qualitative one.

A practical constraint to design around: real DIC data typically uses kernel sizes from about 35x35 pixels on the small end up to about 50x50 pixels on the large end. Every benchmark or worked example aimed at "realistic" DIC scale should stay inside that range, not the 40-pixel figure this book's own teaching examples happen to use.

Heaviside DIC and XFEM. Every correlation technique this book covers assumes a smooth displacement field. Real specimens don't always deform smoothly — a crack or a material interface can produce a genuine discontinuity, a jump rather than a gradient. Image Transformation already generates a synthetic example of exactly that jump, and names the reason: standard DIC can't capture it, and cases like it motivate the Heaviside finite-element formulation. XFEM handles this on the finite element side by enriching the basis with Heaviside step functions, so the mesh doesn't need to conform to the crack. The DIC-side analogue — enriching the correlation itself to detect and locate a discontinuity, not just generating test images that contain one — is worth exploring. Not scoped yet.

2026-08-14

Re-running The First Sweep after the centered-padding fix: checked, not automatically fixed. Recoverable Displacement Range's own opening sweep sizes search_margin_width generously for every percentage tested — always larger than the true displacement — so it was never hitting the asymmetric-padding bug that page's fix addresses. Re-ran it against the fixed locate() to check directly, rather than assume: the collapse is identical to before the fix — 12/12, 12/12, 10/12, 6/12, 1/12, 1/12, 0/12, 0/12 for . The real cause is still the interpolation confound that page already names: stretch's own bilinear interpolation subtly blurs kernel-surrounding texture even where a point's center pixel lands on an exact integer, producing near-miss failures — not the wraparound cliff the fix resolved. Confirms the Postponed subpixel-accuracy item below is still the right next step here, not something this fix already covered.

Postponed

Noted, not being pursued right now:

  • Heaviside DIC and XFEM — enriching the correlation itself to detect and locate a discontinuity, not just generating test images that contain one (see above).
  • grid.locate() windowing demo. windowing has only ever been demonstrated directly on dictk.correlation.phase_correlation (see Correlation Visualization). Every grid.locate() call across the book so far (Multi-Point Motion, Simple Stretch, Recoverable Displacement Range, Pure Rotation, Parallelization) leaves windowing at its default None — the one parameter of grid.locate's own signature with no live worked example yet.

2026-08-18

Pure Rotation: The First Sweep. New page, Pure Rotation, starts checking direction 3 above empirically. Its First Sweep reuses Point Grid's 12-point grid and sweeps rotate's angle, sizing search_margin generously at every step so window size can't be the limiting factor — the same approach Recoverable Displacement Range used. Matching collapses even faster than that page's stretch sweep did: well under half the points still match by 2 degrees, none by 8 degrees. The likely cause, already named in this page's own direction-3 note above, isn't confirmed yet — a large enough rotation turns a kernel's own content around a point, not just moves it, and a translation-only search can't follow that. Checking that hypothesis directly is the next step here, not started yet.

Pure Rotation: hypothesis confirmed. Same page, new Confirming the Content-Rotation Hypothesis section. Two direct checks: handing locate the exact true search center instead of a generous margin barely changes the collapse, ruling out search mechanics; and a plain zncc similarity score between the reference kernel and the true-aligned current-image patch (no search at all) falls off steeply with angle, confirming the real cause is content, not search. One thing this doesn't separate out yet: rotate shares stretch's bilinear interpolation, and Recoverable Displacement Range already found interpolation blur alone can look similar — genuine geometric content rotation and interpolation blur are likely both compounding here. Telling them apart is the next open step, not started.

2026-08-20

Postponed subpixel accuracy item, resolved. Simple Stretch Revisited found the concrete trigger this Postponed item's own wording anticipated: at factor_x = 1.02, only points whose x is a multiple of 50 land on an integer pixel in the deformed configuration. A denser grid mostly doesn't. New Subpixel Accuracy page: dictk.translation.locate_subpixel and dictk.grid.locate_subpixel, exposing phase_cross_correlation's own upsample_factor — separate functions from locate/grid.locate, not a parameter added to them, returning a new dictk.image.SubpixelCoordinate (float x/y) instead of PixelCoordinate. Measured directly against VIC-2D's own 2862-point grid: upsample_factor doesn't make locate's truncated integer answer more often correct (the true target usually isn't an integer at that density, so no refinement changes that) — but it substantially improves how close the tracked position lands to the true, generally fractional, target (mean absolute error 0.26px at upsample_factor=1, down to 0.09px at 10). Parallelization (9) gains this as its first child, 9.1; a second child, 9.2 High Point Density, picking the same subpixel tooling up at real density, is the planned next step, not started yet.

2026-08-24

9.2 High Point Density, shipped. New page, High Point Density, closes the 9.1/9.2 pair under Parallelization. It pushes grid.locate_subpixel to VIC-2D's own point density: 2862 points, 5px spacing, 2756 elements. No new library code — it composes entirely from already-shipped functions, the same way Simple Stretch Revisited did.

A real finding came out of it, verified before writing anything up. The strain field isn't clean at this density. Mean E11 still tracks the true value closely (0.0199 vs. 0.0198), but individual elements scatter widely (std 0.0155, range -0.016 to 0.077). A live 4-point spacing sweep (5/10/20/40px) confirmed the mechanism directly: strain noise scales with displacement-noise divided by element size, so the same small subpixel tracking residual gets amplified more at smaller spacing. Std shrinks monotonically across the sweep (0.0154/0.0125/0.0099/0.0032). The page names VIC-2D's own strain-window averaging as the standard remedy but doesn't implement it — that stays open.