/*** 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"
/* common /tmi/ */
extern tmi_t tmi;
/*common /ggrid/ */
extern ggrid_t ggrid;
/* common /data/ */
extern data_t data;
/* common /crnt/ */
extern crnt_t crnt;
/* common /vsorc/ */
extern vsorc_t vsorc;
/* common /segj/ */
extern segj_t segj;
/* common /yparm/ */
extern yparm_t yparm;
/* common /zload/ */
extern zload_t zload;
/* common /smat/ */
extern smat_t smat;
/* pointers to input/output files */
extern FILE *input_fp, *output_fp, *plot_fp;
/*-----------------------------------------------------------------------*/
/* cabc computes coefficients of the constant (a), sine (b), and */
/* cosine (c) terms in the current interpolation functions for the */
/* current vector cur. */
void cabc (complex double *curx)
{
int i, is, j, jx, jco1, jco2;
double ar, ai, sh;
complex double curd, cs1, cs2;
if (data.n != 0)
{
for (i = 0; i < data.n; i++)
{
crnt.air[i] = 0.;
crnt.aii[i] = 0.;
crnt.bir[i] = 0.;
crnt.bii[i] = 0.;
crnt.cir[i] = 0.;
crnt.cii[i] = 0.;
}
for (i = 0; i < data.n; i++)
{
ar = creall (curx[i]);
ai = cimagl (curx[i]);
tbf (i + 1, 1);
for (jx = 0; jx < segj.jsno; jx++)
{
j = segj.jco[jx] - 1;
crnt.air[j] += segj.ax[jx] * ar;
crnt.aii[j] += segj.ax[jx] * ai;
crnt.bir[j] += segj.bx[jx] * ar;
crnt.bii[j] += segj.bx[jx] * ai;
crnt.cir[j] += segj.cx[jx] * ar;
crnt.cii[j] += segj.cx[jx] * ai;
}
} /* for( i = 0; i < n; i++ ) */
if (vsorc.nqds != 0)
{
for (is = 0; is < vsorc.nqds; is++)
{
i = vsorc.iqds[is] - 1;
jx = data.icon1[i];
data.icon1[i] = 0;
tbf (i + 1, 0);
data.icon1[i] = jx;
sh = data.si[i] * .5;
curd = CCJ * vsorc.vqds[is] /
((logl (2. * sh / data.bi[i]) - 1.) *
(segj.bx[segj.jsno - 1] * cosl (TP * sh) +
segj.cx[segj.jsno - 1] * sinl (TP * sh)) *
data.wlam);
ar = print_creall (curd);
ai = print_cimagl (curd);
for (jx = 0; jx < segj.jsno; jx++)
{
j = segj.jco[jx] - 1;
crnt.air[j] = crnt.air[j] + segj.ax[jx] * ar;
crnt.aii[j] = crnt.aii[j] + segj.ax[jx] * ai;
crnt.bir[j] = crnt.bir[j] + segj.bx[jx] * ar;
crnt.bii[j] = crnt.bii[j] + segj.bx[jx] * ai;
crnt.cir[j] = crnt.cir[j] + segj.cx[jx] * ar;
crnt.cii[j] = crnt.cii[j] + segj.cx[jx] * ai;
}
} /* for( is = 0; is < vsorc.nqds; is++ ) */
} /* if( vsorc.nqds != 0) */
for (i = 0; i < data.n; i++)
curx[i] = cmplx (crnt.air[i] + crnt.cir[i], crnt.aii[i] + crnt.cii[i]);
} /* if( n != 0) */
if (data.m == 0)
return;
/* convert surface currents from */
/* t1,t2 components to x,y,z components */
jco1 = data.np2m;
jco2 = jco1 + data.m;
for (i = 1; i <= data.m; i++)
{
jco1 -= 2;
jco2 -= 3;
cs1 = curx[jco1];
cs2 = curx[jco1 + 1];
curx[jco2] = cs1 * data.t1x[data.m - i] + cs2 * data.t2x[data.m - i];
curx[jco2 + 1] = cs1 * data.t1y[data.m - i] + cs2 * data.t2y[data.m - i];
curx[jco2 + 2] = cs1 * data.t1z[data.m - i] + cs2 * data.t2z[data.m - i];
}
return;
}
/*-----------------------------------------------------------------------*/
/* couple computes the maximum coupling between pairs of segments. */
void couple (complex double *cur, double wlam)
{
int j, j1, j2, l1, i, k, itt1, itt2, its1, its2, isg1, isg2, npm1;
double dbc, c, gmax;
complex double y11, y12, y22, yl, yin, zl, zin, rho;
if ((vsorc.nsant != 1) || (vsorc.nvqd != 0))
return;
j = isegno (yparm.nctag[yparm.icoup], yparm.ncseg[yparm.icoup]);
if (j != vsorc.isant[0])
return;
zin = vsorc.vsant[0];
yparm.icoup++;
mem_realloc ((void *) &yparm.y11a, yparm.icoup * sizeof (complex double));
yparm.y11a[yparm.icoup - 1] = cur[j - 1] * wlam / zin;
l1 = (yparm.icoup - 1) * (yparm.ncoup - 1);
for (i = 0; i < yparm.ncoup; i++)
{
if ((i + 1) == yparm.icoup)
continue;
l1++;
mem_realloc ((void *) &yparm.y12a, l1 * sizeof (complex double));
k = isegno (yparm.nctag[i], yparm.ncseg[i]);
yparm.y12a[l1 - 1] = cur[k - 1] * wlam / zin;
}
if (yparm.icoup < yparm.ncoup)
return;
output_fp,
"\n\n\n"
" -----------"
" ISOLATION DATA -----------\n\n"
" ------- COUPLING BETWEEN ------ MAXIMUM "
" ---------- FOR MAXIMUM COUPLING ----------\n"
" SEG SEG COUPLING LOAD"
" IMPEDANCE (2ND SEG) INPUT IMPEDANCE \n"
" TAG SEG NO. TAG SEG NO. (DB) "
" REAL IMAGINARY REAL IMAGINARY");
npm1 = yparm.ncoup - 1;
for (i = 0; i < npm1; i++)
{
itt1 = yparm.nctag[i];
its1 = yparm.ncseg[i];
isg1 = isegno (itt1, its1);
l1 = i + 1;
for (j = l1; j < yparm.ncoup; j++)
{
itt2 = yparm.nctag[j];
its2 = yparm.ncseg[j];
isg2 = isegno (itt2, its2);
j1 = j + i * npm1 - 1;
j2 = i + j * npm1;
y11 = yparm.y11a[i];
y22 = yparm.y11a[j];
y12 = .5 * (yparm.y12a[j1] + yparm.y12a[j2]);
yin = y12 * y12;
dbc = cabsl (yin);
c = dbc / (2. * creall (y11) * creall (y22) - creall (yin));
if ((c >= 0.0) && (c <= 1.0))
{
if (c >= .01)
gmax = (1. - sqrtl (1. - c * c)) / c;
else
gmax = .5 * (c + .25 * c * c * c);
rho = gmax * conjl (yin) / dbc;
yl = ((1. - rho) / (1. + rho) + 1.) * creall (y22) - y22;
zl = 1. / yl;
yin = y11 - yin / (y22 + yl);
zin = 1. / yin;
dbc = db10 (gmax);
output_fp,
"\n"
" %4d %4d %5d %4d %4d %5d %9.3f"
" %12.5f %12.5f %12.5f %12.5f",
itt1,
its1,
isg1,
itt2,
its2,
isg2,
dbc,
print_creall (zl),
print_cimagl (zl),
print_creall (zin),
print_cimagl (zin));
continue;
} /* if( (c >= 0.0) && (c <= 1.0) ) */
output_fp,
"\n"
" %4d %4d %5d %4d %4d %5d **ERROR** "
"COUPLING IS NOT BETWEEN 0 AND 1. (= %12.5f)",
itt1,
its1,
isg1,
itt2,
its2,
isg2,
c);
} /* for( j = l1; j < yparm.ncoup; j++ ) */
} /* for( i = 0; i < npm1; i++ ) */
return;
}
/*-----------------------------------------------------------------------*/
/* load calculates the impedance of specified */
/* segments for various types of loading */
void load (
int *ldtyp, int *ldtag, int *ldtagf, int *ldtagt, double *zlr, double *zli, double *zlc)
{
int i, iwarn, istep, istepx, l1, l2, ldtags, jump, ichk;
complex double zt = CPLX_00, tpcj;
tpcj = (0.0 + 1.8836989e-9j);
output_fp,
"\n"
" LOCATION RESISTANCE INDUCTANCE CAPACITANCE "
" IMPEDANCE (OHMS) CONDUCTIVITY CIRCUIT\n"
" OHMS HENRYS FARADS "
" REAL IMAGINARY MHOS/METER TYPE");
/* initialize d array, used for temporary */
/* storage of loading information. */
mem_realloc ((void *) &zload.zarray, data.npm * sizeof (complex double));
for (i = 0; i < data.n; i++)
zload.zarray[i] = CPLX_00;
iwarn = FALSE;
istep = 0;
/* cycle over loading cards */
while (TRUE)
{
istepx = istep;
istep++;
if (istep > zload.nload)
{
if (iwarn == TRUE)
output_fp,
"\n NOTE, SOME OF THE ABOVE SEGMENTS "
"HAVE BEEN LOADED TWICE - IMPEDANCES ADDED");
smat.nop = data.n / data.np;
if (smat.nop == 1)
return;
for (i = 0; i < data.np; i++)
{
zt = zload.zarray[i];
l1 = i;
for (l2 = 1; l2 < smat.nop; l2++)
{
l1 += data.np;
zload.zarray[l1] = zt;
}
}
return;
} /* if( istep > zload.nload) */
if (ldtyp[istepx] > 5)
{
output_fp,
"\n IMPROPER LOAD TYPE CHOSEN,"
" REQUESTED TYPE IS %d",
ldtyp[istepx]);
stop (-1);
}
/* search segments for proper itags */
ldtags = ldtag[istepx];
jump = ldtyp[istepx] + 1;
ichk = 0;
l1 = 1;
l2 = data.n;
if (ldtags == 0)
{
if ((ldtagf[istepx] != 0) || (ldtagt[istepx] != 0))
{
l1 = ldtagf[istepx];
l2 = ldtagt[istepx];
} /* if( (ldtagf[istepx] != 0) || (ldtagt[istepx] != 0) ) */
} /* if( ldtags == 0) */
for (i = l1 - 1; i < l2; i++)
{
if (ldtags != 0)
{
if (ldtags != data.itag[i])
continue;
if (ldtagf[istepx] != 0)
{
ichk++;
if ((ichk < ldtagf[istepx]) || (ichk > ldtagt[istepx]))
continue;
}
else
ichk = 1;
} /* if( ldtags != 0) */
else
ichk = 1;
/* calculation of lamda*imped. per unit length, */
/* jump to appropriate section for loading type */
switch (jump)
{
case 1:
zt = zlr[istepx] / data.si[i] +
tpcj * zli[istepx] / (data.si[i] * data.wlam);
if (fabsl (zlc[istepx]) > 1.0e-20)
zt += data.wlam / (tpcj * data.si[i] * zlc[istepx]);
break;
case 2:
zt = tpcj * data.si[i] * zlc[istepx] / data.wlam;
if (fabsl (zli[istepx]) > 1.0e-20)
zt += data.si[i] * data.wlam / (tpcj * zli[istepx]);
if (fabsl (zlr[istepx]) > 1.0e-20)
zt += data.si[i] / zlr[istepx];
zt = 1. / zt;
break;
case 3:
zt = zlr[istepx] * data.wlam + tpcj * zli[istepx];
if (fabsl (zlc[istepx]) > 1.0e-20)
zt += 1. /
(tpcj * data.si[i] * data.si[i] * zlc[istepx]);
break;
case 4:
zt = tpcj * data.si[i] * data.si[i] * zlc[istepx];
if (fabsl (zli[istepx]) > 1.0e-20)
zt += 1. / (tpcj * zli[istepx]);
if (fabsl (zlr[istepx]) > 1.0e-20)
zt += 1. / (zlr[istepx] * data.wlam);
zt = 1. / zt;
break;
case 5:
zt = cmplx (zlr[istepx], zli[istepx]) / data.si[i];
break;
case 6:
zint (zlr[istepx] * data.wlam, data.bi[i], &zt);
} /* switch( jump ) */
if ((fabsl (creall (zload.zarray[i])) +
fabsl (cimagl (zload.zarray[i]))) > 1.0e-20)
iwarn = TRUE;
zload.zarray[i] += zt;
} /* for( i = l1-1; i < l2; i++ ) */
if (ichk == 0)
{
output_fp,
"\n LOADING DATA CARD ERROR,"
" NO SEGMENT HAS AN ITAG = %d",
ldtags);
stop (-1);
}
/* printing the segment loading data, jump to proper print */
switch (jump)
{
case 1:
prnt (
ldtags,
ldtagf[istepx],
ldtagt[istepx],
zlr[istepx],
zli[istepx],
zlc[istepx],
0.,
0.,
0.,
" SERIES ",
2);
break;
case 2:
prnt (
ldtags,
ldtagf[istepx],
ldtagt[istepx],
zlr[istepx],
zli[istepx],
zlc[istepx],
0.,
0.,
0.,
"PARALLEL",
2);
break;
case 3:
prnt (
ldtags,
ldtagf[istepx],
ldtagt[istepx],
zlr[istepx],
zli[istepx],
zlc[istepx],
0.,
0.,
0.,
"SERIES (PER METER)",
5);
break;
case 4:
prnt (
ldtags,
ldtagf[istepx],
ldtagt[istepx],
zlr[istepx],
zli[istepx],
zlc[istepx],
0.,
0.,
0.,
"PARALLEL (PER METER)",
5);
break;
case 5:
prnt (
ldtags,
ldtagf[istepx],
ldtagt[istepx],
0.,
0.,
0.,
zlr[istepx],
zli[istepx],
0.,
"FIXED IMPEDANCE ",
4);
break;
case 6:
prnt (
ldtags,
ldtagf[istepx],
ldtagt[istepx],
0.,
0.,
0.,
0.,
0.,
zlr[istepx],
" WIRE ",
2);
} /* switch( jump ) */
} /* while( TRUE ) */
return;
}
/*-----------------------------------------------------------------------*/
/* gf computes the integrand exp(jkr)/(kr) for numerical integration. */
void gf (double zk, double *co, double *si)
{
double zdk, rk, rks;
zdk = zk - tmi.zpk;
rk = sqrtl (tmi.rkb2 + zdk * zdk);
*si = sinl (rk) / rk;
if (tmi.ij != 0)
{
*co = cosl (rk) / rk;
return;
}
if (rk >= .2)
{
*co = (cosl (rk) - 1.) / rk;
return;
}
rks = rk * rk;
*co = ((-1.38888889e-3 * rks + 4.16666667e-2) * rks - .5) * rk;
return;
}
/*-----------------------------------------------------------------------*/
/* function db10 returns db for magnitude (field) */
double db10 (double x)
{
if (x < 1.e-20)
return (-999.99);
return (10. * log10l (x));
}
/*-----------------------------------------------------------------------*/
/* function db20 returns db for mag**2 (power) i */
double db20 (double x)
{
if (x < 1.e-20)
return (-999.99);
return (20. * log10l (x));
}
/*-----------------------------------------------------------------------*/
/* intrp uses bivariate cubic interpolation to obtain */
/* the values of 4 functions at the point (x,y). */
void intrp (
double x,
double y,
complex double *f1,
complex double *f2,
complex double *f3,
complex double *f4)
{
static int ix, iy, ixs = -10, iys = -10, igrs = -10, ixeg = 0, iyeg = 0;
static int nxm2, nym2, nxms, nyms, nd, ndp;
int nda[3] = {11, 17, 9}, ndpa[3] = {110, 85, 72};
int igr, iadd, iadz, i, k, jump;
static double dx = 1., dy = 1., xs = 0., ys = 0., xz, yz;
double xx, yy;
static complex double a[4][4], b[4][4], c[4][4], d[4][4];
complex double p1 = CPLX_00, p2 = CPLX_00, p3 = CPLX_00, p4 = CPLX_00;
complex double fx1, fx2, fx3, fx4;
jump = FALSE;
if ((x < xs) || (y < ys))
jump = TRUE;
else
{
ix = (int) ((x - xs) / dx) + 1;
iy = (int) ((y - ys) / dy) + 1;
}
/* if point lies in same 4 by 4 point region */
/* as previous point, old values are reused. */
if ((ix
< ixeg
) || (iy
< iyeg
) || (abs (ix
- ixs
) >= 2) || (abs (iy
- iys
) >= 2) ||
jump)
{
/* determine correct grid and grid region */
if (x <= ggrid.xsa[1])
igr = 0;
else
{
if (y > ggrid.ysa[2])
igr = 2;
else
igr = 1;
}
if (igr != igrs)
{
igrs = igr;
dx = ggrid.dxa[igrs];
dy = ggrid.dya[igrs];
xs = ggrid.xsa[igrs];
ys = ggrid.ysa[igrs];
nxm2 = ggrid.nxa[igrs] - 2;
nym2 = ggrid.nya[igrs] - 2;
nxms = ((nxm2 + 1) / 3) * 3 + 1;
nyms = ((nym2 + 1) / 3) * 3 + 1;
nd = nda[igrs];
ndp = ndpa[igrs];
ix = (int) ((x - xs) / dx) + 1;
iy = (int) ((y - ys) / dy) + 1;
} /* if( igr != igrs) */
ixs = ((ix - 1) / 3) * 3 + 2;
if (ixs < 2)
ixs = 2;
ixeg = -10000;
if (ixs > nxm2)
{
ixs = nxm2;
ixeg = nxms;
}
iys = ((iy - 1) / 3) * 3 + 2;
if (iys < 2)
iys = 2;
iyeg = -10000;
if (iys > nym2)
{
iys = nym2;
iyeg = nyms;
}
/* compute coefficients of 4 cubic polynomials in x for */
/* the 4 grid values of y for each of the 4 functions */
iadz = ixs + (iys - 3) * nd - ndp;
for (k = 0; k < 4; k++)
{
iadz += ndp;
iadd = iadz;
for (i = 0; i < 4; i++)
{
iadd += nd;
switch (igrs)
{
case 0:
p1 = ggrid.ar1[iadd - 2];
p2 = ggrid.ar1[iadd - 1];
p3 = ggrid.ar1[iadd];
p4 = ggrid.ar1[iadd + 1];
break;
case 1:
p1 = ggrid.ar2[iadd - 2];
p2 = ggrid.ar2[iadd - 1];
p3 = ggrid.ar2[iadd];
p4 = ggrid.ar2[iadd + 1];
break;
case 2:
p1 = ggrid.ar3[iadd - 2];
p2 = ggrid.ar3[iadd - 1];
p3 = ggrid.ar3[iadd];
p4 = ggrid.ar3[iadd + 1];
} /* switch( igrs ) */
a[i][k] = (p4 - p1 + 3. * (p2 - p3)) * .1666666667;
b[i][k] = (p1 - 2. * p2 + p3) * .5;
c[i][k] = p3 - (2. * p1 + 3. * p2 + p4) * .1666666667;
d[i][k] = p2;
} /* for( i = 0; i < 4; i++ ) */
} /* for( k = 0; k < 4; k++ ) */
xz = (ixs - 1) * dx + xs;
yz = (iys - 1) * dy + ys;
} /* if( (abs(ix- ixs) >= 2) || */
/* evaluate polymomials in x and use cubic */
/* interpolation in y for each of the 4 functions. */
xx = (x - xz) / dx;
yy = (y - yz) / dy;
fx1 = ((a[0][0] * xx + b[0][0]) * xx + c[0][0]) * xx + d[0][0];
fx2 = ((a[1][0] * xx + b[1][0]) * xx + c[1][0]) * xx + d[1][0];
fx3 = ((a[2][0] * xx + b[2][0]) * xx + c[2][0]) * xx + d[2][0];
fx4 = ((a[3][0] * xx + b[3][0]) * xx + c[3][0]) * xx + d[3][0];
p1 = fx4 - fx1 + 3. * (fx2 - fx3);
p2 = 3. * (fx1 - 2. * fx2 + fx3);
p3 = 6. * fx3 - 2. * fx1 - 3. * fx2 - fx4;
*f1 = ((p1 * yy + p2) * yy + p3) * yy * .1666666667 + fx2;
fx1 = ((a[0][1] * xx + b[0][1]) * xx + c[0][1]) * xx + d[0][1];
fx2 = ((a[1][1] * xx + b[1][1]) * xx + c[1][1]) * xx + d[1][1];
fx3 = ((a[2][1] * xx + b[2][1]) * xx + c[2][1]) * xx + d[2][1];
fx4 = ((a[3][1] * xx + b[3][1]) * xx + c[3][1]) * xx + d[3][1];
p1 = fx4 - fx1 + 3. * (fx2 - fx3);
p2 = 3. * (fx1 - 2. * fx2 + fx3);
p3 = 6. * fx3 - 2. * fx1 - 3. * fx2 - fx4;
*f2 = ((p1 * yy + p2) * yy + p3) * yy * .1666666667 + fx2;
fx1 = ((a[0][2] * xx + b[0][2]) * xx + c[0][2]) * xx + d[0][2];
fx2 = ((a[1][2] * xx + b[1][2]) * xx + c[1][2]) * xx + d[1][2];
fx3 = ((a[2][2] * xx + b[2][2]) * xx + c[2][2]) * xx + d[2][2];
fx4 = ((a[3][2] * xx + b[3][2]) * xx + c[3][2]) * xx + d[3][2];
p1 = fx4 - fx1 + 3. * (fx2 - fx3);
p2 = 3. * (fx1 - 2. * fx2 + fx3);
p3 = 6. * fx3 - 2. * fx1 - 3. * fx2 - fx4;
*f3 = ((p1 * yy + p2) * yy + p3) * yy * .1666666667 + fx2;
fx1 = ((a[0][3] * xx + b[0][3]) * xx + c[0][3]) * xx + d[0][3];
fx2 = ((a[1][3] * xx + b[1][3]) * xx + c[1][3]) * xx + d[1][3];
fx3 = ((a[2][3] * xx + b[2][3]) * xx + c[2][3]) * xx + d[2][3];
fx4 = ((a[3][3] * xx + b[3][3]) * xx + c[3][3]) * xx + d[3][3];
p1 = fx4 - fx1 + 3. * (fx2 - fx3);
p2 = 3. * (fx1 - 2. * fx2 + fx3);
p3 = 6. * fx3 - 2. * fx1 - 3. * fx2 - fx4;
*f4 = ((p1 * yy + p2) * yy + p3) * yy * .16666666670 + fx2;
return;
}
/*-----------------------------------------------------------------------*/
/* intx performs numerical integration of exp(jkr)/r by the method of */
/* variable interval width romberg integration. the integrand value */
/* is supplied by subroutine gf. */
void intx (double el1, double el2, double b, int ij, double *sgr, double *sgi)
{
int ns, nt;
int nx = 1, nma = 65536, nts = 4;
int flag = TRUE;
double z, s, ze, fnm, ep, zend, fns, dz = 0., zp, dzot = 0., t00r, g1r, g5r, t00i;
double g1i, g5i, t01r, g3r, t01i, g3i, t10r, t10i, te1i, te1r, t02r;
double g2r, g4r, t02i, g2i, g4i, t11r, t11i, t20r, t20i, te2i, te2r;
double rx = 1.0e-4;
z = el1;
ze = el2;
if (ij == 0)
ze = 0.;
s = ze - z;
fnm = nma;
ep = s / (10. * fnm);
zend = ze - ep;
*sgr = 0.;
*sgi = 0.;
ns = nx;
nt = 0;
gf (z, &g1r, &g1i);
while (TRUE)
{
if (flag)
{
fns = ns;
dz = s / fns;
zp = z + dz;
if (zp > ze)
{
dz = ze - z;
if (fabsl (dz) <= ep)
{
/* add contribution of near singularity for diagonal
* term */
if (ij == 0)
{
*sgr =
2. *
(*sgr +
logl ((sqrtl (b * b + s * s) + s) / b));
*sgi = 2. * *sgi;
}
return;
}
} /* if( zp > ze) */
dzot = dz * .5;
zp = z + dzot;
gf (zp, &g3r, &g3i);
zp = z + dz;
gf (zp, &g5r, &g5i);
} /* if( flag ) */
t00r = (g1r + g5r) * dzot;
t00i = (g1i + g5i) * dzot;
t01r = (t00r + dz * g3r) * 0.5;
t01i = (t00i + dz * g3i) * 0.5;
t10r = (4.0 * t01r - t00r) / 3.0;
t10i = (4.0 * t01i - t00i) / 3.0;
/* test convergence of 3 point romberg result. */
test (t01r, t10r, &te1r, t01i, t10i, &te1i, 0.);
if ((te1i <= rx) && (te1r <= rx))
{
*sgr = *sgr + t10r;
*sgi = *sgi + t10i;
nt += 2;
z += dz;
if (z >= zend)
{
/* add contribution of near singularity for diagonal term */
if (ij == 0)
{
*sgr = 2. *
(*sgr + logl ((sqrtl (b * b + s * s) + s) / b));
*sgi = 2. * *sgi;
}
return;
}
g1r = g5r;
g1i = g5i;
if (nt >= nts)
if (ns > nx)
{
/* Double step size */
ns = ns / 2;
nt = 1;
}
flag = TRUE;
continue;
} /* if( (te1i <= rx) && (te1r <= rx) ) */
zp = z + dz * 0.25;
gf (zp, &g2r, &g2i);
zp = z + dz * 0.75;
gf (zp, &g4r, &g4i);
t02r = (t01r + dzot * (g2r + g4r)) * 0.5;
t02i = (t01i + dzot * (g2i + g4i)) * 0.5;
t11r = (4.0 * t02r - t01r) / 3.0;
t11i = (4.0 * t02i - t01i) / 3.0;
t20r = (16.0 * t11r - t10r) / 15.0;
t20i = (16.0 * t11i - t10i) / 15.0;
/* test convergence of 5 point romberg result. */
test (t11r, t20r, &te2r, t11i, t20i, &te2i, 0.);
if ((te2i > rx) || (te2r > rx))
{
nt = 0;
if (ns >= nma)
fprintf (output_fp
, "\n STEP SIZE LIMITED AT Z= %10.5G", z
);
else
{
/* halve step size */
ns = ns * 2;
fns = ns;
dz = s / fns;
dzot = dz * 0.5;
g5r = g3r;
g5i = g3i;
g3r = g2r;
g3i = g2i;
flag = FALSE;
continue;
}
} /* if( (te2i > rx) || (te2r > rx) ) */
*sgr = *sgr + t20r;
*sgi = *sgi + t20i;
nt++;
z += dz;
if (z >= zend)
{
/* add contribution of near singularity for diagonal term */
if (ij == 0)
{
*sgr = 2. * (*sgr + logl ((sqrtl (b * b + s * s) + s) / b));
*sgi = 2. * *sgi;
}
return;
}
g1r = g5r;
g1i = g5i;
if (nt >= nts)
if (ns > nx)
{
/* Double step size */
ns = ns / 2;
nt = 1;
}
flag = TRUE;
} /* while( TRUE ) */
}
/*-----------------------------------------------------------------------*/
/* returns smallest of two arguments */
int min (int a, int b)
{
if (a < b)
return (a);
else
return (b);
}
/*-----------------------------------------------------------------------*/
/* test for convergence in numerical integration */
void test (double f1r, double f2r, double *tr, double f1i, double f2i, double *ti, double dmin)
{
double den;
den = fabsl (f2r);
*tr = fabsl (f2i);
if (den < *tr)
den = *tr;
if (den < dmin)
den = dmin;
if (den < 1.0e-37)
{
*tr = 0.;
*ti = 0.;
return;
}
*tr = fabsl ((f1r - f2r) / den);
*ti = fabsl ((f1i - f2i) / den);
return;
}
/*-----------------------------------------------------------------------*/
/* compute component of basis function i on segment is. */
void sbf (int i, int is, double *aa, double *bb, double *cc)
{
int ix, jsno, june, jcox, jcoxx, jend, iend, njun1 = 0, njun2;
double d, sig, pp, sdh, cdh, sd, omc, aj, pm = 0, cd, ap, qp, qm, xxi;
*aa = 0.;
*bb = 0.;
*cc = 0.;
june = 0;
jsno = 0;
pp = 0.;
ix = i - 1;
jcox = data.icon1[ix];
if (jcox > PCHCON)
jcox = i;
jcoxx = jcox - 1;
jend = -1;
iend = -1;
sig = -1.;
do
{
if (jcox != 0)
{
if (jcox < 0)
jcox = -jcox;
else
{
sig = -sig;
jend = -jend;
}
jcoxx = jcox - 1;
jsno++;
d = PI * data.si[jcoxx];
sdh = sinl (d);
cdh = cosl (d);
sd = 2. * sdh * cdh;
if (d <= 0.015)
{
omc = 4. * d * d;
omc =
((1.3888889e-3 * omc - 4.1666666667e-2) * omc + .5) * omc;
}
else
omc = 1. - cdh * cdh + sdh * sdh;
aj = 1. / (logl (1. / (PI * data.bi[jcoxx])) - .577215664);
pp -= omc / sd * aj;
if (jcox == is)
{
*aa = aj / sd * sig;
*bb = aj / (2. * cdh);
*cc = -aj / (2. * sdh) * sig;
june = iend;
}
if (jcox != i)
{
if (jend != 1)
jcox = data.icon1[jcoxx];
else
jcox = data.icon2[jcoxx];
{
if (jcox == 0)
{
output_fp,
"\n SBF - SEGMENT CONNECTION ERROR FOR "
"SEGMENT %d",
i);
stop (-1);
}
else
continue;
}
} /* if( jcox != i ) */
else if (jcox == is)
*bb = -*bb;
if (iend == 1)
break;
} /* if( jcox != 0 ) */
pm = -pp;
pp = 0.;
njun1 = jsno;
jcox = data.icon2[ix];
if (jcox > PCHCON)
jcox = i;
jend = 1;
iend = 1;
sig = -1.;
} /* do */
while (jcox != 0);
njun2 = jsno - njun1;
d = PI * data.si[ix];
sdh = sinl (d);
cdh = cosl (d);
sd = 2. * sdh * cdh;
cd = cdh * cdh - sdh * sdh;
if (d <= 0.015)
{
omc = 4. * d * d;
omc = ((1.3888889e-3 * omc - 4.1666666667e-2) * omc + .5) * omc;
}
else
omc = 1. - cd;
ap = 1. / (logl (1. / (PI * data.bi[ix])) - .577215664);
aj = ap;
if (njun1 == 0)
{
if (njun2 == 0)
{
*aa = -1.;
qp = PI * data.bi[ix];
xxi = qp * qp;
xxi = qp * (1. - .5 * xxi) / (1. - xxi);
*cc = 1. / (cdh - xxi * sdh);
return;
}
qp = PI * data.bi[ix];
xxi = qp * qp;
xxi = qp * (1. - .5 * xxi) / (1. - xxi);
qp = -(omc + xxi * sd) / (sd * (ap + xxi * pp) + cd * (xxi * ap - pp));
if (june == 1)
{
*aa = -*aa * qp;
*bb = *bb * qp;
*cc = -*cc * qp;
if (i != is)
return;
}
*aa -= 1.;
d = cd - xxi * sd;
*bb += (sdh + ap * qp * (cdh - xxi * sdh)) / d;
*cc += (cdh + ap * qp * (sdh + xxi * cdh)) / d;
return;
} /* if( njun1 == 0) */
if (njun2 == 0)
{
qm = PI * data.bi[ix];
xxi = qm * qm;
xxi = qm * (1. - .5 * xxi) / (1. - xxi);
qm = (omc + xxi * sd) / (sd * (aj - xxi * pm) + cd * (pm + xxi * aj));
if (june == -1)
{
*aa = *aa * qm;
*bb = *bb * qm;
*cc = *cc * qm;
if (i != is)
return;
}
*aa -= 1.;
d = cd - xxi * sd;
*bb += (aj * qm * (cdh - xxi * sdh) - sdh) / d;
*cc += (cdh - aj * qm * (sdh + xxi * cdh)) / d;
return;
} /* if( njun2 == 0) */
qp = sd * (pm * pp + aj * ap) + cd * (pm * ap - pp * aj);
qm = (ap * omc - pp * sd) / qp;
qp = -(aj * omc + pm * sd) / qp;
if (june != 0)
{
if (june < 0)
{
*aa = *aa * qm;
*bb = *bb * qm;
*cc = *cc * qm;
}
else
{
*aa = -*aa * qp;
*bb = *bb * qp;
*cc = -*cc * qp;
}
if (i != is)
return;
} /* if( june != 0 ) */
*aa -= 1.;
*bb += (aj * qm + ap * qp) * sdh / sd;
*cc += (aj * qm - ap * qp) * cdh / sd;
return;
}
/*-----------------------------------------------------------------------*/
/* compute basis function i */
void tbf (int i, int icap)
{
int ix, jcox, jcoxx, jend, iend, njun1 = 0, njun2, jsnop, jsnox;
double pp, sdh, cdh, sd, omc, aj, pm = 0, cd, ap, qp, qm, xxi;
double d, sig; /*** also global ***/
segj.jsno = 0;
pp = 0.;
ix = i - 1;
jcox = data.icon1[ix];
if (jcox > PCHCON)
jcox = i;
jend = -1;
iend = -1;
sig = -1.;
do
{
if (jcox != 0)
{
if (jcox < 0)
jcox = -jcox;
else
{
sig = -sig;
jend = -jend;
}
jcoxx = jcox - 1;
segj.jsno++;
jsnox = segj.jsno - 1;
segj.jco[jsnox] = jcox;
d = PI * data.si[jcoxx];
sdh = sinl (d);
cdh = cosl (d);
sd = 2. * sdh * cdh;
if (d <= 0.015)
{
omc = 4. * d * d;
omc =
((1.3888889e-3 * omc - 4.1666666667e-2) * omc + .5) * omc;
}
else
omc = 1. - cdh * cdh + sdh * sdh;
aj = 1. / (logl (1. / (PI * data.bi[jcoxx])) - .577215664);
pp = pp - omc / sd * aj;
segj.ax[jsnox] = aj / sd * sig;
segj.bx[jsnox] = aj / (2. * cdh);
segj.cx[jsnox] = -aj / (2. * sdh) * sig;
if (jcox != i)
{
if (jend == 1)
jcox = data.icon2[jcoxx];
else
jcox = data.icon1[jcoxx];
{
if (jcox != 0)
continue;
else
{
output_fp,
"\n TBF - SEGMENT CONNECTION ERROR FOR "
"SEGMENT %5d",
i);
stop (-1);
}
}
} /* if( jcox != i) */
else
segj.bx[jsnox] = -segj.bx[jsnox];
if (iend == 1)
break;
} /* if( jcox != 0 ) */
pm = -pp;
pp = 0.;
njun1 = segj.jsno;
jcox = data.icon2[ix];
if (jcox > PCHCON)
jcox = i;
jend = 1;
iend = 1;
sig = -1.;
} /* do */
while (jcox != 0);
njun2 = segj.jsno - njun1;
jsnop = segj.jsno;
segj.jco[jsnop] = i;
d = PI * data.si[ix];
sdh = sinl (d);
cdh = cosl (d);
sd = 2. * sdh * cdh;
cd = cdh * cdh - sdh * sdh;
if (d <= 0.015)
{
omc = 4. * d * d;
omc = ((1.3888889e-3 * omc - 4.1666666667e-2) * omc + .5) * omc;
}
else
omc = 1. - cd;
ap = 1. / (logl (1. / (PI * data.bi[ix])) - .577215664);
aj = ap;
if (njun1 == 0)
{
if (njun2 == 0)
{
segj.bx[jsnop] = 0.;
if (icap == 0)
xxi = 0.;
else
{
qp = PI * data.bi[ix];
xxi = qp * qp;
xxi = qp * (1. - .5 * xxi) / (1. - xxi);
}
segj.cx[jsnop] = 1. / (cdh - xxi * sdh);
segj.jsno = jsnop + 1;
segj.ax[jsnop] = -1.;
return;
} /* if( njun2 == 0) */
if (icap == 0)
xxi = 0.;
else
{
qp = PI * data.bi[ix];
xxi = qp * qp;
xxi = qp * (1. - .5 * xxi) / (1. - xxi);
}
qp = -(omc + xxi * sd) / (sd * (ap + xxi * pp) + cd * (xxi * ap - pp));
d = cd - xxi * sd;
segj.bx[jsnop] = (sdh + ap * qp * (cdh - xxi * sdh)) / d;
segj.cx[jsnop] = (cdh + ap * qp * (sdh + xxi * cdh)) / d;
for (iend = 0; iend < njun2; iend++)
{
segj.ax[iend] = -segj.ax[iend] * qp;
segj.bx[iend] = segj.bx[iend] * qp;
segj.cx[iend] = -segj.cx[iend] * qp;
}
segj.jsno = jsnop + 1;
segj.ax[jsnop] = -1.;
return;
} /* if( njun1 == 0) */
if (njun2 == 0)
{
if (icap == 0)
xxi = 0.;
else
{
qm = PI * data.bi[ix];
xxi = qm * qm;
xxi = qm * (1. - .5 * xxi) / (1. - xxi);
}
qm = (omc + xxi * sd) / (sd * (aj - xxi * pm) + cd * (pm + xxi * aj));
d = cd - xxi * sd;
segj.bx[jsnop] = (aj * qm * (cdh - xxi * sdh) - sdh) / d;
segj.cx[jsnop] = (cdh - aj * qm * (sdh + xxi * cdh)) / d;
for (iend = 0; iend < njun1; iend++)
{
segj.ax[iend] = segj.ax[iend] * qm;
segj.bx[iend] = segj.bx[iend] * qm;
segj.cx[iend] = segj.cx[iend] * qm;
}
segj.jsno = jsnop + 1;
segj.ax[jsnop] = -1.;
return;
} /* if( njun2 == 0) */
qp = sd * (pm * pp + aj * ap) + cd * (pm * ap - pp * aj);
qm = (ap * omc - pp * sd) / qp;
qp = -(aj * omc + pm * sd) / qp;
segj.bx[jsnop] = (aj * qm + ap * qp) * sdh / sd;
segj.cx[jsnop] = (aj * qm - ap * qp) * cdh / sd;
for (iend = 0; iend < njun1; iend++)
{
segj.ax[iend] = segj.ax[iend] * qm;
segj.bx[iend] = segj.bx[iend] * qm;
segj.cx[iend] = segj.cx[iend] * qm;
}
jend = njun1;
for (iend = jend; iend < segj.jsno; iend++)
{
segj.ax[iend] = -segj.ax[iend] * qp;
segj.bx[iend] = segj.bx[iend] * qp;
segj.cx[iend] = -segj.cx[iend] * qp;
}
segj.jsno = jsnop + 1;
segj.ax[jsnop] = -1.;
}
/*-----------------------------------------------------------------------*/
/* compute the components of all basis functions on segment j */
void trio (int j)
{
int jcox, jcoxx, jsnox, jx, jend = 0, iend = 0;
segj.jsno = 0;
jx = j - 1;
jcox = data.icon1[jx];
jcoxx = jcox - 1;
if (jcox <= PCHCON)
{
jend = -1;
iend = -1;
}
if ((jcox == 0) || (jcox > PCHCON))
{
jcox = data.icon2[jx];
jcoxx = jcox - 1;
if (jcox <= PCHCON)
{
jend = 1;
iend = 1;
}
if (jcox == 0 || (jcox > PCHCON))
{
jsnox = segj.jsno;
segj.jsno++;
/* Allocate to connections buffers */
if (segj.jsno >= segj.maxcon)
{
segj.maxcon = segj.jsno + 1;
mem_realloc ((void *) &segj.jco, segj.maxcon * sizeof (int));
mem_realloc ((void *) &segj.ax, segj.maxcon * sizeof (double));
mem_realloc ((void *) &segj.bx, segj.maxcon * sizeof (double));
mem_realloc ((void *) &segj.cx, segj.maxcon * sizeof (double));
}
sbf (j, j, &segj.ax[jsnox], &segj.bx[jsnox], &segj.cx[jsnox]);
segj.jco[jsnox] = j;
return;
}
} /* if( (jcox == 0) || (jcox > PCHCON) ) */
do
{
if (jcox < 0)
jcox = -jcox;
else
jend = -jend;
jcoxx = jcox - 1;
if (jcox != j)
{
jsnox = segj.jsno;
segj.jsno++;
/* Allocate to connections buffers */
if (segj.jsno >= segj.maxcon)
{
segj.maxcon = segj.jsno + 1;
mem_realloc ((void *) &segj.jco, segj.maxcon * sizeof (int));
mem_realloc ((void *) &segj.ax, segj.maxcon * sizeof (double));
mem_realloc ((void *) &segj.bx, segj.maxcon * sizeof (double));
mem_realloc ((void *) &segj.cx, segj.maxcon * sizeof (double));
}
sbf (jcox, j, &segj.ax[jsnox], &segj.bx[jsnox], &segj.cx[jsnox]);
segj.jco[jsnox] = jcox;
if (jend != 1)
jcox = data.icon1[jcoxx];
else
jcox = data.icon2[jcoxx];
if (jcox == 0)
{
output_fp,
"\n TRIO - SEGMENT CONNENTION ERROR FOR SEGMENT %5d",
j);
stop (-1);
}
else
continue;
} /* if( jcox != j) */
if (iend == 1)
break;
jcox = data.icon2[jx];
if (jcox > PCHCON)
break;
jend = 1;
iend = 1;
} /* do */
while (jcox != 0);
jsnox = segj.jsno;
segj.jsno++;
/* Allocate to connections buffers */
if (segj.jsno >= segj.maxcon)
{
segj.maxcon = segj.jsno + 1;
mem_realloc ((void *) &segj.jco, segj.maxcon * sizeof (int));
mem_realloc ((void *) &segj.ax, segj.maxcon * sizeof (double));
mem_realloc ((void *) &segj.bx, segj.maxcon * sizeof (double));
mem_realloc ((void *) &segj.cx, segj.maxcon * sizeof (double));
}
sbf (j, j, &segj.ax[jsnox], &segj.bx[jsnox], &segj.cx[jsnox]);
segj.jco[jsnox] = j;
return;
}
/*-----------------------------------------------------------------------*/
/* zint computes the internal impedance of a circular wire */
void zint (double sigl, double rolam, complex double *zint)
{
#define cc1 (6.0e-7 + 1.9e-6fj)
#define cc2 (-3.4e-6 + 5.1e-6fj)
#define cc3 (-2.52e-5 + 0.fj)
#define cc4 (-9.06e-5 - 9.01e-5fj)
#define cc5 (0. - 9.765e-4fj)
#define cc6 (.0110486 - .0110485fj)
#define cc7 (0. - .3926991fj)
#define cc8 (1.6e-6 - 3.2e-6fj)
#define cc9 (1.17e-5 - 2.4e-6fj)
#define cc10 (3.46e-5 + 3.38e-5fj)
#define cc11 (5.0e-7 + 2.452e-4fj)
#define cc12 (-1.3813e-3 + 1.3811e-3fj)
#define cc13 (-6.25001e-2 - 1.0e-7fj)
#define cc14 (.7071068 + .7071068fj)
#define cn cc14
#define th(d) \
((((((cc1 * (d) + cc2) * (d) + cc3) * (d) + cc4) * (d) + cc5) * (d) + cc6) * (d) + cc7)
#define ph(d) \
((((((cc8 * (d) + cc9) * (d) + cc10) * (d) + cc11) * (d) + cc12) * (d) + cc13) * \
(d) + \
cc14)
#define f(d) (csqrtl (POT / (d)) * cexpl (-cn * (d) + th (-8. / x)))
#define g(d) (cexpl (cn * (d) + th (8. / x)) / csqrtl (TP * (d)))
double x, y, s, ber, bei;
double tpcmu = 2.368705e+3;
;
double cmotp = 60.00;
complex double br1, br2;
x = sqrtl (tpcmu * sigl) * rolam;
if (x <= 110.)
{
if (x <= 8.)
{
y = x / 8.;
y = y * y;
s = y * y;
ber = ((((((-9.01e-6 * s + 1.22552e-3) * s - .08349609) * s +
2.6419140) *
s -
32.363456) *
s +
113.77778) *
s -
64.) *
s +
1.;
bei = ((((((1.1346e-4 * s - .01103667) * s + .52185615) * s -
10.567658) *
s +
72.817777) *
s -
113.77778) *
s +
16.) *
y;
br1 = cmplx (ber, bei);
ber = (((((((-3.94e-6 * s + 4.5957e-4) * s - .02609253) * s +
.66047849) *
s -
6.0681481) *
s +
14.222222) *
s -
4.) *
y) *
x;
bei = ((((((4.609e-5 * s - 3.79386e-3) * s + .14677204) * s -
2.3116751) *
s +
11.377778) *
s -
10.666667) *
s +
.5) *
x;
br2 = cmplx (ber, bei);
br1 = br1 / br2;
*zint = CPLX_01 * sqrtl (cmotp / sigl) * br1 / rolam;
} /* if( x <= 8.) */
br2 = CPLX_01 * f (x) / PI;
br1 = g (x) + br2;
br2 = g (x) * ph (8. / x) - br2 * ph (-8. / x);
br1 = br1 / br2;
*zint = CPLX_01 * sqrtl (cmotp / sigl) * br1 / rolam;
} /* if( x <= 110.) */
br1 = cmplx (.70710678, -.70710678);
*zint = CPLX_01 * sqrtl (cmotp / sigl) * br1 / rolam;
}
/*-----------------------------------------------------------------------*/
/* cang returns the phase angle of a complex number in degrees. */
double cang (complex double z)
{
return (cargl (z) * TD);
}
/*-----------------------------------------------------------------------*/