-
Notifications
You must be signed in to change notification settings - Fork 109
Description
Hi @stevengj,
I've hit what I think is a surprising performance degradation in a rather particular setting, and I'm wondering if it could be considered a genuine issue. Right off the bat: I'm sorry that the description below is so verbose.
The problem manifests as extremely slow/non-existent convergence (resolution-wise) in an (unphysical) symmetry-breaking of computed frequency spectra.
Specifically, for a (3D) calculation that involves the following three elements:
- ... material properties specified via
material-func(i.e. a level set surface), ... with associated anisotropic material response (i.e. nonzeroepsilon-offdiag),- ... in a non-rectangular lattice,
I observe that frequencies ω(k) and ω(k′) with k and k′ related by a symmetry of the lattice differ (although, physically, ω(k) = ω(k′)). This is of course not terribly surprising due to discretization etc., but I find that |ω(k) - ω(k′)| converges far slower/not at all in the above setting. If either of these three elements are removed, good convergence is restored. [edit: actually, turns out changing point 2 doesn't do anything]
The issue is best illustrated by examples: several included below.
I'm guessing this is related to the subpixel averaging step in src/maxwell/maxwell_eps.c, more specifically around here, but I'm not entirely sure.
I'd be interested in working to fix this, if you think it is a fixable problem (and especially if I could get some pointers on where to investigate further).
Minimal examples demonstrating the issue
Consider the following setup: an oblique lattice (the primitive lattice of a conventional tI Bravais lattice with axis lengths 1, 1, and 0.8) with a gyromagnetic sphere at its center under a B-field along the (Cartesian) z-axis. Among the symmetries of the system is a (Cartesian) y-mirror symmetry m₀₁₀ (m₁₀₁ in the lattice basis).
The following .ctl sets up a system like this (except for the sphere-part; follows next):
; ─────────────────────────── MAIN DEFAULT PARAMETERS ──────────────────────────
(define-param res 32) ; resolution
(define-param kvecs (list (vector3 0.234 0.45 0.321) (vector3 0.234 -0.45 0.321) )) ; list of k-vectors in a Cartesian basis (differ by sign of y-component)
(define-param rvecs (list (vector3 -0.5 0.5 0.4) (vector3 0.5 -0.5 0.4) (vector3 0.5 0.5 -0.4) ))
(define-param has-tr #f) ; whether we assume B = 0 (#t) or apply a B-field along the cartesian z-direction (#f)
; ──────────────────────────── PREP-WORK ────────────────────────────
(set! resolution res)
(set! num-bands 4)
(set! output-epsilon (lambda () (print "... skipping output-epsilon\n"))) ; remove output of *.h5 unitcell files
; ──────────────────── CRYSTAL SYSTEM/DIRECT BASIS ─────────────────────
(set! geometry-lattice (make lattice
(size 1 1 1)
(basis1 (list-ref rvecs 0)) (basis2 (list-ref rvecs 1)) (basis3 (list-ref rvecs 2))
(basis-size (vector3-norm (list-ref rvecs 0)) (vector3-norm (list-ref rvecs 1)) (vector3-norm (list-ref rvecs 2)))
))
; ──────────────────── K-POINTS ─────────────────────
(set! k-points (map cartesian->reciprocal kvecs))
; ──────────────────── MATERIAL ─────────────────────
(define epsin 13)
(define epsin-diag (vector3 14.00142849854971 14.00142849854971 13.0)) ; equiv. to a normalized B field of 0.4, applied to epsin=13
(define epsin-offdiag (cvector3 0.0+5.2i 0.0+0.0i 0.0+0.0i))
(define material-inside
(cond
(has-tr (make dielectric (epsilon epsin)) )
(else (make medium-anisotropic (epsilon-diag epsin-diag) (epsilon-offdiag epsin-offdiag)) )
)
)
(define material-outside (make dielectric (epsilon 1)))
; ──────────────────── GEOMETRY ─────────────────────
; implement a gyromagnetic sphere, either via `sphere` or `material-func`
(define rad 0.25) ; sphere radius
; include("geometry-by-sphere.scm") ; <----------- VARIABLE BITS BELOW
; include("geometry-by-materialfunc.scm") ; <----------- VARIABLE BITS BELOW
; ───────────────────────────────── DISPERSION ─────────────────────────────────
(run-all)make sphere approach
Now, if we create an gyromagnetic sphere using make sphere, everything works well (this is the geometry-by-sphere.scm file above):
(set! geometry (list
(make sphere
(center 0 0 0)
(radius rad)
(material material-inside)
)
))and we can plot the absolute difference between the frequencies at the two k-points (i.e. k and k′ = m₀₁₀k) as a function of computation resolution:

So far, so good.
make material-function approach
If we instead create the same sphere using a level set function (this is the geometry-by-materialfunc.scm file above), convergence slows down significantly:
(define rad2 (* rad rad))
(define (f r)
(let ((rc (lattice->cartesian r)))
(- (abs (vector3-cdot rc rc)) rad2)
)
)
(define (level-set-material r)
(cond
((< (f r) 0.0) material-inside)
(else material-outside)
)
)
(set! default-material (make material-function (material-func level-set-material)))Of course, the `make sphere` and `make material-function` approaches agree roughly about the spectra (click to see plots)
make sphere |
make material-function |
|---|---|
![]() |
![]() |
make material-function for a rectangular lattice
If we swap out the oblique lattice for a rectangular one, e.g. with rvecs equal to (vector3 1 0 0) (vector3 0 1 0) (vector3 0 0 0.8), good convergence is restored:

make material-function with more complicated geometry
Keeping the oblique lattice, but swapping out the sphere for a more complicated geometry (that retains a (Cartesian) {m₀₁₀|0,0,⅖} symmetry though) makes the problem even more evident:
Effectively, bands 2, 3, and 4 stop converging.
k-dependence of issue
Above, I just picked two random k-points; but the issue is k-point dependent - some ponits are strongly affected, and others are not. I found that the issue can be particularly strong when k is near a (symmetry-protected) nodal point at generic k. (This is my research motivation for this)





