| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | /* | 
| 2 |  |  |  |  |  |  | *+ | 
| 3 |  |  |  |  |  |  | *  Name: | 
| 4 |  |  |  |  |  |  | *     palRefro | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | *  Purpose: | 
| 7 |  |  |  |  |  |  | *     Atmospheric refraction for radio and optical/IR wavelengths | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | *  Language: | 
| 10 |  |  |  |  |  |  | *     Starlink ANSI C | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | *  Type of Module: | 
| 13 |  |  |  |  |  |  | *     Library routine | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | *  Invocation: | 
| 16 |  |  |  |  |  |  | *     void palRefro( double zobs, double hm, double tdk, double pmb, | 
| 17 |  |  |  |  |  |  | *                    double rh, double wl, double phi, double tlr, | 
| 18 |  |  |  |  |  |  | *                    double eps, double * ref ) { | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | *  Arguments: | 
| 21 |  |  |  |  |  |  | *     zobs = double (Given) | 
| 22 |  |  |  |  |  |  | *        Observed zenith distance of the source (radian) | 
| 23 |  |  |  |  |  |  | *     hm = double (Given) | 
| 24 |  |  |  |  |  |  | *        Height of the observer above sea level (metre) | 
| 25 |  |  |  |  |  |  | *     tdk = double (Given) | 
| 26 |  |  |  |  |  |  | *        Ambient temperature at the observer (K) | 
| 27 |  |  |  |  |  |  | *     pmb = double (Given) | 
| 28 |  |  |  |  |  |  | *        Pressure at the observer (millibar) | 
| 29 |  |  |  |  |  |  | *     rh = double (Given) | 
| 30 |  |  |  |  |  |  | *        Relative humidity at the observer (range 0-1) | 
| 31 |  |  |  |  |  |  | *     wl = double (Given) | 
| 32 |  |  |  |  |  |  | *        Effective wavelength of the source (micrometre) | 
| 33 |  |  |  |  |  |  | *     phi = double (Given) | 
| 34 |  |  |  |  |  |  | *        Latitude of the observer (radian, astronomical) | 
| 35 |  |  |  |  |  |  | *     tlr = double (Given) | 
| 36 |  |  |  |  |  |  | *        Temperature lapse rate in the troposphere (K/metre) | 
| 37 |  |  |  |  |  |  | *     eps = double (Given) | 
| 38 |  |  |  |  |  |  | *        Precision required to terminate iteration (radian) | 
| 39 |  |  |  |  |  |  | *     ref = double * (Returned) | 
| 40 |  |  |  |  |  |  | *        Refraction: in vacuao ZD minus observed ZD (radian) | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | *  Description: | 
| 43 |  |  |  |  |  |  | *     Calculates the atmospheric refraction for radio and optical/IR | 
| 44 |  |  |  |  |  |  | *     wavelengths. | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | *  Authors: | 
| 47 |  |  |  |  |  |  | *     PTW: Patrick T. Wallace | 
| 48 |  |  |  |  |  |  | *     TIMJ: Tim Jenness (JAC, Hawaii) | 
| 49 |  |  |  |  |  |  | *     {enter_new_authors_here} | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | *  Notes: | 
| 52 |  |  |  |  |  |  | *     - A suggested value for the TLR argument is 0.0065.  The | 
| 53 |  |  |  |  |  |  | *     refraction is significantly affected by TLR, and if studies | 
| 54 |  |  |  |  |  |  | *     of the local atmosphere have been carried out a better TLR | 
| 55 |  |  |  |  |  |  | *     value may be available.  The sign of the supplied TLR value | 
| 56 |  |  |  |  |  |  | *     is ignored. | 
| 57 |  |  |  |  |  |  | * | 
| 58 |  |  |  |  |  |  | *     - A suggested value for the EPS argument is 1E-8.  The result is | 
| 59 |  |  |  |  |  |  | *     usually at least two orders of magnitude more computationally | 
| 60 |  |  |  |  |  |  | *     precise than the supplied EPS value. | 
| 61 |  |  |  |  |  |  | * | 
| 62 |  |  |  |  |  |  | *     - The routine computes the refraction for zenith distances up | 
| 63 |  |  |  |  |  |  | *     to and a little beyond 90 deg using the method of Hohenkerk | 
| 64 |  |  |  |  |  |  | *     and Sinclair (NAO Technical Notes 59 and 63, subsequently adopted | 
| 65 |  |  |  |  |  |  | *     in the Explanatory Supplement, 1992 edition - see section 3.281). | 
| 66 |  |  |  |  |  |  | * | 
| 67 |  |  |  |  |  |  | *     - The code is a development of the optical/IR refraction subroutine | 
| 68 |  |  |  |  |  |  | *     AREF of C.Hohenkerk (HMNAO, September 1984), with extensions to | 
| 69 |  |  |  |  |  |  | *     support the radio case.  Apart from merely cosmetic changes, the | 
| 70 |  |  |  |  |  |  | *     following modifications to the original HMNAO optical/IR refraction | 
| 71 |  |  |  |  |  |  | *     code have been made: | 
| 72 |  |  |  |  |  |  | * | 
| 73 |  |  |  |  |  |  | *     .  The angle arguments have been changed to radians. | 
| 74 |  |  |  |  |  |  | * | 
| 75 |  |  |  |  |  |  | *     .  Any value of ZOBS is allowed (see note 6, below). | 
| 76 |  |  |  |  |  |  | * | 
| 77 |  |  |  |  |  |  | *     .  Other argument values have been limited to safe values. | 
| 78 |  |  |  |  |  |  | * | 
| 79 |  |  |  |  |  |  | *     .  Murray's values for the gas constants have been used | 
| 80 |  |  |  |  |  |  | *        (Vectorial Astrometry, Adam Hilger, 1983). | 
| 81 |  |  |  |  |  |  | * | 
| 82 |  |  |  |  |  |  | *     .  The numerical integration phase has been rearranged for | 
| 83 |  |  |  |  |  |  | *        extra clarity. | 
| 84 |  |  |  |  |  |  | * | 
| 85 |  |  |  |  |  |  | *     .  A better model for Ps(T) has been adopted (taken from | 
| 86 |  |  |  |  |  |  | *        Gill, Atmosphere-Ocean Dynamics, Academic Press, 1982). | 
| 87 |  |  |  |  |  |  | * | 
| 88 |  |  |  |  |  |  | *     .  More accurate expressions for Pwo have been adopted | 
| 89 |  |  |  |  |  |  | *        (again from Gill 1982). | 
| 90 |  |  |  |  |  |  | * | 
| 91 |  |  |  |  |  |  | *     .  The formula for the water vapour pressure, given the | 
| 92 |  |  |  |  |  |  | *        saturation pressure and the relative humidity, is from | 
| 93 |  |  |  |  |  |  | *        Crane (1976), expression 2.5.5. | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | *     .  Provision for radio wavelengths has been added using | 
| 96 |  |  |  |  |  |  | *        expressions devised by A.T.Sinclair, RGO (private | 
| 97 |  |  |  |  |  |  | *        communication 1989).  The refractivity model currently | 
| 98 |  |  |  |  |  |  | *        used is from J.M.Rueger, "Refractive Index Formulae for | 
| 99 |  |  |  |  |  |  | *        Electronic Distance Measurement with Radio and Millimetre | 
| 100 |  |  |  |  |  |  | *        Waves", in Unisurv Report S-68 (2002), School of Surveying | 
| 101 |  |  |  |  |  |  | *        and Spatial Information Systems, University of New South | 
| 102 |  |  |  |  |  |  | *        Wales, Sydney, Australia. | 
| 103 |  |  |  |  |  |  | * | 
| 104 |  |  |  |  |  |  | *     .  The optical refractivity for dry air is from Resolution 3 of | 
| 105 |  |  |  |  |  |  | *        the International Association of Geodesy adopted at the XXIIth | 
| 106 |  |  |  |  |  |  | *        General Assembly in Birmingham, UK, 1999. | 
| 107 |  |  |  |  |  |  | * | 
| 108 |  |  |  |  |  |  | *     .  Various small changes have been made to gain speed. | 
| 109 |  |  |  |  |  |  | * | 
| 110 |  |  |  |  |  |  | *     - The radio refraction is chosen by specifying WL > 100 micrometres. | 
| 111 |  |  |  |  |  |  | *     Because the algorithm takes no account of the ionosphere, the | 
| 112 |  |  |  |  |  |  | *     accuracy deteriorates at low frequencies, below about 30 MHz. | 
| 113 |  |  |  |  |  |  | * | 
| 114 |  |  |  |  |  |  | *     - Before use, the value of ZOBS is expressed in the range +/- pi. | 
| 115 |  |  |  |  |  |  | *     If this ranged ZOBS is -ve, the result REF is computed from its | 
| 116 |  |  |  |  |  |  | *     absolute value before being made -ve to match.  In addition, if | 
| 117 |  |  |  |  |  |  | *     it has an absolute value greater than 93 deg, a fixed REF value | 
| 118 |  |  |  |  |  |  | *     equal to the result for ZOBS = 93 deg is returned, appropriately | 
| 119 |  |  |  |  |  |  | *     signed. | 
| 120 |  |  |  |  |  |  | * | 
| 121 |  |  |  |  |  |  | *     - As in the original Hohenkerk and Sinclair algorithm, fixed values | 
| 122 |  |  |  |  |  |  | *     of the water vapour polytrope exponent, the height of the | 
| 123 |  |  |  |  |  |  | *     tropopause, and the height at which refraction is negligible are | 
| 124 |  |  |  |  |  |  | *     used. | 
| 125 |  |  |  |  |  |  | * | 
| 126 |  |  |  |  |  |  | *     - The radio refraction has been tested against work done by | 
| 127 |  |  |  |  |  |  | *     Iain Coulson, JACH, (private communication 1995) for the | 
| 128 |  |  |  |  |  |  | *     James Clerk Maxwell Telescope, Mauna Kea.  For typical conditions, | 
| 129 |  |  |  |  |  |  | *     agreement at the 0.1 arcsec level is achieved for moderate ZD, | 
| 130 |  |  |  |  |  |  | *     worsening to perhaps 0.5-1.0 arcsec at ZD 80 deg.  At hot and | 
| 131 |  |  |  |  |  |  | *     humid sea-level sites the accuracy will not be as good. | 
| 132 |  |  |  |  |  |  | * | 
| 133 |  |  |  |  |  |  | *     - It should be noted that the relative humidity RH is formally | 
| 134 |  |  |  |  |  |  | *     defined in terms of "mixing ratio" rather than pressures or | 
| 135 |  |  |  |  |  |  | *     densities as is often stated.  It is the mass of water per unit | 
| 136 |  |  |  |  |  |  | *     mass of dry air divided by that for saturated air at the same | 
| 137 |  |  |  |  |  |  | *     temperature and pressure (see Gill 1982). | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | *     - The algorithm is designed for observers in the troposphere. The | 
| 140 |  |  |  |  |  |  | *     supplied temperature, pressure and lapse rate are assumed to be | 
| 141 |  |  |  |  |  |  | *     for a point in the troposphere and are used to define a model | 
| 142 |  |  |  |  |  |  | *     atmosphere with the tropopause at 11km altitude and a constant | 
| 143 |  |  |  |  |  |  | *     temperature above that.  However, in practice, the refraction | 
| 144 |  |  |  |  |  |  | *     values returned for stratospheric observers, at altitudes up to | 
| 145 |  |  |  |  |  |  | *     25km, are quite usable. | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | *  History: | 
| 148 |  |  |  |  |  |  | *     2012-08-24 (TIMJ): | 
| 149 |  |  |  |  |  |  | *        Initial version, direct port of SLA Fortran source. | 
| 150 |  |  |  |  |  |  | *        Adapted with permission from the Fortran SLALIB library. | 
| 151 |  |  |  |  |  |  | *     {enter_further_changes_here} | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | *  Copyright: | 
| 154 |  |  |  |  |  |  | *     Copyright (C) 2005 Patrick T. Wallace | 
| 155 |  |  |  |  |  |  | *     Copyright (C) 2012 Science and Technology Facilities Council. | 
| 156 |  |  |  |  |  |  | *     All Rights Reserved. | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | *  Licence: | 
| 159 |  |  |  |  |  |  | *     This program is free software; you can redistribute it and/or | 
| 160 |  |  |  |  |  |  | *     modify it under the terms of the GNU General Public License as | 
| 161 |  |  |  |  |  |  | *     published by the Free Software Foundation; either version 3 of | 
| 162 |  |  |  |  |  |  | *     the License, or (at your option) any later version. | 
| 163 |  |  |  |  |  |  | * | 
| 164 |  |  |  |  |  |  | *     This program is distributed in the hope that it will be | 
| 165 |  |  |  |  |  |  | *     useful, but WITHOUT ANY WARRANTY; without even the implied | 
| 166 |  |  |  |  |  |  | *     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | 
| 167 |  |  |  |  |  |  | *     PURPOSE. See the GNU General Public License for more details. | 
| 168 |  |  |  |  |  |  | * | 
| 169 |  |  |  |  |  |  | *     You should have received a copy of the GNU General Public License | 
| 170 |  |  |  |  |  |  | *     along with this program; if not, write to the Free Software | 
| 171 |  |  |  |  |  |  | *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | 
| 172 |  |  |  |  |  |  | *     MA 02110-1301, USA. | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | *  Bugs: | 
| 175 |  |  |  |  |  |  | *     {note_any_bugs_here} | 
| 176 |  |  |  |  |  |  | *- | 
| 177 |  |  |  |  |  |  | */ | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  | #include | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | #include "pal.h" | 
| 182 |  |  |  |  |  |  | #include "pal1.h" | 
| 183 |  |  |  |  |  |  | #include "palmac.h" | 
| 184 |  |  |  |  |  |  |  | 
| 185 | 25 |  |  |  |  |  | void palRefro( double zobs, double hm, double tdk, double pmb, | 
| 186 |  |  |  |  |  |  | double rh, double wl, double phi, double tlr, | 
| 187 |  |  |  |  |  |  | double eps, double * ref ) { | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | /* | 
| 190 |  |  |  |  |  |  | *  Fixed parameters | 
| 191 |  |  |  |  |  |  | */ | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | /*  93 degrees in radians */ | 
| 194 |  |  |  |  |  |  | const double D93 = 1.623156204; | 
| 195 |  |  |  |  |  |  | /*  Universal gas constant */ | 
| 196 |  |  |  |  |  |  | const double GCR = 8314.32; | 
| 197 |  |  |  |  |  |  | /*  Molecular weight of dry air */ | 
| 198 |  |  |  |  |  |  | const double DMD = 28.9644; | 
| 199 |  |  |  |  |  |  | /*  Molecular weight of water vapour */ | 
| 200 |  |  |  |  |  |  | const double DMW = 18.0152; | 
| 201 |  |  |  |  |  |  | /*  Mean Earth radius (metre) */ | 
| 202 |  |  |  |  |  |  | const double S = 6378120.; | 
| 203 |  |  |  |  |  |  | /*  Exponent of temperature dependence of water vapour pressure */ | 
| 204 |  |  |  |  |  |  | const double DELTA = 18.36; | 
| 205 |  |  |  |  |  |  | /*  Height of tropopause (metre) */ | 
| 206 |  |  |  |  |  |  | const double HT = 11000.; | 
| 207 |  |  |  |  |  |  | /*  Upper limit for refractive effects (metre) */ | 
| 208 |  |  |  |  |  |  | const double HS = 80000.; | 
| 209 |  |  |  |  |  |  | /*  Numerical integration: maximum number of strips. */ | 
| 210 |  |  |  |  |  |  | const int ISMAX=16384l; | 
| 211 |  |  |  |  |  |  |  | 
| 212 |  |  |  |  |  |  | /* Local variables */ | 
| 213 |  |  |  |  |  |  | int is, k, n, i, j; | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | int optic, loop; /* booleans */ | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | double zobs1,zobs2,hmok,tdkok,pmbok,rhok,wlok,alpha, | 
| 218 |  |  |  |  |  |  | tol,wlsq,gb,a,gamal,gamma,gamm2,delm2, | 
| 219 |  |  |  |  |  |  | tdc,psat,pwo,w, | 
| 220 |  |  |  |  |  |  | c1,c2,c3,c4,c5,c6,r0,tempo,dn0,rdndr0,sk0,f0, | 
| 221 |  |  |  |  |  |  | rt,tt,dnt,rdndrt,sine,zt,ft,dnts,rdndrp,zts,fts, | 
| 222 |  |  |  |  |  |  | rs,dns,rdndrs,zs,fs,refold,z0,zrange,fb,ff,fo,fe, | 
| 223 |  |  |  |  |  |  | h,r,sz,rg,dr,tg,dn,rdndr,t,f,refp,reft; | 
| 224 |  |  |  |  |  |  |  | 
| 225 |  |  |  |  |  |  | /*  The refraction integrand */ | 
| 226 |  |  |  |  |  |  | #define refi(DN,RDNDR) RDNDR/(DN+RDNDR) | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  | /*  Transform ZOBS into the normal range. */ | 
| 229 | 25 |  |  |  |  |  | zobs1 = palDrange(zobs); | 
| 230 | 25 | 50 |  |  |  |  | zobs2 = DMIN(fabs(zobs1),D93); | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | /*  keep other arguments within safe bounds. */ | 
| 233 | 25 | 50 |  |  |  |  | hmok = DMIN(DMAX(hm,-1e3),HS); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 234 | 25 | 50 |  |  |  |  | tdkok = DMIN(DMAX(tdk,100.0),500.0); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 235 | 25 | 50 |  |  |  |  | pmbok = DMIN(DMAX(pmb,0.0),10000.0); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 236 | 25 | 50 |  |  |  |  | rhok = DMIN(DMAX(rh,0.0),1.0); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 237 | 25 | 50 |  |  |  |  | wlok = DMAX(wl,0.1); | 
| 238 | 25 | 50 |  |  |  |  | alpha = DMIN(DMAX(fabs(tlr),0.001),0.01); | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | /*  tolerance for iteration. */ | 
| 241 | 25 | 100 |  |  |  |  | tol = DMIN(DMAX(fabs(eps),1e-12),0.1)/2.0; | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 242 |  |  |  |  |  |  |  | 
| 243 |  |  |  |  |  |  | /*  decide whether optical/ir or radio case - switch at 100 microns. */ | 
| 244 |  |  |  |  |  |  | optic = wlok < 100.0; | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | /*  set up model atmosphere parameters defined at the observer. */ | 
| 247 | 25 |  |  |  |  |  | wlsq = wlok*wlok; | 
| 248 | 25 |  |  |  |  |  | gb = 9.784*(1.0-0.0026*cos(phi+phi)-0.00000028*hmok); | 
| 249 | 25 | 100 |  |  |  |  | if (optic) { | 
| 250 | 20 |  |  |  |  |  | a = (287.6155+(1.62887+0.01360/wlsq)/wlsq) * 273.15e-6/1013.25; | 
| 251 |  |  |  |  |  |  | } else { | 
| 252 |  |  |  |  |  |  | a = 77.6890e-6; | 
| 253 |  |  |  |  |  |  | } | 
| 254 | 25 |  |  |  |  |  | gamal = (gb*DMD)/GCR; | 
| 255 | 25 |  |  |  |  |  | gamma = gamal/alpha; | 
| 256 | 25 |  |  |  |  |  | gamm2 = gamma-2.0; | 
| 257 |  |  |  |  |  |  | delm2 = DELTA-2.0; | 
| 258 | 25 |  |  |  |  |  | tdc = tdkok-273.15; | 
| 259 | 50 |  |  |  |  |  | psat = pow(10.0,(0.7859+0.03477*tdc)/(1.0+0.00412*tdc)) * | 
| 260 | 25 |  |  |  |  |  | (1.0+pmbok*(4.5e-6+6.0e-10*tdc*tdc)); | 
| 261 | 25 | 50 |  |  |  |  | if (pmbok > 0.0) { | 
| 262 | 25 |  |  |  |  |  | pwo = rhok*psat/(1.0-(1.0-rhok)*psat/pmbok); | 
| 263 |  |  |  |  |  |  | } else { | 
| 264 |  |  |  |  |  |  | pwo = 0.0; | 
| 265 |  |  |  |  |  |  | } | 
| 266 | 25 |  |  |  |  |  | w = pwo*(1.0-DMW/DMD)*gamma/(DELTA-gamma); | 
| 267 | 25 |  |  |  |  |  | c1 = a*(pmbok+w)/tdkok; | 
| 268 | 25 | 100 |  |  |  |  | if (optic) { | 
| 269 | 20 |  |  |  |  |  | c2 = (a*w+11.2684e-6*pwo)/tdkok; | 
| 270 |  |  |  |  |  |  | } else { | 
| 271 | 5 |  |  |  |  |  | c2 = (a*w+6.3938e-6*pwo)/tdkok; | 
| 272 |  |  |  |  |  |  | } | 
| 273 | 25 |  |  |  |  |  | c3 = (gamma-1.0)*alpha*c1/tdkok; | 
| 274 | 25 |  |  |  |  |  | c4 = (DELTA-1.0)*alpha*c2/tdkok; | 
| 275 | 25 | 100 |  |  |  |  | if (optic) { | 
| 276 |  |  |  |  |  |  | c5 = 0.0; | 
| 277 |  |  |  |  |  |  | c6 = 0.0; | 
| 278 |  |  |  |  |  |  | } else { | 
| 279 | 5 |  |  |  |  |  | c5 = 375463e-6*pwo/tdkok; | 
| 280 | 5 |  |  |  |  |  | c6 = c5*delm2*alpha/(tdkok*tdkok); | 
| 281 |  |  |  |  |  |  | } | 
| 282 |  |  |  |  |  |  |  | 
| 283 |  |  |  |  |  |  | /*  conditions at the observer. */ | 
| 284 | 25 |  |  |  |  |  | r0 = S+hmok; | 
| 285 | 25 |  |  |  |  |  | pal1Atmt(r0,tdkok,alpha,gamm2,delm2,c1,c2,c3,c4,c5,c6, | 
| 286 |  |  |  |  |  |  | r0,&tempo,&dn0,&rdndr0); | 
| 287 | 25 |  |  |  |  |  | sk0 = dn0*r0*sin(zobs2); | 
| 288 | 25 |  |  |  |  |  | f0 = refi(dn0,rdndr0); | 
| 289 |  |  |  |  |  |  |  | 
| 290 |  |  |  |  |  |  | /*  conditions in the troposphere at the tropopause. */ | 
| 291 | 25 | 50 |  |  |  |  | rt = S+DMAX(HT,hmok); | 
| 292 | 25 |  |  |  |  |  | pal1Atmt(r0,tdkok,alpha,gamm2,delm2,c1,c2,c3,c4,c5,c6, | 
| 293 |  |  |  |  |  |  | rt,&tt,&dnt,&rdndrt); | 
| 294 | 25 |  |  |  |  |  | sine = sk0/(rt*dnt); | 
| 295 | 25 | 50 |  |  |  |  | zt = atan2(sine,sqrt(DMAX(1.0-sine*sine,0.0))); | 
| 296 | 25 |  |  |  |  |  | ft = refi(dnt,rdndrt); | 
| 297 |  |  |  |  |  |  |  | 
| 298 |  |  |  |  |  |  | /*  conditions in the stratosphere at the tropopause. */ | 
| 299 | 25 |  |  |  |  |  | pal1Atms(rt,tt,dnt,gamal,rt,&dnts,&rdndrp); | 
| 300 | 25 |  |  |  |  |  | sine = sk0/(rt*dnts); | 
| 301 | 25 | 50 |  |  |  |  | zts = atan2(sine,sqrt(DMAX(1.0-sine*sine,0.0))); | 
| 302 | 25 |  |  |  |  |  | fts = refi(dnts,rdndrp); | 
| 303 |  |  |  |  |  |  |  | 
| 304 |  |  |  |  |  |  | /*  conditions at the stratosphere limit. */ | 
| 305 |  |  |  |  |  |  | rs = S+HS; | 
| 306 | 25 |  |  |  |  |  | pal1Atms(rt,tt,dnt,gamal,rs,&dns,&rdndrs); | 
| 307 | 25 |  |  |  |  |  | sine = sk0/(rs*dns); | 
| 308 | 25 | 50 |  |  |  |  | zs = atan2(sine,sqrt(DMAX(1.0-sine*sine,0.0))); | 
| 309 | 25 |  |  |  |  |  | fs = refi(dns,rdndrs); | 
| 310 |  |  |  |  |  |  |  | 
| 311 |  |  |  |  |  |  | /*  variable initialization to avoid compiler warning. */ | 
| 312 |  |  |  |  |  |  | reft = 0.0; | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | /*  integrate the refraction integral in two parts;  first in the | 
| 315 |  |  |  |  |  |  | *  troposphere (k=1), then in the stratosphere (k=2). */ | 
| 316 |  |  |  |  |  |  |  | 
| 317 | 75 | 100 |  |  |  |  | for (k=1; k<=2; k++) { | 
| 318 |  |  |  |  |  |  |  | 
| 319 |  |  |  |  |  |  | /*     initialize previous refraction to ensure at least two iterations. */ | 
| 320 |  |  |  |  |  |  | refold = 1.0; | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | /*     start off with 8 strips. */ | 
| 323 |  |  |  |  |  |  | is = 8; | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | /*     start z, z range, and start and end values. */ | 
| 326 | 50 | 100 |  |  |  |  | if (k==1) { | 
| 327 |  |  |  |  |  |  | z0 = zobs2; | 
| 328 | 25 |  |  |  |  |  | zrange = zt-z0; | 
| 329 |  |  |  |  |  |  | fb = f0; | 
| 330 |  |  |  |  |  |  | ff = ft; | 
| 331 |  |  |  |  |  |  | } else { | 
| 332 |  |  |  |  |  |  | z0 = zts; | 
| 333 | 25 |  |  |  |  |  | zrange = zs-z0; | 
| 334 |  |  |  |  |  |  | fb = fts; | 
| 335 |  |  |  |  |  |  | ff = fs; | 
| 336 |  |  |  |  |  |  | } | 
| 337 |  |  |  |  |  |  |  | 
| 338 |  |  |  |  |  |  | /*     sums of odd and even values. */ | 
| 339 |  |  |  |  |  |  | fo = 0.0; | 
| 340 |  |  |  |  |  |  | fe = 0.0; | 
| 341 |  |  |  |  |  |  |  | 
| 342 |  |  |  |  |  |  | /*     first time through the loop we have to do every point. */ | 
| 343 |  |  |  |  |  |  | n = 1; | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | /*     start of iteration loop (terminates at specified precision). */ | 
| 346 |  |  |  |  |  |  | loop = 1; | 
| 347 | 289 | 100 |  |  |  |  | while (loop) { | 
| 348 |  |  |  |  |  |  |  | 
| 349 |  |  |  |  |  |  | /*        strip width. */ | 
| 350 | 239 |  |  |  |  |  | h = zrange/((double)is); | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | /*        initialize distance from earth centre for quadrature pass. */ | 
| 353 | 239 | 100 |  |  |  |  | if (k == 1) { | 
| 354 |  |  |  |  |  |  | r = r0; | 
| 355 |  |  |  |  |  |  | } else { | 
| 356 |  |  |  |  |  |  | r = rt; | 
| 357 |  |  |  |  |  |  | } | 
| 358 |  |  |  |  |  |  |  | 
| 359 |  |  |  |  |  |  | /*        one pass (no need to compute evens after first time). */ | 
| 360 | 14461 | 100 |  |  |  |  | for (i=1; i | 
| 361 |  |  |  |  |  |  |  | 
| 362 |  |  |  |  |  |  | /*           sine of observed zenith distance. */ | 
| 363 | 14222 |  |  |  |  |  | sz = sin(z0+h*(double)(i)); | 
| 364 |  |  |  |  |  |  |  | 
| 365 |  |  |  |  |  |  | /*           find r (to the nearest metre, maximum four iterations). */ | 
| 366 | 14222 | 50 |  |  |  |  | if (sz > 1e-20) { | 
| 367 | 14222 |  |  |  |  |  | w = sk0/sz; | 
| 368 |  |  |  |  |  |  | rg = r; | 
| 369 |  |  |  |  |  |  | dr = 1.0e6; | 
| 370 |  |  |  |  |  |  | j = 0; | 
| 371 | 44274 | 100 |  |  |  |  | while ( fabs(dr) > 1.0 && j < 4 ) { | 
|  |  | 50 |  |  |  |  |  | 
| 372 | 30052 |  |  |  |  |  | j++; | 
| 373 | 30052 | 100 |  |  |  |  | if (k==1) { | 
| 374 | 3662 |  |  |  |  |  | pal1Atmt(r0,tdkok,alpha,gamm2,delm2, | 
| 375 |  |  |  |  |  |  | c1,c2,c3,c4,c5,c6,rg,&tg,&dn,&rdndr); | 
| 376 |  |  |  |  |  |  | } else { | 
| 377 | 26390 |  |  |  |  |  | pal1Atms(rt,tt,dnt,gamal,rg,&dn,&rdndr); | 
| 378 |  |  |  |  |  |  | } | 
| 379 | 30052 |  |  |  |  |  | dr = (rg*dn-w)/(dn+rdndr); | 
| 380 | 30052 |  |  |  |  |  | rg = rg-dr; | 
| 381 |  |  |  |  |  |  | } | 
| 382 |  |  |  |  |  |  | r = rg; | 
| 383 |  |  |  |  |  |  | } | 
| 384 |  |  |  |  |  |  |  | 
| 385 |  |  |  |  |  |  | /*           find the refractive index and integrand at r. */ | 
| 386 | 14222 | 100 |  |  |  |  | if (k==1) { | 
| 387 | 1575 |  |  |  |  |  | pal1Atmt(r0,tdkok,alpha,gamm2,delm2, | 
| 388 |  |  |  |  |  |  | c1,c2,c3,c4,c5,c6,r,&t,&dn,&rdndr); | 
| 389 |  |  |  |  |  |  | } else { | 
| 390 | 12647 |  |  |  |  |  | pal1Atms(rt,tt,dnt,gamal,r,&dn,&rdndr); | 
| 391 |  |  |  |  |  |  | } | 
| 392 | 14222 |  |  |  |  |  | f = refi(dn,rdndr); | 
| 393 |  |  |  |  |  |  |  | 
| 394 |  |  |  |  |  |  | /*           accumulate odd and (first time only) even values. */ | 
| 395 | 14222 | 100 |  |  |  |  | if (n==1 && i%2 == 0) { | 
|  |  | 100 |  |  |  |  |  | 
| 396 | 150 |  |  |  |  |  | fe += f; | 
| 397 |  |  |  |  |  |  | } else { | 
| 398 | 14072 |  |  |  |  |  | fo += f; | 
| 399 |  |  |  |  |  |  | } | 
| 400 |  |  |  |  |  |  | } | 
| 401 |  |  |  |  |  |  |  | 
| 402 |  |  |  |  |  |  | /*        evaluate the integrand using simpson's rule. */ | 
| 403 | 239 |  |  |  |  |  | refp = h*(fb+4.0*fo+2.0*fe+ff)/3.0; | 
| 404 |  |  |  |  |  |  |  | 
| 405 |  |  |  |  |  |  | /*        has the required precision been achieved (or can't be)? */ | 
| 406 | 239 | 100 |  |  |  |  | if (fabs(refp-refold) > tol && is < ISMAX) { | 
|  |  | 50 |  |  |  |  |  | 
| 407 |  |  |  |  |  |  |  | 
| 408 |  |  |  |  |  |  | /*           no: prepare for next iteration.*/ | 
| 409 |  |  |  |  |  |  |  | 
| 410 |  |  |  |  |  |  | /*           save current value for convergence test. */ | 
| 411 |  |  |  |  |  |  | refold = refp; | 
| 412 |  |  |  |  |  |  |  | 
| 413 |  |  |  |  |  |  | /*           double the number of strips. */ | 
| 414 | 189 |  |  |  |  |  | is += is; | 
| 415 |  |  |  |  |  |  |  | 
| 416 |  |  |  |  |  |  | /*           sum of all current values = sum of next pass's even values. */ | 
| 417 | 189 |  |  |  |  |  | fe += fo; | 
| 418 |  |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | /*           prepare for new odd values. */ | 
| 420 |  |  |  |  |  |  | fo = 0.0; | 
| 421 |  |  |  |  |  |  |  | 
| 422 |  |  |  |  |  |  | /*           skip even values next time. */ | 
| 423 | 189 |  |  |  |  |  | n = 2; | 
| 424 |  |  |  |  |  |  | } else { | 
| 425 |  |  |  |  |  |  |  | 
| 426 |  |  |  |  |  |  | /*           yes: save troposphere component and terminate the loop. */ | 
| 427 | 239 | 100 |  |  |  |  | if (k==1) reft = refp; | 
| 428 |  |  |  |  |  |  | loop = 0; | 
| 429 |  |  |  |  |  |  | } | 
| 430 |  |  |  |  |  |  | } | 
| 431 |  |  |  |  |  |  | } | 
| 432 |  |  |  |  |  |  |  | 
| 433 |  |  |  |  |  |  | /*  result. */ | 
| 434 | 25 |  |  |  |  |  | *ref = reft+refp; | 
| 435 | 25 | 50 |  |  |  |  | if (zobs1 < 0.0) *ref = -(*ref); | 
| 436 |  |  |  |  |  |  |  | 
| 437 | 25 |  |  |  |  |  | } |