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_Chunk * | Structure_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 ¢, 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 Fields * | f_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 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.
| 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 |
| typedef Structure_Chunk* meep::Structure_Chunk_ptr |
| enum meep::boundary_side |
| enum meep::component |
| enum meep::connect_phase |
| enum meep::direction |
| enum meep::field_type |
| enum meep::Grace_type |
| enum meep::in_or_out |
| enum meep::ndim |
| enum meep::time_sink |
| e_connecting | |
| e_stepping | |
| e_boundaries | |
| e_mpiTime | |
| e_fieldOutput | |
| e_fourierTransforming | |
| e_other |
00014 { e_connecting, e_stepping, e_boundaries, e_mpiTime, 00015 e_fieldOutput, e_fourierTransforming, e_other };
| 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 }
| 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 | ( | ) |
| int meep::am_master | ( | ) | [inline] |
| bool meep::and_to_all | ( | bool | in | ) |
| 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 | |||
| ) |
| 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 | |||
| ) |
| void meep::broadcast | ( | int | from, | |
| complex< double > * | data, | |||
| int | size | |||
| ) |
| void meep::broadcast | ( | int | from, | |
| char * | data, | |||
| int | size | |||
| ) |
| void meep::broadcast | ( | int | from, | |
| double * | data, | |||
| int | size | |||
| ) |
| 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] |
| 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] |
| bool meep::coordinate_mismatch | ( | ndim | dim, | |
| component | c | |||
| ) | [inline] |
| bool meep::coordinate_mismatch | ( | ndim | dim, | |
| direction | d | |||
| ) | [inline] |
| int meep::count_processors | ( | ) |
| static void meep::cp | ( | const char * | a, | |
| const char * | b | |||
| ) | [static] |
| 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] |
| static bool meep::cross_negative | ( | direction | a, | |
| direction | b | |||
| ) | [inline, static] |
| 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 | ) |
| 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 | ) |
| 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.
| 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] |
| static complex<double> meep::dot_fx_integrand | ( | const complex< double > * | Fields, | |
| const vec & | loc, | |||
| void * | data_ | |||
| ) | [static] |
| static complex<double> meep::dot_integrand | ( | const complex< double > * | Fields, | |
| const vec & | loc, | |||
| void * | data_ | |||
| ) | [static] |
| 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] |
| double meep::expi | ( | int | cmp, | |
| double | x | |||
| ) | [inline] |
| 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] |
| 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] |
| Symmetry meep::identity | ( | ) |
| 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] |
| bool meep::is_derived | ( | int | c | ) | [inline] |
| bool meep::is_electric | ( | component | c | ) | [inline] |
| bool meep::is_energydensity | ( | derived_component | c | ) | [inline] |
| static bool meep::is_like | ( | ndim | d, | |
| component | c1, | |||
| component | c2 | |||
| ) | [static] |
| static bool meep::is_ok_dir | ( | const char * | dirname | ) | [static] |
| bool meep::is_poynting | ( | derived_component | c | ) | [inline] |
| static bool meep::is_tm | ( | component | c | ) | [static] |
| static double meep::it | ( | int | cmp, | |
| double * | f[2], | |||
| int | ind | |||
| ) | [inline, static] |
| ivec meep::iveccyl | ( | int | xx, | |
| int | yy | |||
| ) | [inline] |
| 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] |
| 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] |
| static double meep::Jprime | ( | int | m, | |
| double | kr | |||
| ) | [static] |
| 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 | ) |
| 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 }
| 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 | ) |
| double meep::max_to_all | ( | double | in | ) |
| double meep::max_to_master | ( | double | in | ) |
| 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 }
| 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 | ( | ) |
| static int meep::my_round | ( | double | x | ) | [inline, static] |
| static double meep::norm2 | ( | int | n, | |
| const double * | x | |||
| ) | [static] |
| int meep::number_of_directions | ( | ndim | dim | ) | [inline] |
| 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 | ) |
| int meep::partial_sum_to_all | ( | int | in | ) |
| Boundary_Region meep::pml | ( | double | thickness | ) |
| Boundary_Region meep::pml | ( | double | thickness, | |
| direction | d | |||
| ) |
| Boundary_Region meep::pml | ( | double | thickness, | |
| direction | d, | |||
| boundary_side | side | |||
| ) |
| static double meep::poynting_fun | ( | const complex< double > * | Fields, | |
| const vec & | loc, | |||
| void * | data_ | |||
| ) | [static] |
| static void meep::pt | ( | double | ts[], | |
| time_sink | s | |||
| ) | [static] |
| 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] |
| static complex<double> meep::rfun_wrap | ( | const complex< double > * | Fields, | |
| const vec & | loc, | |||
| void * | data_ | |||
| ) | [static] |
| static complex<double> meep::rintegrand_fun | ( | const complex< double > * | Fields, | |
| const vec & | loc, | |||
| void * | data_ | |||
| ) | [static] |
| int meep::rmin_bulk | ( | int | m | ) | [inline] |
| 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] |
| int meep::rstart_1 | ( | const Volume & | v, | |
| double | m | |||
| ) | [inline] |
| 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 }
| 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 | |||
| ) |
| 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...
| 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 |
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] |
| direction meep::stop_at_direction | ( | ndim | dim | ) | [inline] |
| static complex<double> meep::stupid_A | ( | const vec & | p | ) | [static] |
| static complex<double> meep::stupider_A | ( | const vec & | p | ) | [static] |
| static void meep::stupidsort | ( | ivec * | locs, | |
| double * | w, | |||
| int | l | |||
| ) | [inline, static] |
| static void meep::stupidsort | ( | int * | ind, | |
| double * | w, | |||
| int | l | |||
| ) | [inline, static] |
| complex< long double > meep::sum_to_all | ( | complex< long double > | in | ) |
| complex< double > meep::sum_to_all | ( | complex< double > | in | ) |
| int meep::sum_to_all | ( | int | in | ) |
| long double meep::sum_to_all | ( | long double | in | ) |
| void meep::sum_to_all | ( | const double * | in, | |
| double * | out, | |||
| int | size | |||
| ) |
| double meep::sum_to_all | ( | double | in | ) |
| double meep::sum_to_master | ( | double | in | ) |
| 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 | ) |
| 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] |
| vec meep::unit_vec | ( | ndim | di, | |
| direction | d | |||
| ) | [inline] |
| 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] |
| Volume meep::vol2d | ( | double | xsize, | |
| double | ysize, | |||
| double | a | |||
| ) |
| 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 | |||
| ) |
| Volume meep::volone | ( | double | zsize, | |
| double | a | |||
| ) |
| 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 | ) |
| static void meep::xpay | ( | int | n, | |
| double * | x, | |||
| double | a, | |||
| const double * | y | |||
| ) | [static] |
| static direction meep::yucky_dir | ( | ndim | dim, | |
| int | n | |||
| ) | [static] |
| 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 }
complex<double>(* meep::A_static)(component, const vec &) [static] |
component meep::c_static [static] |
| const double meep::Cmax = 0.5 |
FILE* meep::debf = NULL [static] |
Fields* meep::f_static [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_COMPONENTS = 15 |
| 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" |
1.5.5