#include "slalib.h" #include "slamac.h" void slaRefv ( double vu[3], double refa, double refb, double vr[3] ) /* ** - - - - - - - - ** s l a R e f v ** - - - - - - - - ** ** Adjust an unrefracted Cartesian vector to include the effect of ** atmospheric refraction, using the simple A tan z + B tan^3 z ** model. ** ** Given: ** vu double unrefracted position of the source (az/el 3-vector) ** refa double A: tan z coefficient (radian) ** refb double B: tan^3 z coefficient (radian) ** ** Returned: ** *vr double refracted position of the source (az/el 3-vector) ** ** Notes: ** ** 1 This routine applies the adjustment for refraction in the ** opposite sense to the usual one - it takes an unrefracted ** (in vacuo) position and produces an observed (refracted) ** position, whereas the A tan Z + B tan^3 Z model strictly ** applies to the case where an observed position is to have the ** refraction removed. The unrefracted to refracted case is ** harder, and requires an inverted form of the text-book ** refraction models; the algorithm used here is equivalent to ** one iteration of the Newton-Raphson method applied to the above ** formula. ** ** 2 Though optimized for speed rather than precision, the present ** routine achieves consistency with the refracted-to-unrefracted ** A tan Z + B tan^3 Z model at better than 1 microarcsecond within ** 30 degrees of the zenith and remains within 1 milliarcsecond to ** beyond ZD 70 degrees. The inherent accuracy of the model is, of ** course, far worse than this - see the documentation for slaRefco ** for more information. ** ** 3 At low elevations (below about 3 degrees) the refraction ** correction is held back to prevent arithmetic problems and ** wildly wrong results. Over a wide range of observer heights ** and corresponding temperatures and pressures, the following ** levels of accuracy (arcsec) are achieved, relative to numerical ** integration through a model atmosphere: ** ** ZD error ** ** 80 0.4 ** 81 0.8 ** 82 1.6 ** 83 3 ** 84 7 ** 85 17 ** 86 45 ** 87 150 ** 88 340 ** 89 620 ** 90 1100 ** 91 1900 } relevant only to ** 92 3200 } high-elevation sites ** ** 4 See also the routine slaRefz, which performs the adjustment to ** the zenith distance rather than in Cartesian Az/El coordinates. ** The present routine is faster than slaRefz and, except very low down, ** is equally accurate for all practical purposes. However, beyond ** about ZD 84 degrees slaRefz should be used, and for the utmost ** accuracy iterative use of slaRefro should be considered. ** ** Last revision: 4 June 1997 ** ** Copyright P.T.Wallace. All rights reserved. */ { double x, y, z1, z, zsq, rsq, r, wb, wt, d, cd, f; /* Initial estimate = unrefracted vector */ x = vu[0]; y = vu[1]; z1 = vu[2]; /* Keep correction approximately constant below about 3 deg elevation */ z = gmax ( z1, 0.05 ); /* One Newton-Raphson iteration */ zsq = z * z; rsq = x * x + y * y; r = sqrt ( rsq ); wb = refb * rsq / zsq; wt = ( refa + wb ) / ( 1.0 + ( refa + 3.0 * wb ) * ( zsq + rsq ) / zsq ); d = wt * r / z; cd = 1.0 - d * d / 2.0; f = cd * ( 1.0 - wt ); /* Post-refraction x,y,z */ vr[0] = x * f; vr[1] = y * f; vr[2] = cd * ( z + d * r ) + ( z1 - z ); }