On Mon, 1 May 2006, Jun She wrote:
I wrote, f.initialize_with_n_tm(4). Then I compiled the code and run the program. I saw, "meep: cannot require a hp compoint in a 2D grid"

This function is for cylindrical coordinates only, and initializes the fields with a particular mode of a cylindrical metal waveguide. It's not what you want for your problem. (It's one of several functions in the C++ interface that is fairly old problem-specific cruft and should arguably be removed.)

In general, you don't need to initialize the field at all. To compute band structures, just excite the field (initialized to zero, the default) with a broadband pulse and then analyze the result with harminv.

I don't know why the field need to be intialized twice?

It's not being initialized twice. It's initializing two different components of the field. And the fields:: function calls the fields_chunk:: function to initialize the different "chunks" of the fields (the grid is broken up into a set of chunks corresponding to different CPUs, different update equations, etcetera).

Is require_componet(Ez) for 1d,2d,3d coordinates and require_component(Hp)
for cylindrical coordinates?

No. require_component just makes sure that those components are allocated before they are initialized.

Why not require_component(Hr) here?

Because that component is not initialized here. (In any case, requiring some components automatically implies that other related components are allocated too.)

Could I ask how to compute a band structure using C++?

In general, I recommend using the libctl/Scheme interface, since its usage is better documented. See the example bandstructure calculation in:

        
http://ab-initio.mit.edu/wiki/index.php/Meep_Tutorial/Band_diagram%2C_resonant_modes%2C_and_transmission_in_a_holey_waveguide

If you prefer to use C++, you'll want to use basically the same technique, just with more manual coding. However, for your information I have attached a C++ file that I once used to compute the band diagram of a triangular lattice of metallic rods in Meep.

Steven
#include <math.h>
#include <getopt.h>
#include <stdlib.h>
#include <time.h>

#include <meep.hpp>
using namespace meep;

// parameters:
double eps_rod = -1e12; // defaults to "metal"
double r = 0.47; // radius of metal rods

/* we will make a triangular lattice using a 1 by sqrt(3) supercell */

double eps(const vec &v) {
  double x = v.x(), y = v.y();
  if (hypot(x, y) < r
      || hypot(x - 1, y) < r
      || hypot(x, y - sqrt(3.)) < r
      || hypot(x - 1, y - sqrt(3.)) < r
      || hypot(x - 0.5, y - 0.5 * sqrt(3.)) < r)
    return eps_rod;

  return 1.0;
}

double urand(double a, double b)
{
  return a + rand() * (b - a) / RAND_MAX;
}

#define NUM_K 62
const double kpoints[NUM_K][2] = { /* from MPB (cartesian, w/o 2pi) */
  {0.0, 0.0},
  {0.0, 0.026243194054074},
  {0.0, 0.0524863881081479},
  {0.0, 0.0787295821622218},
  {0.0, 0.104972776216296},
  {0.0, 0.13121597027037},
  {0.0, 0.157459164324444},
  {0.0, 0.183702358378517},
  {0.0, 0.209945552432591},
  {0.0, 0.236188746486665},
  {0.0, 0.262431940540739},
  {0.0, 0.288675134594813},
  {0.0, 0.314918328648887},
  {0.0, 0.341161522702961},
  {0.0, 0.367404716757035},
  {0.0, 0.393647910811109},
  {0.0, 0.419891104865182},
  {0.0, 0.446134298919256},
  {0.0, 0.47237749297333},
  {0.0, 0.498620687027404},
  {0.0, 0.524863881081478},
  {0.0, 0.551107075135552},
  {0.0, 0.577350269189626},
  {-0.0256410256410256, 0.577350269189626},
  {-0.0512820512820513, 0.577350269189626},
  {-0.0769230769230769, 0.577350269189626},
  {-0.102564102564103, 0.577350269189626},
  {-0.128205128205128, 0.577350269189626},
  {-0.153846153846154, 0.577350269189626},
  {-0.179487179487179, 0.577350269189626},
  {-0.205128205128205, 0.577350269189626},
  {-0.230769230769231, 0.577350269189626},
  {-0.256410256410256, 0.577350269189626},
  {-0.282051282051282, 0.577350269189626},
  {-0.307692307692308, 0.577350269189626},
  {-0.333333333333333, 0.577350269189626},
  {-0.320512820512821, 0.555144489605409},
  {-0.307692307692308, 0.532938710021193},
  {-0.294871794871795, 0.510732930436977},
  {-0.282051282051282, 0.48852715085276},
  {-0.269230769230769, 0.466321371268544},
  {-0.256410256410256, 0.444115591684328},
  {-0.243589743589744, 0.421909812100111},
  {-0.230769230769231, 0.399704032515895},
  {-0.217948717948718, 0.377498252931678},
  {-0.205128205128205, 0.355292473347462},
  {-0.192307692307692, 0.333086693763246},
  {-0.17948717948718, 0.310880914179029},
  {-0.166666666666667, 0.288675134594813},
  {-0.153846153846154, 0.266469355010596},
  {-0.141025641025641, 0.24426357542638},
  {-0.128205128205128, 0.222057795842164},
  {-0.115384615384615, 0.199852016257947},
  {-0.102564102564103, 0.177646236673731},
  {-0.0897435897435897, 0.155440457089515},
  {-0.0769230769230769, 0.133234677505298},
  {-0.0641025641025641, 0.111028897921082},
  {-0.0512820512820513, 0.0888231183368655},
  {-0.0384615384615385, 0.0666173387526491},
  {-0.0256410256410256, 0.0444115591684328},
  {-0.0128205128205128, 0.0222057795842164},
  {0.0, 0.0}
};

int main(int argc, char **argv)
{
  initialize mpi(argc, argv);
  double resolution = 40; // pixels/a
  bool hdf_output = false;
  bool te = false;
  double T = 100;
  double freq = 0.3;
  double dfreq = 0.5; // fractional
  int which_k = -1; // default = all

  srand(314159); // deterministic "random" nums
  // srand(broadcast(0,time(NULL)));

  int ch;
  while ((ch = getopt(argc, argv, "a:hr:HAT:f:d:e:k:")) != -1)
    switch (ch) {
    case 'a':
      resolution = atof(optarg);
      break;
    case 'T':
      T = atof(optarg);
      break;
    case 'k':
      which_k = atoi(optarg);
      break;
    case 'H':
      hdf_output = true;
      break;
    case 'h':
      te = true;
      break;
    case 'r':
      r = atof(optarg);
      break;
    case 'e':
      eps_rod = atof(optarg);
      break;
    case 'f':
      freq = atof(optarg);
      break;
    case 'd':
      dfreq = atof(optarg);
      break;
    default:
      meep::abort("unrecognized argument %c", (char) ch);
    }

  volume v = vol2d(1.0, sqrt(3.), resolution);
  structure s(v, eps);

  if (hdf_output) {
    trash_output_directory("trirods-out");
    s.set_output_directory("trirods-out");
  }

  fields f(&s);
  f.use_bloch(vec(0,0));

  if (hdf_output) {
    f.output_hdf5(Dielectric, geometric_volume(vec(-1.0,-sqrt(3.0)),
					       vec(2.0, 2*sqrt(3.0))));
    master_printf("Output dielectric function.\n");
  }

  double freq_min = freq * (1 - dfreq);
  double freq_max = freq * (1 + dfreq);
  gaussian_src_time src((freq_min + freq_max) * 0.5,
                        0.5 / fabs(freq_max - freq_min),
                        0, 5 / fabs(freq_max - freq_min));

  int Ncpt = int(T / f.dt + 0.5) + 1;
  complex<double> *cpt = new complex<double>[Ncpt];
  complex<double> *cpt2 = new complex<double>[Ncpt];

  for (int kindex = 0; kindex < NUM_K; ++kindex) {
    if (which_k > 0) kindex = which_k;

    f.zero_fields();
    f.remove_sources();
    f.t = 0;

    double kx = kpoints[kindex][0], ky = kpoints[kindex][1];
    f.use_bloch(X, kx);
    f.use_bloch(Y, ky);
    
    // add sources, including Bloch-periodic replication of the primitive cell
    double xsrc, ysrc; // random src location...make sure is in air!
    do { xsrc = urand(0,1); ysrc = urand(0,sqrt(3.)); 
    } while (eps(vec(xsrc,ysrc)) != 1.0); 
    double xsrc2 = xsrc, ysrc2 = ysrc; // equiv. src. location (by periodicity)
    for (int i = -5; i < 5; ++i)
      for (int j = -5; j < 5; ++j) {
	double xsrc1 = xsrc + i * 1 + j * 0.5;
	double ysrc1 = ysrc + i * 0 + j * 0.5 * sqrt(3.);
	if ((i != 0 || j != 0)
	    && xsrc1 >= 0 && xsrc1 <= 1.0
	    && ysrc1 >= 0 && ysrc1 <= sqrt(3.))
	  f.add_point_source(Ez, src, vec(xsrc2 = xsrc1, ysrc2 = ysrc1), 
			     polar(1.0, 2*pi*(kx * xsrc1 + ky * ysrc1)));
      }
    master_printf("src locations: (%g,%g) and (%g,%g)\n",
		  xsrc, ysrc, xsrc2, ysrc2);
    
    int NT = int((f.last_source_time() + T) / f.dt + 0.5) + 1;
    while (f.time() < f.last_source_time()) {
      f.step();
      
      if (f.t % 100 == 0)
	master_printf("time step %d, %g%% done\n", f.t, f.t * 100.0 / NT);
    }
    
    int i = 0;
    while (f.time() < f.last_source_time() + T) {
      cpt[i] = f.get_field(Ez, vec(xsrc,ysrc));
      cpt2[i] = f.get_field(Ez, vec(xsrc2,ysrc2));
      i++;

      f.step();
      
      if (f.t % 100 == 0)
	master_printf("time step %d, %g%% done\n", f.t, f.t * 100.0 / NT);
    }
    
    complex<double> amp[100];
    double freq_re[100], freq_im[100], freq_err[100];
    int num_freqs = do_harminv(cpt, i, f.dt, freq_min/4, freq_max*4, 100,
			       amp, freq_re, freq_im, freq_err);
    complex<double> amp2[100];
    double freq_re2[100], freq_im2[100], freq_err2[100];
    int num_freqs2 = do_harminv(cpt2, i, f.dt, freq_min/4, freq_max*4, 100,
				amp2, freq_re2, freq_im2, freq_err2);

    for (int i = 0; i < num_freqs; ++i) {
      master_printf("freq[%d] = %g%+gi +/- %g (amp %g%+gi)\n",
		    i, freq_re[i], freq_im[i], freq_err[i],
		    real(amp[i]), imag(amp[i]));
      int i2 = 0;
      for (int j = 0; j < num_freqs2; ++j)
	if (fabs(freq_re[i] - freq_re2[j]) < fabs(freq_re[i] - freq_re2[i2]))
	  i2 = j;
      if (fabs(freq_re[i] - freq_re2[i2]) < 1e-4) {
	master_printf("   = freq2[%d] = %g%+gi +/- %g (amp %g%+gi)\n",
		      i2, freq_re2[i2], freq_im2[i2], freq_err2[i2],
		      real(amp2[i2]), imag(amp2[i2]));
	complex<double> ph = amp2[i2] / amp[i]
	  / polar(1.0, 2*pi * (kx * (xsrc2 - xsrc) + ky * (ysrc2 - ysrc)));
	master_printf("   (rel. amp. = %g%+gi, phase err = %g)\n",
		      real(ph), imag(ph), abs(ph - 1.0));
	if (abs(ph - 1.0) > 0.2)
	  freq_re[i] = 0;
      }
      else
	freq_re[i] = 0;
    }
    master_printf("freqs:, %d, %g, %g", kindex, kx, ky);
    for (int i = 0; i < num_freqs - 1; ++i) // sort by freq_re
      for (int j = i + 1; j < num_freqs; ++j)
	if (freq_re[i] > freq_re[j]) {
	  double foo = freq_re[i]; freq_re[i] = freq_re[j]; freq_re[j] = foo;
	}
    for (int i = 0; i < num_freqs; ++i)
      if (freq_re[i] != 0.0)
	master_printf(", %g", freq_re[i]);
    master_printf("\n");

    if (hdf_output && which_k > 0) {
      for (int i = 0; i < 2.0 / (freq * f.dt); ++i) {
	f.output_hdf5(Ez, geometric_volume(vec(-1.0,-sqrt(3.0)),
					   vec(2.0, 2*sqrt(3.0))));
	f.step();
      }
      master_printf("Output Ez.\n");
    }

    if (which_k > 0) break;
  }

  delete[] cpt2;
  delete[] cpt;

  return 0;
}
_______________________________________________
meep-discuss mailing list
[email protected]
http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/meep-discuss

Reply via email to