Subversion Repositories Nec2c

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/* last change:  pgm   8 nov 2000    1:04 pm
2
 program somnec(input,output,tape21)
3
 
4
 program to generate nec interpolation grids for fields due to
5
 ground.  field components are computed by numerical evaluation
6
 of modified sommerfeld integrals.
7
 
8
 somnec2d is a double precision version of somnec for use with
9
 nec2d.  an alternate version (somnec2sd) is also provided in which
10
 computation is in single precision but the output file is written
11
 in double precision for use with nec2d.  somnec2sd runs about twic
12
 as fast as the full double precision somnec2d.  the difference
13
 between nec2d results using a for021 file from this code rather
14
 than from somnec2sd was insignficant in the cases tested.
15
 
16
 changes made by j bergervoet, 31-5-95:
17
 parameter 0. --> 0.d0 in calling of routine test
18
 status of output files set to 'unknown' */
19
 
20
#include "nec2c.h"
21
 
22
/* common /evlcom/ */
23
static int jh;
24
static double ck2, ck2sq, tkmag, tsmag, ck1r, zph, rho;
25
static complex double ct1, ct2, ct3, ck1, ck1sq, cksm;
26
 
27
/* common /cntour/ */
28
static complex double a, b;
29
 
30
/*common  /ggrid/ */
31
ggrid_t ggrid;
32
 
33
/*-----------------------------------------------------------------------*/
34
 
35
/* This is the "main" of somnec */
36
void somnec (double epr, double sig, double fmhz)
37
{
38
        int k, nth, ith, irs, ir, nr;
39
        double tim, wlam, tst, dr, dth, r, rk, thet, tfac1, tfac2;
40
        complex double erv, ezv, erh, eph, cl1, cl2, con;
41
 
42
        if (sig >= 0.)
43
        {
44
                wlam = CVEL / fmhz;
45
                ggrid.epscf = cmplx (epr, -sig * wlam * 59.96);
46
        }
47
        else
48
                ggrid.epscf = cmplx (epr, sig);
49
 
50
        secnds (&tst);
51
        ck2 = TP;
52
        ck2sq = ck2 * ck2;
53
 
54
        /* sommerfeld integral evaluation uses exp(-jwt), nec uses exp(+jwt), */
55
        /* hence need conjg(ggrid.epscf).  conjugate of fields occurs in subroutine */
56
        /* evlua. */
57
 
58
        ck1sq = ck2sq * conj (ggrid.epscf);
59
        ck1 = csqrtl (ck1sq);
60
        ck1r = creal (ck1);
61
        tkmag = 100. * cabs (ck1);
62
        tsmag = 100. * ck1 * conj (ck1);
63
        cksm = ck2sq / (ck1sq + ck2sq);
64
        ct1 = .5 * (ck1sq - ck2sq);
65
        erv = ck1sq * ck1sq;
66
        ezv = ck2sq * ck2sq;
67
        ct2 = .125 * (erv - ezv);
68
        erv *= ck1sq;
69
        ezv *= ck2sq;
70
        ct3 = .0625 * (erv - ezv);
71
 
72
        /* loop over 3 grid regions */
73
        for (k = 0; k < 3; k++)
74
        {
75
                nr = ggrid.nxa[k];
76
                nth = ggrid.nya[k];
77
                dr = ggrid.dxa[k];
78
                dth = ggrid.dya[k];
79
                r = ggrid.xsa[k] - dr;
80
                irs = 1;
81
                if (k == 0)
82
                {
83
                        r = ggrid.xsa[k];
84
                        irs = 2;
85
                }
86
 
87
                /*  loop over r.  (r=sqrtl(rho**2 + (z+h)**2)) */
88
                for (ir = irs - 1; ir < nr; ir++)
89
                {
90
                        r += dr;
91
                        thet = ggrid.ysa[k] - dth;
92
 
93
                        /* loop over theta.  (theta=atan((z+h)/rho)) */
94
                        for (ith = 0; ith < nth; ith++)
95
                        {
96
                                thet += dth;
97
                                rho = r * cosl (thet);
98
                                zph = r * sinl (thet);
99
                                if (rho < 1.e-7)
100
                                        rho = 1.e-8;
101
                                if (zph < 1.e-7)
102
                                        zph = 0.;
103
 
104
                                evlua (&erv, &ezv, &erh, &eph);
105
 
106
                                rk = ck2 * r;
107
                                con = -CONST1 * r / cmplx (cosl (rk), -sinl (rk));
108
 
109
                                switch (k)
110
                                {
111
                                case 0:
112
                                        ggrid.ar1[ir + ith * 11 + 0] = erv * con;
113
                                        ggrid.ar1[ir + ith * 11 + 110] = ezv * con;
114
                                        ggrid.ar1[ir + ith * 11 + 220] = erh * con;
115
                                        ggrid.ar1[ir + ith * 11 + 330] = eph * con;
116
                                        break;
117
 
118
                                case 1:
119
                                        ggrid.ar2[ir + ith * 17 + 0] = erv * con;
120
                                        ggrid.ar2[ir + ith * 17 + 85] = ezv * con;
121
                                        ggrid.ar2[ir + ith * 17 + 170] = erh * con;
122
                                        ggrid.ar2[ir + ith * 17 + 255] = eph * con;
123
                                        break;
124
 
125
                                case 2:
126
                                        ggrid.ar3[ir + ith * 9 + 0] = erv * con;
127
                                        ggrid.ar3[ir + ith * 9 + 72] = ezv * con;
128
                                        ggrid.ar3[ir + ith * 9 + 144] = erh * con;
129
                                        ggrid.ar3[ir + ith * 9 + 216] = eph * con;
130
 
131
                                } /* switch( k ) */
132
 
133
                        } /* for( ith = 0; ith < nth; ith++ ) */
134
 
135
                } /* for( ir = irs-1; ir < nr; ir++; ) */
136
 
137
        } /* for( k = 0; k < 3; k++; ) */
138
 
139
        /* fill grid 1 for r equal to zero. */
140
        cl2 = -CONST4 * (ggrid.epscf - 1.) / (ggrid.epscf + 1.);
141
        cl1 = cl2 / (ggrid.epscf + 1.);
142
        ezv = ggrid.epscf * cl1;
143
        thet = -dth;
144
        nth = ggrid.nya[0];
145
 
146
        for (ith = 0; ith < nth; ith++)
147
        {
148
                thet += dth;
149
                if ((ith + 1) != nth)
150
                {
151
                        tfac2 = cosl (thet);
152
                        tfac1 = (1. - sinl (thet)) / tfac2;
153
                        tfac2 = tfac1 / tfac2;
154
                        erv = ggrid.epscf * cl1 * tfac1;
155
                        erh = cl1 * (tfac2 - 1.) + cl2;
156
                        eph = cl1 * tfac2 - cl2;
157
                }
158
                else
159
                {
160
                        erv = 0.;
161
                        erh = cl2 - .5 * cl1;
162
                        eph = -erh;
163
                }
164
 
165
                ggrid.ar1[0 + ith * 11 + 0] = erv;
166
                ggrid.ar1[0 + ith * 11 + 110] = ezv;
167
                ggrid.ar1[0 + ith * 11 + 220] = erh;
168
                ggrid.ar1[0 + ith * 11 + 330] = eph;
169
        }
170
 
171
        secnds (&tim);
172
        tim -= tst;
173
 
174
        return;
175
}
176
 
177
/*-----------------------------------------------------------------------*/
178
 
179
/* bessel evaluates the zero-order bessel function */
180
/* and its derivative for complex argument z. */
181
void bessel (complex double z, complex double *j0, complex double *j0p)
182
{
183
        int k, i, ib, iz, miz;
184
        static int m[101], init = FALSE;
185
        static double a1[25], a2[25];
186
        double tst, zms;
187
        complex double p0z, p1z, q0z, q1z, zi, zi2, zk, cz, sz, j0x = CPLX_00, j0px = CPLX_00;
188
 
189
        /* initialization of constants */
190
        if (!init)
191
        {
192
                for (k = 1; k <= 25; k++)
193
                {
194
                        i = k - 1;
195
                        a1[i] = -.25 / (k * k);
196
                        a2[i] = 1.0 / (k + 1.0);
197
                }
198
 
199
                for (i = 1; i <= 101; i++)
200
                {
201
                        tst = 1.0;
202
                        for (k = 0; k < 24; k++)
203
                        {
204
                                init = k;
205
                                tst *= -i * a1[k];
206
                                if (tst < 1.0e-6)
207
                                        break;
208
                        }
209
 
210
                        m[i - 1] = init + 1;
211
                } /* for( i = 1; i<= 101; i++ ) */
212
 
213
                init = TRUE;
214
        } /* if(init == 0) */
215
 
216
        zms = z * conj (z);
217
        if (zms <= 1.e-12)
218
        {
219
                *j0 = CPLX_10;
220
                *j0p = -.5 * z;
221
                return;
222
        }
223
 
224
        ib = 0;
225
        if (zms <= 37.21)
226
        {
227
                if (zms > 36.)
228
                        ib = 1;
229
 
230
                /* series expansion */
231
                iz = zms;
232
                miz = m[iz];
233
                *j0 = CPLX_10;
234
                *j0p = *j0;
235
                zk = *j0;
236
                zi = z * z;
237
 
238
                for (k = 0; k < miz; k++)
239
                {
240
                        zk *= a1[k] * zi;
241
                        *j0 += zk;
242
                        *j0p += a2[k] * zk;
243
                }
244
                *j0p *= -.5 * z;
245
 
246
                if (ib == 0)
247
                        return;
248
 
249
                j0x = *j0;
250
                j0px = *j0p;
251
        }
252
 
253
        /* asymptotic expansion */
254
        zi = 1. / z;
255
        zi2 = zi * zi;
256
        p0z = 1. + (P20 * zi2 - P10) * zi2;
257
        p1z = 1. + (P11 - P21 * zi2) * zi2;
258
        q0z = (Q20 * zi2 - Q10) * zi;
259
        q1z = (Q11 - Q21 * zi2) * zi;
260
        zk = cexp (CPLX_01 * (z - POF));
261
        zi2 = 1. / zk;
262
        cz = .5 * (zk + zi2);
263
        sz = CPLX_01 * .5 * (zi2 - zk);
264
        zk = C3 * csqrtl (zi);
265
        *j0 = zk * (p0z * cz - q0z * sz);
266
        *j0p = -zk * (p1z * sz + q1z * cz);
267
 
268
        if (ib == 0)
269
                return;
270
 
271
        zms = cosl ((sqrtl (zms) - 6.) * PI10);
272
        *j0 = .5 * (j0x * (1. + zms) + *j0 * (1. - zms));
273
        *j0p = .5 * (j0px * (1. + zms) + *j0p * (1. - zms));
274
 
275
        return;
276
}
277
 
278
/*-----------------------------------------------------------------------*/
279
 
280
/* evlua controls the integration contour in the complex */
281
/* lambda plane for evaluation of the sommerfeld integrals */
282
void evlua (complex double *erv, complex double *ezv, complex double *erh, complex double *eph)
283
{
284
        int i, jump;
285
        static double del, slope, rmis;
286
        static complex double cp1, cp2, cp3, bk, delta, delta2, sum[6], ans[6];
287
 
288
        del = zph;
289
        if (rho > del)
290
                del = rho;
291
 
292
        if (zph >= 2. * rho)
293
        {
294
                /* bessel function form of sommerfeld integrals */
295
                jh = 0;
296
                a = CPLX_00;
297
                del = 1. / del;
298
 
299
                if (del > tkmag)
300
                {
301
                        b = cmplx (.1 * tkmag, -.1 * tkmag);
302
                        rom1 (6, sum, 2);
303
                        a = b;
304
                        b = cmplx (del, -del);
305
                        rom1 (6, ans, 2);
306
                        for (i = 0; i < 6; i++)
307
                                sum[i] += ans[i];
308
                }
309
                else
310
                {
311
                        b = cmplx (del, -del);
312
                        rom1 (6, sum, 2);
313
                }
314
 
315
                delta = PTP * del;
316
                gshank (b, delta, ans, 6, sum, 0, b, b);
317
                ans[5] *= ck1;
318
 
319
                /* conjugate since nec uses exp(+jwt) */
320
                *erv = conj (ck1sq * ans[2]);
321
                *ezv = conj (ck1sq * (ans[1] + ck2sq * ans[4]));
322
                *erh = conj (ck2sq * (ans[0] + ans[5]));
323
                *eph = -conj (ck2sq * (ans[3] + ans[5]));
324
 
325
                return;
326
 
327
        } /* if(zph >= 2.*rho) */
328
 
329
        /* hankel function form of sommerfeld integrals */
330
        jh = 1;
331
        cp1 = cmplx (0.0, .4 * ck2);
332
        cp2 = cmplx (.6 * ck2, -.2 * ck2);
333
        cp3 = cmplx (1.02 * ck2, -.2 * ck2);
334
        a = cp1;
335
        b = cp2;
336
        rom1 (6, sum, 2);
337
        a = cp2;
338
        b = cp3;
339
        rom1 (6, ans, 2);
340
 
341
        for (i = 0; i < 6; i++)
342
                sum[i] = -(sum[i] + ans[i]);
343
 
344
        /* path from imaginary axis to -infinity */
345
        if (zph > .001 * rho)
346
                slope = rho / zph;
347
        else
348
                slope = 1000.;
349
 
350
        del = PTP / del;
351
        delta = cmplx (-1.0, slope) * del / sqrtl (1. + slope * slope);
352
        delta2 = -conj (delta);
353
        gshank (cp1, delta, ans, 6, sum, 0, bk, bk);
354
        rmis = rho * (creal (ck1) - ck2);
355
 
356
        jump = FALSE;
357
        if ((rmis >= 2. * ck2) && (rho >= 1.e-10))
358
        {
359
                if (zph >= 1.e-10)
360
                {
361
                        bk = cmplx (-zph, rho) * (ck1 - cp3);
362
                        rmis = -creal (bk) / fabsl (cimag (bk));
363
                        if (rmis > 4. * rho / zph)
364
                                jump = TRUE;
365
                }
366
 
367
                if (!jump)
368
                {
369
                        /* integrate up between branch cuts, then to + infinity */
370
                        cp1 = ck1 - (.1 + .2fj);
371
                        cp2 = cp1 + .2;
372
                        bk = cmplx (0., del);
373
                        gshank (cp1, bk, sum, 6, ans, 0, bk, bk);
374
                        a = cp1;
375
                        b = cp2;
376
                        rom1 (6, ans, 1);
377
                        for (i = 0; i < 6; i++)
378
                                ans[i] -= sum[i];
379
 
380
                        gshank (cp3, bk, sum, 6, ans, 0, bk, bk);
381
                        gshank (cp2, delta2, ans, 6, sum, 0, bk, bk);
382
                }
383
 
384
                jump = TRUE;
385
 
386
        } /* if( (rmis >= 2.*ck2) || (rho >= 1.e-10) ) */
387
        else
388
                jump = FALSE;
389
 
390
        if (!jump)
391
        {
392
                /* integrate below branch points, then to + infinity */
393
                for (i = 0; i < 6; i++)
394
                        sum[i] = -ans[i];
395
 
396
                rmis = creal (ck1) * 1.01;
397
                if ((ck2 + 1.) > rmis)
398
                        rmis = ck2 + 1.;
399
 
400
                bk = cmplx (rmis, .99 * cimag (ck1));
401
                delta = bk - cp3;
402
                delta *= del / cabs (delta);
403
                gshank (cp3, delta, ans, 6, sum, 1, bk, delta2);
404
 
405
        } /* if( ! jump ) */
406
 
407
        ans[5] *= ck1;
408
 
409
        /* conjugate since nec uses exp(+jwt) */
410
        *erv = conj (ck1sq * ans[2]);
411
        *ezv = conj (ck1sq * (ans[1] + ck2sq * ans[4]));
412
        *erh = conj (ck2sq * (ans[0] + ans[5]));
413
        *eph = -conj (ck2sq * (ans[3] + ans[5]));
414
 
415
        return;
416
}
417
 
418
/*-----------------------------------------------------------------------*/
419
 
420
/* fbar is sommerfeld attenuation function for numerical distance p */
421
void fbar (complex double p, complex double *fbar)
422
{
423
        int i, minus;
424
        double tms, sms;
425
        complex double z, zs, sum, pow, term;
426
 
427
        z = CPLX_01 * csqrtl (p);
428
        if (cabs (z) <= 3.)
429
        {
430
                /* series expansion */
431
                zs = z * z;
432
                sum = z;
433
                pow = z;
434
 
435
                for (i = 1; i <= 100; i++)
436
                {
437
                        pow = -pow * zs / (double) i;
438
                        term = pow / (2. * i + 1.);
439
                        sum = sum + term;
440
                        tms = creal (term * conj (term));
441
                        sms = creal (sum * conj (sum));
442
                        if (tms / sms < ACCS)
443
                                break;
444
                }
445
 
446
                *fbar = 1. - (1. - sum * TOSP) * z * cexp (zs) * SP;
447
 
448
        } /* if( cabs( z) <= 3.) */
449
 
450
        /* asymptotic expansion */
451
        if (creal (z) < 0.)
452
        {
453
                minus = 1;
454
                z = -z;
455
        }
456
        else
457
                minus = 0;
458
 
459
        zs = .5 / (z * z);
460
        sum = CPLX_00;
461
        term = CPLX_10;
462
 
463
        for (i = 1; i <= 6; i++)
464
        {
465
                term = -term * (2. * i - 1.) * zs;
466
                sum += term;
467
        }
468
 
469
        if (minus == 1)
470
                sum -= 2. * SP * z * cexp (z * z);
471
        *fbar = -sum;
472
}
473
 
474
/*-----------------------------------------------------------------------*/
475
 
476
/* gshank integrates the 6 sommerfeld integrals from start to */
477
/* infinity (until convergence) in lambda.  at the break point, bk, */
478
/* the step increment may be changed from dela to delb.  shank's */
479
/* algorithm to accelerate convergence of a slowly converging series */
480
/* is used */
481
void gshank (
482
    complex double start,
483
    complex double dela,
484
    complex double *sum,
485
    int nans,
486
    complex double *seed,
487
    int ibk,
488
    complex double bk,
489
    complex double delb)
490
{
491
        int ibx, j, i, jm, intx, inx, brk = 0;
492
        static double rbk, amg, den, denm;
493
        complex double a1, a2, as1, as2, del, aa;
494
        complex double q1[6][20], q2[6][20], ans1[6], ans2[6];
495
 
496
        rbk = creal (bk);
497
        del = dela;
498
        if (ibk == 0)
499
                ibx = 1;
500
        else
501
                ibx = 0;
502
 
503
        for (i = 0; i < nans; i++)
504
                ans2[i] = seed[i];
505
 
506
        b = start;
507
        for (intx = 1; intx <= MAXH; intx++)
508
        {
509
                inx = intx - 1;
510
                a = b;
511
                b += del;
512
 
513
                if ((ibx == 0) && (creal (b) >= rbk))
514
                {
515
                        /* hit break point.  reset seed and start over. */
516
                        ibx = 1;
517
                        b = bk;
518
                        del = delb;
519
                        rom1 (nans, sum, 2);
520
                        if (ibx != 2)
521
                        {
522
                                for (i = 0; i < nans; i++)
523
                                        ans2[i] += sum[i];
524
                                intx = 0;
525
                                continue;
526
                        }
527
 
528
                        for (i = 0; i < nans; i++)
529
                                ans2[i] = ans1[i] + sum[i];
530
                        intx = 0;
531
                        continue;
532
 
533
                } /* if( (ibx == 0) && (creal(b) >= rbk) ) */
534
 
535
                rom1 (nans, sum, 2);
536
                for (i = 0; i < nans; i++)
537
                        ans1[i] = ans2[i] + sum[i];
538
                a = b;
539
                b += del;
540
 
541
                if ((ibx == 0) && (creal (b) >= rbk))
542
                {
543
                        /* hit break point.  reset seed and start over. */
544
                        ibx = 2;
545
                        b = bk;
546
                        del = delb;
547
                        rom1 (nans, sum, 2);
548
                        if (ibx != 2)
549
                        {
550
                                for (i = 0; i < nans; i++)
551
                                        ans2[i] += sum[i];
552
                                intx = 0;
553
                                continue;
554
                        }
555
 
556
                        for (i = 0; i < nans; i++)
557
                                ans2[i] = ans1[i] + sum[i];
558
                        intx = 0;
559
                        continue;
560
 
561
                } /* if( (ibx == 0) && (creal(b) >= rbk) ) */
562
 
563
                rom1 (nans, sum, 2);
564
                for (i = 0; i < nans; i++)
565
                        ans2[i] = ans1[i] + sum[i];
566
 
567
                den = 0.;
568
                for (i = 0; i < nans; i++)
569
                {
570
                        as1 = ans1[i];
571
                        as2 = ans2[i];
572
 
573
                        if (intx >= 2)
574
                        {
575
                                for (j = 1; j < intx; j++)
576
                                {
577
                                        jm = j - 1;
578
                                        aa = q2[i][jm];
579
                                        a1 = q1[i][jm] + as1 - 2. * aa;
580
 
581
                                        if ((creal (a1) != 0.) || (cimag (a1) != 0.))
582
                                        {
583
                                                a2 = aa - q1[i][jm];
584
                                                a1 = q1[i][jm] - a2 * a2 / a1;
585
                                        }
586
                                        else
587
                                                a1 = q1[i][jm];
588
 
589
                                        a2 = aa + as2 - 2. * as1;
590
                                        if ((creal (a2) != 0.) || (cimag (a2) != 0.))
591
                                                a2 = aa - (as1 - aa) * (as1 - aa) / a2;
592
                                        else
593
                                                a2 = aa;
594
 
595
                                        q1[i][jm] = as1;
596
                                        q2[i][jm] = as2;
597
                                        as1 = a1;
598
                                        as2 = a2;
599
 
600
                                } /* for( j = 1; i < intx; i++ ) */
601
 
602
                        } /* if(intx >= 2) */
603
 
604
                        q1[i][intx - 1] = as1;
605
                        q2[i][intx - 1] = as2;
606
                        amg = fabsl (creal (as2)) + fabsl (cimag (as2));
607
                        if (amg > den)
608
                                den = amg;
609
 
610
                } /* for( i = 0; i < nans; i++ ) */
611
 
612
                denm = 1.e-3 * den * CRIT;
613
                jm = intx - 3;
614
                if (jm < 1)
615
                        jm = 1;
616
 
617
                for (j = jm - 1; j < intx; j++)
618
                {
619
                        brk = FALSE;
620
                        for (i = 0; i < nans; i++)
621
                        {
622
                                a1 = q2[i][j];
623
                                den = (fabsl (creal (a1)) + fabsl (cimag (a1))) * CRIT;
624
                                if (den < denm)
625
                                        den = denm;
626
                                a1 = q1[i][j] - a1;
627
                                amg = fabsl (creal (a1) + fabsl (cimag (a1)));
628
                                if (amg > den)
629
                                {
630
                                        brk = TRUE;
631
                                        break;
632
                                }
633
 
634
                        } /* for( i = 0; i < nans; i++ ) */
635
 
636
                        if (brk)
637
                                break;
638
 
639
                } /* for( j = jm-1; j < intx; j++ ) */
640
 
641
                if (!brk)
642
                {
643
                        for (i = 0; i < nans; i++)
644
                                sum[i] = .5 * (q1[i][inx] + q2[i][inx]);
645
                        return;
646
                }
647
 
648
        } /* for( intx = 1; intx <= maxh; intx++ ) */
649
 
650
        /* No convergence */
651
        abort_on_error (-6);
652
}
653
 
654
/*-----------------------------------------------------------------------*/
655
 
656
/* hankel evaluates hankel function of the first kind,   */
657
/* order zero, and its derivative for complex argument z */
658
void hankel (complex double z, complex double *h0, complex double *h0p)
659
{
660
        int i, k, ib, iz, miz;
661
        static int m[101], init = FALSE;
662
        static double a1[25], a2[25], a3[25], a4[25], psi, tst, zms;
663
        complex double clogz, j0, j0p, p0z, p1z, q0z, q1z, y0 = CPLX_00, y0p = CPLX_00, zi,
664
                                                           zi2, zk;
665
 
666
        /* initialization of constants */
667
        if (!init)
668
        {
669
                psi = -GAMMA;
670
                for (k = 1; k <= 25; k++)
671
                {
672
                        i = k - 1;
673
                        a1[i] = -.25 / (k * k);
674
                        a2[i] = 1.0 / (k + 1.0);
675
                        psi += 1.0 / k;
676
                        a3[i] = psi + psi;
677
                        a4[i] = (psi + psi + 1.0 / (k + 1.0)) / (k + 1.0);
678
                }
679
 
680
                for (i = 1; i <= 101; i++)
681
                {
682
                        tst = 1.0;
683
                        for (k = 0; k < 24; k++)
684
                        {
685
                                init = k;
686
                                tst *= -i * a1[k];
687
                                if (tst * a3[k] < 1.e-6)
688
                                        break;
689
                        }
690
                        m[i - 1] = init + 1;
691
                }
692
 
693
                init = TRUE;
694
 
695
        } /* if( ! init ) */
696
 
697
        zms = z * conj (z);
698
        if (zms == 0.)
699
                abort_on_error (-7);
700
 
701
        ib = 0;
702
        if (zms <= 16.81)
703
        {
704
                if (zms > 16.)
705
                        ib = 1;
706
 
707
                /* series expansion */
708
                iz = zms;
709
                miz = m[iz];
710
                j0 = CPLX_10;
711
                j0p = j0;
712
                y0 = CPLX_00;
713
                y0p = y0;
714
                zk = j0;
715
                zi = z * z;
716
 
717
                for (k = 0; k < miz; k++)
718
                {
719
                        zk *= a1[k] * zi;
720
                        j0 += zk;
721
                        j0p += a2[k] * zk;
722
                        y0 += a3[k] * zk;
723
                        y0p += a4[k] * zk;
724
                }
725
 
726
                j0p *= -.5 * z;
727
                clogz = clogl (.5 * z);
728
                y0 = (2. * j0 * clogz - y0) / PI + C2;
729
                y0p = (2. / z + 2. * j0p * clogz + .5 * y0p * z) / PI + C1 * z;
730
                *h0 = j0 + CPLX_01 * y0;
731
                *h0p = j0p + CPLX_01 * y0p;
732
 
733
                if (ib == 0)
734
                        return;
735
 
736
                y0 = *h0;
737
                y0p = *h0p;
738
 
739
        } /* if(zms <= 16.81) */
740
 
741
        /* asymptotic expansion */
742
        zi = 1. / z;
743
        zi2 = zi * zi;
744
        p0z = 1. + (P20 * zi2 - P10) * zi2;
745
        p1z = 1. + (P11 - P21 * zi2) * zi2;
746
        q0z = (Q20 * zi2 - Q10) * zi;
747
        q1z = (Q11 - Q21 * zi2) * zi;
748
        zk = cexp (CPLX_01 * (z - POF)) * csqrtl (zi) * C3;
749
        *h0 = zk * (p0z + CPLX_01 * q0z);
750
        *h0p = CPLX_01 * zk * (p1z + CPLX_01 * q1z);
751
 
752
        if (ib == 0)
753
                return;
754
 
755
        zms = cosl ((sqrtl (zms) - 4.) * 31.41592654);
756
        *h0 = .5 * (y0 * (1. + zms) + *h0 * (1. - zms));
757
        *h0p = .5 * (y0p * (1. + zms) + *h0p * (1. - zms));
758
 
759
        return;
760
}
761
 
762
/*-----------------------------------------------------------------------*/
763
 
764
/* compute integration parameter xlam=lambda from parameter t. */
765
void lambda (double t, complex double *xlam, complex double *dxlam)
766
{
767
        *dxlam = b - a;
768
        *xlam = a + *dxlam * t;
769
        return;
770
}
771
 
772
/*-----------------------------------------------------------------------*/
773
 
774
/* rom1 integrates the 6 sommerfeld integrals from a to b in lambda. */
775
/* the method of variable interval width romberg integration is used. */
776
void rom1 (int n, complex double *sum, int nx)
777
{
778
        int jump, lstep, nogo, i, ns, nt;
779
        static double z, ze, s, ep, zend, dz = 0., dzot = 0., tr, ti;
780
        static complex double t00, t11, t02;
781
        static complex double g1[6], g2[6], g3[6], g4[6], g5[6], t01[6], t10[6], t20[6];
782
 
783
        lstep = 0;
784
        z = 0.;
785
        ze = 1.;
786
        s = 1.;
787
        ep = s / (1.e4 * NM);
788
        zend = ze - ep;
789
        for (i = 0; i < n; i++)
790
                sum[i] = CPLX_00;
791
        ns = nx;
792
        nt = 0;
793
        saoa (z, g1);
794
 
795
        jump = FALSE;
796
        while (TRUE)
797
        {
798
                if (!jump)
799
                {
800
                        dz = s / ns;
801
                        if ((z + dz) > ze)
802
                        {
803
                                dz = ze - z;
804
                                if (dz <= ep)
805
                                        return;
806
                        }
807
 
808
                        dzot = dz * .5;
809
                        saoa (z + dzot, g3);
810
                        saoa (z + dz, g5);
811
 
812
                } /* if( ! jump ) */
813
 
814
                nogo = FALSE;
815
                for (i = 0; i < n; i++)
816
                {
817
                        t00 = (g1[i] + g5[i]) * dzot;
818
                        t01[i] = (t00 + dz * g3[i]) * .5;
819
                        t10[i] = (4. * t01[i] - t00) / 3.;
820
 
821
                        /* test convergence of 3 point romberg result */
822
                        test (
823
                            creal (t01[i]),
824
                            creal (t10[i]),
825
                            &tr,
826
                            cimag (t01[i]),
827
                            cimag (t10[i]),
828
                            &ti,
829
                            0.);
830
                        if ((tr > CRIT) || (ti > CRIT))
831
                                nogo = TRUE;
832
                }
833
 
834
                if (!nogo)
835
                {
836
                        for (i = 0; i < n; i++)
837
                                sum[i] += t10[i];
838
 
839
                        nt += 2;
840
                        z += dz;
841
                        if (z > zend)
842
                                return;
843
 
844
                        for (i = 0; i < n; i++)
845
                                g1[i] = g5[i];
846
 
847
                        if ((nt >= NTS) && (ns > nx))
848
                        {
849
                                ns = ns / 2;
850
                                nt = 1;
851
                        }
852
 
853
                        jump = FALSE;
854
                        continue;
855
 
856
                } /* if( ! nogo ) */
857
 
858
                saoa (z + dz * .25, g2);
859
                saoa (z + dz * .75, g4);
860
                nogo = FALSE;
861
                for (i = 0; i < n; i++)
862
                {
863
                        t02 = (t01[i] + dzot * (g2[i] + g4[i])) * .5;
864
                        t11 = (4. * t02 - t01[i]) / 3.;
865
                        t20[i] = (16. * t11 - t10[i]) / 15.;
866
 
867
                        /* test convergence of 5 point romberg result */
868
                        test (
869
                            creal (t11),
870
                            creal (t20[i]),
871
                            &tr,
872
                            cimag (t11),
873
                            cimag (t20[i]),
874
                            &ti,
875
                            0.);
876
                        if ((tr > CRIT) || (ti > CRIT))
877
                                nogo = TRUE;
878
                }
879
 
880
                if (!nogo)
881
                {
882
                        for (i = 0; i < n; i++)
883
                                sum[i] += t20[i];
884
 
885
                        nt++;
886
                        z += dz;
887
                        if (z > zend)
888
                                return;
889
 
890
                        for (i = 0; i < n; i++)
891
                                g1[i] = g5[i];
892
 
893
                        if ((nt >= NTS) && (ns > nx))
894
                        {
895
                                ns = ns / 2;
896
                                nt = 1;
897
                        }
898
 
899
                        jump = FALSE;
900
                        continue;
901
 
902
                } /* if( ! nogo ) */
903
 
904
                nt = 0;
905
                if (ns < NM)
906
                {
907
                        ns *= 2;
908
                        dz = s / ns;
909
                        dzot = dz * .5;
910
 
911
                        for (i = 0; i < n; i++)
912
                        {
913
                                g5[i] = g3[i];
914
                                g3[i] = g2[i];
915
                        }
916
 
917
                        jump = TRUE;
918
                        continue;
919
 
920
                } /* if(ns < nm) */
921
 
922
                if (!lstep)
923
                {
924
                        lstep = TRUE;
925
                        lambda (z, &t00, &t11);
926
                }
927
 
928
                for (i = 0; i < n; i++)
929
                        sum[i] += t20[i];
930
 
931
                nt++;
932
                z += dz;
933
                if (z > zend)
934
                        return;
935
 
936
                for (i = 0; i < n; i++)
937
                        g1[i] = g5[i];
938
 
939
                if ((nt >= NTS) && (ns > nx))
940
                {
941
                        ns /= 2;
942
                        nt = 1;
943
                }
944
 
945
                jump = FALSE;
946
 
947
        } /* while( TRUE ) */
948
}
949
 
950
/*-----------------------------------------------------------------------*/
951
 
952
/* saoa computes the integrand for each of the 6 sommerfeld */
953
/* integrals for source and observer above ground */
954
void saoa (double t, complex double *ans)
955
{
956
        double xlr, sign;
957
        static complex double xl, dxl, cgam1, cgam2, b0, b0p, com, dgam, den1, den2;
958
 
959
        lambda (t, &xl, &dxl);
960
        if (jh == 0)
961
        {
962
                /* bessel function form */
963
                bessel (xl * rho, &b0, &b0p);
964
                b0 *= 2.;
965
                b0p *= 2.;
966
                cgam1 = csqrtl (xl * xl - ck1sq);
967
                cgam2 = csqrtl (xl * xl - ck2sq);
968
                if (creal (cgam1) == 0.)
969
                        cgam1 = cmplx (0., -fabsl (cimag (cgam1)));
970
                if (creal (cgam2) == 0.)
971
                        cgam2 = cmplx (0., -fabsl (cimag (cgam2)));
972
        }
973
        else
974
        {
975
                /* hankel function form */
976
                hankel (xl * rho, &b0, &b0p);
977
                com = xl - ck1;
978
                cgam1 = csqrtl (xl + ck1) * csqrtl (com);
979
                if (creal (com) < 0. && cimag (com) >= 0.)
980
                        cgam1 = -cgam1;
981
                com = xl - ck2;
982
                cgam2 = csqrtl (xl + ck2) * csqrtl (com);
983
                if (creal (com) < 0. && cimag (com) >= 0.)
984
                        cgam2 = -cgam2;
985
        }
986
 
987
        xlr = xl * conj (xl);
988
        if (xlr >= tsmag)
989
        {
990
                if (cimag (xl) >= 0.)
991
                {
992
                        xlr = creal (xl);
993
                        if (xlr >= ck2)
994
                        {
995
                                if (xlr <= ck1r)
996
                                        dgam = cgam2 - cgam1;
997
                                else
998
                                {
999
                                        sign = 1.;
1000
                                        dgam = 1. / (xl * xl);
1001
                                        dgam = sign * ((ct3 * dgam + ct2) * dgam + ct1) / xl;
1002
                                }
1003
                        }
1004
                        else
1005
                        {
1006
                                sign = -1.;
1007
                                dgam = 1. / (xl * xl);
1008
                                dgam = sign * ((ct3 * dgam + ct2) * dgam + ct1) / xl;
1009
                        } /* if(xlr >= ck2) */
1010
 
1011
                } /* if(cimag(xl) >= 0.) */
1012
                else
1013
                {
1014
                        sign = 1.;
1015
                        dgam = 1. / (xl * xl);
1016
                        dgam = sign * ((ct3 * dgam + ct2) * dgam + ct1) / xl;
1017
                }
1018
 
1019
        } /* if(xlr < tsmag) */
1020
        else
1021
                dgam = cgam2 - cgam1;
1022
 
1023
        den2 = cksm * dgam / (cgam2 * (ck1sq * cgam2 + ck2sq * cgam1));
1024
        den1 = 1. / (cgam1 + cgam2) - cksm / cgam2;
1025
        com = dxl * xl * cexp (-cgam2 * zph);
1026
        ans[5] = com * b0 * den1 / ck1;
1027
        com *= den2;
1028
 
1029
        if (rho != 0.)
1030
        {
1031
                b0p = b0p / rho;
1032
                ans[0] = -com * xl * (b0p + b0 * xl);
1033
                ans[3] = com * xl * b0p;
1034
        }
1035
        else
1036
        {
1037
                ans[0] = -com * xl * xl * .5;
1038
                ans[3] = ans[0];
1039
        }
1040
 
1041
        ans[1] = com * cgam2 * cgam2 * b0;
1042
        ans[2] = -ans[3] * cgam2 * rho;
1043
        ans[4] = com * b0;
1044
 
1045
        return;
1046
}