Skip to content

Add native biquadratic RKKY interlayer coupling (ext_RKKYBiquadratic)#407

Open
SanthoshSivasubramani wants to merge 2 commits into
mumax:masterfrom
SanthoshSivasubramani:feature/native-biquad
Open

Add native biquadratic RKKY interlayer coupling (ext_RKKYBiquadratic)#407
SanthoshSivasubramani wants to merge 2 commits into
mumax:masterfrom
SanthoshSivasubramani:feature/native-biquad

Conversation

@SanthoshSivasubramani

Copy link
Copy Markdown

Add native biquadratic RKKY interlayer coupling (ext_RKKYBiquadratic)

This adds bilinear + biquadratic interlayer exchange (RKKY) coupling as an
effective-field term. The biquadratic term is the standard mechanism behind the
90° interlayer state in synthetic antiferromagnets, which purely bilinear
coupling cannot represent, and which mumax3 currently has no native term for.

Physics

For two magnetic regions coupled across a (possibly nonmagnetic) spacer, the
areal energy is

E = -J1 (m1·m2) - J2 (m1·m2)^2

whose exact variational-derivative effective field is

B = ( J1 + 2·J2·(m·m_partner) ) / (Msat·dz) · m_partner

with J1 the bilinear and J2 the biquadratic areal coupling (J/m²) and dz
the cell size along z. J1 < 0 is antiferromagnetic; J2 < 0 favours the 90°
(perpendicular) state. With J2 = 0 this reduces exactly to bilinear RKKY. The
kernel uses the 1/Msat convention (no explicit µ0) and locates the partner
cell by scanning the z-column, so the coupling spans a spacer gap rather
than only coupling immediately-adjacent cells.

API

ext_RKKYBiquadratic(region1, region2, J1, J2)   // J1, J2 in J/m^2

May be called multiple times to couple several region pairs. Exposes a
B_rkkybiquad vector output and self-guards to a no-op in SetEffectiveField
when no pair is defined.

Validation (NVIDIA L4, CUDA 12.3)

test/biquad.mx3 passes, matching the analytic field to 6 significant figures.
With J1 = −2e−3, J2 = −1e−3 J/m², Msat = 1e6 A/m, dz = 0.9e−9 m:

configuration m·m_partner expected B result
parallel (both +x) 1 (J1+2J2)/(Msat·dz) = −4.44444 T along partner
perpendicular (+x, +y) 0 biquadratic vanishes → J1/(Msat·dz) = −2.22222 T along partner

The perpendicular case confirms the biquadratic term correctly drops out at 90°,
isolating the bilinear contribution.

The CUDA wrapper is generated with cuda2go for the full compute-capability set
(50 52 53 60 61 62 70 72 75 80 86 87 89 90). Code is gofmt-clean.

Files

  • cuda/biquad.cu — kernel (addbiquadrkky)
  • cuda/biquad.go, cuda/biquad_wrapper.go — host wrapper (cuda2go-generated)
  • engine/biquad.goext_RKKYBiquadratic API + B_rkkybiquad field term
  • engine/effectivefield.go — one line: AddBiquadraticRKKYField(dst)
  • test/biquad.mx3 — regression test

Follows the same structure as the ext_RKKY PR (this is its biquadratic
generalization). Happy to adapt to your conventions.

Adds bilinear+biquadratic interlayer exchange E = -J1(m1.m2) - J2(m1.m2)^2 as an effective-field term B = (J1 + 2*J2*(m.mp))/(Msat*dz)*mp. J2<0 favours the 90-degree SAF state that bilinear coupling cannot represent; J2=0 reduces to bilinear RKKY. Uses 1/Msat convention (no mu0), z-column partner scan spans a spacer gap, self-guards in SetEffectiveField. L4-validated: parallel B=-4.44444T, perpendicular B=-2.22222T match analytic to 6 sig figs. cuda2go wrapper for the full CC set; gofmt-clean.
Copilot AI review requested due to automatic review settings July 3, 2026 17:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a native bilinear + biquadratic RKKY interlayer coupling effective-field term (ext_RKKYBiquadratic) with a CUDA implementation, integrates it into the main effective-field pipeline, and adds a regression test validating the analytic field for parallel/perpendicular configurations.

Changes:

  • Added ext_RKKYBiquadratic engine API and a B_rkkybiquad output field term.
  • Implemented the CUDA kernel (addbiquadrkky) and wired a cuda2go-generated wrapper for execution.
  • Added a regression test (test/biquad.mx3) that checks the expected field values.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/biquad.mx3 Adds regression coverage validating the new field term against analytic expectations.
engine/effectivefield.go Includes the new RKKY-biquadratic term in SetEffectiveField.
engine/biquad.go Defines the scripting API, stores coupled region pairs, and computes B_rkkybiquad.
cuda/biquad.go Host-side Go wrapper that launches the CUDA kernel with mesh/region inputs.
cuda/biquad.cu CUDA kernel computing the coupling field by locating partner cells along z.
cuda/biquad_wrapper.go Auto-generated cuda2go wrapper/embedded PTX for the kernel across compute capabilities.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cuda/biquad.cu
Comment on lines +57 to +61
// locate the nearest partner-region cell in the same (x,y) column along z,
// scanning outward from iz and stopping at the first hit (checking the
// lower side first for a deterministic tie-break).
int P = -1;
for (int d = 1; d < Nz; d++) {
Comment thread engine/biquad.go
Comment on lines +44 to +46
func RKKYBiquadratic(region1, region2 int, J1, J2 float64) {
biquadPairs = append(biquadPairs, biquadPair{region1, region2, J1, J2})
}
Comment thread engine/biquad.go
Comment on lines +31 to +38
var (
biquadPairs []biquadPair
B_rkkybiquad = NewVectorField("B_rkkybiquad", "T", "Biquadratic RKKY interlayer coupling field", AddBiquadraticRKKYField)
)

func init() {
DeclFunc("ext_RKKYBiquadratic", RKKYBiquadratic, "Adds native bilinear+biquadratic RKKY coupling J1,J2 (J/m2) between region1 and region2 (J2<0 favours 90 deg; spans a spacer gap).")
}
…, correct quartic energy

Addresses Copilot review: apply coupling only at the interface cell (thickness-independent), validate region ids, overwrite duplicate pairs, and register the energy. Because the biquadratic term is quartic in m, a dedicated energy-density kernel (biquadenergy.cu) is used instead of the generic -1/2 M.B density (which would double-count the J2 term). Added test/biquad_thick.mx3 verifying E = -(J1+J2)A (not the doubled value). VM-validated on L4: all tests OK.
@SanthoshSivasubramani

Copy link
Copy Markdown
Author

Thanks for the review — pushed 1cc9c5d addressing all three comments:

  • Interface-only coupling. The areal field is now applied only at the interface cell, so the coupling is independent of layer thickness. Added test/biquad_thick.mx3 (2-cell layers).
  • Duplicate pairs. Re-calling ext_RKKYBiquadratic for the same region pair now overwrites instead of appending.
  • Energy registration. Added E_rkkybiquad / Edens_rkkybiquad. Because the biquadratic term is quartic in m, the generic -1/2 M·B energy density would double-count the J2 term, so a dedicated energy-density kernel (biquadenergy.cu) is used. test/biquad_thick.mx3 asserts E = -(J1+J2)·A (the correct value; the double-counted result would be -(J1+2·J2)·A).

Validated on an NVIDIA L4 (CUDA 12.3): all tests pass.

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.

2 participants