meep Namespace Reference


Classes

class  Boundary_Region
struct  fieldop_data
struct  Dft_Chunk_Data
class  Fields
class  Fields_Chunk
class  Grace_Point
struct  h5_output_data
struct  rintegrand_data
class  H5file
 H5file.cpp: HDF5 file I/O. More...
struct  integrate_data
struct  rfun_wrap_data
class  Material_Function
class  Simple_Material_Function
class  Dft_Chunk
class  Dft_Flux
class  Flux_Vol
class  Polarizability_Identifier
class  Grace
class  Polarizability
class  Polarization
class  Bandsdata
 Yet another all public class. More...
class  initialize
class  Monitor_Point
struct  Src_Vol_Chunkloop_Data
class  Src_Time
 Time-dependence of a current source, intended to be overridden by subclasses. More...
class  Gaussian_Src_Time
 Gaussian-envelope source with given frequency, width, peak-time, cutoff I would guess that this provides a dipole source, with the following behavior: tt = time - peak_time. More...
class  Continuous_Src_Time
class  Custom_Src_Time
 user-specified source function with start and end times More...
class  Src_Vol
class  Structure_Chunk
class  Structure
struct  signed_direction
class  vec
 A general use class for storing and manipulating low rank vectors. More...
class  ivec
class  Geometric_Volume
class  Volume
class  Symmetry
class  Geometric_Volume_List

Typedefs

typedef double * pdouble
typedef void(* bicgstab_op )(const double *x, double *y, void *data)
typedef double(* fx_func )(const vec &)
typedef void(* field_chunkloop )(Fields_Chunk *fc, int ichunk, component cgrid, ivec is, ivec ie, vec s0, vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift, complex< double > shift_phase, const Symmetry &S, int sn, void *chunkloop_data)
 field_chunkloop function pointer definition.
typedef complex< double >(* field_function )(const complex< double > *Fields, const vec &loc, void *integrand_data_)
typedef double(* field_rfunction )(const complex< double > *Fields, const vec &loc, void *integrand_data_)
typedef Structure_ChunkStructure_Chunk_ptr

Enumerations

enum  in_or_out { e_incoming = 0, e_outgoing }
enum  connect_phase { e_CONNECT_PHASE = 0, e_CONNECT_NEGATE = 1, e_CONNECT_COPY = 2 }
enum  boundary_condition { e_periodic = 0, e_metallic, e_magnetic, e_none }
enum  time_sink {
  e_connecting, e_stepping, e_boundaries, e_mpiTime,
  e_fieldOutput, e_fourierTransforming, e_other
}
enum  Grace_type { e_XY, e_ERROR_BARS }
enum  component {
  Ex = 0, Ey, Er, Ep,
  Ez, Hx, Hy, Hr,
  Hp, Hz, Dx, Dy,
  Dr, Dp, Dz, Dielectric
}
enum  derived_component {
  Sx = 100, Sy, Sr, Sp,
  Sz, EnergyDensity, D_EnergyDensity, H_EnergyDensity
}
enum  ndim { D1 = 0, D2, D3, Dcyl }
enum  field_type { E_stuff = 0, H_stuff = 1, D_stuff = 2, P_stuff = 3 }
enum  boundary_side { High = 0, Low }
enum  direction {
  X = 0, Y, Z, R,
  P, NO_DIRECTION
}

Functions

static vec sphere_pt (const vec &cent, double R, int n, double &weight)
static void anisoaverage (Material_Function &epsilon, const Geometric_Volume dV, component ec, double invepsrow[3], double tol, int maxeval)
int do_harminv (complex< double > *data, int n, double dt, double fmin, double fmax, int maxbands, complex< double > *amps, double *freq_re, double *freq_im, double *errors, double spectral_density, double Q_thresh, double rel_err_thresh, double err_thresh, double rel_amp_thresh, double amp_thresh)
 Performs harmonic inversion of a given signal.
static double dot (int n, const double *x, const double *y)
static double norm2 (int n, const double *x)
static void xpay (int n, double *x, double a, const double *y)
int bicgstabL (const int L, const int n, double *x, bicgstab_op A, void *Adata, const double *b, const double tol, int *iters, double *work, const bool quiet)
Boundary_Region pml (double thickness, direction d, boundary_side side)
Boundary_Region pml (double thickness, direction d)
Boundary_Region pml (double thickness)
static void handle_control_c (int i)
void deal_with_ctrl_c (int stop_now=2)
 Allows you to hit ctrl-C to tell your calculation to stop and clean up.
static void Fields_to_array (const Fields &f, complex< double > *x)
static void array_to_Fields (const complex< double > *x, Fields &f)
static void fieldop (const double *xr, double *yr, void *data_)
static void add_Dft_Chunkloop (meep::Fields_Chunk *fc, int ichunk, component cgrid, ivec is, ivec ie, vec s0, vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift, complex< double > shift_phase, const Symmetry &S, int sn, void *chunkloop_data)
static int Dft_Chunks_Ntotal (Dft_Chunk *Dft_Chunks, int *my_start)
void save_dft_hdf5 (Dft_Chunk *Dft_Chunks, component c, H5file *file, const char *dprefix)
void load_dft_hdf5 (Dft_Chunk *Dft_Chunks, component c, H5file *file, const char *dprefix)
static complex< double > dot_integrand (const complex< double > *Fields, const vec &loc, void *data_)
static void thermo_chunkloop (Fields_Chunk *fc, int ichunk, component cgrid, ivec is, ivec ie, vec s0, vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift, complex< double > shift_phase, const Symmetry &S, int sn, void *sum_)
static complex< double > dot3_max_integrand (const complex< double > *Fields, const vec &loc, void *data_)
static complex< double > dot_fx_integrand (const complex< double > *Fields, const vec &loc, void *data_)
complex< double > one (const vec &v)
field_rfunction derived_component_func (derived_component c, const Volume &v, int &nFields, component cs[6])
static bool cross_negative (direction a, direction b)
static direction cross (direction a, direction b)
static bool is_tm (component c)
static bool is_like (ndim d, component c1, component c2)
static void h5_findsize_chunkloop (Fields_Chunk *fc, int ichnk, component cgrid, ivec is, ivec ie, vec s0, vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift, complex< double > shift_phase, const Symmetry &S, int sn, void *data_)
static void h5_output_chunkloop (Fields_Chunk *fc, int ichnk, component cgrid, ivec is, ivec ie, vec s0, vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift, complex< double > shift_phase, const Symmetry &S, int sn, void *data_)
static complex< double > rintegrand_fun (const complex< double > *Fields, const vec &loc, void *data_)
static complex< double > component_fun (const complex< double > *Fields, const vec &loc, void *data_)
static double J (int m, double kr)
static double Jprime (int m, double kr)
static double Jroot (int m, int n)
static double Jmax (int m, int n)
static complex< double > JJ (const vec &v)
static complex< double > JP (const vec &v)
static complex< double > stupid_A (const vec &p)
static complex< double > stupider_A (const vec &p)
static void integrate_chunkloop (Fields_Chunk *fc, int ichunk, component cgrid, ivec is, ivec ie, vec s0, vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift, complex< double > shift_phase, const Symmetry &S, int sn, void *data_)
static complex< double > rfun_wrap (const complex< double > *Fields, const vec &loc, void *data_)
static complex< double > return_the_field (const complex< double > *Fields, const vec &loc, void *integrand_data_)
static ivec vec2diel_floor (const vec &v, double a, const ivec &equal_shift)
static ivec vec2diel_ceil (const vec &v, double a, const ivec &equal_shift)
static int iabs (int i)
const char * make_output_directory (const char *exename, const char *jobname=NULL)
 Utility function to parse the executable name use it to come up with a directory name, avoiding overwriting any existing directory, unless the source file hasn't changed.
void trash_output_directory (const char *dirname)
FILE * create_output_file (const char *dirname, const char *fname)
double max (double a, double b)
double min (double a, double b)
int max (int a, int b)
int min (int a, int b)
static int abs (int a)
static double abs (double a)
static int my_round (double x)
int small_r_metal (int m)
int rmin_bulk (int m)
Symmetry r_to_minus_r_Symmetry (int m)
double wall_time (void)
void abort (const char *fmt,...)
void send (int from, int to, double *data, int size)
void broadcast (int from, double *data, int size)
void broadcast (int from, char *data, int size)
void broadcast (int from, complex< double > *data, int size)
void broadcast (int from, int *data, int size)
complex< double > broadcast (int from, complex< double > data)
double broadcast (int from, double data)
int broadcast (int from, int data)
bool broadcast (int from, bool b)
double max_to_master (double in)
double max_to_all (double in)
int max_to_all (int in)
ivec max_to_all (const ivec &v)
double sum_to_master (double in)
double sum_to_all (double in)
void sum_to_all (const double *in, double *out, int size)
long double sum_to_all (long double in)
int sum_to_all (int in)
int partial_sum_to_all (int in)
complex< double > sum_to_all (complex< double > in)
complex< long double > sum_to_all (complex< long double > in)
bool or_to_all (bool in)
bool and_to_all (bool in)
void all_wait ()
int my_rank ()
int count_processors ()
void master_printf (const char *fmt,...)
void debug_printf (const char *fmt,...)
void master_fprintf (FILE *f, const char *fmt,...)
FILE * master_fopen (const char *name, const char *mode)
void master_fclose (FILE *f)
void begin_critical_section (int tag)
void end_critical_section (int tag)
int am_master ()
static void cp (const char *a, const char *b)
static bool is_ok_dir (const char *dirname)
double expi (int cmp, double x)
bool Src_Times_equal (const Src_Time &t1, const Src_Time &t2)
 this function is necessary to make equality commutative .
void Src_Vol_chunkloop (Fields_Chunk *fc, int ichunk, component c, ivec is, ivec ie, vec s0, vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift, complex< double > shift_phase, const Symmetry &S, int sn, void *data_)
 Adding source volumes can be treated as a kind of "integration" problem, since we need to loop over all the chunks that intersect the source volume, with appropriate interpolation weights at the boundaries so that the integral of the current is fixed regardless of resolution.
static double it (int cmp, double *(f[2]), int ind)
int rstart_0 (const Volume &v, double m)
int rstart_1 (const Volume &v, double m)
static const char * ts2n (time_sink s)
static void pt (double ts[], time_sink s)
double calc_nonlinear_inveps (const double Dsqr, const double Di, const double inveps, const double chi2, const double chi3)
const char * dimension_name (ndim dim)
const char * direction_name (direction d)
const char * component_name (component c)
const char * component_name (derived_component c)
const char * component_name (int c)
vec min (const vec &vec1, const vec &vec2)
vec max (const vec &vec1, const vec &vec2)
ivec min (const ivec &ivec1, const ivec &ivec2)
ivec max (const ivec &ivec1, const ivec &ivec2)
static direction yucky_dir (ndim dim, int n)
static void stupidsort (int *ind, double *w, int l)
static void stupidsort (ivec *locs, double *w, int l)
Geometric_Volume empty_volume (ndim dim)
Volume volone (double zsize, double a)
Volume voltwo (double xsize, double ysize, double a)
Volume vol1d (double zsize, double a)
Volume vol2d (double xsize, double ysize, double a)
Volume vol3d (double xsize, double ysize, double zsize, double a)
Volume volcyl (double rsize, double zsize, double a)
Symmetry rotate4 (direction axis, const Volume &v)
Symmetry rotate2 (direction axis, const Volume &v)
Symmetry mirror (direction axis, const Volume &v)
Symmetry r_to_minus_r_symmetry (double m)
Symmetry identity ()
static double poynting_fun (const complex< double > *Fields, const vec &loc, void *data_)
static double energy_fun (const complex< double > *Fields, const vec &loc, void *data_)
int number_of_directions (ndim dim)
direction start_at_direction (ndim dim)
direction stop_at_direction (ndim dim)
signed_direction flip (signed_direction d)
bool has_direction (ndim dim, direction d)
bool coordinate_mismatch (ndim dim, direction d)
bool is_electric (component c)
bool is_magnetic (component c)
bool is_D (component c)
bool is_derived (int c)
bool is_poynting (derived_component c)
bool is_energydensity (derived_component c)
field_type type (component c)
direction component_direction (int c)
int direction_component (int c, direction d)
direction component_direction (component c)
direction component_direction (derived_component c)
component direction_component (component c, direction d)
derived_component direction_component (derived_component c, direction d)
bool coordinate_mismatch (ndim dim, component c)
bool coordinate_mismatch (ndim dim, derived_component c)
vec veccyl (double rr, double zz)
double abs (const vec &v)
vec zero_vec (ndim di)
vec unit_vec (ndim di, direction d)
vec clean_vec (const vec &v, double val_unused=0.0)
ivec iveccyl (int xx, int yy)
ivec zero_ivec (ndim di)
ivec one_ivec (ndim di)
ivec unit_ivec (ndim di, direction d)
Symmetry r_to_minus_r_Symmetry (double m)

Variables

static const int num_sphere_quad [3] = { 2, 12, 50 }
static const double sphere_quad [3][50][4]
int interrupt = 0
 Incremented when ctrl-C is called.(starts with a zero).
static int kill_time = 2
const double infinity = 1e20
 this should be big enough for us
const double nan = -1.23454321e123
 ideally, a value never encountered in practice
const char Grace_header []
static double ktrans
static double kax
static int m_for_J
static complex< double >(* A_static )(component, const vec &)
static component c_static
static Fieldsf_static
static complex< double > prefactor_static
bool quiet = false
 if true, suppress all non-error messages from Meep
const double pi = 3.141592653589793238462643383276
const int num_bandpts = 32
static FILE * debf = NULL
const char symlink_name [] = "latest_output"
const double Cmax = 0.5
const int NUM_FIELD_COMPONENTS = 15
const int NUM_FIELD_TYPES = 4
vec zero_vec (ndim)
ivec zero_ivec (ndim)
ivec one_ivec (ndim)


Typedef Documentation

typedef void(* meep::bicgstab_op)(const double *x, double *y, void *data)

typedef void(* meep::field_chunkloop)(Fields_Chunk *fc, int ichunk, component cgrid, ivec is, ivec ie, vec s0, vec s1, vec e0, vec e1, double dV0, double dV1, ivec shift, complex< double > shift_phase, const Symmetry &S, int sn, void *chunkloop_data)

field_chunkloop function pointer definition.

Parameters:
fc pointer to the Fields_Chunk to be operated on.
ichun chunk index?
cgrid ?
is ?
ie ?
e0 ?
e1 ?
dV0 ?
dV1 ?
shift ?
shift_phase ?
S a symmetry.
sn ?
chunkloop_data Data needed for the operation presumably.

typedef complex<double>(* meep::field_function)(const complex< double > *Fields, const vec &loc, void *integrand_data_)

typedef double(* meep::field_rfunction)(const complex< double > *Fields, const vec &loc, void *integrand_data_)

typedef double(* meep::fx_func)(const vec &)

typedef double* meep::pdouble


Enumeration Type Documentation

Enumerator:
e_periodic 
e_metallic 
e_magnetic 
e_none 

Enumerator:
High 
Low 
00037 { High=0, Low };

Enumerator:
Ex 
Ey 
Er 
Ep 
Ez 
Hx 
Hy 
Hr 
Hp 
Hz 
Dx 
Dy 
Dr 
Dp 
Dz 
Dielectric 
00031                { Ex=0, Ey, Er, Ep, Ez, Hx, Hy, Hr, Hp, Hz,
00032                  Dx, Dy, Dr, Dp, Dz, Dielectric };

Enumerator:
e_CONNECT_PHASE 
e_CONNECT_NEGATE 
e_CONNECT_COPY 

Enumerator:
Sx 
Sy 
Sr 
Sp 
Sz 
EnergyDensity 
D_EnergyDensity 
H_EnergyDensity 
00033                        { Sx=100, Sy, Sr, Sp, Sz, EnergyDensity,
00034                          D_EnergyDensity, H_EnergyDensity };

Enumerator:
X 
Y 
Z 
R 
P 
NO_DIRECTION 
00038 { X=0,Y,Z,R,P, NO_DIRECTION };

Enumerator:
E_stuff 
H_stuff 
D_stuff 
P_stuff 
00036 { E_stuff=0, H_stuff=1, D_stuff=2, P_stuff=3 };

Enumerator:
e_XY 
e_ERROR_BARS 
00016 { e_XY, e_ERROR_BARS };

Enumerator:
e_incoming 
e_outgoing 
00011 { e_incoming=0, e_outgoing };

enum meep::ndim

Enumerator:
D1 
D2 
D3 
Dcyl 
00035 { D1=0, D2, D3, Dcyl };

Enumerator:
e_connecting 
e_stepping 
e_boundaries 
e_mpiTime 
e_fieldOutput 
e_fourierTransforming 
e_other 


Function Documentation

void meep::abort ( const char *  fmt,
  ... 
)

00105                                  {
00106   va_list ap;
00107   va_start(ap, fmt);
00108   fprintf(stderr, "meep: ");
00109   vfprintf(stderr, fmt, ap);
00110   va_end(ap);
00111   if (fmt[strlen(fmt) - 1] != '\n') fputc('\n', stderr); // force newline
00112 #ifdef HAVE_MPI
00113   MPI_Abort(MPI_COMM_WORLD, 1);
00114 #endif
00115   exit(1);
00116 }

double meep::abs ( const vec &  v  )  [inline]

00366 { return sqrt(v & v); }

static double meep::abs ( double  a  )  [inline, static]

00030 { return fabs(a); }

static int meep::abs ( int  a  )  [inline, static]

00029 { return a < 0 ? -a : a; }

static void meep::add_Dft_Chunkloop ( meep::Fields_Chunk fc,
int  ichunk,
component  cgrid,
ivec  is,
ivec  ie,
vec  s0,
vec  s1,
vec  e0,
vec  e1,
double  dV0,
double  dV1,
ivec  shift,
complex< double >  shift_phase,
const Symmetry &  S,
int  sn,
void *  chunkloop_data 
) [static]

00118   {
00119         Dft_Chunk_Data *data = (Dft_Chunk_Data *) chunkloop_data;
00120         (void) shift; (void) ichunk; // unused
00121 
00122         if (cgrid != Dielectric) abort("dft chunks should use the Dielectric grid");
00123   
00124         component c = S.transform(data->c, -sn);
00125         if (c >= NUM_FIELD_COMPONENTS || !fc->m_f[c][0])
00126           return; // this chunk doesn't have component c
00127 
00128         data->Dft_Chunks = new Dft_Chunk(fc,is,ie,s0,s1,e0,e1,dV0,dV1,
00129                                                                          shift_phase * S.phase_shift(c, sn),
00130                                                                          c, chunkloop_data);
00131   }

void void meep::all_wait (  ) 

00323                 {
00324 #ifdef HAVE_MPI
00325   MPI_Barrier(MPI_COMM_WORLD);
00326 #endif
00327 }

int meep::am_master (  )  [inline]

00051 { return my_rank() == 0; }

bool meep::and_to_all ( bool  in  ) 

00315                          {
00316   int out = in;
00317 #ifdef HAVE_MPI
00318   MPI_Allreduce(&in,&out,1,MPI_INT,MPI_LAND,MPI_COMM_WORLD);
00319 #endif
00320   return (bool) out;
00321 }

static void meep::anisoaverage ( Material_Function &  epsilon,
const Geometric_Volume  dV,
component  ec,
double  invepsrow[3],
double  tol,
int  maxeval 
) [static]

00224                                  {
00225           IVEC_LOOP_LOC(m_v, here);
00226           m_inveps[c][c_d][i] = 1/epsilon.eps(here);
00227         }
00228 #endif
00229       }
00230   } else {
00231     const double smoothing_diameter = 1.0; // FIXME: make this user-changable?
00232 
00233     // may take a long time in 3d, so prepare to print status messages
00234     int npixels = 0, ipixel = 0;
00235     FOR_ELECTRIC_COMPONENTS(c) if (m_v.has_field(c)) {
00236       int loop_npixels = 0;
00237       LOOP_OVER_VOL(m_v, c, i) {
00238         loop_npixels = loop_n1 * loop_n2 * loop_n3;
00239         goto breakout;
00240       }
00241     breakout: npixels += loop_npixels;
00242     }
00243     double last_output_time = wall_time();
00244 
00245     FOR_ELECTRIC_COMPONENTS(c)
00246       if (m_v.has_field(c)) {
00247         FOR_ELECTRIC_COMPONENTS(c2) if (m_v.has_field(c2)) {
00248           direction d = component_direction(c2);
00249           if (!m_inveps[c][d]) m_inveps[c][d] = new double[m_v.ntot()];
00250           if (!m_inveps[c][d]) abort("Memory allocation error.\n");
00251         }

static void meep::array_to_Fields ( const complex< double > *  x,
Fields &  f 
) [static]

00045 {
00046   int ix = 0;
00047   for (int i=0;i<f.m_num_chunks;i++)
00048     if (f.m_chunks[i]->is_mine())
00049       FOR_COMPONENTS(c)
00050         if (f.m_chunks[i]->m_f[c][0] && (is_D(c) || is_magnetic(c))) {
00051           double *fs[3][2];
00052           DOCMP2 { fs[0][cmp] = f.m_chunks[i]->m_f[c][cmp];
00053                    fs[1][cmp] = f.m_chunks[i]->m_f_p_pml[c][cmp];
00054                    fs[2][cmp] = f.m_chunks[i]->m_f_m_pml[c][cmp]; }
00055           for (int k = 0; k < 3; ++k)
00056             if (fs[k][0]) {
00057               LOOP_OVER_VOL_OWNED(f.m_chunks[i]->m_vol, c, idx) {
00058                 fs[k][0][idx] = real(x[ix]);
00059                 fs[k][1][idx] = imag(x[ix]);
00060                 ++ix;
00061               }
00062             }
00063         }
00064   f.force_consistency(H_stuff);
00065   f.force_consistency(D_stuff);
00066 }

void meep::begin_critical_section ( int  tag  ) 

00407 {
00408 #ifdef HAVE_MPI
00409      int process_rank;
00410      MPI_Comm_rank(MPI_COMM_WORLD, &process_rank);
00411      if (process_rank > 0) { /* wait for a message before continuing */
00412           MPI_Status status;
00413           int recv_tag = tag - 1; /* initialize to wrong value */
00414           MPI_Recv(&recv_tag, 1, MPI_INT, process_rank - 1, tag, 
00415                    MPI_COMM_WORLD, &status);
00416           if (recv_tag != tag) abort("invalid tag received in begin_critical_section");
00417      }
00418 #else
00419      UNUSED(tag);
00420 #endif
00421 }

int meep::bicgstabL ( const int  L,
const int  n,
double *  x,
bicgstab_op  A,
void *  Adata,
const double *  b,
const double  tol,
int *  iters,
double *  work,
const bool  quiet 
)

00108 {
00109   if (!work) return (2*L+3)*n; // required workspace
00110 
00111   pdouble *r = new pdouble[L+1];
00112   pdouble *u = new pdouble[L+1];
00113   for (int i = 0; i <= L; ++i) {
00114     r[i] = work + i * n;
00115     u[i] = work + (L+1 + i) * n;
00116   }
00117 
00118   double bnrm = norm2(n, b);
00119   if (bnrm == 0.0) bnrm = 1.0;
00120   
00121   int iter = 0;
00122   double last_output_wall_time = wall_time();
00123 
00124   double *gamma = new double[L + 1];
00125   double *gamma_p = new double[L + 1];
00126   double *gamma_pp = new double[L + 1];
00127 
00128   double *tau = new double[L * L];
00129   double *sigma = new double[L + 1];
00130 
00131   int ierr = 0; // error code to return, if any
00132   const double breaktol = 1e-30;
00133 
00134   /**** FIXME: check for breakdown conditions(?) during iteration  ****/
00135 
00136   // rtilde = r[0] = b - Ax
00137   double *rtilde = work + (2*L+2) * n;
00138   A(x, r[0], Adata);
00139   for (int m = 0; m < n; ++m) rtilde[m] = r[0][m] = b[m] - r[0][m];
00140 
00141   { /* Sleipjen normalizes rtilde in his code; it seems to help slightly */
00142     double s = 1.0 / norm2(n, rtilde);
00143     for (int m = 0; m < n; ++m) rtilde[m] *= s;
00144   }
00145 
00146   memset(u[0], 0, sizeof(double) * n); // u[0] = 0
00147 
00148   double rho = 1.0, alpha = 0, omega = 1;
00149 
00150   double resid;
00151   while ((resid = norm2(n, r[0])) > tol * bnrm) {
00152     ++iter;
00153     if (!quiet && wall_time() > last_output_wall_time + MIN_OUTPUT_TIME) {
00154       master_printf("residual[%d] = %g\n", iter, resid / bnrm);
00155       last_output_wall_time = wall_time();
00156     }
00157 
00158     rho = -omega * rho;
00159     for (int j = 0; j < L; ++j) {
00160       if (fabs(rho) < breaktol) { ierr = -1; goto finish; }
00161       double rho1 = dot(n, r[j], rtilde);
00162       double beta = alpha * rho1 / rho;
00163       rho = rho1;
00164       for (int i = 0; i <= j; ++i)
00165         for (int m = 0; m < n; ++m) u[i][m] = r[i][m] - beta * u[i][m];
00166       A(u[j], u[j+1], Adata);
00167       alpha = rho / dot(n, u[j+1], rtilde);
00168       for (int i = 0; i <= j; ++i)
00169         xpay(n, r[i], -alpha, u[i+1]);
00170       A(r[j], r[j+1], Adata);
00171       xpay(n, x, alpha, u[0]);
00172     }
00173 
00174     for (int j = 1; j <= L; ++j) {
00175       for (int i = 1; i < j; ++i) {
00176         int ij = (j-1)*L + (i-1);
00177         tau[ij] = dot(n, r[j], r[i]) / sigma[i];
00178         xpay(n, r[j], -tau[ij], r[i]);
00179       }
00180       sigma[j] = dot(n, r[j],r[j]);
00181       gamma_p[j] = dot(n, r[0], r[j]) / sigma[j];
00182     }
00183 
00184     omega = gamma[L] = gamma_p[L];
00185     for (int j = L-1; j >= 1; --j) {
00186       gamma[j] = gamma_p[j];
00187       for (int i = j+1; i <= L; ++i)
00188         gamma[j] -= tau[(i-1)*L + (j-1)] * gamma[i];
00189     }
00190     for (int j = 1; j < L; ++j) {
00191       gamma_pp[j] = gamma[j+1];
00192       for (int i = j+1; i < L; ++i)
00193         gamma_pp[j] += tau[(i-1)*L + (j-1)] * gamma[i+1];
00194     }
00195     
00196     xpay(n, x, gamma[1], r[0]);
00197     xpay(n, r[0], -gamma_p[L], r[L]);
00198     xpay(n, u[0], -gamma[L], u[L]);
00199     for (int j = 1; j < L; ++j) { /* TODO: use blas DGEMV (for L > 2) */
00200       xpay(n, x, gamma_pp[j], r[j]);
00201       xpay(n, r[0], -gamma_p[j], r[j]);
00202       xpay(n, u[0], -gamma[j], u[j]);
00203     }
00204 
00205     if (iter == *iters) { ierr = 1; break; }
00206   }
00207 
00208   if (!quiet) master_printf("final residual = %g\n", norm2(n, r[0]) / bnrm);
00209 
00210  finish:
00211   delete[] sigma;
00212   delete[] tau;
00213   delete[] gamma_pp;
00214   delete[] gamma_p;
00215   delete[] gamma;
00216   delete[] u;
00217   delete[] r;
00218 
00219   *iters = iter;
00220   return ierr;
00221 }

bool meep::broadcast ( int  from,
bool  b 
)

00205                                  {
00206   return broadcast(from, (int) b);
00207 }

int meep::broadcast ( int  from,
int  data 
)

00196                                   {
00197 #ifdef HAVE_MPI
00198   MPI_Bcast(&data, 1, MPI_INT, from, MPI_COMM_WORLD);
00199 #else
00200   UNUSED(from);
00201 #endif
00202   return data;
00203 }

double meep::broadcast ( int  from,
double  data 
)

00187                                         {
00188 #ifdef HAVE_MPI
00189   MPI_Bcast(&data, 1, MPI_DOUBLE, from, MPI_COMM_WORLD);
00190 #else
00191   UNUSED(from);
00192 #endif
00193   return data;
00194 }

complex< double > meep::broadcast ( int  from,
complex< double >  data 
)

00178                                                           {
00179 #ifdef HAVE_MPI
00180   MPI_Bcast(&data, 2, MPI_DOUBLE, from, MPI_COMM_WORLD);
00181 #else
00182   UNUSED(from);
00183 #endif
00184   return data;
00185 }

void meep::broadcast ( int  from,
int *  data,
int  size 
)

00167                                               {
00168 #ifdef HAVE_MPI
00169   if (size == 0) return;
00170   MPI_Bcast(data, size, MPI_INT, from, MPI_COMM_WORLD);
00171 #else
00172   UNUSED(from);
00173   UNUSED(data);
00174   UNUSED(size);
00175 #endif
00176 }

void meep::broadcast ( int  from,
complex< double > *  data,
int  size 
)

00156                                                           {
00157 #ifdef HAVE_MPI
00158   if (size == 0) return;
00159   MPI_Bcast(data, 2*size, MPI_DOUBLE, from, MPI_COMM_WORLD);
00160 #else
00161   UNUSED(from);
00162   UNUSED(data);
00163   UNUSED(size);
00164 #endif
00165 }

void meep::broadcast ( int  from,
char *  data,
int  size 
)

00145                                                {
00146 #ifdef HAVE_MPI
00147   if (size == 0) return;
00148   MPI_Bcast(data, size, MPI_CHAR, from, MPI_COMM_WORLD);
00149 #else
00150   UNUSED(from);
00151   UNUSED(data);
00152   UNUSED(size);
00153 #endif
00154 }

void meep::broadcast ( int  from,
double *  data,
int  size 
)

00134                                                  {
00135 #ifdef HAVE_MPI
00136   if (size == 0) return;
00137   MPI_Bcast(data, size, MPI_DOUBLE, from, MPI_COMM_WORLD);
00138 #else
00139   UNUSED(from);
00140   UNUSED(data);
00141   UNUSED(size);
00142 #endif
00143 }

double meep::calc_nonlinear_inveps ( const double  Dsqr,
const double  Di,
const double  inveps,
const double  chi2,
const double  chi3 
) [inline]

Given Dsqr = |D|^2 and Di = component of D, compute the factor f so that Ei = inveps * f * Di. In principle, this would involve solving a cubic equation, but instead we use a Pade approximant that is accurate to several orders. This is inaccurate if the nonlinear index change is large, of course, but in that case the chi2/chi3 power-series expansion isn't accurate anyway, so the cubic isn't physical there either.

00033                                                                           {
00034   double c2 = Di*chi2*(inveps*inveps);
00035   double c3 = Dsqr*chi3*(inveps*(inveps*inveps));
00036   return (1 + c2 + 2*c3)/(1 + 2*c2 + 3*c3);
00037 }

vec meep::clean_vec ( const vec &  v,
double  val_unused = 0.0 
) [inline]

00379                                                             {
00380   vec vc(v.dim, val_unused);
00381   LOOP_OVER_DIRECTIONS(v.dim, d) vc.set_direction(d, v.in_direction(d));
00382   return vc;
00383 }

direction meep::component_direction ( derived_component  c  )  [inline]

00206                                                           {
00207   switch (c) {
00208   case Sx: return X;
00209   case Sy: return Y;
00210   case Sz: return Z;
00211   case Sr: return R;
00212   case Sp: return P;
00213   case EnergyDensity: case D_EnergyDensity: case H_EnergyDensity:
00214     return NO_DIRECTION;
00215   }
00216   return X; // This code is never reached...
00217 }

direction meep::component_direction ( component  c  )  [inline]

00195                                                   {
00196   switch (c) {
00197   case Ex: case Hx: case Dx: return X;
00198   case Ey: case Hy: case Dy: return Y;
00199   case Ez: case Hz: case Dz: return Z;
00200   case Er: case Hr: case Dr: return R;
00201   case Ep: case Hp: case Dp: return P;
00202   case Dielectric: return NO_DIRECTION;
00203   }
00204   return X; // This code is never reached...
00205 }

direction meep::component_direction ( int  c  )  [inline]

00218                                             {
00219   if (is_derived(c))
00220     return component_direction(derived_component(c));
00221   else
00222     return component_direction(component(c));
00223 }

static complex<double> meep::component_fun ( const complex< double > *  Fields,
const vec &  loc,
void *  data_ 
) [static]

00346 {
00347      (void) loc; // unused
00348      (void) data_; // unused
00349      return Fields[0];
00350 }

const char * meep::component_name ( int  c  ) 

00108                                   {
00109   return (is_derived(c) ? component_name(derived_component(c))
00110           : component_name(component(c)));
00111 }

const char * meep::component_name ( derived_component  c  ) 

00093                                                 {
00094   if (!is_derived(int(c))) return component_name(component(c));
00095   switch (c) {
00096   case Sr: return "sr";
00097   case Sp: return "sp";
00098   case Sz: return "sz";
00099   case Sx: return "sx";
00100   case Sy: return "sy";
00101   case EnergyDensity: return "energy";
00102   case D_EnergyDensity: return "denergy";
00103   case H_EnergyDensity: return "henergy";
00104   }
00105   return "Error in component_name";
00106 }

const char * meep::component_name ( component  c  ) 

00070                                         {
00071   if (is_derived(int(c))) return component_name(derived_component(c));
00072   switch (c) {
00073   case Er: return "er";
00074   case Ep: return "ep";
00075   case Ez: return "ez";
00076   case Hr: return "hr";
00077   case Hp: return "hp";
00078   case Hz: return "hz";
00079   case Ex: return "ex";
00080   case Ey: return "ey";
00081   case Hx: return "hx";
00082   case Hy: return "hy";
00083   case Dx: return "dx";
00084   case Dy: return "dy";
00085   case Dz: return "dz";
00086   case Dr: return "dr";
00087   case Dp: return "dp";
00088   case Dielectric: return "eps";
00089   }
00090   return "Error in component_name";
00091 }

bool meep::coordinate_mismatch ( ndim  dim,
derived_component  c 
) [inline]

00266                                                                {
00267   return coordinate_mismatch(dim, component_direction(c));
00268 }

bool meep::coordinate_mismatch ( ndim  dim,
component  c 
) [inline]

00263                                                        {
00264   return coordinate_mismatch(dim, component_direction(c));
00265 }

bool meep::coordinate_mismatch ( ndim  dim,
direction  d 
) [inline]

00166                                                        {
00167   return (d != NO_DIRECTION &&
00168           ((dim >= D1 && dim <= D3 && d != X && d != Y && d != Z) ||
00169            (dim == Dcyl && d != R && d != P && d != Z)));
00170 }

int meep::count_processors (  ) 

00339                        {
00340 #ifdef HAVE_MPI
00341   int n;
00342   MPI_Comm_size(MPI_COMM_WORLD, &n);
00343   return n;
00344 #else
00345   return 1;
00346 #endif
00347 }

static void meep::cp ( const char *  a,
const char *  b 
) [static]

00057                                              {
00058   FILE *fa = fopen(a,"r");
00059   FILE *fb = fopen(b,"w");
00060   if (!fa || !fb) return;
00061   int ca;
00062   while (1) {
00063     ca = getc(fa);
00064     if (ca == EOF) break;
00065     putc(ca,fb);
00066   }
00067   fclose(fa);
00068   fclose(fb);
00069 }

FILE * meep::create_output_file ( const char *  dirname,
const char *  fname 
)

00083                                                                  {
00084   const int buflen = 300;
00085   char n[buflen];
00086   snprintf(n, buflen, "%s/%s", dirname, fname);
00087   FILE *o = master_fopen(n, "w");
00088   if (!o) abort("Unable to create file %s!\n", n);
00089   return o;
00090 }

static direction meep::cross ( direction  a,
direction  b 
) [inline, static]

00039                                                           {
00040     if (a < R && b < R) return (direction)((3+2*a-b)%3);
00041     return (direction) (2 + (3+2*(a-2)-(b-2))%3);
00042   }

static bool meep::cross_negative ( direction  a,
direction  b 
) [inline, static]

00033                                                               {
00034     return ((3+b-a)%3) == 2;
00035   }

void meep::deal_with_ctrl_c ( int  stop_now  ) 

Allows you to hit ctrl-C to tell your calculation to stop and clean up.

00041                                     {
00042   kill_time = stop_now;
00043   if (signal(SIGINT, handle_control_c) == SIG_IGN)
00044     signal(SIGINT, SIG_IGN); // ignore if parent process was ignoring
00045 }

void void meep::debug_printf ( const char *  fmt,
  ... 
)

00360                                         {
00361   va_list ap;
00362   va_start(ap, fmt);
00363   if (debf == NULL) {
00364     char temp[50];
00365     snprintf(temp, 50, "debug_out_%d", my_rank());
00366     debf = fopen(temp,"w");
00367     if (!debf) abort("Unable to open debug output %s\n", temp);
00368   }
00369   vfprintf(debf, fmt, ap);
00370   fflush(debf);
00371   va_end(ap);
00372 }

field_rfunction meep::derived_component_func ( derived_component  c,
const Volume &  v,
int &  nFields,
component  cs[6] 
)

01409                                                                       {
01410   switch (c) {
01411   case Sx: case Sy: case Sz: case Sr: case Sp:
01412     switch (c) {
01413     case Sx: cs[0] = Ey; cs[1] = Hz; break;
01414     case Sy: cs[0] = Ez; cs[1] = Hx; break;
01415     case Sz: cs[0] = Ex; cs[1] = Hy; break;
01416     case Sr: cs[0] = Ep; cs[1] = Hz; break;
01417     case Sp: cs[0] = Ez; cs[1] = Hr; break;
01418     default: break; // never reached
01419     }
01420     nFields = 4;
01421     cs[2] = direction_component(Ex, component_direction(cs[1]));
01422     cs[3] = direction_component(Hx, component_direction(cs[0]));
01423     return poynting_fun;
01424 
01425   case EnergyDensity: case D_EnergyDensity: case H_EnergyDensity:
01426     nFields = 0;
01427     if (c != H_EnergyDensity)
01428       FOR_ELECTRIC_COMPONENTS(c0) if (v.has_field(c0)) {
01429         cs[nFields++] = c0;
01430         cs[nFields++] = direction_component(Dx, component_direction(c0));
01431       }
01432     if (c != D_EnergyDensity)
01433       FOR_MAGNETIC_COMPONENTS(c0) if (v.has_field(c0)) {
01434         cs[nFields++] = c0;
01435         cs[nFields++] = c0;
01436       }
01437     if (nFields > 6) abort("too many field components");
01438     return energy_fun;
01439 
01440   default: 
01441     abort("unknown derived_component in derived_component_func");
01442   }
01443   return 0;
01444 }

static int meep::Dft_Chunks_Ntotal ( Dft_Chunk *  Dft_Chunks,
int *  my_start 
) [static]

00244                                                                      {
00245         int n = 0;
00246         for (Dft_Chunk *cur = Dft_Chunks; cur; cur = cur->m_next_in_dft)
00247           n += cur->m_N * cur->m_Nomega * 2;
00248         *my_start = partial_sum_to_all(n) - n; // sum(n) for processes before this
00249         return sum_to_all(n);
00250   }

const char * meep::dimension_name ( ndim  dim  ) 

00048                                      {
00049   switch (dim) {
00050   case D1: return "1D";
00051   case D2: return "2D";
00052   case D3: return "3D";
00053   case Dcyl: return "Cylindrical";
00054   }
00055   return "Error in dimension_name";
00056 }

derived_component meep::direction_component ( derived_component  c,
direction  d 
) [inline]

00241                                                                                {
00242   derived_component start_point;
00243   if (is_poynting(c)) start_point = Sx;
00244   else if (is_energydensity(c) && d == NO_DIRECTION) return c;
00245   else abort("unknown field component %d", c);
00246   switch (d) {
00247   case X: return start_point;
00248   case Y: return (derived_component) (start_point + 1);
00249   case Z: return (derived_component) (start_point + 4);
00250   case R: return (derived_component) (start_point + 2);
00251   case P: return (derived_component) (start_point + 3);
00252   case NO_DIRECTION: abort("vector %d derived_component in NO_DIRECTION", c);
00253   }
00254   return Sx; // This is never reached.
00255 }

component meep::direction_component ( component  c,
direction  d 
) [inline]

00224                                                                {
00225   component start_point;
00226   if (is_electric(c)) start_point = Ex;
00227   else if (is_magnetic(c)) start_point = Hx;
00228   else if (is_D(c)) start_point = Dx;
00229   else if (c == Dielectric && d == NO_DIRECTION) return Dielectric;
00230   else abort("unknown field component %d", c);
00231   switch (d) {
00232   case X: return start_point;
00233   case Y: return (component) (start_point + 1);
00234   case Z: return (component) (start_point + 4);
00235   case R: return (component) (start_point + 2);
00236   case P: return (component) (start_point + 3);
00237   case NO_DIRECTION: abort("vector %d component in NO_DIRECTION", c);
00238   }
00239   return Ex; // This is never reached.
00240 }

int meep::direction_component ( int  c,
direction  d 
) [inline]

00256                                                    {
00257   if (is_derived(c))
00258     return int(direction_component(derived_component(c), d));
00259   else
00260     return int(direction_component(component(c), d));
00261 }

const char * meep::direction_name ( direction  d  ) 

00058                                         {
00059   switch (d) {
00060   case X: return "x";
00061   case Y: return "y";
00062   case Z: return "z";
00063   case R: return "r";
00064   case P: return "phi";
00065   case NO_DIRECTION: return "no_direction";
00066   }
00067   return "Error in direction_name";
00068 }

int meep::do_harminv ( complex< double > *  data,
int  n,
double  dt,
double  fmin,
double  fmax,
int  maxbands,
complex< double > *  amps,
double *  freq_re,
double *  freq_im,
double *  errors,
double  spectral_density,
double  Q_thresh,
double  rel_err_thresh,
double  err_thresh,
double  rel_amp_thresh,
double  amp_thresh 
)

Performs harmonic inversion of a given signal.

Perform harmonic inversion.

See harminv documentation for detail.

Parameters:
data Complex data for harmonic inversion.
n The size of the data for inversion.
dt Size of the timestep-> gets you units right.
fmin Minimum frequency.
fmax Maximum frequency.
maxbands Maximum number of modes to find.
amps Complex amplitudes.
freq_re Pointer to real frequency of modes.
freq_im Pointer to imaginary frequencies.
errors Pointer to errors array.
spectral_density No idea.
Q_thresh No idea.
rel_err_thress No idea.
err_thresh No idea.
rel_amp_thresh No idea.
amp_thres No idea.
00096   {
00097 #ifndef HAVE_HARMINV
00098     abort("compiled without Harminv library, required for do_harminv");
00099     return 0;
00100 #else
00101     int numfreqs = int(fabs(fmax-fmin)*dt*n*spectral_density); // c.f. harminv
00102     if (numfreqs > 150) numfreqs = 150; // prevent matrices from getting too big
00103     if (numfreqs < 2) numfreqs = 2;
00104 
00105     if (maxbands > numfreqs)
00106       numfreqs = maxbands;
00107 
00108     // check for all zeros in input
00109     // data is a size n array.
00110     {
00111       int i;
00112       for (i = 0; i < n && data[i] == 0.0; i++)
00113         ;
00114       if (i == n)
00115         return 0;
00116     }
00117 
00118 #if 0
00119     // debugging: save data file and arguments for standalone harminv program
00120     {
00121       FILE *f = fopen("harminv.dat", "w");
00122       fprintf(f, "# -f %d -t %g %g-%g -Q %e -e %e -E %e -a %e -A %e -F\n",
00123               numfreqs, dt, fmin, fmax,
00124               Q_thresh, rel_err_thresh, err_thresh, rel_amp_thresh, amp_thresh);
00125       for (int i = 0; i < n; ++i)
00126         fprintf(f, "%g%+gi\n", real(data[i]), imag(data[i]));
00127       fclose(f);
00128     }
00129 #endif
00130 
00131     harminv_data hd = harminv_data_create(n, data, fmin*dt, fmax*dt, numfreqs);
00132     harminv_solve(hd);
00133 
00134     int nf = harminv_get_num_freqs(hd);
00135     if (nf == 0) return 0;
00136     int *fsort = new int[nf]; // indices of frequencies, sorted as needed
00137   
00138     for (int i = 0; i < nf; ++i)
00139       fsort[i] = i;
00140     for (int i = 0; i < nf; ++i) // sort in increasing order of error
00141       for (int j = i + 1; j < nf; ++j) 
00142         if (harminv_get_freq_error(hd, fsort[i]) >
00143             harminv_get_freq_error(hd, fsort[j])) {
00144           int k = fsort[i];
00145           fsort[i] = fsort[j];
00146           fsort[j] = k;
00147         }
00148   
00149     double min_err = harminv_get_freq_error(hd, fsort[0]);
00150     double max_amp = abs(harminv_get_amplitude(hd, 0));
00151     for (int i = 1; i < nf; ++i) {
00152       double amp = abs(harminv_get_amplitude(hd, i));
00153       if (max_amp < amp)
00154         max_amp = amp;
00155     }
00156     { // eliminate modes that fall outside the various thresholds:
00157       int j = 0;
00158       for (int i = 0; i < nf; ++i) {
00159         double f = abs(harminv_get_freq(hd, fsort[i]) / dt);
00160         double err = harminv_get_freq_error(hd, fsort[i]);
00161         double amp = abs(harminv_get_amplitude(hd, fsort[i]));
00162         if (f >= fmin && f <= fmax
00163             && abs(harminv_get_Q(hd, fsort[i])) > Q_thresh
00164             && err < err_thresh
00165             && err < rel_err_thresh * min_err
00166             && amp > amp_thresh
00167             && amp > rel_amp_thresh * max_amp) {
00168           fsort[j++] = fsort[i];
00169         }
00170       }
00171       nf = j;
00172     }
00173     { // eliminate positive/negative frequency pairs
00174       // set indices to -1 for frequencies to be eliminated
00175       for (int i = 0; i < nf; ++i) 
00176         if (fsort[i] != -1) { // i hasn't been eliminated yet
00177           double f = harminv_get_freq(hd, fsort[i]);
00178           if (f < 0.0) {
00179             double kdiff = -2 * f;
00180             int kpos = i;
00181             for (int k = 0; k < nf; ++k) // search for closest positive freq.
00182               if (fsort[k] != -1) { // k hasn't been eliminated yet
00183                 double fdiff = abs(harminv_get_freq(hd, fsort[k]) + f);
00184                 if (fdiff < kdiff) {
00185                   kpos = k;
00186                   kdiff = fdiff;
00187                 }
00188               }
00189             if (kpos != i && kdiff < 2.0 / n) { // consider them the same
00190               // pick the one with the smaller error
00191               if (harminv_get_freq_error(hd, fsort[i]) <
00192                   harminv_get_freq_error(hd, fsort[kpos]))
00193                 fsort[kpos] = -1;
00194               else
00195                 fsort[i] = -1;
00196             }
00197           }
00198         }
00199       int j = 0;
00200       for (int i = 0; i < nf; ++i) // remove the eliminated indices
00201         if (fsort[i] != -1)
00202           fsort[j++] = fsort[i];
00203       nf = j;
00204     }
00205   
00206     if (nf > maxbands)
00207       nf = maxbands;
00208   
00209     // sort again, this time in increasing order of freq:
00210     for (int i = 0; i < nf; ++i) // simple O(nf^2) sort
00211       for (int j = i + 1; j < nf; ++j) 
00212         if (abs(harminv_get_freq(hd, fsort[i])) >
00213             abs(harminv_get_freq(hd, fsort[j]))) {
00214           int k = fsort[i];
00215           fsort[i] = fsort[j];
00216           fsort[j] = k;
00217         }
00218   
00219     for (int i = 0; i < nf; ++i) {
00220       complex<double> freq = harminv_get_omega(hd, fsort[i]) / (2*pi*dt);
00221       freq_re[i] = abs(real(freq));
00222       freq_im[i] = imag(freq);
00223       amps[i] = harminv_get_amplitude(hd, fsort[i]);
00224       if (errors)
00225         errors[i] = harminv_get_freq_error(hd, fsort[i]);
00226     }
00227 
00228     delete[] fsort;
00229     harminv_data_destroy(hd);
00230     return nf;
00231 #endif
00232   }

static double meep::dot ( int  n,
const double *  x,
const double *  y 
) [static]

00079 {
00080   double sum = 0;
00081   for (int i = 0; i < n; ++i) sum += x[i] * y[i];
00082   return sum_to_all(sum);
00083 }

static complex<double> meep::dot3_max_integrand ( const complex< double > *  Fields,
const vec &  loc,
void *  data_ 
) [static]

00245 {
00246   (void) loc; (void) data_; // unused;
00247   return (real(conj(Fields[0]) * Fields[3]) +
00248           real(conj(Fields[1]) * Fields[4]) +
00249           real(conj(Fields[2]) * Fields[5]));
00250 }

static complex<double> meep::dot_fx_integrand ( const complex< double > *  Fields,
const vec &  loc,
void *  data_ 
) [static]

00282                                                                      {
00283   fx_func fx = (fx_func) data_;
00284   return (real(conj(Fields[0]) * Fields[1]) * fx(loc));
00285 }

static complex<double> meep::dot_integrand ( const complex< double > *  Fields,
const vec &  loc,
void *  data_ 
) [static]

00075 {
00076   (void) loc; (void) data_; // unused;
00077   return real(conj(Fields[0]) * Fields[1]);
00078 }

Geometric_Volume meep::empty_volume ( ndim  dim  ) 

00596                                         {
00597   Geometric_Volume out(dim);
00598   LOOP_OVER_DIRECTIONS(dim,d) {
00599     out.set_direction_max(d,0.0);
00600     out.set_direction_min(d,0.0);
00601   }
00602   return out;
00603 }

void meep::end_critical_section ( int  tag  ) 

00424 {
00425 #ifdef HAVE_MPI
00426      int process_rank, num_procs;
00427      MPI_Comm_rank(MPI_COMM_WORLD, &process_rank);
00428      MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
00429      if (process_rank != num_procs - 1) { /* send a message to next process */
00430           MPI_Send(&tag, 1, MPI_INT, process_rank + 1, tag, 
00431                    MPI_COMM_WORLD);
00432      }
00433 #else
00434      UNUSED(tag);
00435 #endif
00436 }

static double meep::energy_fun ( const complex< double > *  Fields,
const vec &  loc,
void *  data_ 
) [static]

01399 {
01400      (void) loc; // unused
01401      int nFields = *((int *) data_) / 2;
01402      double sum = 0;
01403      for (int k = 0; k < nFields; ++k)
01404        sum += real(conj(Fields[2*k]) * Fields[2*k+1]);
01405      return sum * 0.5;
01406 }

double meep::expi ( int  cmp,
double  x 
) [inline]

00292                                         {
00293          return (cmp) ? cos(x) : sin(x);
00294   }

static void meep::fieldop ( const double *  xr,
double *  yr,
void *  data_ 
) [static]

00076 {
00077   const complex<double> *x = reinterpret_cast<const complex<double>*>(xr);
00078   complex<double> *y = reinterpret_cast<complex<double>*>(yr);
00079   fieldop_data *data = (fieldop_data *) data_;
00080   array_to_Fields(x, *data->f);
00081   data->f->step();
00082   Fields_to_array(*data->f, y);
00083   int n = data->n;
00084   double dt_inv = 1.0 / data->f->m_dt;
00085   complex<double> iomega = data->iomega;
00086   for (int i = 0; i < n; ++i) y[i] = (y[i] - x[i]) * dt_inv + iomega * x[i];
00087   data->iters++;
00088 }

static void meep::Fields_to_array ( const Fields &  f,
complex< double > *  x 
) [static]

00024 {
00025   int ix = 0;
00026   for (int i=0;i<f.m_num_chunks;i++)
00027     if (f.m_chunks[i]->is_mine())
00028       FOR_COMPONENTS(c)
00029         if (f.m_chunks[i]->m_f[c][0] && (is_D(c) || is_magnetic(c))) {
00030           double *fs[3][2];
00031           // TODO: this is somewhat wasteful, because at least
00032           // one of f/m_f_p_pml/m_f_m_pml is redundant.
00033           DOCMP2 { fs[0][cmp] = f.m_chunks[i]->m_f[c][cmp];
00034                    fs[1][cmp] = f.m_chunks[i]->m_f_p_pml[c][cmp];
00035                    fs[2][cmp] = f.m_chunks[i]->m_f_m_pml[c][cmp]; }
00036           for (int k = 0; k < 3; ++k)
00037             if (fs[k][0]) {
00038               LOOP_OVER_VOL_OWNED(f.m_chunks[i]->m_vol, c, idx)
00039                 x[ix++] = complex<double>(fs[k][0][idx], fs[k][1][idx]);
00040             }
00041         }
00042 }

signed_direction meep::flip ( signed_direction  d  )  [inline]

00154                                                  {
00155   signed_direction d2 = d;
00156   d2.flipped = !d.flipped;
00157   return d2;
00158 }

static void meep::h5_findsize_chunkloop ( Fields_Chunk *  fc,
int  ichnk,
component  cgrid,
ivec  is,
ivec  ie,
vec  s0,
vec  s1,
vec  e0,
vec  e1,
double  dV0,
double  dV1,
ivec  shift,
complex< double >  shift_phase,
const Symmetry &  S,
int  sn,
void *  data_ 
) [static]

00067 {
00068   h5_output_data *data = (h5_output_data *) data_;
00069   ivec isS = S.transform(is, sn) + shift;
00070   ivec ieS = S.transform(ie, sn) + shift;
00071   data->min_corner = min(data->min_corner, min(isS, ieS));
00072   data->max_corner = max(data->max_corner, max(isS, ieS));
00073   data->num_chunks++;
00074   int bufsz = 1;
00075   LOOP_OVER_DIRECTIONS(fc->m_vol.m_dim, d)
00076     bufsz *= (ie.in_direction(d) - is.in_direction(d)) / 2 + 1;
00077   data->bufsz = max(data->bufsz, bufsz);
00078 }

static void meep::h5_output_chunkloop ( Fields_Chunk *  fc,
int  ichnk,
component  cgrid,
ivec  is,
ivec  ie,
vec  s0,
vec  s1,
vec  e0,
vec  e1,
double  dV0,
double  dV1,
ivec  shift,
complex< double >  shift_phase,
const Symmetry &  S,
int  sn,
void *  data_ 
) [static]

00087 {
00088   h5_output_data *data = (h5_output_data *) data_;
00089 
00090   //-----------------------------------------------------------------------//
00091   // Find output chunk dimensions and strides, etc.
00092 
00093   int start[3]={0,0,0}, count[3]={1,1,1};
00094   int offset[3]={0,0,0}, stride[3]={1,1,1};
00095 
00096   ivec isS = S.transform(is, sn) + shift;
00097   ivec ieS = S.transform(ie, sn) + shift;
00098   
00099   // figure out what yucky_directions (in LOOP_OVER_IVECS)
00100   // correspond to what directions in the transformed vectors (in output).
00101   ivec permute(zero_ivec(fc->m_vol.m_dim));
00102   for (int i = 0; i < 3; ++i) 
00103     permute.set_direction(fc->m_vol.yucky_direction(i), i);
00104   permute = S.transform_unshifted(permute, sn);
00105   LOOP_OVER_DIRECTIONS(permute.dim, d)
00106     permute.set_direction(d, abs(permute.in_direction(d)));
00107   
00108   // compute the size of the chunk to output, and its strides etc.
00109   for (int i = 0; i < data->rank; ++i) {
00110     direction d = data->ds[i];
00111     int isd = isS.in_direction(d), ied = ieS.in_direction(d);
00112     start[i] = (min(isd, ied) - data->min_corner.in_direction(d)) / 2;
00113     count[i] = abs(ied - isd) / 2 + 1;
00114     int j = permute.in_direction(d);
00115     if (ied < isd) offset[permute.in_direction(d)] = count[i] - 1;
00116   }
00117   for (int i = 0; i < data->rank; ++i) {
00118     direction d = data->ds[i];
00119     int j = permute.in_direction(d);
00120     for (int k = i + 1; k < data->rank; ++k) stride[j] *= count[k];
00121     offset[j] *= stride[j];
00122     if (offset[j]) stride[j] *= -1;
00123   }
00124   
00125   //-----------------------------------------------------------------------//
00126   // Compute the function to output, exactly as in Fields::integrate,
00127   // except that here we store its values in a buffer instead of integrating.
00128 
00129   int *off = data->offsets;
00130   component *cS = data->cS;
00131   complex<double> *Fields = data->Fields, *ph = data->ph;
00132   complex<long double> sum = 0.0;
00133   double maxabs = 0;
00134   const component *iecs = data->inveps_cs;
00135   const direction *ieds = data->inveps_ds;
00136   int *ieos = data->inveps_offsets;
00137 
00138   for (int i = 0; i < data->num_Fields; ++i) {
00139     cS[i] = S.transform(data->components[i], -sn);
00140     if (cS[i] == Dielectric)
00141       ph[i] = 1.0;
00142     else {
00143       fc->m_vol.yee2diel_offsets(cS[i], off[2*i], off[2*i+1]);
00144       ph[i] = shift_phase * S.phase_shift(cS[i], sn);
00145     }
00146   }
00147   for (int k = 0; k < data->ninveps; ++k)
00148     fc->m_vol.yee2diel_offsets(iecs[k], ieos[2*k], ieos[2*k+1]);
00149 
00150   vec rshift(shift * (0.5*fc->m_vol.m_inva));
00151   LOOP_OVER_IVECS(fc->m_vol, is, ie, idx) {
00152     IVEC_LOOP_LOC(fc->m_vol, loc);
00153     loc = S.transform(loc, sn) + rshift;
00154 
00155     for (int i = 0; i < data->num_Fields; ++i) {
00156       if (cS[i] == Dielectric) {
00157         double tr = 0.0;
00158         for (int k = 0; k < data->ninveps; ++k)
00159           tr += (fc->m_structChunk->m_inveps[iecs[k]][ieds[k]][idx]
00160                  + fc->m_structChunk->m_inveps[iecs[k]][ieds[k]][idx+ieos[2*k]]
00161                  + fc->m_structChunk->m_inveps[iecs[k]][ieds[k]][idx+ieos[1+2*k]]
00162                  + fc->m_structChunk->m_inveps[iecs[k]][ieds[k]][idx+ieos[2*k]+ieos[1+2*k]]);
00163         Fields[i] = (4 * data->ninveps) / tr;
00164       }
00165       else {
00166         double f[2];
00167         for (int k = 0; k < 2; ++k)
00168           if (fc->m_f[cS[i]][k])
00169             f[k] = 0.25 * (fc->m_f[cS[i]][k][idx]
00170                            + fc->m_f[cS[i]][k][idx+off[2*i]]
00171                            + fc->m_f[cS[i]][k][idx+off[2*i+1]]
00172                            + fc->m_f[cS[i]][k][idx+off[2*i]+off[2*i+1]]);
00173           else
00174             f[k] = 0;
00175         Fields[i] = complex<double>(f[0], f[1]) * ph[i];
00176       }
00177     }
00178 
00179     complex<double> fun = data->fun(Fields, loc, data->fun_data_);
00180     int idx2 = ((((offset[0] + offset[1] + offset[2])
00181                   + loop_i1 * stride[0]) 
00182                  + loop_i2 * stride[1]) + loop_i3 * stride[2]);
00183     data->buf[idx2] = data->reim ? imag(fun) : real(fun);
00184   }
00185 
00186   //-----------------------------------------------------------------------//
00187 
00188   data->file->write_chunk(data->rank, start, count, data->buf);
00189 }

static void meep::handle_control_c ( int  i  )  [static]

00029                                     {
00030   (void) i; // unused: should equal SIGINT
00031   interrupt++;
00032   if (interrupt >= kill_time) {
00033     abort("interrupted");
00034   } else if (interrupt + 1 == kill_time) {
00035     printf("Be patient... hit ctrl-C one more time to kill me.\n");
00036   } else {
00037     printf("Be patient... hit ctrl-C %d more times to kill me.\n", kill_time - interrupt);
00038   }
00039 }

bool meep::has_direction ( ndim  dim,
direction  d 
) [inline]

00160                                                  {
00161   LOOP_OVER_DIRECTIONS(dim, dd) if (dd == d) return true;
00162   return false;
00163 }

static int meep::iabs ( int  i  )  [inline, static]

00212 { return (i < 0 ? -i : i); }

Symmetry meep::identity (  ) 

01090                     {
01091   return Symmetry();
01092 }

static void meep::integrate_chunkloop ( Fields_Chunk *  fc,
int  ichunk,
component  cgrid,
ivec  is,
ivec  ie,
vec  s0,
vec  s1,
vec  e0,
vec  e1,
double  dV0,
double  dV1,
ivec  shift,
complex< double >  shift_phase,
const Symmetry &  S,
int  sn,
void *  data_ 
) [static]

00049 {
00050   integrate_data *data = (integrate_data *) data_;
00051   int *off = data->offsets;
00052   component *cS = data->cS;
00053   complex<double> *Fields = data->Fields, *ph = data->ph;
00054   complex<long double> sum = 0.0;
00055   double maxabs = 0;
00056   const component *iecs = data->inveps_cs;
00057   const direction *ieds = data->inveps_ds;
00058   int *ieos = data->inveps_offsets;
00059 
00060   for (int i = 0; i < data->num_Fields; ++i) {
00061     cS[i] = S.transform(data->components[i], -sn);
00062     if (cS[i] == Dielectric)
00063       ph[i] = 1.0;
00064     else {
00065       if (cgrid == Dielectric)
00066                 fc->m_vol.yee2diel_offsets(cS[i], off[2*i], off[2*i+1]);
00067       ph[i] = shift_phase * S.phase_shift(cS[i], sn);
00068     }
00069   }
00070   for (int k = 0; k < data->ninveps; ++k)
00071     fc->m_vol.yee2diel_offsets(iecs[k], ieos[2*k], ieos[2*k+1]);
00072 
00073   vec rshift(shift * (0.5*fc->m_vol.m_inva));
00074   LOOP_OVER_IVECS(fc->m_vol, is, ie, idx) {
00075     IVEC_LOOP_LOC(fc->m_vol, loc);
00076     loc = S.transform(loc, sn) + rshift;
00077 
00078     for (int i = 0; i < data->num_Fields; ++i) {
00079       if (cS[i] == Dielectric) {
00080         double tr = 0.0;
00081         for (int k = 0; k < data->ninveps; ++k)
00082           tr += (fc->m_structChunk->m_inveps[iecs[k]][ieds[k]][idx]
00083                  + fc->m_structChunk->m_inveps[iecs[k]][ieds[k]][idx+ieos[2*k]]
00084                  + fc->m_structChunk->m_inveps[iecs[k]][ieds[k]][idx+ieos[1+2*k]]
00085                  + fc->m_structChunk->m_inveps[iecs[k]][ieds[k]][idx+ieos[2*k]+ieos[1+2*k]]);
00086         Fields[i] = (4 * data->ninveps) / tr;
00087       }
00088       else {
00089         double f[2];
00090         for (int k = 0; k < 2; ++k)
00091           if (fc->m_f[cS[i]][k])
00092             f[k] = 0.25 * (fc->m_f[cS[i]][k][idx]
00093                            + fc->m_f[cS[i]][k][idx+off[2*i]]
00094                            + fc->m_f[cS[i]][k][idx+off[2*i+1]]
00095                            + fc->m_f[cS[i]][k][idx+off[2*i]+off[2*i+1]]);
00096           else
00097             f[k] = 0;
00098         Fields[i] = complex<double>(f[0], f[1]) * ph[i];
00099       }
00100     }
00101 
00102     complex<double> integrand = 
00103       data->integrand(Fields, loc, data->integrand_data_);
00104     maxabs = max(maxabs, abs(integrand));
00105     sum += integrand * IVEC_LOOP_WEIGHT(s0, s1, e0, e1, dV0 + dV1 * loop_i2);
00106   }
00107 
00108   data->maxabs = max(data->maxabs, maxabs);
00109   data->sum += sum;
00110 }

bool meep::is_D ( component  c  )  [inline]

00176 { return c >= Dx && c < Dielectric; }

bool meep::is_derived ( int  c  )  [inline]

00177 { return c >= Sx; }

bool meep::is_electric ( component  c  )  [inline]

00174 { return c < Hx; }

bool meep::is_energydensity ( derived_component  c  )  [inline]

00179 { return c>=EnergyDensity; }

static bool meep::is_like ( ndim  d,
component  c1,
component  c2 
) [static]

00057                                                           {
00058     if (d != D2) return true;
00059     return !(is_tm(c1) ^ is_tm(c2));
00060   }

bool meep::is_magnetic ( component  c  )  [inline]

00175 { return c >= Hx && c < Dx; }

static bool meep::is_ok_dir ( const char *  dirname  )  [static]

00071                                            {
00072   DIR *dir;
00073   bool direxists;
00074   if (am_master()) {
00075     direxists = (dir = opendir(dirname)) != NULL;
00076     if (direxists) closedir(dir);
00077     else mkdir(dirname, 00777);
00078   }
00079   direxists = broadcast(0, direxists);
00080   return !direxists;
00081 }

bool meep::is_poynting ( derived_component  c  )  [inline]

00178 { return c < EnergyDensity; }

static bool meep::is_tm ( component  c  )  [static]

00047                                  {
00048     switch (c) {
00049     case Hx: case Hy: case Ez: case Dz: return true;
00050     default: return false;
00051     }
00052     return false;
00053   }

static double meep::it ( int  cmp,
double *  f[2],
int  ind 
) [inline, static]

00029                                                           {
00030   return (f[1-cmp]) ? (1-2*cmp)*f[1-cmp][ind] : 0;
00031 }

ivec meep::iveccyl ( int  xx,
int  yy 
) [inline]

00517                                     {
00518   ivec v(Dcyl); v.t[R] = rr; v.t[Z] = zz; return v;
00519 }

static double meep::J ( int  m,
double  kr 
) [static]

00035                                   {
00036 #ifdef HAVE_LIBGSL
00037   return gsl_sf_bessel_Jn(m, kr);
00038 #else
00039   abort("not compiled with GSL, required for Bessel functions");
00040   return 0;
00041 #endif
00042 }

static complex<double> meep::JJ ( const vec &  v  )  [static]

00071                                         {
00072   return polar(J(m_for_J, ktrans*v.r()),kax*v.r());
00073 }

static double meep::Jmax ( int  m,
int  n 
) [static]

00055                                  {
00056   double rlow, rhigh = Jroot(m,n), rtry;
00057   if (n == 0) rlow = 0;
00058   else rlow = Jroot(m, n-1);
00059   double jplow = Jprime(m,rlow), jptry;
00060   do {
00061     rtry = rlow + (rhigh - rlow)*0.5;
00062     jptry = Jprime(m,rtry);
00063     if (jplow*jptry < 0) rhigh = rtry;
00064     else rlow = rtry;
00065   } while (rhigh - rlow > rhigh*1e-15);
00066   return rtry;
00067 }

static complex<double> meep::JP ( const vec &  v  )  [static]

00074                                         {
00075   return polar(Jprime(m_for_J, ktrans*v.r()),kax*v.r());
00076 }

static double meep::Jprime ( int  m,
double  kr 
) [static]

00043                                        { 
00044   if (m) return 0.5*(J(m-1,kr)-J(m+1,kr));
00045   else return -J(1,kr);
00046 }

static double meep::Jroot ( int  m,
int  n 
) [static]

00047                                   {
00048 #ifdef HAVE_LIBGSL
00049   return gsl_sf_bessel_zero_Jnu(m, n+1);
00050 #else
00051   abort("not compiled with GSL, required for Bessel functions");
00052   return 0;
00053 #endif
00054 }

void meep::load_dft_hdf5 ( Dft_Chunk *  Dft_Chunks,
component  c,
H5file *  file,
const char *  dprefix 
)

00273                                                               {
00274         int istart;
00275         int n = Dft_Chunks_Ntotal(Dft_Chunks, &istart);
00276 
00277         char dataname[1024];
00278         snprintf(dataname, 1024, "%s%s" "%s_dft", 
00279                          dprefix ? dprefix : "", dprefix && dprefix[0] ? "_" : "",
00280                          component_name(c));
00281         int file_rank, file_dims;
00282         file->read_size(dataname, &file_rank, &file_dims, 1);
00283         if (file_rank != 1 || file_dims != n)
00284           abort("incorrect dataset size (%d vs. %d) in load_dft_hdf5 %s:%s", file_dims, n, file->file_name(), dataname);
00285   
00286         for (Dft_Chunk *cur = Dft_Chunks; cur; cur = cur->m_next_in_dft) {
00287           int Nchunk = cur->m_N * cur->m_Nomega * 2;
00288           file->read_chunk(1, &istart, &Nchunk, (double *) cur->m_dft);
00289           istart += Nchunk;
00290         }
00291   }

const char * meep::make_output_directory ( const char *  exename,
const char *  jobname = NULL 
)

Utility function to parse the executable name use it to come up with a directory name, avoiding overwriting any existing directory, unless the source file hasn't changed.

00092                                                                             {
00093   const int buflen = 300;
00094   char basename[buflen];
00095   const char * const evil_suffs[] = { ".dac", ".cpp", ".cc", ".cxx", ".C" };
00096   char stripped_name[buflen];
00097   const char *bnp = exename; // stripped_name holds the actual name of the executable (dirs removed).
00098   const char *t;
00099   for (t=exename;*t;t++) {
00100     if (*t == '/') bnp = t+1;
00101   }
00102   
00103   snprintf(stripped_name, buflen, "%s", bnp);
00104   for (int i = 0; i < (int)(sizeof(evil_suffs) / sizeof(evil_suffs[0])); ++i) {
00105     int sufflen = strlen(evil_suffs[i]);
00106     if (strcmp(stripped_name + strlen(stripped_name) - sufflen, 
00107                evil_suffs[i]) == 0
00108         && strlen(stripped_name) > size_t(sufflen)) {
00109       stripped_name[strlen(stripped_name) - sufflen] = (char)0;
00110       break;
00111     }
00112   }
00113 
00114   char sourcename[buflen]; // Holds the "example.cpp" filename.
00115   snprintf(sourcename, buflen, "%s.cpp", stripped_name);
00116 
00117   if (jobname != NULL) {
00118     snprintf(basename, buflen, "%s", jobname);
00119   }
00120   else {
00121     snprintf(basename, buflen, "%s", stripped_name);
00122   }
00123 
00124   static char outdirname[buflen];
00125   snprintf(outdirname, buflen, "%s-out", basename);
00126   {
00127     int i = 0;
00128     while (!is_ok_dir(outdirname)) {
00129       if (!quiet)
00130         master_printf("Output directory %s already exists!\n", outdirname);
00131       snprintf(outdirname, buflen, "%s-out-%d", basename, i++);
00132     }
00133   }
00134   char outsrcname[buflen];
00135   snprintf(outsrcname, buflen, "%s/%s", outdirname, sourcename);
00136   cp(sourcename, outsrcname);
00137 
00138   return outdirname;
00139 }

void meep::master_fclose ( FILE *  f  ) 

00391                             {
00392   if (am_master()) fclose(f);
00393 }

void void void FILE * meep::master_fopen ( const char *  name,
const char *  mode 
)

00380                                                        {
00381   FILE *f = am_master() ? fopen(name, mode) : 0;
00382 
00383   /* other processes need to know if fopen returned zero, in order
00384      to abort if fopen failed.  If fopen was successfully, just return
00385      a random non-zero pointer (which is never used except to compare to zero)
00386      on non-master processes */
00387   if (broadcast(0, bool(f != 0)) && !am_master())
00388     f = (FILE *) name;
00389   return f;
00390 }

void void void meep::master_fprintf ( FILE *  f,
const char *  fmt,
  ... 
)

00374                                                    {
00375   va_list ap;
00376   va_start(ap, fmt);
00377   if (am_master()) { vfprintf(f, fmt, ap); fflush(f); }
00378   va_end(ap);
00379 }

void meep::master_printf ( const char *  fmt,
  ... 
)

00351                                          {
00352   va_list ap;
00353   va_start(ap, fmt);
00354   if (am_master()) { vprintf(fmt, ap); fflush(stdout); }
00355   va_end(ap);
00356 }

ivec meep::max ( const ivec &  ivec1,
const ivec &  ivec2 
)

00134                                                {
00135   ivec m(ivec1.dim);
00136   LOOP_OVER_DIRECTIONS(ivec1.dim, d)
00137     m.set_direction(d, max(ivec1.in_direction(d), ivec2.in_direction(d)));
00138   return m;
00139 }

vec meep::max ( const vec &  vec1,
const vec &  vec2 
)

00120                                           {
00121   vec m(vec1.dim);
00122   LOOP_OVER_DIRECTIONS(vec1.dim, d)
00123     m.set_direction(d, max(vec1.in_direction(d), vec2.in_direction(d)));
00124   return m;
00125 }

int meep::max ( int  a,
int  b 
) [inline]

00027 { return (a > b) ? a : b; }

double meep::max ( double  a,
double  b 
) [inline]

00025 { return (a > b) ? a : b; }

ivec meep::max_to_all ( const ivec &  v  ) 

00233                                {
00234   int in[5], out[5];
00235   for (int i=0; i<5; ++i) in[i] = out[i] = v.in_direction(direction(i));
00236 #ifdef HAVE_MPI
00237   MPI_Allreduce(&in,&out,5,MPI_INT,MPI_MAX,MPI_COMM_WORLD);
00238 #endif
00239   ivec vout(v.dim);
00240   for (int i=0; i<5; ++i) vout.set_direction(direction(i), out[i]);
00241   return vout;
00242 }

int meep::max_to_all ( int  in  ) 

00225                        {
00226   int out = in;
00227 #ifdef HAVE_MPI
00228   MPI_Allreduce(&in,&out,1,MPI_INT,MPI_MAX,MPI_COMM_WORLD);
00229 #endif
00230   return out;
00231 }

double meep::max_to_all ( double  in  ) 

00217                              {
00218   double out = in;
00219 #ifdef HAVE_MPI
00220   MPI_Allreduce(&in,&out,1,MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD);
00221 #endif
00222   return out;
00223 }

double meep::max_to_master ( double  in  ) 

00209                                 {
00210   double out = in;
00211 #ifdef HAVE_MPI
00212   MPI_Reduce(&in,&out,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD);
00213 #endif
00214   return out;
00215 }

ivec meep::min ( const ivec &  ivec1,
const ivec &  ivec2 
)

00127                                                {
00128   ivec m(ivec1.dim);
00129   LOOP_OVER_DIRECTIONS(ivec1.dim, d)
00130     m.set_direction(d, min(ivec1.in_direction(d), ivec2.in_direction(d)));
00131   return m;
00132 }

vec meep::min ( const vec &  vec1,
const vec &  vec2 
)

00113                                           {
00114   vec m(vec1.dim);
00115   LOOP_OVER_DIRECTIONS(vec1.dim, d)
00116     m.set_direction(d, min(vec1.in_direction(d), vec2.in_direction(d)));
00117   return m;
00118 }

int meep::min ( int  a,
int  b 
) [inline]

00028 { return (a < b) ? a : b; }

double meep::min ( double  a,
double  b 
) [inline]

00026 { return (a < b) ? a : b; }

Symmetry meep::mirror ( direction  axis,
const Volume &  v 
)

01067                                                  {
01068   Symmetry s = identity();
01069   s.m_g = 2;
01070   s.m_S[axis].flipped = true;
01071   s.m_symmetry_point = v.center();
01072   s.m_i_symmetry_point = v.icenter();
01073   return s;
01074 }

int meep::my_rank (  ) 

00329               {
00330 #ifdef HAVE_MPI
00331   int rank;
00332   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
00333   return rank;
00334 #else
00335   return 0;
00336 #endif
00337 }

static int meep::my_round ( double  x  )  [inline, static]

00033                                      {
00034   return int(floor(fabs(x) + 0.5) * (x < 0 ? -1 : 1));
00035 }

static double meep::norm2 ( int  n,
const double *  x 
) [static]

00086 { return sqrt(dot(n, x, x)); }

int meep::number_of_directions ( ndim  dim  )  [inline]

00056                                           {
00057   return (int) (dim + 1 - 2 * (dim == Dcyl));
00058 }

complex<double> meep::one ( const vec &  v  ) 

Warning:
Badly named?
00037 {(void) v; return 1.0;}

ivec meep::one_ivec ( ndim  di  )  [inline]

00506                               {
00507   ivec v; v.dim = di; LOOP_OVER_DIRECTIONS(di, d) v.set_direction(d, 1);
00508   return v;
00509 }

bool meep::or_to_all ( bool  in  ) 

00307                         {
00308   int out = in;
00309 #ifdef HAVE_MPI
00310   MPI_Allreduce(&in,&out,1,MPI_INT,MPI_LOR,MPI_COMM_WORLD);
00311 #endif
00312   return (bool) out;
00313 }

int meep::partial_sum_to_all ( int  in  ) 

00283                                {
00284   int out = in;
00285 #ifdef HAVE_MPI
00286   MPI_Scan(&in,&out,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);
00287 #endif
00288   return out;
00289 }

Boundary_Region meep::pml ( double  thickness  ) 

00176                                       {
00177   Boundary_Region r;
00178   for (int id = 0; id < 5; ++id)
00179     r = r + pml(thickness, (direction) id);
00180   return r;
00181 }

Boundary_Region meep::pml ( double  thickness,
direction  d 
)

00173                                                    {
00174   return (pml(thickness, d, Low) + pml(thickness, d, High));
00175 }

Boundary_Region meep::pml ( double  thickness,
direction  d,
boundary_side  side 
)

00170                                                                        {
00171   return Boundary_Region(Boundary_Region::PML, thickness, 1.0, d, side, NULL);
00172 }

static double meep::poynting_fun ( const complex< double > *  Fields,
const vec &  loc,
void *  data_ 
) [static]

01390 {
01391      (void) loc; // unused
01392      (void) data_; // unused
01393      return (real(conj(Fields[0]) * Fields[1])
01394              - real(conj(Fields[2])*Fields[3]));
01395 }

static void meep::pt ( double  ts[],
time_sink  s 
) [static]

00057                                          {
00058   if (ts[s]) master_printf("    %18s: %g s\n", ts2n(s), ts[s]);
00059 }

Symmetry meep::r_to_minus_r_Symmetry ( double  m  ) 

Symmetry meep::r_to_minus_r_symmetry ( double  m  ) 

01076                                          {
01077   Symmetry s = identity();
01078   s.m_g = 2;
01079   s.m_S[R].flipped = true;
01080   s.m_S[P].flipped = true;
01081   s.m_symmetry_point = zero_vec(Dcyl);
01082   s.m_i_symmetry_point = zero_ivec(Dcyl);
01083   if (m == int(m)) // phase is purely real (+/- 1) when m an integer
01084     s.m_ph = (int(m) & 1) ? -1.0 : 1.0;
01085   else
01086     s.m_ph = polar(1.0, m * pi); // general case
01087   return s;
01088 }

Symmetry meep::r_to_minus_r_Symmetry ( int  m  ) 

static complex<double> meep::return_the_field ( const complex< double > *  Fields,
const vec &  loc,
void *  integrand_data_ 
) [static]

00219 {
00220   (void) integrand_data_; (void) loc; // unused
00221   return Fields[0];
00222 }

static complex<double> meep::rfun_wrap ( const complex< double > *  Fields,
const vec &  loc,
void *  data_ 
) [static]

00176                                                               {
00177   rfun_wrap_data *data = (rfun_wrap_data *) data_;
00178   return data->integrand(Fields, loc, data->integrand_data);
00179 }

static complex<double> meep::rintegrand_fun ( const complex< double > *  Fields,
const vec &  loc,
void *  data_ 
) [static]

00316 {
00317   rintegrand_data *data = (rintegrand_data *) data_;
00318   return data->fun(Fields, loc, data->fun_data_);
00319 }

int meep::rmin_bulk ( int  m  )  [inline]

00041                             {
00042   int r = 1 + small_r_metal(m);
00043   if (r < 1) r = 1;
00044   return r;
00045 }

Symmetry meep::rotate2 ( direction  axis,
const Volume &  v 
)

01056                                                   {
01057   Symmetry s = identity();
01058   if (axis > 2) abort("Can only rotate2 in 2D or 3D.\n");
01059   s.m_g = 2;
01060   s.m_S[(axis+1)%3].flipped = true;
01061   s.m_S[(axis+2)%3].flipped = true;
01062   s.m_symmetry_point = v.center();
01063   s.m_i_symmetry_point = v.icenter();
01064   return s;
01065 }

Symmetry meep::rotate4 ( direction  axis,
const Volume &  v 
)

01040                                                   {
01041   Symmetry s = identity();
01042   if (axis > 2) abort("Can only rotate4 in 2D or 3D.\n");
01043   s.m_g = 4;
01044   FOR_DIRECTIONS(d) {
01045     s.m_S[d].d = d;
01046     s.m_S[d].flipped = false;
01047   }
01048   s.m_S[(axis+1)%3].d = (direction)((axis+2)%3);
01049   s.m_S[(axis+1)%3].flipped = true;
01050   s.m_S[(axis+2)%3].d = (direction)((axis+1)%3);
01051   s.m_symmetry_point = v.center();
01052   s.m_i_symmetry_point = v.icenter();
01053   return s;
01054 }

int meep::rstart_0 ( const Volume &  v,
double  m 
) [inline]

00033                                                {
00034   return (int) max(0.0, m - (int)(v.origin_r()*v.m_a+0.5) - 1.0);
00035 }

int meep::rstart_1 ( const Volume &  v,
double  m 
) [inline]

00036                                                {
00037   return (int) max(1.0, m - (int)(v.origin_r()*v.m_a+0.5));
00038 }

void meep::save_dft_hdf5 ( Dft_Chunk *  Dft_Chunks,
component  c,
H5file *  file,
const char *  dprefix 
)

00254                                                               {
00255         int istart;
00256         int n = Dft_Chunks_Ntotal(Dft_Chunks, &istart);
00257 
00258         char dataname[1024];
00259         snprintf(dataname, 1024, "%s%s" "%s_dft", 
00260                          dprefix ? dprefix : "", dprefix && dprefix[0] ? "_" : "", 
00261                          component_name(c));
00262         file->create_data(dataname, 1, &n);
00263 
00264         for (Dft_Chunk *cur = Dft_Chunks; cur; cur = cur->m_next_in_dft) {
00265           int Nchunk = cur->m_N * cur->m_Nomega * 2;
00266           file->write_chunk(1, &istart, &Nchunk, (double *) cur->m_dft);
00267           istart += Nchunk;
00268         }
00269         file->done_writing_chunks();
00270   }

void meep::send ( int  from,
int  to,
double *  data,
int  size 
)

00118                                                     {
00119 #ifdef HAVE_MPI
00120   if (from == to) return;
00121   if (size == 0) return;
00122   const int me = my_rank();
00123   if (from == me) MPI_Send(data, size, MPI_DOUBLE, to, 1, MPI_COMM_WORLD);
00124   MPI_Status stat;
00125   if (to == me) MPI_Recv(data, size, MPI_DOUBLE, from, 1, MPI_COMM_WORLD, &stat);
00126 #else
00127   UNUSED(from);
00128   UNUSED(to);
00129   UNUSED(data);
00130   UNUSED(size);
00131 #endif
00132 }

int meep::small_r_metal ( int  m  )  [inline]

00037                                 {
00038   return m-1;
00039 }

static vec meep::sphere_pt ( const vec &  cent,
double  R,
int  n,
double &  weight 
) [static]

00095          :
00096     while ((fabs(meps-old_meps) > tol*old_meps) && (fabs(minveps-old_minveps) > tol*old_minveps)) {
00097       old_meps=meps; old_minveps=minveps;
00098       meps = minveps = 0;
00099       for (int j=0; j < ms; j++)
00100         for (int i=0; i < ms; i++) {
00101           double ep = eps(gv.get_min_corner() + vec(i*d.x()/ms, j*d.y()/ms));
00102           meps += ep; minveps += 1/ep;
00103         }
00104       meps /= ms*ms;
00105       minveps /= ms*ms;
00106       ms *= 2; 
00107       if (maxeval && (iter += ms*ms) >= maxeval) return;
00108     }
00109     break;
00110   case Dcyl:
00111     while ((fabs(meps-old_meps) > tol*old_meps) && (fabs(minveps-old_minveps) > tol*old_minveps)) {
00112       old_meps=meps; old_minveps=minveps;
00113       meps = minveps = 0;
00114       double sumvol = 0;
00115       for (int j=0; j < ms; j++)
00116         for (int i=0; i < ms; i++) {
00117           double r = gv.get_min_corner().r() + i*d.r()/ms;
00118           double ep = eps(gv.get_min_corner() + veccyl(i*d.r()/ms, j*d.z()/ms));
00119           sumvol += r;
00120           meps += ep * r; minveps += r/ep;
00121         }
00122       meps /= sumvol;
00123       minveps /= sumvol;
      ms *= 2; 

bool meep::Src_Times_equal ( const Src_Time &  t1,
const Src_Time &  t2 
)

this function is necessary to make equality commutative .

.. ugh warning Grok Me!

00035   {
00036         return t1.is_equal(t2) && t2.is_equal(t1);
00037   }

void meep::Src_Vol_chunkloop ( Fields_Chunk *  fc,
int  ichunk,
component  c,
ivec  is,
ivec  ie,
vec  s0,
vec  s1,
vec  e0,
vec  e1,
double  dV0,
double  dV1,
ivec  shift,
complex< double >  shift_phase,
const Symmetry &  S,
int  sn,
void *  data_ 
)

Adding source volumes can be treated as a kind of "integration" problem, since we need to loop over all the chunks that intersect the source volume, with appropriate interpolation weights at the boundaries so that the integral of the current is fixed regardless of resolution.

Unlike most uses of Fields::loop_in_chunks, however, we set use_Symmetry=false: we only find the intersection of the volume with the untransformed chunks (since the transformed versions are implicit).

I put this in the header becuase it's declared static, and called in fields, and this was a shortcut. This, and other static functions, need to check if it really needs to be static. If so, then do it properly...

Parameters:
fc pointer to Fields_Chunk.
ichunk dunno.
c A component, why this needs to be spec'd I don't know.
is dunno.
ie dunno.
s0 dunno.
s1 dunno.
e0 dunno.
e1 dunno.
dV0 dunno.
dV1 dunno.
shift dunno.
shift_phase dunno.
S reference to a Symmetry.
sn dunno.
data Okay, declared with a void* type, but there is a
Warning:
I removed the static qualifier here becuase I saw no need for it. need to check performance, also compare parallel code, make sure nothing is broken.
00279   {
00280         Src_Vol_Chunkloop_Data* data = (Src_Vol_Chunkloop_Data *) data_;
00281         (void) S; (void) sn; // these should be the identity
00282         (void) dV0; (void) dV1; // volume weighting is included in data->amp
00283         (void) ichunk;
00284 
00285         int npts = 1;
00286         LOOP_OVER_DIRECTIONS(is.dim, d)
00287           npts *= (ie.in_direction(d) - is.in_direction(d)) / 2 + 1;
00288         int *index_array = new int[npts];
00289         complex<double> *amps_array = new complex<double>[npts];
00290 
00291         complex<double> amp = data->amp * conj(shift_phase);
00292 
00293         direction cd = component_direction(c);
00294         double inva = fc->m_vol.m_inva;
00295         int idx_vol = 0;
00296         LOOP_OVER_IVECS(fc->m_vol, is, ie, idx) {
00297           IVEC_LOOP_LOC(fc->m_vol, loc);
00298           loc += shift * (0.5*inva) - data->center;
00299 
00300           amps_array[idx_vol] = IVEC_LOOP_WEIGHT(s0,s1,e0,e1,1) * amp * data->A(loc);
00301 
00302           /* for "D" sources, multiply by epsilon.  FIXME: this is not quite
00303                  right because it doesn't handle non-diagonal inveps! */
00304           if (is_D(c) && fc->m_structChunk->m_inveps[c][cd]) 
00305                 amps_array[idx_vol] /= fc->m_structChunk->m_inveps[c][cd][idx];
00306 
00307           index_array[idx_vol++] = idx;
00308         }
00309 
00310         if (idx_vol != npts)
00311           abort("add_volume_source: computed wrong npts (%d vs. %d)", npts, idx_vol);
00312 
00313         Src_Vol *tmp = new Src_Vol(c, data->src, npts, index_array, amps_array);
00314         if (is_magnetic(c))
00315           fc->m_h_sources = tmp->add_to(fc->m_h_sources);
00316         else
00317           fc->m_e_sources = tmp->add_to(fc->m_e_sources);
00318   }

direction meep::start_at_direction ( ndim  dim  )  [inline]

00060                                               {
00061   return (direction) (((dim == D1) || (dim == Dcyl)) ? 2 : 0);
00062 }

direction meep::stop_at_direction ( ndim  dim  )  [inline]

00064                                              {
00065   return (direction) (dim + 1 + 2 * (dim == D1));
00066 }

static complex<double> meep::stupid_A ( const vec &  p  )  [static]

00142                                               {
00143   return A_static(c_static, p);
00144 }

static complex<double> meep::stupider_A ( const vec &  p  )  [static]

00147                                                 {
00148   return prefactor_static*f_static->get_field(c_static, p);
00149 }

static void meep::stupidsort ( ivec *  locs,
double *  w,
int  l 
) [inline, static]

00493                                                             {
00494   while (l) {
00495     if (fabs(w[0]) < 2e-15) {
00496       w[0] = w[l-1];
00497       locs[0] = locs[l-1];
00498       w[l-1] = 0.0;
00499       locs[l-1] = 0;
00500     } else {
00501       w += 1;
00502       locs += 1;
00503     }
00504     l -= 1;
00505   }
00506 }

static void meep::stupidsort ( int *  ind,
double *  w,
int  l 
) [inline, static]

00478                                                           {
00479   while (l) {
00480     if (fabs(w[0]) < 2e-15) {
00481       w[0] = w[l-1];
00482       ind[0] = ind[l-1];
00483       w[l-1] = 0.0;
00484       ind[l-1] = 0;
00485     } else {
00486       w += 1;
00487       ind += 1;
00488     }
00489     l -= 1;
00490   }
00491 }

complex< long double > meep::sum_to_all ( complex< long double >  in  ) 

00299                                                          {
00300   complex<long double> out = in;
00301 #ifdef HAVE_MPI
00302   MPI_Allreduce(&in,&out,2,MPI_LONG_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
00303 #endif
00304   return out;
00305 }

complex< double > meep::sum_to_all ( complex< double >  in  ) 

00291                                                {
00292   complex<double> out = in;
00293 #ifdef HAVE_MPI
00294   MPI_Allreduce(&in,&out,2,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
00295 #endif
00296   return out;
00297 }

int meep::sum_to_all ( int  in  ) 

00275                        {
00276   int out = in;
00277 #ifdef HAVE_MPI
00278   MPI_Allreduce(&in,&out,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);
00279 #endif
00280   return out;
00281 }

long double meep::sum_to_all ( long double  in  ) 

00267                                        {
00268   long double out = in;
00269 #ifdef HAVE_MPI
00270   MPI_Allreduce(&in,&out,1,MPI_LONG_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
00271 #endif
00272   return out;
00273 }

void meep::sum_to_all ( const double *  in,
double *  out,
int  size 
)

00260                                                          {
00261   memcpy(out, in, sizeof(double) * size);
00262 #ifdef HAVE_MPI
00263   MPI_Allreduce((void*) in, out, size, MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
00264 #endif
00265 }

double meep::sum_to_all ( double  in  ) 

00252                              {
00253   double out = in;
00254 #ifdef HAVE_MPI
00255   MPI_Allreduce(&in,&out,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
00256 #endif
00257   return out;
00258 }

double meep::sum_to_master ( double  in  ) 

00244                                 {
00245   double out = in;
00246 #ifdef HAVE_MPI
00247   MPI_Reduce(&in,&out,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
00248 #endif
00249   return out;
00250 }

static void meep::thermo_chunkloop ( Fields_Chunk *  fc,
int  ichunk,
component  cgrid,
ivec  is,
ivec  ie,
vec  s0,
vec  s1,
vec  e0,
vec  e1,
double  dV0,
double  dV1,
ivec  shift,
complex< double >  shift_phase,
const Symmetry &  S,
int  sn,
void *  sum_ 
) [static]

00152                                          {
00153   long double *sum = (long double *) sum_;
00154   (void) shift; (void) shift_phase; (void) S; (void) sn; // unused
00155   if (fc->m_pol && fc->m_pol->m_energy[cgrid])
00156     LOOP_OVER_IVECS(fc->m_vol, is, ie, idx)
00157       *sum += IVEC_LOOP_WEIGHT(s0, s1, e0, e1, dV0 + dV1 * loop_i2)
00158           * fc->m_pol->m_energy[cgrid][idx];
00159 }

void meep::trash_output_directory ( const char *  dirname  ) 

00141                                                  {
00142   if (am_master()) mkdir(dirname, 00777);
00143 }

static const char* meep::ts2n ( time_sink  s  )  [static]

00044                                      {
00045   switch (s) {
00046   case e_stepping: return "time stepping";
00047   case e_connecting: return "connnecting chunks";
00048   case e_boundaries: return "copying borders";
00049   case e_mpiTime: return "communicating";
00050   case e_fieldOutput: return "outputting Fields";
00051   case e_fourierTransforming: return "Fourier transforming";
00052   case e_other: break;
00053   }
00054   return "everything else";
00055 }

field_type meep::type ( component  c  )  [inline]

00180                                     {
00181   if (is_electric(c)) return E_stuff;
00182   else if (is_magnetic(c)) return H_stuff;
00183   else if (is_D(c)) return D_stuff;
00184   abort("Invalid field in type.\n");
00185   return E_stuff; // This is never reached.
00186 }

ivec meep::unit_ivec ( ndim  di,
direction  d 
) [inline]

00511                                             {
00512   ivec v(zero_ivec(di));
00513   v.set_direction(d, 1);
00514   return v;
00515 }

vec meep::unit_vec ( ndim  di,
direction  d 
) [inline]

00373                                           {
00374   vec v(zero_vec(di));
00375   v.set_direction(d, 1.0);
00376   return v;
00377 }

static ivec meep::vec2diel_ceil ( const vec &  v,
double  a,
const ivec &  equal_shift 
) [static]

00202                                                                            {
00203   ivec iv(v.dim);
00204   LOOP_OVER_DIRECTIONS(v.dim, d) {
00205     iv.set_direction(d, 1+2*int(ceil(v.in_direction(d)*a-.5)));
00206     if (iv.in_direction(d) == v.in_direction(d))
00207       iv.set_direction(d, iv.in_direction(d) + equal_shift.in_direction(d));
00208   }
00209   return iv;
00210 }

static ivec meep::vec2diel_floor ( const vec &  v,
double  a,
const ivec &  equal_shift 
) [static]

00193                                                                             {
00194   ivec iv(v.dim);
00195   LOOP_OVER_DIRECTIONS(v.dim, d) {
00196     iv.set_direction(d, 1+2*int(floor(v.in_direction(d)*a-.5)));
00197     if (iv.in_direction(d) == v.in_direction(d))
00198       iv.set_direction(d, iv.in_direction(d) + equal_shift.in_direction(d));
00199   }
00200   return iv;
00201 }

vec meep::veccyl ( double  rr,
double  zz 
) [inline]

00385                                         {
00386   vec v(Dcyl); v.t[R] = rr; v.t[Z] = zz; return v;
00387 }

Volume meep::vol1d ( double  zsize,
double  a 
)

00884                                      {
00885   return volone(zsize, a);
00886 }

Volume meep::vol2d ( double  xsize,
double  ysize,
double  a 
)

00888                                                    {
00889   return voltwo(xsize, ysize, a);
00890 }

Volume meep::vol3d ( double  xsize,
double  ysize,
double  zsize,
double  a 
)

00892                                                                  {
00893   return Volume(D3, a,(xsize==0)?1:(int) (xsize*a + 0.5),
00894                       (ysize==0)?1:(int) (ysize*a + 0.5),
00895                       (zsize==0)?1:(int) (zsize*a + 0.5));
00896 }

Volume meep::volcyl ( double  rsize,
double  zsize,
double  a 
)

00898                                                     {
00899   if (zsize == 0.0) return Volume(Dcyl, a, (int) (rsize*a + 0.5), 0, 1);
00900   else return Volume(Dcyl, a, (int) (rsize*a + 0.5), 0, (int) (zsize*a + 0.5));
00901 }

Volume meep::volone ( double  zsize,
double  a 
)

00875                                       {
00876   return Volume(D1, a, 0, 0, (int) (zsize*a + 0.5));
00877 }

Volume meep::voltwo ( double  xsize,
double  ysize,
double  a 
)

00879                                                     {
00880   return Volume(D2, a, (xsize==0)?1:(int) (xsize*a + 0.5),
00881                        (ysize==0)?1:(int) (ysize*a + 0.5),0);
00882 }

double meep::wall_time ( void   ) 

00093                        {
00094 #ifdef HAVE_MPI
00095   return MPI_Wtime();
00096 #elif HAVE_GETTIMEOFDAY
00097   struct timeval tv;
00098   gettimeofday(&tv, 0);
00099   return(tv.tv_sec + tv.tv_usec * 1e-6);
00100 #else
00101   return (clock() * 1.0 / CLOCKS_PER_SECOND);
00102 #endif
00103 }

static void meep::xpay ( int  n,
double *  x,
double  a,
const double *  y 
) [static]

00092                                                               {
00093   for (int m = 0; m < n; ++m) x[m] += a * y[m];
00094 }

static direction meep::yucky_dir ( ndim  dim,
int  n 
) [static]

00240                                             {
00241   if (dim == Dcyl)
00242     switch (n) {
00243     case 0: return P;
00244     case 1: return R;
00245     case 2: return Z;
00246     }
00247   else if (dim == D2)
00248     return (direction) ((n + 2) % 3); /* n = 0,1,2 gives Z, X, Y */
00249   return (direction) n ;
00250 }

ivec meep::zero_ivec ( ndim  di  )  [inline]

00501                                {
00502   ivec v; v.dim = di; LOOP_OVER_DIRECTIONS(di, d) v.set_direction(d, 0);
00503   return v;
00504 }

vec meep::zero_vec ( ndim  di  )  [inline]

00368                              {
00369   vec v(di); LOOP_OVER_DIRECTIONS(di, d) v.set_direction(d, 0.0);
00370   return v;
00371 }


Variable Documentation

complex<double>(* meep::A_static)(component, const vec &) [static]

const double meep::Cmax = 0.5

FILE* meep::debf = NULL [static]

const char meep::Grace_header[]

Initial value:

 "# Grace project file\
#\
@page size 792, 612\
@default symbol size 0.330000\
@g0 on\
@with g0\
"

const double meep::infinity = 1e20

this should be big enough for us

int meep::interrupt = 0

Incremented when ctrl-C is called.(starts with a zero).

double meep::kax [static]

int meep::kill_time = 2 [static]

double meep::ktrans [static]

int meep::m_for_J [static]

const double meep::nan = -1.23454321e123

ideally, a value never encountered in practice

const int meep::num_bandpts = 32

const int meep::NUM_FIELD_TYPES = 4

const int meep::num_sphere_quad[3] = { 2, 12, 50 } [static]

const double meep::pi = 3.141592653589793238462643383276

complex<double> meep::prefactor_static [static]

bool meep::quiet = false

if true, suppress all non-error messages from Meep

const double meep::sphere_quad[3][50][4] [static]

const char meep::symlink_name[] = "latest_output"


Generated on Sat Apr 5 00:25:02 2008 for MEEP by  doxygen 1.5.5