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


libscuff API Documentation:
Defining Incident Fields with IncField

In libscuff, the incident field in an electromagnetic scattering problem is described by a C++ base class named IncField. libscuff comes with several built-in implementations (that is, derived subclasses) of this class for commonly-encountered types of incident field (including plane waves, point sources, and Gaussian laser beams), but it is also easy to write your own implementation by mimicing the example below.

The basic way to use a derived subclass of IncField in a libscuff program is to create an instance of the class and then pass (a pointer to) this instance to the AssembleRHSVector class method of RWGGeometry:

   MyIncFieldType *IF = new MyIncFieldType( MyParameters, ... )

   HVector *V = G->AssembleRHSVector(Omega, IF);

Within the AssembleRHSVector routine, the incident field will be evaluated at a large number of points on the surfaces of the scattering objects in your geometry to compute the elements of the RHS vector in the BEM scattering problem.

Although the values of the incident-field components depend on the angular frequency ω and on the permittivity ε and permeability μ of the medium in which the field propagates, you will see below that the class constructors below do not require that these parameters be specified. Instead, their values are configured automatically by libscuff using the value of the Omega parameter specified when AssembleRHSVector() is called.

The first few sections below describe how to instantiate the built-in derived subclasses of IncField that come with the libscuff distribution. The final section discusses an example of how to write a homemade IncField routine for describing a non-standard type incident field.

Describing Incident Fields using IncField
1. Plane waves
2. Point sources
3. Gaussian laser beams
4. Composite incident fields
5. Customizing IncField for an arbitrary incident field profile

1. Plane waves

The fields of a plane wave are

where E0 and n are the complex E-field polarization vector and the propagation vector, respectively.

The corresponding derived subclass of IncField is PlaneWave; the constructor is

  PlaneWave( const cdouble E0[3], const double nHat[3] );

where E0 and nHat define the components of E0 and n.


A linearly-polarized plane wave traveling in the positive z direction with E-field pointing in the x direction:

   cdouble lPol[3] = { 1.0, 0.0, 0.0 };
   double nHat[3]  = { 0.0, 0.0, 1.0 };
   PlaneWave lpw( lPol, nHat );

   HVector *B=AssembleRHSVector(Omega, &lpw); 

   lpw = scuff.PlaneWave([1,0,0], [0,0,1])

A right-circularly-polarized plane wave traveling in the positive z direction:

   cdouble cPol[3] = { cdouble(1.0,0.0), cdouble(0.0,1.0), 0.0 };
   double nHat[3]  = { 0.0, 0.0, 1.0 };
   PlaneWave cpw( cPol, nHat );

   HVector *B=AssembleRHSVector(Omega, &cpw); 

   cpw = scuff.PlaneWave( [1+1i,1+1i,0], [0,0,1])
   RHS = G.AssembleRHSVector(Omega, cpw)

2. Point dipole sources

The field of a point electric dipole located at x0 is

The corresponding derived subclass of IncField is PointSource; the constructor is

  PointSource( const double X0[3], 
               const cdouble P[3]);
               int Type = LIF_ELECTRIC_DIPOLE);

where X0 and P define the components of x0 and P.

(Note that if you are measuring length in units of μm, as is common in scuff-em applications, then a point electric dipole with moment e.g. P={0.0 0.0 1.0} has magnitude 8.85•10-18 coulombs•μm or 8.85•10-12 coulombs•meters.)

The optional Type parameter may be set to LIF_MAGNETIC_DIPOLE to obtain the fields of a point magnetic dipole; these are related to the fields of a point electric dipole according to

Note that, for the magnetic dipole case, the quantity P should be set to the magnetic dipole moment times Z divided by μ0.

It is perfectly acceptable for the location of a point dipole source to lie inside one of the material bodies in your scattering geometry. You don't have to do anything special in this case; if the point X0 lies inside one of the material objects specified in your .scuffgeo file, libscuff will automatically detect this and proceed accordingly.

3. Gaussian laser beams

The scuff-em implementation of the field of a Gaussian laser beam was contributed by Johannes Feist and follows this paper:

  • "Electromagnetic Gaussian Beams Beyond the Paraxial Approximation," by C. J. R. Sheppard and S. Saghafi, Journal of the Optical Society of America A 16 1381 (1999) ( http://dx.doi.org/10.1364/JOSAA.16.001381).

The corresponding derived subclass of IncField is GaussianBeam; the constructor is

  GaussianBeam( const double X0[3], 
                const double KProp[3], 
                const cdouble E0[3],
                const double W[3],

Here X0 is the location of the beam center, KProp is the propagation vector, E0 is the complex E-field polarization vector, and W is the beam waist. (In the limit of infinite W, the field becomes a plane wave with E-field polarization vector E0 and propagation vector KProp.)

4. Composite incident fields

The IncField class contains a Next field that you can use to contruct an incident field consisting of a combination of the various types of fields described above.

Here's an example in which the incident field in a scattering problem consists of two incoming plane waves together with the field of a point source:

     PlaneWave *PW  = new PlaneWave( Pol1, nHat1 ); 
     PW->Next       = new PlaneWave( Pol2, nHat2 ); 
     PW->Next->Next = new PointSource( X0, P );

     // the parameter passed to AssembleRHSVector is the head of the list
     AssembleRHSVector( Omega, PW );

5. Customizing IncField for an arbitrary incident field profile

If you need to solve scattering problems involving other types of incident fields, you can create your own derived subclass of IncField.

Probably the easiest way to do this is to copy the file src/libs/libIncField/PlaneWave.cc that comes with the scuff-em source distribution and modify the constructor and the GetFields() routine.

Incident Field Sources Inside Scattering Objects

The discussion so far has assumed that the incident field arises from sources that lie in the exterior medium of a scattering problem. In some cases you may need to solve scattering problems in which the incident field arises from sources contained inside one of the material bodies in your geometry. In contrast to other scattering formulations, in SIE/BEM approaches this distinction is important and must be communicated to the scuff-em core library routines.

There are two ways to tell libscuff that the sources of an IncField are contained inside a material body.

  • You can set the ObjectLabel field in the IncField to the label of the object inside of which the field sources lie. (The label is the string following the OBJECT keyword in the .scuffgeo file.) In the case of nested objects (i.e. the field sources lie inside an object which is itself contained in another object), set ObjectLabel to the label of the immediate containing object. The default value of ObjectLabel is NULL, which corresponds to field sources in the exterior medium.

  • Alternatively, if you are implementing your own derived subclass of IncField, you can leave the ObjectLabel field equal to NULL and instead provide an implementation of the GetSourcePoint() virtual class method:

               bool GetSourcePoint(double X[3]);

    Your implementation of this method should fill in the components of X with the cartesian coordinates of the point at which your field sources lie, and should return true. libscuff will then automatically figure out which (if any) object in the scattering geometry contains this point.

    The default implementation of GetSourcePoint in the IncField base class simply returns false, which tells libscuff to look at the ObjectLabel field instead.

Core Library

libscuff documentation: Defining Incident Fields with IncField, by Homer Reid
Last Modified: 11/16/16