602aa0b6d607046f4cebde3ec1b50d7aec6c62a2
[debian/splat] / itm.cpp
1 /****************************************************************************
2 *                                                                           *
3 * This file was obtained from ftp://flattop.its.bldrdoc.gov/itm/ITMDLL.cpp  *
4 * on Jan. 10, 2004 and is public domain.  It was modified by J. D. McDonald *
5 * to remove Microsoft Windows dll-isms and to correct one case where a      *
6 * compiler found an ambguity in overloaded calls.  It was further modified  *
7 * by John A. Magliacane to remove unused variables, unneeded #includes,     *
8 * and to replace pow() statements with explicit multiplications wherever    *
9 * possible to increase execution speed and improve accuracy.                *
10 *                                                                           *
11 ****************************************************************************/
12
13 // *************************************
14 // C++ routines for this program are taken from
15 // a translation of the FORTRAN code written by
16 // U.S. Department of Commerce NTIA/ITS
17 // Institute for Telecommunication Sciences
18 // *****************
19 // Irregular Terrain Model (ITM) (Longley-Rice)
20 // *************************************
21
22 #include <math.h>
23 #include <complex>
24 #include <assert.h>
25 #include <string.h>
26
27 #define THIRD (1.0/3.0)
28
29 using namespace std;
30
31 struct tcomplex
32 {       double tcreal;
33         double tcimag;
34 };
35
36 struct prop_type
37 {       double aref;
38         double dist;
39         double hg[2];
40         double wn;
41         double dh;
42         double ens;
43         double gme;
44         double zgndreal;
45         double zgndimag;
46         double he[2];
47         double dl[2];
48         double the[2];
49         int kwx;
50         int mdp;
51 };
52
53 struct propv_type
54 {       double sgc;
55         int lvar;
56         int mdvar;
57         int klim;
58 };
59
60 struct propa_type
61 {       double dlsa;
62         double dx;
63         double ael;
64         double ak1;
65         double ak2;
66         double aed;
67         double emd;
68         double aes;
69         double ems;
70         double dls[2];
71         double dla;
72         double tha;
73 };
74
75 int mymin(const int &i, const int &j)
76 {
77         if (i<j)
78                 return i;
79         else
80                 return j;
81 }
82
83 int mymax(const int &i, const int &j)
84 {
85         if (i>j)
86                 return i;
87         else
88                 return j;
89 }
90
91 double mymin(const double &a, const double &b)
92 {
93         if (a<b)
94                 return a;
95         else
96                 return b;
97 }
98
99 double mymax(const double &a, const double &b)
100 {
101         if (a>b)
102                 return a;
103         else
104                 return b;
105 }
106
107 double FORTRAN_DIM(const double &x, const double &y)
108 {
109          /* This performs the FORTRAN DIM function.  Result is x-y
110             if x is greater than y; otherwise result is 0.0 */
111
112         if (x>y)
113                 return x-y;
114         else
115                 return 0.0;
116 }
117
118 double aknfe(const double &v2)
119 {
120         double a;
121
122         if (v2<5.76)
123                 a=6.02+9.11*sqrt(v2)-1.27*v2;
124         else
125                 a=12.953+4.343*log(v2);
126         return a;
127 }
128
129 double fht(const double& x, const double& pk)
130 {
131         double w, fhtv;
132
133         if (x<200.0)
134         {
135                 w=-log(pk);
136
137                 /* if (pk<1e-5 || x*pow(w,3.0) > 5495.0) */
138                 if (pk<1.0e-5 || x*w*w*w > 5495.0)
139                 {
140                         fhtv=-117.0;
141
142                         if (x>1.0)
143                                 fhtv=17.372*log(x)+fhtv;
144                 }
145                 else
146                         fhtv=2.5e-5*x*x/pk-8.686*w-15.0;
147         }
148
149         else
150         {
151                 fhtv=0.05751*x-4.343*log(x);
152
153                 if (x<2000.0)
154                 {
155                         w=0.0134*x*exp(-0.005*x);
156                         fhtv=(1.0-w)*fhtv+w*(17.372*log(x)-117.0);
157                 }
158         }
159         return fhtv;
160 }
161
162 double h0f(double r, double et)
163 {
164         double a[5]={25.0, 80.0, 177.0, 395.0, 705.0};
165         double b[5]={24.0, 45.0,  68.0,  80.0, 105.0};
166         double q, x;
167         double h0fv, temp; 
168         int it;
169
170         it=(int)et;
171
172         if (it<=0)
173         {
174                 it=1;
175                 q=0.0;
176         }
177
178         else if (it>=5)
179         {
180                 it=5;
181                 q=0.0;
182         }
183
184         else
185                 q=et-it;
186
187         /* x=pow(1.0/r,2.0); */
188
189         temp=1.0/r;
190         x=temp*temp;
191
192         h0fv=4.343*log((a[it-1]*x+b[it-1])*x+1.0);
193
194         if (q!=0.0)
195                 h0fv=(1.0-q)*h0fv+q*4.343*log((a[it]*x+b[it])*x+1.0);
196
197         return h0fv;
198 }
199
200 double ahd(double td)
201 {
202         int i;
203         double a[3]={   133.4,    104.6,     71.8};
204         double b[3]={0.332e-3, 0.212e-3, 0.157e-3};
205         double c[3]={  -4.343,   -1.086,    2.171};
206
207         if (td<=10e3)
208                 i=0;
209
210         else if (td<=70e3)
211                 i=1;
212
213         else
214                 i=2;
215
216         return a[i]+b[i]*td+c[i]*log(td);
217 }
218
219 double adiff(double d, prop_type &prop, propa_type &propa)
220 {
221         complex<double> prop_zgnd(prop.zgndreal,prop.zgndimag);
222         static double wd1, xd1, afo, qk, aht, xht;
223         double a, q, pk, ds, th, wa, ar, wd, adiffv;
224
225         if (d==0)
226         {
227                 q=prop.hg[0]*prop.hg[1];
228                 qk=prop.he[0]*prop.he[1]-q;
229
230                 if (prop.mdp<0.0)
231                         q+=10.0;
232
233                 wd1=sqrt(1.0+qk/q);
234                 xd1=propa.dla+propa.tha/prop.gme;
235                 q=(1.0-0.8*exp(-propa.dlsa/50e3))*prop.dh;
236                 q*=0.78*exp(-pow(q/16.0,0.25));
237                 afo=mymin(15.0,2.171*log(1.0+4.77e-4*prop.hg[0]*prop.hg[1]*prop.wn*q));
238                 qk=1.0/abs(prop_zgnd);
239                 aht=20.0;
240                 xht=0.0;
241
242                 for (int j=0; j<2; ++j)
243                 {
244                         /* a=0.5*pow(prop.dl[j],2.0)/prop.he[j]; */
245                         a=0.5*(prop.dl[j]*prop.dl[j])/prop.he[j];
246                         wa=pow(a*prop.wn,THIRD);
247                         pk=qk/wa;
248                         q=(1.607-pk)*151.0*wa*prop.dl[j]/a;
249                         xht+=q;
250                         aht+=fht(q,pk);
251                 }
252
253                 adiffv=0.0;
254         }
255
256         else
257         {
258                 th=propa.tha+d*prop.gme;
259                 ds=d-propa.dla;
260                 /* q=0.0795775*prop.wn*ds*pow(th,2.0); */
261                 q=0.0795775*prop.wn*ds*th*th;
262                 adiffv=aknfe(q*prop.dl[0]/(ds+prop.dl[0]))+aknfe(q*prop.dl[1]/(ds+prop.dl[1]));
263                 a=ds/th;
264                 wa=pow(a*prop.wn,THIRD);
265                 pk=qk/wa;
266                 q=(1.607-pk)*151.0*wa*th+xht;
267                 ar=0.05751*q-4.343*log(q)-aht;
268                 q=(wd1+xd1/d)*mymin(((1.0-0.8*exp(-d/50e3))*prop.dh*prop.wn),6283.2);
269                 wd=25.1/(25.1+sqrt(q));
270                 adiffv=ar*wd+(1.0-wd)*adiffv+afo;
271         }
272
273         return adiffv;
274 }
275
276 double ascat( double d, prop_type &prop, propa_type &propa)
277 {
278         static double ad, rr, etq, h0s;
279         double h0, r1, r2, z0, ss, et, ett, th, q;
280         double ascatv, temp;
281
282         if (d==0.0)
283         {
284                 ad=prop.dl[0]-prop.dl[1];
285                 rr=prop.he[1]/prop.he[0];
286
287                 if (ad<0.0)
288                 {
289                         ad=-ad;
290                         rr=1.0/rr;
291                 }
292
293                 etq=(5.67e-6*prop.ens-2.32e-3)*prop.ens+0.031;
294                 h0s=-15.0;
295                 ascatv=0.0;
296         }
297
298         else
299         {
300                 if (h0s>15.0)
301                         h0=h0s;
302                 else
303                 {
304                         th=prop.the[0]+prop.the[1]+d*prop.gme;
305                         r2=2.0*prop.wn*th;
306                         r1=r2*prop.he[0];
307                         r2*=prop.he[1];
308
309                         if (r1<0.2 && r2<0.2)
310                                 return 1001.0;  // <==== early return
311
312                         ss=(d-ad)/(d+ad);
313                         q=rr/ss;
314                         ss=mymax(0.1,ss);
315                         q=mymin(mymax(0.1,q),10.0);
316                         z0=(d-ad)*(d+ad)*th*0.25/d;
317                         /* et=(etq*exp(-pow(mymin(1.7,z0/8.0e3),6.0))+1.0)*z0/1.7556e3; */
318
319                         temp=mymin(1.7,z0/8.0e3);
320                         temp=temp*temp*temp*temp*temp*temp;
321                         et=(etq*exp(-temp)+1.0)*z0/1.7556e3;
322
323                         ett=mymax(et,1.0);
324                         h0=(h0f(r1,ett)+h0f(r2,ett))*0.5;
325                         h0+=mymin(h0,(1.38-log(ett))*log(ss)*log(q)*0.49);
326                         h0=FORTRAN_DIM(h0,0.0);
327
328                         if (et<1.0)
329                         {
330                                 /* h0=et*h0+(1.0-et)*4.343*log(pow((1.0+1.4142/r1)*(1.0+1.4142/r2),2.0)*(r1+r2)/(r1+r2+2.8284)); */
331
332                                 temp=((1.0+1.4142/r1)*(1.0+1.4142/r2));
333                                 h0=et*h0+(1.0-et)*4.343*log((temp*temp)*(r1+r2)/(r1+r2+2.8284));
334                         }
335
336                         if (h0>15.0 && h0s>=0.0)
337                                 h0=h0s;
338                 }
339
340                 h0s=h0;
341                 th=propa.tha+d*prop.gme;
342                 /* ascatv=ahd(th*d)+4.343*log(47.7*prop.wn*pow(th,4.0))-0.1*(prop.ens-301.0)*exp(-th*d/40e3)+h0; */
343                 ascatv=ahd(th*d)+4.343*log(47.7*prop.wn*(th*th*th*th))-0.1*(prop.ens-301.0)*exp(-th*d/40e3)+h0;
344         }
345
346         return ascatv;
347 }
348
349 double qerfi(double q)
350 {
351         double x, t, v;
352         double c0=2.515516698;
353         double c1=0.802853;
354         double c2=0.010328;
355         double d1=1.432788;
356         double d2=0.189269;
357         double d3=0.001308;
358
359         x=0.5-q;
360         t=mymax(0.5-fabs(x),0.000001);
361         t=sqrt(-2.0*log(t));
362         v=t-((c2*t+c1)*t+c0)/(((d3*t+d2)*t+d1)*t+1.0);
363
364         if (x<0.0)
365                 v=-v;
366
367         return v;
368 }
369
370 void qlrps(double fmhz, double zsys, double en0, int ipol, double eps, double sgm, prop_type &prop)
371 {
372         double gma=157e-9;
373
374         prop.wn=fmhz/47.7;
375         prop.ens=en0;
376
377         if (zsys!=0.0)
378                 prop.ens*=exp(-zsys/9460.0);
379
380         prop.gme=gma*(1.0-0.04665*exp(prop.ens/179.3));
381         complex<double> zq, prop_zgnd(prop.zgndreal,prop.zgndimag);
382         zq=complex<double> (eps,376.62*sgm/prop.wn);
383         prop_zgnd=sqrt(zq-1.0);
384
385         if (ipol!=0.0)
386                 prop_zgnd=prop_zgnd/zq;
387
388         prop.zgndreal=prop_zgnd.real();
389         prop.zgndimag=prop_zgnd.imag();
390 }
391
392 double abq_alos (complex<double> r)
393 {
394         return r.real()*r.real()+r.imag()*r.imag();
395 }
396
397 double alos(double d, prop_type &prop, propa_type &propa)
398 {
399         complex<double> prop_zgnd(prop.zgndreal,prop.zgndimag);
400         static double wls;
401         complex<double> r;
402         double s, sps, q;
403         double alosv;
404
405         if (d==0.0)
406         {
407                 wls=0.021/(0.021+prop.wn*prop.dh/mymax(10e3,propa.dlsa));
408                 alosv=0.0;
409         }
410
411         else
412         {
413                 q=(1.0-0.8*exp(-d/50e3))*prop.dh;
414                 s=0.78*q*exp(-pow(q/16.0,0.25));
415                 q=prop.he[0]+prop.he[1];
416                 sps=q/sqrt(d*d+q*q);
417                 r=(sps-prop_zgnd)/(sps+prop_zgnd)*exp(-mymin(10.0,prop.wn*s*sps));
418                 q=abq_alos(r);
419
420                 if (q<0.25 || q<sps)
421                         r=r*sqrt(sps/q);
422
423                 alosv=propa.emd*d+propa.aed;
424                 q=prop.wn*prop.he[0]*prop.he[1]*2.0/d;
425
426                 if (q>1.57)
427                         q=3.14-2.4649/q;
428
429                 alosv=(-4.343*log(abq_alos(complex<double>(cos(q),-sin(q))+r))-alosv)*wls+alosv;
430
431         }
432         return alosv;
433 }
434
435
436 void qlra(int kst[], int klimx, int mdvarx, prop_type &prop, propv_type &propv)
437 {
438         double q;
439
440         for (int j=0; j<2; ++j)
441         {
442                 if (kst[j]<=0)
443                          prop.he[j]=prop.hg[j];
444                 else
445                 {
446                         q=4.0;
447
448                         if (kst[j]!=1)
449                                 q=9.0;
450
451                         if (prop.hg[j]<5.0)
452                                 q*=sin(0.3141593*prop.hg[j]);
453
454                         prop.he[j]=prop.hg[j]+(1.0+q)*exp(-mymin(20.0,2.0*prop.hg[j]/mymax(1e-3,prop.dh)));
455                 }
456
457                 q=sqrt(2.0*prop.he[j]/prop.gme);
458                 prop.dl[j]=q*exp(-0.07*sqrt(prop.dh/mymax(prop.he[j],5.0)));
459                 prop.the[j]=(0.65*prop.dh*(q/prop.dl[j]-1.0)-2.0*prop.he[j])/q;
460         }
461
462         prop.mdp=1;
463         propv.lvar=mymax(propv.lvar,3);
464   
465         if (mdvarx>=0)
466         {
467                 propv.mdvar=mdvarx;
468                 propv.lvar=mymax(propv.lvar,4);
469         }
470
471         if (klimx>0)
472         {
473                 propv.klim=klimx;
474                 propv.lvar=5;
475         }
476 }
477
478 void freds_lrprop (double d, prop_type &prop, propa_type &propa)
479 {
480         /* freds_lrprop */
481
482         static bool wlos, wscat;
483         static double dmin, xae;
484         complex<double> prop_zgnd(prop.zgndreal,prop.zgndimag);
485         double a0, a1, a2, a3, a4, a5, a6;
486         double d0, d1, d2, d3, d4, d5, d6;
487         double q;
488         int j;
489
490         if (prop.mdp!=0)
491         {
492                 for (j=0; j<2; ++j)
493                         propa.dls[j]=sqrt(2.0*prop.he[j]/prop.gme);
494
495                 propa.dlsa=propa.dls[0]+propa.dls[1];
496                 propa.dla=prop.dl[0]+prop.dl[1];
497                 propa.tha=mymax(prop.the[0]+prop.the[1],-propa.dla*prop.gme);
498                 wlos=false;
499                 wscat=false;
500
501                 if (prop.wn<0.838 || prop.wn>210.0)
502                         prop.kwx=mymax(prop.kwx,1);
503
504                 for (j=0; j<2; ++j)
505                         if (prop.hg[j]<1.0 || prop.hg[j]>1000.0)
506                                 prop.kwx=mymax(prop.kwx,1);
507
508                 for (j=0; j<2; ++j)
509                         if (abs(prop.the[j]) >200e-3 || prop.dl[j]<0.1*propa.dls[j] || prop.dl[j]>3.0*propa.dls[j])
510                                 prop.kwx=mymax(prop.kwx,3);
511
512                 if (prop.ens < 250.0 || prop.ens > 400.0 || prop.gme < 75e-9 || prop.gme > 250e-9 || prop_zgnd.real() <= abs(prop_zgnd.imag()) || prop.wn < 0.419 || prop.wn > 420.0)
513                         prop.kwx=4;
514
515                 for (j=0; j<2; ++j)
516                         if (prop.hg[j]<0.5 || prop.hg[j]>3000.0)
517                                 prop.kwx=4;
518
519                 dmin=abs(prop.he[0]-prop.he[1])/200e-3;
520                 q=adiff(0.0,prop,propa);
521                 xae=pow(prop.wn*prop.gme*prop.gme,-THIRD);
522                 d3=mymax(propa.dlsa,1.3787*xae+propa.dla);
523                 d4=d3+2.7574*xae;
524                 a3=adiff(d3,prop,propa);
525                 a4=adiff(d4,prop,propa);
526                 propa.emd=(a4-a3)/(d4-d3);
527                 propa.aed=a3-propa.emd*d3;
528
529                 if (prop.mdp==0)
530                         prop.dist=0;
531
532                 else if (prop.mdp>0)
533                 {
534                         prop.mdp=0;
535                         prop.dist=0;
536                 }
537
538                 if ((prop.dist>0.0) || (prop.mdp<0.0))
539                 {
540                         if (prop.dist>1000e3)
541                                 prop.kwx=mymax(prop.kwx,1);
542
543                         if (prop.dist<dmin)
544                                 prop.kwx=mymax(prop.kwx,3);
545
546                         if (prop.dist<1e3 || prop.dist>2000e3)
547                                 prop.kwx=4;
548                 }
549         }
550
551         else
552         {
553                 prop.dist=d;
554
555                 if (prop.dist>0.0)
556                 {
557                         if (prop.dist>1000e3)
558                                 prop.kwx=mymax(prop.kwx,1);
559
560                         if (prop.dist<dmin)
561                                 prop.kwx=mymax(prop.kwx,3);
562
563                         if (prop.dist<1e3 || prop.dist>2000e3)
564                                 prop.kwx=4;
565                 }
566         }
567
568         if (prop.dist<propa.dlsa)
569         {
570                 if (!wlos)
571                 {
572                         /* Coefficients for the line-of-sight range */
573
574                         q=alos(0.0,prop,propa);
575                         d2=propa.dlsa;
576                         a2=propa.aed+d2*propa.emd;
577                         d0=1.908*prop.wn*prop.he[0]*prop.he[1];
578
579                         if (propa.aed>=0.0)
580                         {
581                                 d0=mymin(d0,0.5*propa.dla);
582                                 d1=d0+0.25*(propa.dla-d0);
583                         }
584
585                         else
586                                 d1=mymax(-propa.aed/propa.emd,0.25*propa.dla);
587
588                         a1=alos(d1,prop,propa);
589         
590                         if (d0<d1)
591                         {
592                                 a0=alos(d0,prop,propa);
593                                 q=log(d2/d0);
594                                 propa.ak2=mymax(0.0,((d2-d0)*(a1-a0)-(d1-d0)*(a2-a0))/((d2-d0)*log(d1-d0)-(d1-d0)*q));
595
596                                 if (propa.ak2<=0.0 && propa.aed<0.0)
597                                 {
598                                         propa.ak2=0.0;
599                                         propa.ak1=(a2-a1)/(d2-d1);
600
601                                         if (propa.ak1<=0.0)
602                                                 propa.ak2=propa.emd;
603                                 }
604
605                                 else
606                                 {
607                                         propa.ak1=(a2-a0-propa.ak2*q)/(d2-d0);
608
609                                         if (propa.ak1<0.0)
610                                         {
611                                                 propa.ak1=0.0;
612                                                 propa.ak2=FORTRAN_DIM(a2,a0)/q;
613
614                                                 if (propa.ak2<=0.0)
615                                                         propa.ak1=propa.emd;
616                                         }
617                                 }
618                                 propa.ael=a2-propa.ak1*d2-propa.ak2*log(d2);
619                                 wlos=true;
620                         }
621                 }
622
623                 if (prop.dist>0.0)
624                         prop.aref=propa.ael+propa.ak1*prop.dist+propa.ak2*log(prop.dist);
625         }
626
627         else
628         {
629                 if (!wscat)
630                 {
631                         q=ascat(0.0,prop,propa);
632                         d5=propa.dla+200e3;
633                         d6=d5+200e3;
634                         a6=ascat(d6,prop,propa);
635                         a5=ascat(d5,prop,propa);
636
637                         if (a5>=1000.0)
638                         {
639                                 propa.ems=propa.emd;
640                                 propa.aes=propa.aed;
641                                 propa.dx=10e6;
642                         }
643
644                         else
645                         {
646                                 propa.ems=(a6-a5)/200e3;
647                                 propa.dx=mymax(propa.dlsa,mymax(propa.dla+0.3*xae*log(47.7*prop.wn),(a5-propa.aed-propa.ems*d5)/(propa.emd-propa.ems)));
648                                 propa.aes=(propa.emd-propa.ems)*propa.dx+propa.aed;
649                         }
650
651                         wscat=true;
652                 }
653
654                 if (prop.dist<=propa.dx)
655                         prop.aref=propa.aed+propa.emd*prop.dist;
656                 else
657                         prop.aref=propa.aes+propa.ems*prop.dist;
658         }
659
660         prop.aref=FORTRAN_DIM(prop.aref,0.0);
661 }
662
663 void lrprop (double d, prop_type &prop, propa_type &propa)
664 {
665         /* PaulM_lrprop */
666         static bool wlos, wscat;
667         static double dmin, xae;
668         complex<double> prop_zgnd(prop.zgndreal,prop.zgndimag);
669         double a0, a1, a2, a3, a4, a5, a6;
670         double d0, d1, d2, d3, d4, d5, d6;
671         bool wq;
672         double q;
673         int j;
674
675         if (prop.mdp!=0)
676         {
677                 for (j=0; j<2; j++)
678                         propa.dls[j]=sqrt(2.0*prop.he[j]/prop.gme);
679
680                 propa.dlsa=propa.dls[0]+propa.dls[1];
681                 propa.dla=prop.dl[0]+prop.dl[1];
682                 propa.tha=mymax(prop.the[0]+prop.the[1],-propa.dla*prop.gme);
683                 wlos=false;
684                 wscat=false;
685
686                 if (prop.wn<0.838 || prop.wn>210.0)
687                         prop.kwx=mymax(prop.kwx,1);
688
689                 for (j=0; j<2; j++)
690                         if (prop.hg[j]<1.0 || prop.hg[j]>1000.0)
691                                 prop.kwx=mymax(prop.kwx,1);
692
693                 for (j=0; j<2; j++)
694                         if (abs(prop.the[j]) >200e-3 || prop.dl[j]<0.1*propa.dls[j] || prop.dl[j]>3.0*propa.dls[j] )
695                                 prop.kwx=mymax(prop.kwx,3);
696
697                 if (prop.ens < 250.0 || prop.ens > 400.0 || prop.gme < 75e-9 || prop.gme > 250e-9 || prop_zgnd.real() <= abs(prop_zgnd.imag()) || prop.wn < 0.419 || prop.wn > 420.0)
698                         prop.kwx=4;
699
700                 for (j=0; j<2; j++)
701                         if (prop.hg[j]<0.5 || prop.hg[j]>3000.0)
702                                 prop.kwx=4;
703
704                 dmin=abs(prop.he[0]-prop.he[1])/200e-3;
705                 q=adiff(0.0,prop,propa);
706                 /* xae=pow(prop.wn*pow(prop.gme,2.),-THIRD); -- JDM made argument 2 a double */
707                 xae=pow(prop.wn*(prop.gme*prop.gme),-THIRD);  /* No 2nd pow() */
708                 d3=mymax(propa.dlsa,1.3787*xae+propa.dla);
709                 d4=d3+2.7574*xae;
710                 a3=adiff(d3,prop,propa);
711                 a4=adiff(d4,prop,propa);
712                 propa.emd=(a4-a3)/(d4-d3);
713                 propa.aed=a3-propa.emd*d3;
714         }
715
716         if (prop.mdp>=0)
717         {
718                 prop.mdp=0;
719                 prop.dist=d;
720         }
721
722         if (prop.dist>0.0)
723         {
724                 if (prop.dist>1000e3)
725                         prop.kwx=mymax(prop.kwx,1);
726
727                 if (prop.dist<dmin)
728                         prop.kwx=mymax(prop.kwx,3);
729
730                 if (prop.dist<1e3 || prop.dist>2000e3)
731                         prop.kwx=4;
732         }
733
734         if (prop.dist<propa.dlsa)
735         {
736                 if (!wlos)
737                 {
738                         q=alos(0.0,prop,propa);
739                         d2=propa.dlsa;
740                         a2=propa.aed+d2*propa.emd;
741                         d0=1.908*prop.wn*prop.he[0]*prop.he[1];
742
743                         if (propa.aed>=0.0)
744                         {
745                                 d0=mymin(d0,0.5*propa.dla);
746                                 d1=d0+0.25*(propa.dla-d0);
747                         }
748
749                         else
750                                 d1=mymax(-propa.aed/propa.emd,0.25*propa.dla);
751
752                         a1=alos(d1,prop,propa);
753                         wq=false;
754
755                         if (d0<d1)
756                         {
757                                 a0=alos(d0,prop,propa);
758                                 q=log(d2/d0);
759                                 propa.ak2=mymax(0.0,((d2-d0)*(a1-a0)-(d1-d0)*(a2-a0))/((d2-d0)*log(d1/d0)-(d1-d0)*q));
760                                 wq=propa.aed>=0.0 || propa.ak2>0.0;
761
762                                 if (wq)
763                                 { 
764                                         propa.ak1=(a2-a0-propa.ak2*q)/(d2-d0);
765
766                                         if (propa.ak1<0.0)
767                                         {
768                                                 propa.ak1=0.0;
769                                                 propa.ak2=FORTRAN_DIM(a2,a0)/q;
770
771                                                 if (propa.ak2==0.0)
772                                                         propa.ak1=propa.emd;
773                                         }
774                                 }
775
776                                 else
777                                 {
778                                         propa.ak2=0.0;
779                                         propa.ak1=(a2-a1)/(d2-d1);
780
781                                         if (propa.ak1<=0.0)
782                                                 propa.ak1=propa.emd;
783                                 }
784                         }
785         
786                         else
787                         {
788                                 propa.ak1=(a2-a1)/(d2-d1);
789                                 propa.ak2=0.0;
790
791                                 if (propa.ak1<=0.0)
792                                         propa.ak1=propa.emd;
793                         }
794
795                         propa.ael=a2-propa.ak1*d2-propa.ak2*log(d2);
796                         wlos=true;
797                 }
798
799                 if (prop.dist>0.0)
800                         prop.aref=propa.ael+propa.ak1*prop.dist+propa.ak2*log(prop.dist);
801
802         }
803
804         if (prop.dist<=0.0 || prop.dist>=propa.dlsa)
805         {
806                 if(!wscat)
807                 { 
808                         q=ascat(0.0,prop,propa);
809                         d5=propa.dla+200e3;
810                         d6=d5+200e3;
811                         a6=ascat(d6,prop,propa);
812                         a5=ascat(d5,prop,propa);
813
814                         if (a5<1000.0)
815                         {
816                                 propa.ems=(a6-a5)/200e3;
817                                 propa.dx=mymax(propa.dlsa,mymax(propa.dla+0.3*xae*log(47.7*prop.wn),(a5-propa.aed-propa.ems*d5)/(propa.emd-propa.ems)));
818                                 propa.aes=(propa.emd-propa.ems)*propa.dx+propa.aed;
819                         }
820
821                         else
822                         {
823                                 propa.ems=propa.emd;
824                                 propa.aes=propa.aed;
825                                 propa.dx=10.e6;
826                         }
827
828                         wscat=true;
829                 }
830
831                 if (prop.dist>propa.dx)
832                         prop.aref=propa.aes+propa.ems*prop.dist;
833                 else
834                         prop.aref=propa.aed+propa.emd*prop.dist;
835         }
836
837         prop.aref=mymax(prop.aref,0.0);
838 }
839
840 double curve (double const &c1, double const &c2, double const &x1,
841               double const &x2, double const &x3, double const &de)
842 {
843         /* return (c1+c2/(1.0+pow((de-x2)/x3,2.0)))*pow(de/x1,2.0)/(1.0+pow(de/x1,2.0)); */
844         double temp1, temp2;
845
846         temp1=(de-x2)/x3;
847         temp2=de/x1;
848
849         temp1*=temp1;
850         temp2*=temp2;
851
852         return (c1+c2/(1.0+temp1))*temp2/(1.0+temp2);
853 }
854
855 double avar(double zzt, double zzl, double zzc, prop_type &prop, propv_type &propv)
856 {
857         static  int kdv;
858         static  double dexa, de, vmd, vs0, sgl, sgtm, sgtp, sgtd, tgtd,
859                 gm, gp, cv1, cv2, yv1, yv2, yv3, csm1, csm2, ysm1, ysm2,
860                 ysm3, csp1, csp2, ysp1, ysp2, ysp3, csd1, zd, cfm1, cfm2,
861                 cfm3, cfp1, cfp2, cfp3;
862
863         double bv1[7]={-9.67,-0.62,1.26,-9.21,-0.62,-0.39,3.15};
864         double bv2[7]={12.7,9.19,15.5,9.05,9.19,2.86,857.9};
865         double xv1[7]={144.9e3,228.9e3,262.6e3,84.1e3,228.9e3,141.7e3,2222.e3};
866         double xv2[7]={190.3e3,205.2e3,185.2e3,101.1e3,205.2e3,315.9e3,164.8e3};
867         double xv3[7]={133.8e3,143.6e3,99.8e3,98.6e3,143.6e3,167.4e3,116.3e3};
868         double bsm1[7]={2.13,2.66,6.11,1.98,2.68,6.86,8.51};
869         double bsm2[7]={159.5,7.67,6.65,13.11,7.16,10.38,169.8};
870         double xsm1[7]={762.2e3,100.4e3,138.2e3,139.1e3,93.7e3,187.8e3,609.8e3};
871         double xsm2[7]={123.6e3,172.5e3,242.2e3,132.7e3,186.8e3,169.6e3,119.9e3};
872         double xsm3[7]={94.5e3,136.4e3,178.6e3,193.5e3,133.5e3,108.9e3,106.6e3};
873         double bsp1[7]={2.11,6.87,10.08,3.68,4.75,8.58,8.43};
874         double bsp2[7]={102.3,15.53,9.60,159.3,8.12,13.97,8.19};
875         double xsp1[7]={636.9e3,138.7e3,165.3e3,464.4e3,93.2e3,216.0e3,136.2e3};
876         double xsp2[7]={134.8e3,143.7e3,225.7e3,93.1e3,135.9e3,152.0e3,188.5e3};
877         double xsp3[7]={95.6e3,98.6e3,129.7e3,94.2e3,113.4e3,122.7e3,122.9e3};
878         double bsd1[7]={1.224,0.801,1.380,1.000,1.224,1.518,1.518};
879         double bzd1[7]={1.282,2.161,1.282,20.,1.282,1.282,1.282};
880         double bfm1[7]={1.0,1.0,1.0,1.0,0.92,1.0,1.0};
881         double bfm2[7]={0.0,0.0,0.0,0.0,0.25,0.0,0.0};
882         double bfm3[7]={0.0,0.0,0.0,0.0,1.77,0.0,0.0};
883         double bfp1[7]={1.0,0.93,1.0,0.93,0.93,1.0,1.0};
884         double bfp2[7]={0.0,0.31,0.0,0.19,0.31,0.0,0.0};
885         double bfp3[7]={0.0,2.00,0.0,1.79,2.00,0.0,0.0};
886         static bool ws, w1;
887         double rt=7.8, rl=24.0, avarv, q, vs, zt, zl, zc;
888         double sgt, yr, temp1, temp2;
889         int temp_klim=propv.klim-1;
890
891         if (propv.lvar>0)
892         {
893                 switch (propv.lvar)
894                 {
895                         default:
896                         if (propv.klim<=0 || propv.klim>7)
897                         {
898                                 propv.klim=5;
899                                 temp_klim=4;
900                                 prop.kwx=mymax(prop.kwx,2);
901                         }
902
903                         cv1=bv1[temp_klim];
904                         cv2=bv2[temp_klim];
905                         yv1=xv1[temp_klim];
906                         yv2=xv2[temp_klim];
907                         yv3=xv3[temp_klim];
908                         csm1=bsm1[temp_klim];
909                         csm2=bsm2[temp_klim];
910                         ysm1=xsm1[temp_klim];
911                         ysm2=xsm2[temp_klim];
912                         ysm3=xsm3[temp_klim];
913                         csp1=bsp1[temp_klim];
914                         csp2=bsp2[temp_klim];
915                         ysp1=xsp1[temp_klim];
916                         ysp2=xsp2[temp_klim];
917                         ysp3=xsp3[temp_klim];
918                         csd1=bsd1[temp_klim];
919                         zd=bzd1[temp_klim];
920                         cfm1=bfm1[temp_klim];
921                         cfm2=bfm2[temp_klim];
922                         cfm3=bfm3[temp_klim];
923                         cfp1=bfp1[temp_klim];
924                         cfp2=bfp2[temp_klim];
925                         cfp3=bfp3[temp_klim];
926
927                         case 4:
928                         kdv=propv.mdvar;
929                         ws=kdv>=20;
930
931                         if (ws)
932                                 kdv-=20;
933
934                         w1=kdv>=10;
935
936                         if (w1)
937                                 kdv-=10;
938
939                         if (kdv<0 || kdv>3)
940                         {
941                                 kdv=0;
942                                 prop.kwx=mymax(prop.kwx,2);
943                         }
944
945                         case 3:
946                         q=log(0.133*prop.wn);
947
948                         /* gm=cfm1+cfm2/(pow(cfm3*q,2.0)+1.0); */
949                         /* gp=cfp1+cfp2/(pow(cfp3*q,2.0)+1.0); */
950
951                         gm=cfm1+cfm2/((cfm3*q*cfm3*q)+1.0);
952                         gp=cfp1+cfp2/((cfp3*q*cfp3*q)+1.0);
953
954                         case 2:
955                         dexa=sqrt(18e6*prop.he[0])+sqrt(18e6*prop.he[1])+pow((575.7e12/prop.wn),THIRD);
956
957                         case 1:
958                         if (prop.dist<dexa)
959                                 de=130e3*prop.dist/dexa;
960                         else
961                                 de=130e3+prop.dist-dexa;
962                 }
963
964                 vmd=curve(cv1,cv2,yv1,yv2,yv3,de);
965                 sgtm=curve(csm1,csm2,ysm1,ysm2,ysm3,de)*gm;
966                 sgtp=curve(csp1,csp2,ysp1,ysp2,ysp3,de)*gp;
967                 sgtd=sgtp*csd1;
968                 tgtd=(sgtp-sgtd)*zd;
969
970                 if (w1)
971                         sgl=0.0;
972                 else
973                 {
974                         q=(1.0-0.8*exp(-prop.dist/50e3))*prop.dh*prop.wn;
975                         sgl=10.0*q/(q+13.0);
976                 }
977
978                 if (ws)
979                         vs0=0.0;
980                 else
981                 {
982                         /* vs0=pow(5.0+3.0*exp(-de/100e3),2.0); */
983                         temp1=(5.0+3.0*exp(-de/100e3));
984                         vs0=temp1*temp1;
985
986                 }
987
988                 propv.lvar=0;
989         }
990
991         zt=zzt;
992         zl=zzl;
993         zc=zzc;
994
995         switch (kdv)
996         {
997                 case 0:
998                 zt=zc;
999                 zl=zc;
1000                 break;
1001
1002                 case 1:
1003                 zl=zc;
1004                 break;
1005
1006                 case 2:
1007                 zl=zt;
1008         }
1009
1010         if (fabs(zt)>3.1 || fabs(zl)>3.1 || fabs(zc)>3.1)
1011                 prop.kwx=mymax(prop.kwx,1);
1012
1013         if (zt<0.0)
1014                 sgt=sgtm;
1015
1016         else if (zt<=zd)
1017                 sgt=sgtp;
1018
1019         else
1020                 sgt=sgtd+tgtd/zt;
1021
1022         /* vs=vs0+pow(sgt*zt,2.0)/(rt+zc*zc)+pow(sgl*zl,2.0)/(rl+zc*zc); */
1023
1024         temp1=sgt*zt;
1025         temp2=sgl*zl;
1026
1027         vs=vs0+(temp1*temp1)/(rt+zc*zc)+(temp2*temp2)/(rl+zc*zc);
1028
1029         if (kdv==0)
1030         {
1031                 yr=0.0;
1032                 propv.sgc=sqrt(sgt*sgt+sgl*sgl+vs);
1033         }
1034
1035         else if (kdv==1)
1036         {
1037                 yr=sgt*zt;
1038                 propv.sgc=sqrt(sgl*sgl+vs);
1039         }
1040
1041         else if (kdv==2)
1042         {
1043                 yr=sqrt(sgt*sgt+sgl*sgl)*zt;
1044                 propv.sgc=sqrt(vs);
1045         }
1046
1047         else
1048         {
1049                 yr=sgt*zt+sgl*zl;
1050                 propv.sgc=sqrt(vs);
1051         }
1052
1053         avarv=prop.aref-vmd-yr-propv.sgc*zc;
1054
1055         if (avarv<0.0)
1056                 avarv=avarv*(29.0-avarv)/(29.0-10.0*avarv);
1057
1058         return avarv;
1059 }
1060
1061 void hzns (double pfl[], prop_type &prop)
1062 {
1063         bool wq;
1064         int np;
1065         double xi, za, zb, qc, q, sb, sa;
1066
1067         np=(int)pfl[0];
1068         xi=pfl[1];
1069         za=pfl[2]+prop.hg[0];
1070         zb=pfl[np+2]+prop.hg[1];
1071         qc=0.5*prop.gme;
1072         q=qc*prop.dist;
1073         prop.the[1]=(zb-za)/prop.dist;
1074         prop.the[0]=prop.the[1]-q;
1075         prop.the[1]=-prop.the[1]-q;
1076         prop.dl[0]=prop.dist;
1077         prop.dl[1]=prop.dist;
1078
1079         if (np>=2)
1080         {
1081                 sa=0.0;
1082                 sb=prop.dist;
1083                 wq=true;
1084
1085                 for (int i=1; i<np; i++)
1086                 {
1087                         sa+=xi;
1088                         sb-=xi;
1089                         q=pfl[i+2]-(qc*sa+prop.the[0])*sa-za;
1090
1091                         if (q>0.0)
1092                         {
1093                                 prop.the[0]+=q/sa;
1094                                 prop.dl[0]=sa;
1095                                 wq=false;
1096                         }
1097
1098                         if (!wq)
1099                         {
1100                                 q=pfl[i+2]-(qc*sb+prop.the[1])*sb-zb;
1101
1102                                 if (q>0.0)
1103                                 {
1104                                         prop.the[1]+=q/sb;
1105                                         prop.dl[1]=sb;
1106                                 }
1107                         }
1108                 }
1109         }
1110 }
1111   
1112 void z1sq1 (double z[], const double &x1, const double &x2, double& z0, double& zn)
1113 {
1114         double xn, xa, xb, x, a, b;
1115         int n, ja, jb;
1116
1117         xn=z[0];
1118         xa=int(FORTRAN_DIM(x1/z[1],0.0));
1119         xb=xn-int(FORTRAN_DIM(xn,x2/z[1]));
1120
1121         if (xb<=xa)
1122         {
1123                 xa=FORTRAN_DIM(xa,1.0);
1124                 xb=xn-FORTRAN_DIM(xn,xb+1.0);
1125         }
1126
1127         ja=(int)xa;
1128         jb=(int)xb;
1129         n=jb-ja;
1130         xa=xb-xa;
1131         x=-0.5*xa;
1132         xb+=x;
1133         a=0.5*(z[ja+2]+z[jb+2]);
1134         b=0.5*(z[ja+2]-z[jb+2])*x;
1135
1136         for (int i=2; i<=n; ++i)
1137         {
1138                 ++ja;
1139                 x+=1.0;
1140                 a+=z[ja+2];
1141                 b+=z[ja+2]*x;
1142         }
1143
1144         a/=xa;
1145         b=b*12.0/((xa*xa+2.0)*xa);
1146         z0=a-b*xb;
1147         zn=a+b*(xn-xb);
1148 }
1149
1150 double qtile (const int &nn, double a[], const int &ir)
1151 {
1152         double q=0.0, r; /* q initialization -- KD2BD */
1153         int m, n, i, j, j1=0, i0=0, k;  /* more initializations -- KD2BD */
1154         bool done=false;
1155         bool goto10=true;
1156
1157         m=0;
1158         n=nn;
1159         k=mymin(mymax(0,ir),n);
1160
1161         while (!done)
1162         {
1163                 if (goto10)
1164                 {
1165                         q=a[k];
1166                         i0=m;
1167                         j1=n;
1168                 }
1169
1170                 i=i0;
1171
1172                 while (i<=n && a[i]>=q)
1173                         i++;
1174
1175                 if (i>n)
1176                         i=n;
1177
1178                 j=j1;
1179
1180                 while (j>=m && a[j]<=q)
1181                         j--;
1182
1183                 if (j<m)
1184                         j=m;
1185
1186                 if (i<j)
1187                 {
1188                         r=a[i];
1189                         a[i]=a[j];
1190                         a[j]=r;
1191                         i0=i+1;
1192                         j1=j-1;
1193                         goto10=false;
1194                 }
1195
1196                 else if (i<k)
1197                 {
1198                         a[k]=a[i];
1199                         a[i]=q;
1200                         m=i+1;
1201                         goto10=true;
1202                 }
1203
1204                 else if (j>k)
1205                 {
1206                         a[k]=a[j];
1207                         a[j]=q;
1208                         n=j-1;
1209                         goto10=true;
1210                 }
1211
1212                 else
1213                 done=true;
1214         }
1215
1216         return q;
1217 }
1218
1219 double qerf(const double &z)
1220 {
1221         double b1=0.319381530, b2=-0.356563782, b3=1.781477937;
1222         double b4=-1.821255987, b5=1.330274429;
1223         double rp=4.317008, rrt2pi=0.398942280;
1224         double t, x, qerfv;
1225
1226         x=z;
1227         t=fabs(x);
1228
1229         if (t>=10.0)
1230                 qerfv=0.0;
1231         else
1232         {
1233                 t=rp/(t+rp);
1234                 qerfv=exp(-0.5*x*x)*rrt2pi*((((b5*t+b4)*t+b3)*t+b2)*t+b1)*t;
1235         }
1236
1237         if (x<0.0)
1238                 qerfv=1.0-qerfv;
1239
1240         return qerfv;
1241 }
1242
1243 double d1thx(double pfl[], const double &x1, const double &x2)
1244 {
1245         int np, ka, kb, n, k, j;
1246         double d1thxv, sn, xa, xb;
1247         double *s;
1248
1249         np=(int)pfl[0];
1250         xa=x1/pfl[1];
1251         xb=x2/pfl[1];
1252         d1thxv=0.0;
1253
1254         if (xb-xa<2.0)  // exit out
1255                 return d1thxv;
1256
1257         ka=(int)(0.1*(xb-xa+8.0));
1258         ka=mymin(mymax(4,ka),25);
1259         n=10*ka-5;
1260         kb=n-ka+1;
1261         sn=n-1;
1262         assert((s=new double[n+2])!=0);
1263         s[0]=sn;
1264         s[1]=1.0;
1265         xb=(xb-xa)/sn;
1266         k=(int)(xa+1.0);
1267         xa-=(double)k;
1268
1269         for (j=0; j<n; j++)
1270         {
1271                 while (xa>0.0 && k<np)
1272                 {
1273                         xa-=1.0;
1274                         ++k;
1275                 }
1276
1277                 s[j+2]=pfl[k+2]+(pfl[k+2]-pfl[k+1])*xa;
1278                 xa=xa+xb;
1279         }
1280
1281         z1sq1(s,0.0,sn,xa,xb);
1282         xb=(xb-xa)/sn;
1283
1284         for (j=0; j<n; j++)
1285         {
1286                 s[j+2]-=xa;
1287                 xa=xa+xb;
1288         }
1289
1290         d1thxv=qtile(n-1,s+2,ka-1)-qtile(n-1,s+2,kb-1);
1291         d1thxv/=1.0-0.8*exp(-(x2-x1)/50.0e3);
1292         delete[] s;
1293
1294         return d1thxv;
1295 }
1296
1297 void qlrpfl(double pfl[], int klimx, int mdvarx, prop_type &prop, propa_type &propa, propv_type &propv)
1298 {
1299         int np, j;
1300         double xl[2], q, za, zb, temp;
1301
1302         prop.dist=pfl[0]*pfl[1];
1303         np=(int)pfl[0];
1304         hzns(pfl,prop);
1305
1306         for (j=0; j<2; j++)
1307                 xl[j]=mymin(15.0*prop.hg[j],0.1*prop.dl[j]);
1308
1309         xl[1]=prop.dist-xl[1];
1310         prop.dh=d1thx(pfl,xl[0],xl[1]);
1311
1312         if (prop.dl[0]+prop.dl[1]>1.5*prop.dist)
1313         {
1314                 z1sq1(pfl,xl[0],xl[1],za,zb);
1315                 prop.he[0]=prop.hg[0]+FORTRAN_DIM(pfl[2],za);
1316                 prop.he[1]=prop.hg[1]+FORTRAN_DIM(pfl[np+2],zb);
1317
1318                 for (j=0; j<2; j++)
1319                         prop.dl[j]=sqrt(2.0*prop.he[j]/prop.gme)*exp(-0.07*sqrt(prop.dh/mymax(prop.he[j],5.0)));
1320
1321                 q=prop.dl[0]+prop.dl[1];
1322
1323                 if (q<=prop.dist)
1324                 {
1325                         /* q=pow(prop.dist/q,2.0); */
1326                         temp=prop.dist/q;
1327                         q=temp*temp;
1328
1329                         for (j=0; j<2; j++)
1330                         {
1331                                 prop.he[j]*=q;
1332                                 prop.dl[j]=sqrt(2.0*prop.he[j]/prop.gme)*exp(-0.07*sqrt(prop.dh/mymax(prop.he[j],5.0)));
1333                         }
1334                 }
1335
1336                 for (j=0; j<2; j++)
1337                 {
1338                         q=sqrt(2.0*prop.he[j]/prop.gme);
1339                         prop.the[j]=(0.65*prop.dh*(q/prop.dl[j]-1.0)-2.0*prop.he[j])/q;
1340                 }
1341         }
1342
1343         else
1344         {
1345                 z1sq1(pfl,xl[0],0.9*prop.dl[0],za,q);
1346                 z1sq1(pfl,prop.dist-0.9*prop.dl[1],xl[1],q,zb);
1347                 prop.he[0]=prop.hg[0]+FORTRAN_DIM(pfl[2],za);
1348                 prop.he[1]=prop.hg[1]+FORTRAN_DIM(pfl[np+2],zb);
1349         }
1350
1351         prop.mdp=-1;
1352         propv.lvar=mymax(propv.lvar,3);
1353
1354         if (mdvarx>=0)
1355         {
1356                 propv.mdvar=mdvarx;
1357                 propv.lvar=mymax(propv.lvar,4);
1358         }
1359
1360         if (klimx>0)
1361         {
1362                 propv.klim=klimx;
1363                 propv.lvar=5;
1364         }
1365
1366         lrprop(0.0,prop,propa);
1367 }
1368
1369 double deg2rad(double d)
1370 {
1371         return d*3.1415926535897/180.0;
1372 }
1373
1374 //********************************************************
1375 //* Point-To-Point Mode Calculations                     *
1376 //********************************************************
1377
1378 void point_to_point(double elev[], double tht_m, double rht_m, double eps_dielect, double sgm_conductivity, double eno_ns_surfref, double frq_mhz, int radio_climate, int pol, double conf, double rel, double &dbloss, char *strmode, int &errnum)
1379
1380 /******************************************************************************
1381
1382         pol:
1383                 0-Horizontal, 1-Vertical
1384
1385         radio_climate:
1386                 1-Equatorial, 2-Continental Subtropical,
1387                 3-Maritime Tropical, 4-Desert, 5-Continental Temperate,
1388                 6-Maritime Temperate, Over Land, 7-Maritime Temperate,
1389                 Over Sea
1390
1391         conf, rel: .01 to .99
1392
1393         elev[]: [num points - 1], [delta dist(meters)],
1394                 [height(meters) point 1], ..., [height(meters) point n]
1395
1396         errnum: 0- No Error.
1397                 1- Warning: Some parameters are nearly out of range.
1398                             Results should be used with caution.
1399                 2- Note: Default parameters have been substituted for
1400                          impossible ones.
1401                 3- Warning: A combination of parameters is out of range.
1402                             Results are probably invalid.
1403                 Other-  Warning: Some parameters are out of range.
1404                         Results are probably invalid.
1405
1406 *****************************************************************************/
1407 {
1408         prop_type   prop;
1409         propv_type  propv;
1410         propa_type  propa;
1411         double zsys=0;
1412         double zc, zr;
1413         double eno, enso, q;
1414         long ja, jb, i, np;
1415         double dkm, xkm;
1416         double fs;
1417
1418         prop.hg[0]=tht_m;
1419         prop.hg[1]=rht_m;
1420         propv.klim=radio_climate;
1421         prop.kwx=0;
1422         propv.lvar=5;
1423         prop.mdp=-1;
1424         zc=qerfi(conf);
1425         zr=qerfi(rel);
1426         np=(long)elev[0];
1427         dkm=(elev[1]*elev[0])/1000.0;
1428         xkm=elev[1]/1000.0;
1429         eno=eno_ns_surfref;
1430         enso=0.0;
1431         q=enso;
1432
1433         if (q<=0.0)
1434         {
1435                 ja=(long)(3.0+0.1*elev[0]);  /* KD2BD added (long) */
1436                 jb=np-ja+6;
1437
1438                 for (i=ja-1; i<jb; ++i)
1439                         zsys+=elev[i];
1440
1441                 zsys/=(jb-ja+1);
1442                 q=eno;
1443         }
1444
1445         propv.mdvar=12;
1446         qlrps(frq_mhz,zsys,q,pol,eps_dielect,sgm_conductivity,prop);
1447         qlrpfl(elev,propv.klim,propv.mdvar,prop,propa,propv);
1448         fs=32.45+20.0*log10(frq_mhz)+20.0*log10(prop.dist/1000.0);
1449         q=prop.dist-propa.dla;
1450
1451         if (int(q)<0.0)
1452                 strcpy(strmode,"Line-Of-Sight Mode");
1453         else
1454         {
1455                 if (int(q)==0.0)
1456                         strcpy(strmode,"Single Horizon");
1457
1458                 else if (int(q)>0.0)
1459                         strcpy(strmode,"Double Horizon");
1460
1461                 if (prop.dist<=propa.dlsa || prop.dist <= propa.dx)
1462                         strcat(strmode,", Diffraction Dominant");
1463
1464                 else if (prop.dist>propa.dx)
1465                         strcat(strmode, ", Troposcatter Dominant");
1466         }
1467
1468         dbloss=avar(zr,0.0,zc,prop,propv)+fs;
1469         errnum=prop.kwx;
1470 }
1471
1472 //********************************************************
1473 //* Area Mode Calculations                               *
1474 //********************************************************
1475
1476 void area(long ModVar, double deltaH, double tht_m, double rht_m, double dist_km, int TSiteCriteria, int RSiteCriteria, double eps_dielect, double sgm_conductivity, double eno_ns_surfref, double frq_mhz, int radio_climate, int pol, double pctTime, double pctLoc, double pctConf, double &dbloss, char *strmode, int &errnum)
1477 {
1478         // pol: 0-Horizontal, 1-Vertical
1479         // TSiteCriteria, RSiteCriteria:
1480         //                 0 - random, 1 - careful, 2 - very careful
1481
1482         // radio_climate: 1-Equatorial, 2-Continental Subtropical, 3-Maritime Tropical,
1483         //                4-Desert, 5-Continental Temperate, 6-Maritime Temperate, Over Land,
1484         //                7-Maritime Temperate, Over Sea
1485         // ModVar: 0 - Single: pctConf is "Time/Situation/Location", pctTime, pctLoc not used
1486     //         1 - Individual: pctTime is "Situation/Location", pctConf is "Confidence", pctLoc not used
1487     //         2 - Mobile: pctTime is "Time/Locations (Reliability)", pctConf is "Confidence", pctLoc not used
1488     //         3 - Broadcast: pctTime is "Time", pctLoc is "Location", pctConf is "Confidence"
1489         // pctTime, pctLoc, pctConf: .01 to .99
1490         // errnum: 0- No Error.
1491         //         1- Warning: Some parameters are nearly out of range.
1492         //                     Results should be used with caution.
1493         //         2- Note: Default parameters have been substituted for impossible ones.
1494         //         3- Warning: A combination of parameters is out of range.
1495         //                     Results are probably invalid.
1496         //         Other-  Warning: Some parameters are out of range.
1497         //                          Results are probably invalid.
1498         // NOTE: strmode is not used at this time.
1499
1500         prop_type prop;
1501         propv_type propv;
1502         propa_type propa;
1503         double zt, zl, zc, xlb;
1504         double fs;
1505         long ivar;
1506         double eps, eno, sgm;
1507         long ipol;
1508         int kst[2];
1509
1510         kst[0]=(int)TSiteCriteria;
1511         kst[1]=(int)RSiteCriteria;
1512         zt=qerfi(pctTime/100.0);
1513         zl=qerfi(pctLoc/100.0);
1514         zc=qerfi(pctConf/100.0);
1515         eps=eps_dielect;
1516         sgm=sgm_conductivity;
1517         eno=eno_ns_surfref;
1518         prop.dh=deltaH;
1519         prop.hg[0]=tht_m;
1520         prop.hg[1]=rht_m;
1521         /* propv.klim = (__int32) radio_climate; -KD2BD replaced below */
1522         propv.klim=(long)radio_climate;
1523         prop.ens=eno;
1524         prop.kwx=0;
1525         ivar=(long)ModVar;
1526         ipol=(long)pol;
1527         qlrps(frq_mhz, 0.0, eno, ipol, eps, sgm, prop);
1528         qlra(kst, propv.klim, ivar, prop, propv);
1529
1530         if (propv.lvar<1)
1531                 propv.lvar=1;
1532
1533         lrprop(dist_km*1000.0, prop, propa);
1534         fs=32.45+20.0*log10(frq_mhz)+20.0*log10(prop.dist/1000.0);
1535         xlb=fs+avar(zt, zl, zc, prop, propv);
1536         dbloss=xlb;
1537  
1538         if (prop.kwx==0)
1539                 errnum=0;
1540         else
1541                 errnum=prop.kwx;
1542 }