Skip to content

sem: 3-D acoustic CUDA without C-PML solves the c^2 Laplacian - #132

Merged
GeophyAI merged 1 commit into
devfrom
fix/sem-acoustic3d-bare-cuda
Oct 27, 2026
Merged

GeophyAI merged 1 commit into
devfrom
fix/sem-acoustic3d-bare-cuda

Conversation

@GeophyAI

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #131. The 3-D acoustic SEM CUDA kernels without C-PML (sem3d_acoustic, flat and deformed) solved the wrong equation: c² was folded into the stiffness integral, i.e. they solved div(c² grad u) instead of c²∇²u, which flips the reflection polarity at velocity contrasts. #131 fixed the eager classes and temporarily rejected impl='c' for this case; this PR fixes the kernels themselves and restores the route.

Kernels (src/sweep/csrc/cuda/equations/sem3d/)

  • Forward/adjoint now use the c²-free stiffness K0 and apply c² per node. The adjoint is K0 C M⁻¹; a new nodal kernel sem3d_accum_grad_c2 accumulates the c² gradient.
  • The two imaging kernels (sem3d_acoustic_imaging, sem3d_acoustic_imaging_deformed) are removed.
  • Struct layout is unchanged (abi.py / layout.cu regenerate with no diff): c2_node now holds per-node c², its gradient comes back in grad_c2_jx, and c2_j{x,y,z} hold the c²-free weights.

Python routing

  • impl='c' routes both no-C-PML paths again (rejected in sem: acoustic c² Laplacian without C-PML, one-copy node materials #131).
  • Flat and deformed meshes share one autograd Function in sem/drivers/bare.py; the material input is a single copy of vp_squared_node. The old deformed path passed per-element nodal c², which amplified the gradient at shared nodes.

Tests

  • New 3-D two-layer (1000 / 3000 m/s) c vs eager polarity test in test_sem_acoustic_reflection_polarity.py: the old kernel gives cos 0.603, the new kernel passes (threshold 1 − 1e-5).
  • Restored c-vs-eager forward / gradient / boundary-saving tests for the flat and deformed cases.
  • Strong-contrast model, PropSEM with abcn=0, c vs eager: forward and mesh gradient cos 1.0000000.
  • On GPU, test/sem: 946 passed. The one failure, test_sem_dd_elastic::test_dd_elastic_per_family_store_dtype, also fails on dev.

The CPU CI does not build the core, so the CUDA tests above are skipped there; the GPU validation was done locally. A local replica of the CPU CI (clean venv, CPU torch, 4 cores) passes.

🤖 Generated with Claude Code

The sem3d_acoustic forward/adjoint kernels put c^2 inside the stiffness,
i.e. div(c^2 grad u). They now use the c^2-free stiffness and apply c^2
per node (adjoint K0 C M^-1, c^2 gradient by a nodal kernel); the imaging
kernels are gone. Struct layout unchanged: c2_node is per node, its
gradient comes back in grad_c2_jx. impl='c' routes the bare pair again.
Test: two-layer c vs eager (old kernel cos 0.603).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@GeophyAI
GeophyAI merged commit 4f277bf into dev Oct 27, 2026
1 check passed
@GeophyAI
GeophyAI deleted the fix/sem-acoustic3d-bare-cuda branch October 27, 2026 16:21
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