/*** Translated to the C language by N. Kyriazis 20 Aug 2003 ***
Program NEC(input,tape5=input,output,tape11,tape12,tape13,tape14,
tape15,tape16,tape20,tape21)
Numerical Electromagnetics Code (NEC2) developed at Lawrence
Livermore lab., Livermore, CA. (contact G. Burke at 415-422-8414
for problems with the NEC code. For problems with the vax implem-
entation, contact J. Breakall at 415-422-8196 or E. Domning at 415
422-5936)
file created 4/11/80.
***********Notice**********
This computer code material was prepared as an account of work
sponsored by the United States government. Neither the United
States nor the United States Department Of Energy, nor any of
their employees, nor any of their contractors, subcontractors,
or their employees, makes any warranty, express or implied, or
assumes any legal liability or responsibility for the accuracy,
completeness or usefulness of any information, apparatus, product
or process disclosed, or represents that its use would not infringe
privately-owned rights.
*******************************************************************/
#include "nec2c.h"
#include <omp.h>
/* common /data/ */
extern data_t data;
/* common /dataj/ */
extern dataj_t dataj;
/* common /matpar/ */
extern matpar_t matpar;
/* common /segj/ */
extern segj_t segj;
/* common /zload/ */
extern zload_t zload;
/* common /smat/ */
extern smat_t smat;
/* common /gnd/ */
extern gnd_t gnd;
/* common /vsorc/ */
extern vsorc_t vsorc;
/* pointers to input/output files */
extern FILE *input_fp, *output_fp, *plot_fp;
/*-------------------------------------------------------------------*/
/* cmset sets up the complex structure matrix in the array cm */
void cmset (int nrow, complex double *cm, double rkhx, int iexkx)
{
int mp2, neq, npeq, it, i, j, i1, i2, in2;
// int iout;
int im1, im2, ist, ij, ipr, jss, jm1, jm2, jst, k, ka, kk;
complex double zaj, deter, *scm = NULL;
mp2 = 2 * data.mp;
npeq = data.np + mp2;
neq = data.n + 2 * data.m;
smat.nop = neq / npeq;
dataj.rkh = rkhx;
dataj.iexk = iexkx;
// iout=2* matpar.npblk* nrow;
it = matpar.nlast;
for (i = 0; i < nrow; i++)
for (j = 0; j < it; j++)
cm[i + j * nrow] = CPLX_00;
i1 = 1;
i2 = it;
in2 = i2;
if (in2 > data.np)
in2 = data.np;
im1 = i1 - data.np;
im2 = i2 - data.np;
if (im1 < 1)
im1 = 1;
ist = 1;
if (i1 <= data.np)
ist = data.np - i1 + 2;
/* wire source loop */
if (data.n != 0)
{
for (j = 1; j <= data.n; j++)
{
trio (j);
for (i = 0; i < segj.jsno; i++)
{
ij = segj.jco[i];
segj.jco[i] = ((ij - 1) / data.np) * mp2 + ij;
}
if (i1 <= in2)
cmww (j, i1, in2, cm, nrow, cm, nrow, 1);
if (im1 <= im2)
cmws (j, im1, im2, &cm[(ist - 1) * nrow], nrow, cm, nrow, 1);
/* matrix elements modified by loading */
if (zload.nload == 0)
continue;
if (j > data.np)
continue;
ipr = j;
if ((ipr < 1) || (ipr > it))
continue;
zaj = zload.zarray[j - 1];
for (i = 0; i < segj.jsno; i++)
{
jss = segj.jco[i];
cm[(jss - 1) + (ipr - 1) * nrow] -=
(segj.ax[i] + segj.cx[i]) * zaj;
}
} /* for( j = 1; j <= n; j++ ) */
} /* if( n != 0) */
if (data.m != 0)
{
/* matrix elements for patch current sources */
jm1 = 1 - data.mp;
jm2 = 0;
jst = 1 - mp2;
for (i = 0; i < smat.nop; i++)
{
jm1 += data.mp;
jm2 += data.mp;
jst += npeq;
if (i1 <= in2)
cmsw (jm1, jm2, i1, in2, &cm[(jst - 1)], cm, 0, nrow, 1);
if (im1 <= im2)
cmss (
jm1,
jm2,
im1,
im2,
&cm[(jst - 1) + (ist - 1) * nrow],
nrow,
1);
}
} /* if( m != 0) */
if (matpar.icase == 1)
return;
/* Allocate to scratch memory */
mem_alloc ((void *) &scm, data.np2m * sizeof (complex double));
/* combine elements for symmetry modes */
for (i = 0; i < it; i++)
{
for (j = 0; j < npeq; j++)
{
for (k = 0; k < smat.nop; k++)
{
ka = j + k * npeq;
scm[k] = cm[ka + i * nrow];
}
deter = scm[0];
for (kk = 1; kk < smat.nop; kk++)
deter += scm[kk];
cm[j + i * nrow] = deter;
for (k = 1; k < smat.nop; k++)
{
ka = j + k * npeq;
deter = scm[0];
for (kk = 1; kk < smat.nop; kk++)
{
deter += scm[kk] * smat.ssx[k + kk * smat.nop];
cm[ka + i * nrow] = deter;
}
} /* for( k = 1; k < smat.nop; k++ ) */
} /* for( j = 0; j < npeq; j++ ) */
} /* for( i = 0; i < it; i++ ) */
free_ptr ((void *) &scm);
return;
}
/*-----------------------------------------------------------------------*/
/* cmss computes matrix elements for surface-surface interactions. */
void cmss (int j1, int j2, int im1, int im2, complex double *cm, int nrow, int itrp)
{
int i1, i2, icomp, ii1, i, il, ii2, jj1, j, jl, jj2;
double t1xi, t1yi, t1zi, t2xi, t2yi, t2zi, xi, yi, zi;
complex double g11, g12, g21, g22;
i1 = (im1 + 1) / 2;
i2 = (im2 + 1) / 2;
icomp = i1 * 2 - 3;
ii1 = -2;
if (icomp + 2 < im1)
ii1 = -3;
/* loop over observation patches */
il = -1;
for (i = i1; i <= i2; i++)
{
il++;
icomp += 2;
ii1 += 2;
ii2 = ii1 + 1;
t1xi = data.t1x[il] * data.psalp[il];
t1yi = data.t1y[il] * data.psalp[il];
t1zi = data.t1z[il] * data.psalp[il];
t2xi = data.t2x[il] * data.psalp[il];
t2yi = data.t2y[il] * data.psalp[il];
t2zi = data.t2z[il] * data.psalp[il];
xi = data.px[il];
yi = data.py[il];
zi = data.pz[il];
/* loop over source patches */
jj1 = -2;
for (j = j1; j <= j2; j++)
{
jl = j - 1;
jj1 += 2;
jj2 = jj1 + 1;
dataj.s = data.pbi[jl];
dataj.xj = data.px[jl];
dataj.yj = data.py[jl];
dataj.zj = data.pz[jl];
dataj.t1xj = data.t1x[jl];
dataj.t1yj = data.t1y[jl];
dataj.t1zj = data.t1z[jl];
dataj.t2xj = data.t2x[jl];
dataj.t2yj = data.t2y[jl];
dataj.t2zj = data.t2z[jl];
hintg (xi, yi, zi);
g11 = -(t2xi * dataj.exk + t2yi * dataj.eyk + t2zi * dataj.ezk);
g12 = -(t2xi * dataj.exs + t2yi * dataj.eys + t2zi * dataj.ezs);
g21 = -(t1xi * dataj.exk + t1yi * dataj.eyk + t1zi * dataj.ezk);
g22 = -(t1xi * dataj.exs + t1yi * dataj.eys + t1zi * dataj.ezs);
if (i == j)
{
g11 -= .5;
g22 += .5;
}
/* normal fill */
if (itrp == 0)
{
if (icomp >= im1)
{
cm[ii1 + jj1 * nrow] = g11;
cm[ii1 + jj2 * nrow] = g12;
}
if (icomp >= im2)
continue;
cm[ii2 + jj1 * nrow] = g21;
cm[ii2 + jj2 * nrow] = g22;
continue;
} /* if( itrp == 0) */
/* transposed fill */
if (icomp >= im1)
{
cm[jj1 + ii1 * nrow] = g11;
cm[jj2 + ii1 * nrow] = g12;
}
if (icomp >= im2)
continue;
cm[jj1 + ii2 * nrow] = g21;
cm[jj2 + ii2 * nrow] = g22;
} /* for( j = j1; j <= j2; j++ ) */
} /* for( i = i1; i <= i2; i++ ) */
return;
}
/*-----------------------------------------------------------------------*/
/* computes matrix elements for e along wires due to patch current */
void cmsw (
int j1,
int j2,
int i1,
int i2,
complex double *cm,
complex double *cw,
int ncw,
int nrow,
int itrp)
{
// int neqs;
int k, icgo, i, ipch, jl, j, js, il, ip;
int jsnox; /* -1 offset to "jsno" for array indexing */
double xi, yi, zi, cabi, sabi, salpi, fsign = 1., pyl, pxl;
complex double emel[9];
// neqs= data.np2m;
jsnox = segj.jsno - 1;
if (itrp >= 0)
{
k = -1;
icgo = 0;
/* observation loop */
for (i = i1 - 1; i < i2; i++)
{
k++;
xi = data.x[i];
yi = data.y[i];
zi = data.z[i];
cabi = data.cab[i];
sabi = data.sab[i];
salpi = data.salp[i];
ipch = 0;
if (data.icon1[i] >= PCHCON)
{
ipch = data.icon1[i] - PCHCON;
fsign = -1.;
}
if (data.icon2[i] >= PCHCON)
{
ipch = data.icon2[i] - PCHCON;
fsign = 1.;
}
/* source loop */
jl = -1;
for (j = j1; j <= j2; j++)
{
jl += 2;
js = j - 1;
dataj.t1xj = data.t1x[js];
dataj.t1yj = data.t1y[js];
dataj.t1zj = data.t1z[js];
dataj.t2xj = data.t2x[js];
dataj.t2yj = data.t2y[js];
dataj.t2zj = data.t2z[js];
dataj.xj = data.px[js];
dataj.yj = data.py[js];
dataj.zj = data.pz[js];
dataj.s = data.pbi[js];
/* ground loop */
for (ip = 1; ip <= gnd.ksymp; ip++)
{
dataj.ipgnd = ip;
if (((ipch == j) || (icgo != 0)) && (ip != 2))
{
if (icgo <= 0)
{
pcint (
xi,
yi,
zi,
cabi,
sabi,
salpi,
emel);
pyl = PI * data.si[i] * fsign;
pxl = sinl (pyl);
pyl = cosl (pyl);
dataj.exc = emel[8] * fsign;
trio (i + 1);
il = i - ncw;
if (i < data.np)
il += (il / data.np) * 2 *
data.mp;
if (itrp == 0)
cw[k + il * nrow] +=
dataj.exc *
(segj.ax[jsnox] +
segj.bx[jsnox] * pxl +
segj.cx[jsnox] * pyl);
else
cw[il + k * nrow] +=
dataj.exc *
(segj.ax[jsnox] +
segj.bx[jsnox] * pxl +
segj.cx[jsnox] * pyl);
} /* if( icgo <= 0 ) */
if (itrp == 0)
{
cm[k + (jl - 1) * nrow] = emel[icgo];
cm[k + jl * nrow] = emel[icgo + 4];
}
else
{
cm[(jl - 1) + k * nrow] = emel[icgo];
cm[jl + k * nrow] = emel[icgo + 4];
}
icgo++;
if (icgo == 4)
icgo = 0;
continue;
} /* if( ((ipch == (j+1)) || (icgo != 0)) && (ip != 2)
) */
unere (xi, yi, zi);
/* normal fill */
if (itrp == 0)
{
cm[k + (jl - 1) * nrow] += dataj.exk * cabi +
dataj.eyk * sabi +
dataj.ezk * salpi;
cm[k + jl * nrow] += dataj.exs * cabi +
dataj.eys * sabi +
dataj.ezs * salpi;
continue;
}
/* transposed fill */
cm[(jl - 1) + k * nrow] += dataj.exk * cabi +
dataj.eyk * sabi +
dataj.ezk * salpi;
cm[jl + k * nrow] += dataj.exs * cabi +
dataj.eys * sabi +
dataj.ezs * salpi;
} /* for( ip = 1; ip <= gnd.ksymp; ip++ ) */
} /* for( j = j1; j <= j2; j++ ) */
} /* for( i = i1-1; i < i2; i++ ) */
} /* if( itrp >= 0) */
return;
}
/*-----------------------------------------------------------------------*/
/* cmws computes matrix elements for wire-surface interactions */
void cmws (
int j, int i1, int i2, complex double *cm, int nr, complex double *cw, int nw, int itrp)
{
int ipr, i, ipatch, ik, js = 0, ij, jx;
double xi, yi, zi, tx, ty, tz;
complex double etk, ets, etc;
i = nw;
j--;
dataj.s = data.si[j];
dataj.b = data.bi[j];
dataj.xj = data.x[j];
dataj.yj = data.y[j];
dataj.zj = data.z[j];
dataj.cabj = data.cab[j];
dataj.sabj = data.sab[j];
dataj.salpj = data.salp[j];
/* observation loop */
ipr = -1;
for (i = i1; i <= i2; i++)
{
ipr++;
ipatch = (i + 1) / 2;
ik = i - (i / 2) * 2;
if ((ik != 0) || (ipr == 0))
{
js = ipatch - 1;
xi = data.px[js];
yi = data.py[js];
zi = data.pz[js];
hsfld (xi, yi, zi, 0.);
if (ik != 0)
{
tx = data.t2x[js];
ty = data.t2y[js];
tz = data.t2z[js];
}
else
{
tx = data.t1x[js];
ty = data.t1y[js];
tz = data.t1z[js];
}
} /* if( (ik != 0) || (ipr == 0) ) */
else
{
tx = data.t1x[js];
ty = data.t1y[js];
tz = data.t1z[js];
} /* if( (ik != 0) || (ipr == 0) ) */
etk = -(dataj.exk * tx + dataj.eyk * ty + dataj.ezk * tz) * data.psalp[js];
ets = -(dataj.exs * tx + dataj.eys * ty + dataj.ezs * tz) * data.psalp[js];
etc = -(dataj.exc * tx + dataj.eyc * ty + dataj.ezc * tz) * data.psalp[js];
/* fill matrix elements. element locations */
/* determined by connection data. */
/* normal fill */
if (itrp == 0)
{
for (ij = 0; ij < segj.jsno; ij++)
{
jx = segj.jco[ij] - 1;
cm[ipr + jx * nr] +=
etk * segj.ax[ij] + ets * segj.bx[ij] + etc * segj.cx[ij];
}
continue;
} /* if( itrp == 0) */
/* transposed fill */
if (itrp != 2)
{
for (ij = 0; ij < segj.jsno; ij++)
{
jx = segj.jco[ij] - 1;
cm[jx + ipr * nr] +=
etk * segj.ax[ij] + ets * segj.bx[ij] + etc * segj.cx[ij];
}
continue;
} /* if( itrp != 2) */
/* transposed fill - c(ws) and d(ws)prime (=cw) */
for (ij = 0; ij < segj.jsno; ij++)
{
jx = segj.jco[ij] - 1;
if (jx < nr)
cm[jx + ipr * nr] +=
etk * segj.ax[ij] + ets * segj.bx[ij] + etc * segj.cx[ij];
else
{
jx -= nr;
cw[jx + ipr * nr] +=
etk * segj.ax[ij] + ets * segj.bx[ij] + etc * segj.cx[ij];
}
} /* for( ij = 0; ij < segj.jsno; ij++ ) */
} /* for( i = i1; i <= i2; i++ ) */
return;
}
/*-----------------------------------------------------------------------*/
/* cmww computes matrix elements for wire-wire interactions */
void cmww (
int j, int i1, int i2, complex double *cm, int nr, complex double *cw, int nw, int itrp)
{
int ipr, iprx, i, ij, jx;
double xi, yi, zi, ai, cabi, sabi, salpi;
complex double etk, ets, etc;
/* set source segment parameters */
jx = j;
j--;
dataj.s = data.si[j];
dataj.b = data.bi[j];
dataj.xj = data.x[j];
dataj.yj = data.y[j];
dataj.zj = data.z[j];
dataj.cabj = data.cab[j];
dataj.sabj = data.sab[j];
dataj.salpj = data.salp[j];
/* decide whether ext. t.w. approx. can be used */
if (dataj.iexk != 0)
{
ipr = data.icon1[j];
if (ipr > PCHCON)
dataj.ind1 = 0;
else if (ipr < 0)
{
ipr = -ipr;
iprx = ipr - 1;
if (-data.icon1[iprx] != jx)
dataj.ind1 = 2;
else
{
xi = fabsl (
dataj.cabj * data.cab[iprx] + dataj.sabj * data.sab[iprx] +
dataj.salpj * data.salp[iprx]);
if ((xi < 0.999999) ||
(fabsl (data.bi[iprx] / dataj.b - 1.) > 1.e-6))
dataj.ind1 = 2;
else
dataj.ind1 = 0;
} /* if( -data.icon1[iprx] != jx ) */
} /* if( ipr < 0 ) */
else
{
iprx = ipr - 1;
if (ipr == 0)
dataj.ind1 = 1;
else
{
if (ipr != jx)
{
if (data.icon2[iprx] != jx)
dataj.ind1 = 2;
else
{
xi = fabsl (
dataj.cabj * data.cab[iprx] +
dataj.sabj * data.sab[iprx] +
dataj.salpj * data.salp[iprx]);
if ((xi < 0.999999) ||
(fabsl (data.bi[iprx] / dataj.b - 1.) >
1.e-6))
dataj.ind1 = 2;
else
dataj.ind1 = 0;
} /* if( data.icon2[iprx] != jx ) */
} /* if( ipr != jx ) */
else if (
dataj.cabj * dataj.cabj + dataj.sabj * dataj.sabj > 1.e-8)
dataj.ind1 = 2;
else
dataj.ind1 = 0;
} /* if( ipr == 0 ) */
} /* if( ipr < 0 ) */
ipr = data.icon2[j];
if (ipr > PCHCON)
dataj.ind2 = 2;
else if (ipr < 0)
{
ipr = -ipr;
iprx = ipr - 1;
if (-data.icon2[iprx] != jx)
dataj.ind2 = 2;
else
{
xi = fabsl (
dataj.cabj * data.cab[iprx] + dataj.sabj * data.sab[iprx] +
dataj.salpj * data.salp[iprx]);
if ((xi < 0.999999) ||
(fabsl (data.bi[iprx] / dataj.b - 1.) > 1.e-6))
dataj.ind2 = 2;
else
dataj.ind2 = 0;
} /* if( -data.icon1[iprx] != jx ) */
} /* if( ipr < 0 ) */
else
{
iprx = ipr - 1;
if (ipr == 0)
dataj.ind2 = 1;
else
{
if (ipr != jx)
{
if (data.icon1[iprx] != jx)
dataj.ind2 = 2;
else
{
xi = fabsl (
dataj.cabj * data.cab[iprx] +
dataj.sabj * data.sab[iprx] +
dataj.salpj * data.salp[iprx]);
if ((xi < 0.999999) ||
(fabsl (data.bi[iprx] / dataj.b - 1.) >
1.e-6))
dataj.ind2 = 2;
else
dataj.ind2 = 0;
} /* if( data.icon2[iprx] != jx ) */
} /* if( ipr != jx ) */
else if (
dataj.cabj * dataj.cabj + dataj.sabj * dataj.sabj > 1.e-8)
dataj.ind2 = 2;
else
dataj.ind2 = 0;
} /* if( ipr == 0 ) */
} /* if( ipr < 0 ) */
} /* if( dataj.iexk != 0) */
/* observation loop */
ipr = -1;
for (i = i1 - 1; i < i2; i++)
{
ipr++;
ij = i - j;
xi = data.x[i];
yi = data.y[i];
zi = data.z[i];
ai = data.bi[i];
cabi = data.cab[i];
sabi = data.sab[i];
salpi = data.salp[i];
efld (xi, yi, zi, ai, ij);
etk = dataj.exk * cabi + dataj.eyk * sabi + dataj.ezk * salpi;
ets = dataj.exs * cabi + dataj.eys * sabi + dataj.ezs * salpi;
etc = dataj.exc * cabi + dataj.eyc * sabi + dataj.ezc * salpi;
/* fill matrix elements. element locations */
/* determined by connection data. */
/* normal fill */
if (itrp == 0)
{
for (ij = 0; ij < segj.jsno; ij++)
{
jx = segj.jco[ij] - 1;
cm[ipr + jx * nr] +=
etk * segj.ax[ij] + ets * segj.bx[ij] + etc * segj.cx[ij];
}
continue;
}
/* transposed fill */
if (itrp != 2)
{
for (ij = 0; ij < segj.jsno; ij++)
{
jx = segj.jco[ij] - 1;
cm[jx + ipr * nr] +=
etk * segj.ax[ij] + ets * segj.bx[ij] + etc * segj.cx[ij];
}
continue;
}
/* trans. fill for c(ww) - test for elements for d(ww)prime. (=cw) */
for (ij = 0; ij < segj.jsno; ij++)
{
jx = segj.jco[ij] - 1;
if (jx < nr)
cm[jx + ipr * nr] +=
etk * segj.ax[ij] + ets * segj.bx[ij] + etc * segj.cx[ij];
else
{
jx -= nr;
cw[jx * ipr * nw] +=
etk * segj.ax[ij] + ets * segj.bx[ij] + etc * segj.cx[ij];
}
} /* for( ij = 0; ij < segj.jsno; ij++ ) */
} /* for( i = i1-1; i < i2; i++ ) */
return;
}
/*-----------------------------------------------------------------------*/
/* etmns fills the array e with the negative of the */
/* electric field incident on the structure. e is the */
/* right hand side of the matrix equation. */
void etmns (
double p1,
double p2,
double p3,
double p4,
double p5,
double p6,
int ipr,
complex double *e)
{
int i, is, i1, i2 = 0, neq;
double cth, sth, cph, sph, cet, set, pxl, pyl, pzl, wx;
double wy, wz, qx, qy, qz, arg, ds, dsh, rs, r;
complex double cx, cy, cz, er, et, ezh, erh, rrv = CPLX_00, rrh = CPLX_00, tt1, tt2;
neq = data.n + 2 * data.m;
vsorc.nqds = 0;
/* applied field of voltage sources for transmitting case */
if ((ipr == 0) || (ipr == 5))
{
for (i = 0; i < neq; i++)
e[i] = CPLX_00;
if (vsorc.nsant != 0)
{
for (i = 0; i < vsorc.nsant; i++)
{
is = vsorc.isant[i] - 1;
e[is] = -vsorc.vsant[i] / (data.si[is] * data.wlam);
}
}
if (vsorc.nvqd == 0)
return;
for (i = 0; i < vsorc.nvqd; i++)
{
is = vsorc.ivqd[i];
qdsrc (is, vsorc.vqd[i], e);
}
return;
} /* if( (ipr == 0) || (ipr == 5) ) */
/* incident plane wave, linearly polarized. */
if (ipr <= 3)
{
cth = cosl (p1);
sth = sinl (p1);
cph = cosl (p2);
sph = sinl (p2);
cet = cosl (p3);
set = sinl (p3);
pxl = cth * cph * cet - sph * set;
pyl = cth * sph * cet + cph * set;
pzl = -sth * cet;
wx = -sth * cph;
wy = -sth * sph;
wz = -cth;
qx = wy * pzl - wz * pyl;
qy = wz * pxl - wx * pzl;
qz = wx * pyl - wy * pxl;
if (gnd.ksymp != 1)
{
if (gnd.iperf != 1)
{
rrv = csqrtl (1. - gnd.zrati * gnd.zrati * sth * sth);
rrh = gnd.zrati * cth;
rrh = (rrh - rrv) / (rrh + rrv);
rrv = gnd.zrati * rrv;
rrv = -(cth - rrv) / (cth + rrv);
}
else
{
rrv = -CPLX_10;
rrh = -CPLX_10;
} /* if( gnd.iperf != 1) */
} /* if( gnd.ksymp != 1) */
if (ipr == 1)
{
if (data.n != 0)
{
for (i = 0; i < data.n; i++)
{
arg = -TP * (wx * data.x[i] + wy * data.y[i] +
wz * data.z[i]);
e[i] = -(pxl * data.cab[i] + pyl * data.sab[i] +
pzl * data.salp[i]) *
cmplx (cosl (arg), sinl (arg));
}
if (gnd.ksymp != 1)
{
tt1 = (pyl * cph - pxl * sph) * (rrh - rrv);
cx = rrv * pxl - tt1 * sph;
cy = rrv * pyl + tt1 * cph;
cz = -rrv * pzl;
for (i = 0; i < data.n; i++)
{
arg = -TP * (wx * data.x[i] + wy * data.y[i] -
wz * data.z[i]);
e[i] = e[i] -
(cx * data.cab[i] + cy * data.sab[i] +
cz * data.salp[i]) *
cmplx (cosl (arg), sinl (arg));
}
} /* if( gnd.ksymp != 1) */
} /* if( data.n != 0) */
if (data.m == 0)
return;
i = -1;
i1 = data.n - 2;
for (is = 0; is < data.m; is++)
{
i++;
i1 += 2;
i2 = i1 + 1;
arg = -TP *
(wx * data.px[i] + wy * data.py[i] + wz * data.pz[i]);
tt1 = cmplx (cosl (arg), sinl (arg)) * data.psalp[i] * RETA;
e[i2] =
(qx * data.t1x[i] + qy * data.t1y[i] + qz * data.t1z[i]) *
tt1;
e[i1] =
(qx * data.t2x[i] + qy * data.t2y[i] + qz * data.t2z[i]) *
tt1;
}
if (gnd.ksymp == 1)
return;
tt1 = (qy * cph - qx * sph) * (rrv - rrh);
cx = -(rrh * qx - tt1 * sph);
cy = -(rrh * qy + tt1 * cph);
cz = rrh * qz;
i = -1;
i1 = data.n - 2;
for (is = 0; is < data.m; is++)
{
i++;
i1 += 2;
i2 = i1 + 1;
arg = -TP *
(wx * data.px[i] + wy * data.py[i] - wz * data.pz[i]);
tt1 = cmplx (cosl (arg), sinl (arg)) * data.psalp[i] * RETA;
e[i2] = e[i2] + (cx * data.t1x[i] + cy * data.t1y[i] +
cz * data.t1z[i]) *
tt1;
e[i1] = e[i1] + (cx * data.t2x[i] + cy * data.t2y[i] +
cz * data.t2z[i]) *
tt1;
}
return;
} /* if( ipr == 1) */
/* incident plane wave, elliptic polarization. */
tt1 = -(CPLX_01) *p6;
if (ipr == 3)
tt1 = -tt1;
if (data.n != 0)
{
cx = pxl + tt1 * qx;
cy = pyl + tt1 * qy;
cz = pzl + tt1 * qz;
for (i = 0; i < data.n; i++)
{
arg = -TP * (wx * data.x[i] + wy * data.y[i] + wz * data.z[i]);
e[i] = -(cx * data.cab[i] + cy * data.sab[i] +
cz * data.salp[i]) *
cmplx (cosl (arg), sinl (arg));
}
if (gnd.ksymp != 1)
{
tt2 = (cy * cph - cx * sph) * (rrh - rrv);
cx = rrv * cx - tt2 * sph;
cy = rrv * cy + tt2 * cph;
cz = -rrv * cz;
for (i = 0; i < data.n; i++)
{
arg = -TP * (wx * data.x[i] + wy * data.y[i] -
wz * data.z[i]);
e[i] = e[i] - (cx * data.cab[i] + cy * data.sab[i] +
cz * data.salp[i]) *
cmplx (cosl (arg), sinl (arg));
}
} /* if( gnd.ksymp != 1) */
} /* if( n != 0) */
if (data.m == 0)
return;
cx = qx - tt1 * pxl;
cy = qy - tt1 * pyl;
cz = qz - tt1 * pzl;
i = -1;
i1 = data.n - 2;
for (is = 0; is < data.m; is++)
{
i++;
i1 += 2;
i2 = i1 + 1;
arg = -TP * (wx * data.px[i] + wy * data.py[i] + wz * data.pz[i]);
tt2 = cmplx (cosl (arg), sinl (arg)) * data.psalp[i] * RETA;
e[i2] = (cx * data.t1x[i] + cy * data.t1y[i] + cz * data.t1z[i]) * tt2;
e[i1] = (cx * data.t2x[i] + cy * data.t2y[i] + cz * data.t2z[i]) * tt2;
}
if (gnd.ksymp == 1)
return;
tt1 = (cy * cph - cx * sph) * (rrv - rrh);
cx = -(rrh * cx - tt1 * sph);
cy = -(rrh * cy + tt1 * cph);
cz = rrh * cz;
i = -1;
i1 = data.n - 2;
for (is = 0; is < data.m; is++)
{
i++;
i1 += 2;
i2 = i1 + 1;
arg = -TP * (wx * data.px[i] + wy * data.py[i] - wz * data.pz[i]);
tt1 = cmplx (cosl (arg), sinl (arg)) * data.psalp[i] * RETA;
e[i2] = e[i2] +
(cx * data.t1x[i] + cy * data.t1y[i] + cz * data.t1z[i]) * tt1;
e[i1] = e[i1] +
(cx * data.t2x[i] + cy * data.t2y[i] + cz * data.t2z[i]) * tt1;
}
return;
} /* if( ipr <= 3) */
/* incident field of an elementary current source. */
wz = cosl (p4);
wx = wz * cosl (p5);
wy = wz * sinl (p5);
wz = sinl (p4);
ds = p6 * 59.958;
dsh = p6 / (2. * TP);
is = 0;
i1 = data.n - 2;
for (i = 0; i < data.npm; i++)
{
if (i >= data.n)
{
i1 += 2;
i2 = i1 + 1;
pxl = data.px[is] - p1;
pyl = data.py[is] - p2;
pzl = data.pz[is] - p3;
}
else
{
pxl = data.x[i] - p1;
pyl = data.y[i] - p2;
pzl = data.z[i] - p3;
}
rs = pxl * pxl + pyl * pyl + pzl * pzl;
if (rs < 1.0e-30)
continue;
r = sqrtl (rs);
pxl = pxl / r;
pyl = pyl / r;
pzl = pzl / r;
cth = pxl * wx + pyl * wy + pzl * wz;
sth = sqrtl (1. - cth * cth);
qx = pxl - wx * cth;
qy = pyl - wy * cth;
qz = pzl - wz * cth;
arg = sqrtl (qx * qx + qy * qy + qz * qz);
if (arg >= 1.e-30)
{
qx = qx / arg;
qy = qy / arg;
qz = qz / arg;
}
else
{
qx = 1.;
qy = 0.;
qz = 0.;
} /* if( arg >= 1.e-30) */
arg = -TP * r;
tt1 = cmplx (cosl (arg), sinl (arg));
if (i < data.n)
{
tt2 = cmplx (1.0, -1.0 / (r * TP)) / rs;
er = ds * tt1 * tt2 * cth;
et = .5 * ds * tt1 * ((CPLX_01) *TP / r + tt2) * sth;
ezh = er * cth - et * sth;
erh = er * sth + et * cth;
cx = ezh * wx + erh * qx;
cy = ezh * wy + erh * qy;
cz = ezh * wz + erh * qz;
e[i] = -(cx * data.cab[i] + cy * data.sab[i] + cz * data.salp[i]);
}
else
{
pxl = wy * qz - wz * qy;
pyl = wz * qx - wx * qz;
pzl = wx * qy - wy * qx;
tt2 = dsh * tt1 * cmplx (1. / r, TP) / r * sth * data.psalp[is];
cx = tt2 * pxl;
cy = tt2 * pyl;
cz = tt2 * pzl;
e[i2] = cx * data.t1x[is] + cy * data.t1y[is] + cz * data.t1z[is];
e[i1] = cx * data.t2x[is] + cy * data.t2y[is] + cz * data.t2z[is];
is++;
} /* if( i < data.n) */
} /* for( i = 0; i < npm; i++ ) */
return;
}
/*-----------------------------------------------------------------------*/
/* subroutine to factor a matrix into a unit lower triangular matrix */
/* and an upper triangular matrix using the gauss-doolittle algorithm */
/* presented on pages 411-416 of a. ralston--a first course in */
/* numerical analysis. comments below refer to comments in ralstons */
/* text. (matrix transposed.) */
void factr (int n, complex double *a, int *ip, int ndim)
{
int r, rm1, rp1, pj, pr, iflg, k, j, jp1, i;
double dmax, elmag;
complex double arj, *scm = NULL;
/* Allocate to scratch memory */
mem_alloc ((void *) &scm, data.np2m * sizeof (complex double));
/* Un-transpose the matrix for Gauss elimination */
for (i = 1; i < n; i++)
for (j = 0; j < i; j++)
{
arj = a[i + j * ndim];
a[i + j * ndim] = a[j + i * ndim];
a[j + i * ndim] = arj;
}
iflg = FALSE;
/* step 1 */
for (r = 0; r < n; r++)
{
for (k = 0; k < n; k++)
scm[k] = a[k + r * ndim];
/* steps 2 and 3 */
rm1 = r;
if (rm1 > 0)
{
for (j = 0; j < rm1; j++)
{
pj = ip[j] - 1;
arj = scm[pj];
a[j + r * ndim] = arj;
scm[pj] = scm[j];
jp1 = j + 1;
for (i = jp1; i < n; i++)
scm[i] -= a[i + j * ndim] * arj;
} /* for( j = 0; j < rm1; j++ ) */
} /* if( rm1 >= 0.) */
/* step 4 */
dmax
= creal (scm
[r
] * conjl
(scm
[r
]));
rp1 = r + 1;
ip[r] = rp1;
if (rp1 < n)
{
for (i = rp1; i < n; i++)
{
elmag
= creal (scm
[i
] * conjl
(scm
[i
]));
if (elmag >= dmax)
{
dmax = elmag;
ip[r] = i + 1;
}
}
} /* if( rp1 < n) */
if (dmax < 1.e-10)
iflg = TRUE;
pr = ip[r] - 1;
a[r + r * ndim] = scm[pr];
scm[pr] = scm[r];
/* step 5 */
if (rp1 < n)
{
arj = 1. / a[r + r * ndim];
for (i = rp1; i < n; i++)
a[i + r * ndim] = scm[i] * arj;
}
if (iflg == TRUE)
{
fprintf (output_fp
, "\n PIVOT(%d)= %16.8E", r
, dmax
);
iflg = FALSE;
}
} /* for( r=0; r < n; r++ ) */
free_ptr ((void *) &scm);
return;
}
/*-----------------------------------------------------------------------*/
/* factrs, for symmetric structure, transforms submatricies to form */
/* matricies of the symmetric modes and calls routine to factor */
/* matricies. if no symmetry, the routine is called to factor the */
/* complete matrix. */
void factrs (int np, int nrow, complex double *a, int *ip)
{
int kk, ka;
smat.nop = nrow / np;
for (kk = 0; kk < smat.nop; kk++)
{
ka = kk * np;
factr (np, &a[ka], &ip[ka], nrow);
}
return;
}
/*-----------------------------------------------------------------------*/
/* fblock sets parameters for out-of-core */
/* solution for the primary matrix (a) */
void fblock (int nrow, int ncol, int imax, int ipsym)
{
int i, j, k, ka, kk;
double phaz, arg;
complex double deter;
if (nrow * ncol <= imax)
{
matpar.npblk = nrow;
matpar.nlast = nrow;
matpar.imat = nrow * ncol;
if (nrow == ncol)
{
matpar.icase = 1;
return;
}
else
matpar.icase = 2;
} /* if( nrow*ncol <= imax) */
smat.nop = ncol / nrow;
if (smat.nop * nrow != ncol)
{
fprintf (output_fp
, "\n SYMMETRY ERROR - NROW: %d NCOL: %d", nrow
, ncol
);
stop (-1);
}
/* set up smat.ssx matrix for rotational symmetry. */
if (ipsym <= 0)
{
phaz = TP / smat.nop;
for (i = 1; i < smat.nop; i++)
{
for (j = i; j < smat.nop; j++)
{
arg = phaz * (double) i * (double) j;
smat.ssx[i + j * smat.nop] = cmplx (cosl (arg), sinl (arg));
smat.ssx[j + i * smat.nop] = smat.ssx[i + j * smat.nop];
}
}
return;
} /* if( ipsym <= 0) */
/* set up smat.ssx matrix for plane symmetry */
kk = 1;
smat.ssx[0] = CPLX_10;
k = 2;
for (ka = 1; k != smat.nop; ka++)
k *= 2;
for (k = 0; k < ka; k++)
{
for (i = 0; i < kk; i++)
{
for (j = 0; j < kk; j++)
{
deter = smat.ssx[i + j * smat.nop];
smat.ssx[i + (j + kk) * smat.nop] = deter;
smat.ssx[i + kk + (j + kk) * smat.nop] = -deter;
smat.ssx[i + kk + j * smat.nop] = deter;
}
}
kk *= 2;
} /* for( k = 0; k < ka; k++ ) */
return;
}
/*-----------------------------------------------------------------------*/
/* subroutine to solve the matrix equation lu*x=b where l is a unit */
/* lower triangular matrix and u is an upper triangular matrix both */
/* of which are stored in a. the rhs vector b is input and the */
/* solution is returned through vector b. (matrix transposed. */
void solve (int n, complex double *a, int *ip, complex double *b, int ndim)
{
int i, ip1, j, k, pia;
complex double sum, *scm = NULL;
/* Allocate to scratch memory */
mem_alloc ((void *) &scm, data.np2m * sizeof (complex double));
/* forward substitution */
for (i = 0; i < n; i++)
{
pia = ip[i] - 1;
scm[i] = b[pia];
b[pia] = b[i];
ip1 = i + 1;
if (ip1 < n)
for (j = ip1; j < n; j++)
b[j] -= a[j + i * ndim] * scm[i];
}
/* backward substitution */
for (k = 0; k < n; k++)
{
i = n - k - 1;
sum = CPLX_00;
ip1 = i + 1;
if (ip1 < n)
for (j = ip1; j < n; j++)
sum += a[i + j * ndim] * b[j];
b[i] = (scm[i] - sum) / a[i + i * ndim];
}
free_ptr ((void *) &scm);
return;
}
/*-----------------------------------------------------------------------*/
/* subroutine solves, for symmetric structures, handles the */
/* transformation of the right hand side vector and solution */
/* of the matrix eq. */
void solves (
complex double *a,
int *ip,
complex double *b,
int neq,
int nrh,
int np,
int n,
int mp,
int m)
{
int npeq, nrow, ic, i, kk, ia, ib, j, k;
double fnop, fnorm;
complex double sum, *scm = NULL;
npeq = np + 2 * mp;
smat.nop = neq / npeq;
fnop = smat.nop;
fnorm = 1. / fnop;
nrow = neq;
/* Allocate to scratch memory */
mem_alloc ((void *) &scm, data.np2m * sizeof (complex double));
if (smat.nop != 1)
{
for (ic = 0; ic < nrh; ic++)
{
if ((n != 0) && (m != 0))
{
for (i = 0; i < neq; i++)
scm[i] = b[i + ic * neq];
kk = 2 * mp;
ia = np - 1;
ib = n - 1;
j = np - 1;
for (k = 0; k < smat.nop; k++)
{
if (k != 0)
{
for (i = 0; i < np; i++)
{
ia++;
j++;
b[j + ic * neq] = scm[ia];
}
if (k == (smat.nop - 1))
continue;
} /* if( k != 0 ) */
for (i = 0; i < kk; i++)
{
ib++;
j++;
b[j + ic * neq] = scm[ib];
}
} /* for( k = 0; k < smat.nop; k++ ) */
} /* if( (n != 0) && (m != 0) ) */
/* transform matrix eq. rhs vector according to symmetry modes */
for (i = 0; i < npeq; i++)
{
for (k = 0; k < smat.nop; k++)
{
ia = i + k * npeq;
scm[k] = b[ia + ic * neq];
}
sum = scm[0];
for (k = 1; k < smat.nop; k++)
sum += scm[k];
b[i + ic * neq] = sum * fnorm;
for (k = 1; k < smat.nop; k++)
{
ia = i + k * npeq;
sum = scm[0];
for (j = 1; j < smat.nop; j++)
sum += scm[j] *
conjl (smat.ssx[k + j * smat.nop]);
b[ia + ic * neq] = sum * fnorm;
}
} /* for( i = 0; i < npeq; i++ ) */
} /* for( ic = 0; ic < nrh; ic++ ) */
} /* if( smat.nop != 1) */
/* solve each mode equation */
for (kk = 0; kk < smat.nop; kk++)
{
ia = kk * npeq;
ib = ia;
for (ic = 0; ic < nrh; ic++)
solve (npeq, &a[ib], &ip[ia], &b[ia + ic * neq], nrow);
} /* for( kk = 0; kk < smat.nop; kk++ ) */
if (smat.nop == 1)
{
free_ptr ((void *) &scm);
return;
}
/* inverse transform the mode solutions */
for (ic = 0; ic < nrh; ic++)
{
for (i = 0; i < npeq; i++)
{
for (k = 0; k < smat.nop; k++)
{
ia = i + k * npeq;
scm[k] = b[ia + ic * neq];
}
sum = scm[0];
for (k = 1; k < smat.nop; k++)
sum += scm[k];
b[i + ic * neq] = sum;
for (k = 1; k < smat.nop; k++)
{
ia = i + k * npeq;
sum = scm[0];
for (j = 1; j < smat.nop; j++)
sum += scm[j] * smat.ssx[k + j * smat.nop];
b[ia + ic * neq] = sum;
}
} /* for( i = 0; i < npeq; i++ ) */
if ((n == 0) || (m == 0))
continue;
for (i = 0; i < neq; i++)
scm[i] = b[i + ic * neq];
kk = 2 * mp;
ia = np - 1;
ib = n - 1;
j = np - 1;
for (k = 0; k < smat.nop; k++)
{
if (k != 0)
{
for (i = 0; i < np; i++)
{
ia++;
j++;
b[ia + ic * neq] = scm[j];
}
if (k == smat.nop)
continue;
} /* if( k != 0 ) */
for (i = 0; i < kk; i++)
{
ib++;
j++;
b[ib + ic * neq] = scm[j];
}
} /* for( k = 0; k < smat.nop; k++ ) */
} /* for( ic = 0; ic < nrh; ic++ ) */
free_ptr ((void *) &scm);
return;
}
/*-----------------------------------------------------------------------*/