This page collects a variety of general facts about
the scuff-em suite and
the application programs it contains.
1. Complex numbers in scuff-em
Many of the standalone programs in the
scuff-em suite have options for which
you may specify complex numbers. (An example is
--omega option accepted by
scuff-scatter and other programs, for
which you may specify complex or even pure imaginary numbers
to do calculations at complex frequencies.)
To specify a complex number as a parameter value, write
both the real and imaginary parts together as a single
string (no spaces), separated by
with the imaginary part terminated by
(you may also use
For example, all of the following are valid frequency specifications:
Complex Numbers in API Programs
Complex numbers in the scuff-em C++ API
are represented by the type
typedef std::complex cdouble;
You can convert character strings to
and vice-versa, using the
routines in libscuff:
int Error = CD2S("3.4+5.6i", &Omega);
printf("Omega = %s.\n",CD2S(Omega));
2. Passing command-line options via text file
All of the standalone applications in the
scuff-em suite allow their
command-line options to be passed via a text file fed into
Each line of this text file should consist of a single
command-line option (minus the
-- at the beginning)
followed by any arguments the option might take.
For example, running the scuff-scatter
code with the command-line options
% scuff-scatter --geometry Spheres.scuffgeo --omega 1.0 --pwPolarization 1 0 0 --pwDirection 0 0 1 --EPFile MyEPFile
is equivalent to running
% scuff-scatter < MyOptionsFile
where the file
MyOptionsFile looks like this:
# options for scuff-scatter
pwPolarization 1 0 0
pwDirection 0 0 1
Note that blank lines and comments (lines starting with
#) are ignored.
You may also combine the two methods of specifying
options by passing some options via text file and others on
the command line. If there are any conflicts, the values
specified on the command line take precedence. For instance, to
re-run the example above at a new frequency with everything
else unchanged, you could say
% scuff-scatter --Omega 2.0 < MyOptionsFile
Note that if you will be doing calculations at more than one
frequency on the same structure, you will definitely want to make
geometric data caching,
as discussed below.
3. scuff-em Log files
The application codes in the scuff-em
suite write information to log files that you can use
to monitor the progress of your calculations. These log files are
.log (for example,
and are created in the directory from which you launched the code run.
Here's a snippet of a log file created by
03/16/12::20:46:26: Assembling the BEM matrix at Omega=0.234...
03/16/12::20:46:26: 00 % (0/654)...
03/16/12::20:46:53: 10 % (65/654)...
03/16/12::20:47:13: 20 % (130/654)...
03/16/12::20:47:35: 30 % (196/654)...
03/16/12::20:47:55: 40 % (261/654)...
03/16/12::20:48:10: 50 % (327/654)...
03/16/12::20:48:23: 60 % (392/654)...
03/16/12::20:48:38: 70 % (457/654)...
03/16/12::20:48:55: 80 % (523/654)...
03/16/12::20:49:12: 201634/20840 cache hits/misses
03/16/12::20:49:12: LU-factorizing BEM matrix...
03/16/12::20:49:13: Assembling the RHS vector...
03/16/12::20:49:13: Solving the BEM system...
03/16/12::20:49:13: Computing scattered and absorbed power...
03/16/12::20:49:13: Assembling the BEM matrix at Omega=0.456...
03/16/12::20:49:13: 00 % (0/654)...
03/16/12::20:49:36: 10 % (65/654)...
You can use the
tail command to monitor the progress of a code
in real time. For example, if you just launched a scuff-scatter
run from a terminal window, you can open up a new terminal window and say
% tail -f scuff-scatter.log
This will dump to console a running list of the various steps in the
scuff-scatter calculation. This is useful,
among other things, for giving you a sense of how much time is being
consumed by the various stages in the problem -- assembling the BEM
matrix, assembling the RHS vector, computing scattered fields, etc.
You can also combine real-time monitoring of the
with status-monitoring commands like
to ensure that scuff-em is taking maximal
advantage of your machine's CPU resources during the most
CPU-intensive portions of the computation. In particular, when
real-time monitoring of the
.log file indicates that
the code is in the process of assembling the BEM matrix (in the above
.log file example, this would be between
20:49:12), running the
top command should bring up a display something like
The point of this display is that, for a machine with 8 CPU cores,
the CPU usage reported by
top should be around 800%
during the BEM matrix assembly. If, instead, you see a number closer
to 100%, then either
scuff-em was not properly compiled
with the multithreading libraries available on your machine, or
you need to tweak the environment variables to achieve maximal
performance. For example, on my workstation, I need to set the
following environment variable to encourage
openmp to use all 8 of my CPU cores:
% export GOMP_CPU_AFFINITY=0-7
Logging in API Programs
To write a line of status information to the log file,
Log API function, which accepts
printf- style format semantics. (Note the
absence of a training newline.)
Log("Run %i: Beginning optimization phase ... ",Index);
By default, logging is disabled (and calls to
no effect). To enable logging, define the name
of the log file using the
SetLogFileName API function:
4. Caching geometric data in
A very important feature of scuff-em
is its ability to reuse geometric data on meshed surfaces to
accelerate repeated computations. In particular, if your calculation
does a calculation at one frequency and then repeats the calculation
at a second frequency, the second calculation will be significantly
faster, because much of the first computation can be reused.
This feature is automatically enabled within any single run
of a scuff-em program. Thus, for example,
if you run scuff-scatter with a list of
two or more frequencies, then the second, third, etc. frequencies will
automatically be faster than the first.
However, it is also possible to reuse information between runs -- so
that, for example, if you have already done a
scuff-scatter run on a given geometry,
then you can do a second run of the code on that same geometry
with geometric data from the first run reused to speed things up.
The feature that enables the reuse of geometric data between runs is
called caching. The simplest way to use it is to pass
the command-line argument
--cache MyCacheFile.cache to
scuff-scatter and the other application
MyCacheFile.cache with whatever cache
filename you like.) This option has the following effect:
- When the code starts up, it will attempt to read geometric data from
the specified file (if that file exists). If the file doesn't exist,
the option will be silently ignored.
- When the code is finished, it will write geometric data to
the specified file. This will include any geometric data that were
present in the file originally, together with any additional data
that may have been computed during the code run.
Thus, if you create a new
.scuffgeo file and run a bunch
of scuff-scatter calculations on it,
you should add
--cache MyCacheFile.cache to whatever other
command-line options you have; the cache file will be created after
the first code run, and then all subsequent runs involving that geometry
will be accelerated.
Here are a couple of facts about geometric data caching in
- Cached data are frequency-independent. If you run a
calculation at a given frequency, then run a second
calculation at a different frequency, the geometric cache
data can be reused to accelerate the second calculation.
- Cached data are also independent of material properties
(permittivity ε and permeability μ). If you run
a calculation on a given
.scuffgeo file, and then
MATERIAL specifications in that file
while keeping the same mesh files, the geometric cache data from
the first run can be reused to accelerate the second calculation.
- On the other hand, cached data are heavily mesh-dependent.
If you run a scattering calculation on an object meshed with a
given resolution, then replace the meshfile with a
finer-resolution surface mesh for the same object, the cache
data cannot be reused and must be recomputed.
For details of how caching is implemented in scuff-em,
scuff-em technical memo.
Separate preload and write caches
The file specified by the
--cache option serves a dual purpose
as both the cache input file (if it exists when the code starts up)
and the cache dump file when the code finishes. In some cases, it may be
convenient to specify separate file names (for example, if you want to
preload from two or more cache files, or if you want to write to a new cache
file without overwriting an existing cache file.)
For this purpose, the scuff-em application codes
support the separate command-line options
--ReadCache may be specified
multiple times to preload from multiple cache files.) Using the simpler
--Cache option is equivalent to specifying
--WriteCache with the same
cache file names.
Caching in API Programs
Use the API functions
to preload from, and store to, a cache file. These functions each take
const char * argument (the name of the cache file)
and have no return value. If the specified file does not exist,
PreloadCache will simply print a console warning message
StoreCache will create it anew. If the file does exist,
PreloadCache will attempt to read cache information from it,
StoreCache will overwrite it.
using namespace scuff;
G = new RWGGeometry("MyGeometry.scuffgeo");
// do a bunch of calculations
G = scuff.RWGGeometry("MyGeometry.scuffgeo");
// do a bunch of calculations