verg: code for computing eigenvalues lying in a small interval, and
corresponding eigenfunctions, of Dirichlet Laplacian in various
classes of planar billiards (aka domains). Uses various
generalizations of the scaling method of Vergini-Saraceno 1994.
Alex Barnett. 9/18/12
http://www.math.dartmouth.edu/~ahb
-----------------------------------------
0) COMPILING
Edit the Makefile for your library locations.
You will need a C compliler (currently set for g++ from GCC).
You will need BLAS, LAPACK, GNU Scientific Library (GSL), and, if
you want parallel efficiency, OpenMP. All are standard on modern linux
package managers. Then type:
make verg
1) HOW TO USE
This code has various billiard families hard-coded, in particular, the
Bunimovich stadium, a generalized Sinai (whas Sarnak calls the Barnett
billiard), a smooth radial function with a couple of lowest Fourier modes,
the mushroom, and the triangle. Some desymmetrized versions also exist
(meaning you are restricted to one symmetry class of eigenfunctions,
but gain more efficiency).
The billiard is chosen by the flag "-l family:a:b:...:z" where family
is the billiard name, and a,b,...,z the parameters.
For instance "-l qust:2" chooses a quarter of the "2x4" stadium,
ie the unit square with a quarter-disc adjoined to its right edge.
The user has to choose a basis set appropriate for the billiard shape.
This is done with the "-s type:a:b:...:z" flag, where type is the basis
type, and a,b,..,z various parameters. For accuracy, the basis set has
to be carefully chosen (such is the problem with these global-basis methods).
See below for examples.
The user also chooses a frequency range and task, which is usually
the Vergini scaling method via eg the option "-k 100 -V 0.2" which
tries to find all eigenfrequencies in [99.8,100.2]. The width of this
window must be no larger than around 1/4 the diameter of the billiard.
We use the notation eigenfrequency k to mean sqrt(eigenvalue); the
code works with eigenfrequencies rather than eigenvalues. One may
choose an asymmetric window via eg "-k 100 -V 0.1:0.2" which would
look in the interval [99.9,100.2]. The flag "-u" removes spurious-looking
eigenpairs. The flag "-b 10" sets boundary discretization to 10 points
per wavelength (fine at high k).
Finally, the user may ask for certain eigenfunction output: evaluation
on the boundary eg "-p 1000" which asks for 1000 uniformly-spaced grid
points (or "-p 0" for a default number), or eg "-g 0.01:1" which
evaluates on a grid of size 0.01 (the 0 tells it to zero values
outside the billiard). A faster method for multiple eigenfunctions on
a grid is "-f 0.01:1" but this actually outputs slightly dilated
versions of the eigenfunctions, so be careful if here if you care
about much accuracy.
The "tension" values output to the screen and to the t.sum file (where
t is a file header that may be set via the "-o" option) indicate roughly
the square of k errors (and, roughly the square of eigenfunction errors too,
although no error analysis exists for the scaling method).
A reference for the method is Sec. 7 of the Barnett-Hassell 2012 paper,
available in preprint form at http://arxiv.org/abs/1112.5665, and references
therein. That paper advocates an improved method that has not been
coded up in C yet; however, see MPSpack at http://code.google.com/p/mpspack/
which is much higher accuracy but doesn't yet have shapes with corners.
The command line help for verg documents available billiard and basis.
2) EXAMPLE BILLIARD AND BASIS COMBINATIONS THAT WORK
I now give a few common combinations of billiard type and basis sets,
via valid command lines that compute eigenvalues. If you want to
output eigenfunctions in the interior, see above, but a safe first bet
is to append "-f 0.01:1" at least to eyeball them. Generally the
first ("eta") parameter can tend to 1 from above as k gets large, but
must be made several times higher at "small" k (eg < 100). Some
billiard shapes only contain a partial boundary because they are
designed to work with a basis set which enforces Dirichlet condition
on the remaining part (eg qust, qurf, hamush, line, ell, ...).
Keep this in mind for the "-p" option.
Quarter-stadium: (using Vergini's amazing plave-wave + evanescent combo)
verg -l qust:2 -s vepwoo:1.3:10:1.5 -u -4 5 -b 10 -k 500 -V 0.2 -p 0 -f 0.01:1
Quarter-Sinai (Barnett, using symmetrized method of fundamental solutions)
verg -l qugrs:1:0.2:0.4 -b 10 -s oyooo:2:3:1 -u -k 200 -V 0.1:0.2
Quarter smooth radial function: (using symmetrized MFS)
verg -l qurf:0:0.2:0.2 s oyooo:1.5:7:1 -b 10 -u -k 300 -V 0.2
Half-mushroom: (using Fourier-Bessel sine basis as in CHAOS 2007 paper)
verg -l hamush:1:1 -s fb:1:0:1.5 -u -4 3 -k 100 -V 0.2 -f 0.01:1
(note here I included a "fast-but-dilated" output)
L-shaped billiard: (as half-mushroom)
verg -l ell:0 -s fb:1:0:1.5 -u -4 3 -k 100 -V 0.2 -f 0.01:1
Ellipse: (with plane wave basis)
verg -l rf:2:0.5:0:0:0 -s pw:2 -u -k 100 -V 0.2 -f 0.01:1
Triangle billiard: (using line object, and Fourier-Bessel sine basis)
verg -l line:0.7:0.8:1:0 -s fb:1.8:0:0.271189304634946 -b 10 -u -4 4 -k 100 -x 0:1:0:0.8 -V 0.3 -f 0.01:1
(note the FB angle has to match that at the origin. The "-x" option is
needed since the bounding box of "line" is too small. If "-f 0.01:1"
were used, the masking only occurs at the line, not the full triangle)
Triangle billiard: (complete boundary and MFS basis, slower but more reliable)
verg -l tri:0.7:0.8:-0.57:-0.27 -s oyo:3:4:1 -u -4 1 -b 30 -k 300 -V 0.2
(this masks correctly; also see gen_tri_*.m below)
More billiards are described in billiard.cc, eg in rad_func().
New types can be added in billiard.h and all relevant routines in billiard.cc
One can find other basis choices by digging around in the various
gen_*.m drivers (see below)
3) DRIVERS AND RELATED PACKAGES
MATLAB driver codes are included which use repeated system calls
to the verg executable to collect data over a larger range of k,
say [100 200]. Some of these are:
gen_tri_fb.m - the most recent example, uses FB basis for triangle, fast
esp. for narrow triangles, but not accurate (tension 1e-4),
misses 2% of eigenvalues for k<100
gen_tri_mfs.m - uses MFS (oyo) basis, more accurate (tension 1e-7), no missed
eigenvalues for reasonable triangle shapes, slower.
gen_qust.m - old code
gen_qusta.m - ditto
gen_qurf.m
gen_mush.m
...
These codes call other useful MATLAB I/O routines such as load_*.m, save_sta.m
The verg output files t.per, t.ngr, and t.sta_bin (where t is a generic
file header name set by the "-o" option), are readable by the
VIEWER package by the author, available at
http://www.math.dartmouth.edu/~ahb/software/viewer/
It is especially fun to view eigenfunctions t.sta_bin generated quickly
by "-f" straight into the viewer.
---------------------------------------