static complex<double> do_ft(fields &f, component c, const vec &pt, double freq) { complex<double> ft = 0.0; double emax = 0; while (f.time() < f.last_source_time()) { complex <double> fpt = f.get_field(c, pt); ft += fpt * polar(1.0, 2*pi*freq * f.time()); emax = max(emax, abs(fpt)); f.step(); } do { double emaxcur = 0; double T = f.time() + 50; while (f.time() < T) { complex <double> fpt = f.get_field(c, pt); ft += fpt * polar(1.0, 2*pi*freq * f.time()); double e = abs(fpt); emax = max(emax, e); emaxcur = max(emaxcur, e); f.step(); } if (emaxcur < (sizeof(realnum)==sizeof(float) ? 1e-4 : 1e-6) * emax) break; if (T > 500 && emaxcur > 1e-2 * emax) abort("fields do not seem to be decaying"); } while(1); return ft; }
void check_unequal_layout(const fields &f1, const fields &f2) { if (f1.equal_layout(f2) || !f1.equal_layout(f1) || !f2.equal_layout(f2)) abort("fields::equal_layout did not return expected result"); }
void check_integral(fields &f, linear_integrand_data &d, const volume &v, component cgrid) { double x1 = v.in_direction_min(d.dx); double x2 = v.in_direction_max(d.dx); double y1 = v.in_direction_min(d.dy); double y2 = v.in_direction_max(d.dy); double z1 = v.in_direction_min(d.dz); double z2 = v.in_direction_max(d.dz); master_printf("Check %d-dim. %s integral in %s cell with %s integrand...", (x2 - x1 > 0) + (y2 - y1 > 0) + (z2 - z1 > 0), component_name(cgrid), v.dim == D3 ? "3d" : (v.dim == D2 ? "2d" : (v.dim == Dcyl ? "cylindrical" : "1d")), (d.c == 1.0 && !d.axy && !d.ax && !d.ay && !d.az && !d.axy && !d.ayz && !d.axz) ? "unit" : "linear"); if (0) master_printf("\n... grid_volume (%g,%g,%g) at (%g,%g,%g) with integral (%g, %g,%g,%g, %g,%g,%g, %g)...\n", x2 - x1, y2 - y1, z2 - z1, (x1+x2)/2, (y1+y2)/2, (z1+z2)/2, d.c, d.ax,d.ay,d.az, d.axy,d.ayz,d.axz, d.axyz); double sum = real(f.integrate(0, 0, linear_integrand, (void *) &d, v)); if (fabs(sum - correct_integral(v, d)) > 1e-9 * fabs(sum)) abort("FAILED: %0.16g instead of %0.16g\n", (double) sum, correct_integral(v, d)); master_printf("...PASSED.\n"); }
/* -------------------------------------------------------------------------------- */ void write(fields& fds, int start, int end) { for (int i = start; i < end; i++) { fds.clear(); fds[fn_id] = i; fds[fn_name] = i; insertRecord(fds); } }
int compare_point(fields &f1, fields &f2, const vec &p) { monitor_point m1, m_test; f1.get_point(&m_test, p); f2.get_point(&m1, p); for (int i = 0; i < 10; i++) { component c = (component)i; if (f1.gv.has_field(c)) { complex<double> v1 = m_test.get_component(c), v2 = m1.get_component(c); if (abs(v1 - v2) > tol * abs(v2) && abs(v2) > thresh) { master_printf("%s differs: %g %g out of %g %g\n", component_name(c), real(v2 - v1), imag(v2 - v1), real(v2), imag(v2)); master_printf("This comes out to a fractional error of %g\n", abs(v1 - v2) / abs(v2)); master_printf("Right now I'm looking at %g, time %g\n", p.z(), f1.time()); return 0; } } } return 1; }
int compare_point(fields &f1, fields &f2, const vec &p, double eps=4e-8) { if (sizeof(realnum) == sizeof(float)) eps = sqrt(eps); monitor_point m1, m_test; f1.get_point(&m_test, p); f2.get_point(&m1, p); for (int i=0;i<10;i++) { component c = (component) i; if (f1.gv.has_field(c)) { complex<double> v1 = m_test.get_component(c), v2 = m1.get_component(c); if (abs(v1 - v2) > eps*abs(v2) && abs(v2) > eps*100) { master_printf("%s differs: %g %g out of %g %g\n", component_name(c), real(v2-v1), imag(v2-v1), real(v2), imag(v2)); master_printf("This comes out to a fractional error of %g\n", abs(v1 - v2)/abs(v2)); master_printf("Right now I'm looking at %g %g, time %g\n", p.r(), p.z(), f1.time()); all_wait(); return 0; } } } return 1; }
int compare_point(fields &f1, fields &f2, const vec &p) { monitor_point m1, m_test; f1.get_point(&m_test, p); f2.get_point(&m1, p); for (int i=0;i<10;i++) { component c = (component) i; if (f1.gv.has_field(c)) { complex<double> v1 = m_test.get_component(c), v2 = m1.get_component(c); if (!compare(real(v1),real(v2),"real part") || !compare(imag(v1),imag(v2),"imaginary part")) { master_printf("%s differs by %g%+gi from %g%+gi\n", component_name(c), real(v2-v1), imag(v2-v1), real(v2), imag(v2)); master_printf("This comes out to a fractional error of %g\n", abs(v1 - v2)/abs(v2)); master_printf("Right now I'm looking at "); LOOP_OVER_DIRECTIONS(p.dim,d) master_printf("%s = %g, ", direction_name(d), p.in_direction(d)); master_printf("time %g\n", f1.time()); return 0; } } } return 1; }
void dft_ldos::update(fields &f) { complex<double> EJ = 0.0; // integral E * J* complex<double> HJ = 0.0; // integral H * J* for magnetic currents double scale = (f.dt/sqrt(2*pi)); // compute Jsum for LDOS normalization purposes // ...don't worry about the tiny inefficiency of recomputing this repeatedly Jsum = 0.0; for (int ic=0;ic<f.num_chunks;ic++) if (f.chunks[ic]->is_mine()) { for (src_vol *sv = f.chunks[ic]->sources[D_stuff]; sv; sv = sv->next) { component c = direction_component(Ex, component_direction(sv->c)); realnum *fr = f.chunks[ic]->f[c][0]; realnum *fi = f.chunks[ic]->f[c][1]; if (fr && fi) // complex E for (meep::integer j=0; j<sv->npts; j++) { const meep::integer idx = sv->index[j]; const complex<double> A = sv->A[j]; EJ += complex<double>(fr[idx],fi[idx]) * conj(A); Jsum += abs(A); } else if (fr) { // E is purely real for (meep::integer j=0; j<sv->npts; j++) { const meep::integer idx = sv->index[j]; const complex<double> A = sv->A[j]; EJ += double(fr[idx]) * conj(A); Jsum += abs(A); } } } for (src_vol *sv = f.chunks[ic]->sources[B_stuff]; sv; sv = sv->next) { component c = direction_component(Hx, component_direction(sv->c)); realnum *fr = f.chunks[ic]->f[c][0]; realnum *fi = f.chunks[ic]->f[c][1]; if (fr && fi) // complex H for (meep::integer j=0; j<sv->npts; j++) { const meep::integer idx = sv->index[j]; const complex<double> A = sv->A[j]; HJ += complex<double>(fr[idx],fi[idx]) * conj(A); Jsum += abs(A); } else if (fr) { // H is purely real for (meep::integer j=0; j<sv->npts; j++) { const meep::integer idx = sv->index[j]; const complex<double> A = sv->A[j]; HJ += double(fr[idx]) * conj(A); Jsum += abs(A); } } } } for (int i = 0; i < Nomega; ++i) { complex<double> Ephase = polar(1.0, (omega_min+i*domega)*f.time())*scale; complex<double> Hphase = polar(1.0, (omega_min+i*domega)*(f.time()-f.dt/2))*scale; Fdft[i] += Ephase * EJ + Hphase * HJ; // NOTE: take only 1st time dependence: assumes all sources have same J(t) if (f.sources) { if (f.is_real) // todo: not quite right if A is complex Jdft[i] += Ephase * real(f.sources->current()); else Jdft[i] += Ephase * f.sources->current(); } } // correct for dV factors Jsum *= sqrt(f.gv.dV(f.gv.icenter(),1).computational_volume()); }