M. T. Homer Reid MIT Home Page
Physics Problems Research teaching My Music About Me Miscellany


Miscellaneous facts about scuff-em

This page collects a variety of general facts about the scuff-em suite and the application programs it contains.

Miscellaneous facts about scuff-em
1. Complex numbers
2. Passing command-line options via text file
3. scuff-em log files
4. Caching geometric data in scuff-em

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 the --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 + or -, with the imaginary part terminated by i or I (you may also use j or J). For example, all of the following are valid frequency specifications:

      --omega 2.3+4.5i
      --omega 2.3
      --omega 4.5j
      --omega 12.3e2+45.4e2I

Complex Numbers in API Programs

Complex numbers in the scuff-em C++ API are represented by the type cdouble:

    typedef std::complex cdouble;

You can convert character strings to cdoubles, and vice-versa, using the S2CD and CD2S routines in libscuff:

    cdouble Omega;
    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 standard input.

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 
     geometry Spheres.scuffgeo
     omega 1.0

     pwPolarization 1 0 0 
     pwDirection 0 0 1

     EPFile MyEPFile

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 use of 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 named application-name.log (for example, scuff-scatter.log, scuff-rf.log, etc.) and are created in the directory from which you launched the code run.

Here's a snippet of a log file created by scuff-scatter:

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 .log file with status-monitoring commands like top or htop 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:46:26 and 20:49:12), running the top command should bring up a display something like this:

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 (a) scuff-em was not properly compiled with the multithreading libraries available on your machine, or (b) 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, use the 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 Log have no effect). To enable logging, define the name of the log file using the SetLogFileName API function:


4. Caching geometric data in scuff-em

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 codes. (Replace 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 scuff-em.

  • 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 change the 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, see the 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 and --WriteCache. (--ReadCache may be specified multiple times to preload from multiple cache files.) Using the simpler --Cache option is equivalent to specifying --ReadCache and --WriteCache with the same cache file names.

Caching in API Programs

Use the API functions PreloadCache and StoreCache to preload from, and store to, a cache file. These functions each take a single 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 and return, while StoreCache will create it anew. If the file does exist, PreloadCache will attempt to read cache information from it, while StoreCache will overwrite it.

C++ example:

      using namespace scuff; 



      G = new RWGGeometry("MyGeometry.scuffgeo");
      // do a bunch of calculations


Python example:

      import scuff;


      G = scuff.RWGGeometry("MyGeometry.scuffgeo");

      // do a bunch of calculations


Core Library

Miscellaneous Facts about SCUFF-EM, by Homer Reid
Last Modified: 11/16/16