Пример #1
0
/* Project X to its even or odd component, so that we can solve
   for only one parity of states (the projection operator, like the
   mirror flip operator, commutes with the Maxwell operator, so this
   projection should not slow convergence).  */
void maxwell_zparity_constraint(evectmatrix X, void *data)
{
     maxwell_data *d = (maxwell_data *) data;
     int i, j, b, nxy, nz;
     int zparity = ((d->parity & EVEN_Z_PARITY) ? +1 :
		    ((d->parity & ODD_Z_PARITY) ? -1 : 0));
     
     if (zparity == 0)
	  return;

     CHECK(d, "null maxwell data pointer!");
     CHECK(X.c == 2, "fields don't have 2 components!");

     if (d->nz > 1) {
	  nxy = d->other_dims;
	  nz = d->last_dim;
     }
     else {  /* common case (2d system): even/odd == TE/TM */
	  nxy = d->other_dims * d->last_dim;
	  if (zparity == +1)
	       for (i = 0; i < nxy; ++i) 
		    for (b = 0; b < X.p; ++b) {
			 ASSIGN_ZERO(X.data[(i * X.c + 1) * X.p + b]);
		    }
	  else if (zparity == -1)
	       for (i = 0; i < nxy; ++i) 
		    for (b = 0; b < X.p; ++b) {
			 ASSIGN_ZERO(X.data[(i * X.c) * X.p + b]);
		    }
	  return;
     }

     for (i = 0; i < nxy; ++i) {
	  for (j = 0; 2*j <= nz; ++j) {
	       int ij = i * nz + j; 
	       int ij2 = i * nz + (j > 0 ? nz - j : 0);
	       for (b = 0; b < X.p; ++b) {
		    scalar u,v, u2,v2;
		    u = X.data[(ij * 2) * X.p + b];
		    v = X.data[(ij * 2 + 1) * X.p + b];
		    u2 = X.data[(ij2 * 2) * X.p + b];
		    v2 = X.data[(ij2 * 2 + 1) * X.p + b];
		    ASSIGN_SCALAR(X.data[(ij * 2) * X.p + b],
				  0.5*(SCALAR_RE(u) + zparity*SCALAR_RE(u2)),
				  0.5*(SCALAR_IM(u) + zparity*SCALAR_IM(u2)));
		    ASSIGN_SCALAR(X.data[(ij * 2 + 1) * X.p + b],
				  0.5*(SCALAR_RE(v) - zparity*SCALAR_RE(v2)),
				  0.5*(SCALAR_IM(v) - zparity*SCALAR_IM(v2)));
		    ASSIGN_SCALAR(X.data[(ij2 * 2) * X.p + b],
				  0.5*(SCALAR_RE(u2) + zparity*SCALAR_RE(u)),
				  0.5*(SCALAR_IM(u2) + zparity*SCALAR_IM(u)));
		    ASSIGN_SCALAR(X.data[(ij2 * 2 + 1) * X.p + b],
				  0.5*(SCALAR_RE(v2) - zparity*SCALAR_RE(v)),
				  0.5*(SCALAR_IM(v2) - zparity*SCALAR_IM(v)));
	       }
	  }
     }
}
Пример #2
0
/* Project X to its even or odd component, so that we can solve
   for only one parity of states (the projection operator, like the
   mirror flip operator, commutes with the Maxwell operator, so this
   projection should not slow convergence).  */
void maxwell_yparity_constraint(evectmatrix X, void *data)
{
     maxwell_data *d = (maxwell_data *) data;
     int i, j, k, b, nx, ny, nz;
     int yparity = ((d->parity & EVEN_Y_PARITY) ? +1 :
		    ((d->parity & ODD_Y_PARITY) ? -1 : 0));

     if (yparity == 0)
	  return;

     CHECK(d, "null maxwell data pointer!");
     CHECK(X.c == 2, "fields don't have 2 components!");

     nx = d->local_nx;
     ny = d->ny;
     nz = d->nz;

     for (i = 0; i < nx; ++i) {
	  for (j = 0; 2*j <= ny; ++j) {
	       int ij = i * ny + j; 
	       int ij2 = i * ny + (j > 0 ? ny - j : 0);
	       for (k = 0; k < nz; ++k) {
		    int ijk = ij * nz + k;
		    int ijk2 = ij2 * nz + k;
		    for (b = 0; b < X.p; ++b) {
			 scalar u,v, u2,v2;
			 u = X.data[(ijk * 2) * X.p + b];
			 v = X.data[(ijk * 2 + 1) * X.p + b];
			 u2 = X.data[(ijk2 * 2) * X.p + b];
			 v2 = X.data[(ijk2 * 2 + 1) * X.p + b];
			 ASSIGN_SCALAR(X.data[(ijk * 2) * X.p + b],
				  0.5*(SCALAR_RE(u) - yparity*SCALAR_RE(u2)),
				  0.5*(SCALAR_IM(u) - yparity*SCALAR_IM(u2)));
			 ASSIGN_SCALAR(X.data[(ijk * 2 + 1) * X.p + b],
				  0.5*(SCALAR_RE(v) + yparity*SCALAR_RE(v2)),
				  0.5*(SCALAR_IM(v) + yparity*SCALAR_IM(v2)));
			 ASSIGN_SCALAR(X.data[(ijk2 * 2) * X.p + b],
				  0.5*(SCALAR_RE(u2) - yparity*SCALAR_RE(u)),
				  0.5*(SCALAR_IM(u2) - yparity*SCALAR_IM(u)));
			 ASSIGN_SCALAR(X.data[(ijk2 * 2 + 1) * X.p + b],
				  0.5*(SCALAR_RE(v2) + yparity*SCALAR_RE(v)),
				  0.5*(SCALAR_IM(v2) + yparity*SCALAR_IM(v)));
		    }
	       }
	  }
     }
}
Пример #3
0
real norm_diff(scalar *a, scalar *b, int n)
{
     real bmag = 0.0, diffmag = 0.0;
     int i;
     for (i = 0; i < n; ++i) {
	  scalar d;
	  ASSIGN_SCALAR(d,
			SCALAR_RE(b[i]) - SCALAR_RE(a[i]), 
			SCALAR_IM(b[i]) - SCALAR_IM(a[i]));
	  bmag += SCALAR_NORMSQR(b[i]);
	  diffmag += SCALAR_NORMSQR(d);
     }
     return sqrt(diffmag / bmag);
}
Пример #4
0
void maxwell_zero_k_set_const_bands(evectmatrix X, maxwell_data *d)
{
     int i, j, num_const_bands, m_band = 1, n_band = 1;
     
     CHECK(d, "null maxwell data pointer!");
     CHECK(X.c == 2, "fields don't have 2 components!");

     if (X.p < 1)
	  return;

     num_const_bands = maxwell_zero_k_num_const_bands(X, d);

     /* Initialize num_const_bands to zero: */
     for (i = 0; i < X.n; ++i) 
	  for (j = 0; j < num_const_bands; ++j) {
	       ASSIGN_ZERO(X.data[i * X.p + j]);
	  }
     
     if (X.Nstart > 0)
	  return;  /* DC frequency is not on this process */
		      
     /* Set DC components to 1 (in two parities) for num_const_bands: */

     if (d->parity & (ODD_Z_PARITY | EVEN_Y_PARITY))
	  m_band = 0;
     if (d->parity & (ODD_Y_PARITY | EVEN_Z_PARITY))
	  n_band = 0;

     if (m_band) {
	  ASSIGN_SCALAR(X.data[0], 1.0, 0.0);
	  ASSIGN_SCALAR(X.data[X.p], 0.0, 0.0);
     }
     if (n_band && (!m_band || X.p >= 2)) {
	  ASSIGN_SCALAR(X.data[m_band], 0.0, 0.0);
	  ASSIGN_SCALAR(X.data[X.p + m_band], 1.0, 0.0);
     }
}
Пример #5
0
void scale_eigenvector(integer b, cnumber scale)
{
     scalar s;

     CHECK(mdata, "init-params must be called before scale-eigenvector");
     CHECK(b > 0 && b <= H.p, "invalid band number in scale-eigenvector");

#ifndef SCALAR_COMPLEX
     CHECK(fabs(cnumber_im(scale) * cnumber_re(scale)) < 1e-14,
	   "scale-eigenvector must be called with real argument in mpbi");
#endif     
     ASSIGN_SCALAR(s, cnumber_re(scale), cnumber_im(scale));
     blasglue_scal(H.n, s, H.data + b-1, H.p);
     curfield_reset();
}