00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <math.h>
00048 #include "troposphere.h"
00049 #include "constants.h"
00050
00051
00052
00053
00054
00055
00056 #define TROPOSPHERE_K1 (77.604) // K/mbar
00057 #define TROPOSPHERE_K2 (382000.0) // K^2/mbar
00058 #define TROPOSPHERE_RD (287.054) // J/kg/K
00059 #define TROPOSPHERE_GM (9.784) // m/s^2
00060
00061
00062 #define TROPOSPHERE_G (9.80665) // m/s^2
00063
00064
00065 #define TROPOSPHERE_AVERAGE_PRESSURE {1013.25, 1017.25, 1015.75, 1011.75, 1013.00} // mbar
00066 #define TROPOSPHERE_AVERAGE_TEMPERATURE { 299.65, 294.15, 283.15, 272.15, 263.65} // K
00067 #define TROPOSPHERE_AVERAGE_WATER_VAPOR_PRESSURE { 26.31, 21.79, 11.66, 6.78, 4.11} // mbar
00068 #define TROPOSPHERE_AVERAGE_TEMPERATURE_LAPSE_RATE {6.30e-3, 6.05e-3, 5.58e-3, 5.39e-3, 4.53e-3} // K/m
00069 #define TROPOSPHERE_AVERAGE_WATER_VAPOR_LAPSE_RATE { 2.77, 3.15, 2.57, 1.81, 1.55} // dimensionless
00070
00071
00072 #define TROPOSPHERE_SEASONAL_VARIATION_PRESSURE {0.0, -3.75, -2.25, -1.75, -0.50} // mbar
00073 #define TROPOSPHERE_SEASONAL_VARIATION_TEMPERATURE {0.0, 7.00, 11.00, 15.00, 14.50} // K
00074 #define TROPOSPHERE_SEASONAL_VARIATION_WATER_VAPOR_PRESSURE {0.0, 8.85, 7.24, 5.36, 3.39} // mbar
00075 #define TROPOSPHERE_SEASONAL_VARIATION_TEMPERATURE_LAPSE_RATE {0.0, 0.25e-3, 0.32e-3, 0.81e-3, 0.62e-3} // K/m
00076 #define TROPOSPHERE_SEASONAL_VARIATION_WATER_VAPOR_LAPSE_RATE {0.0, 0.33, 0.46, 0.74, 0.30} // dimensionless
00077
00078
00079
00080 static const double P_Table[5] = TROPOSPHERE_AVERAGE_PRESSURE;
00081 static const double dP_Table[5] = TROPOSPHERE_SEASONAL_VARIATION_PRESSURE;
00082 static const double T_Table[5] = TROPOSPHERE_AVERAGE_TEMPERATURE;
00083 static const double dT_Table[5] = TROPOSPHERE_SEASONAL_VARIATION_TEMPERATURE;
00084 static const double E_Table[5] = TROPOSPHERE_AVERAGE_WATER_VAPOR_PRESSURE;
00085 static const double dE_Table[5] = TROPOSPHERE_SEASONAL_VARIATION_WATER_VAPOR_PRESSURE;
00086 static const double B_Table[5] = TROPOSPHERE_AVERAGE_TEMPERATURE_LAPSE_RATE;
00087 static const double dB_Table[5] = TROPOSPHERE_SEASONAL_VARIATION_TEMPERATURE_LAPSE_RATE;
00088 static const double L_Table[5] = TROPOSPHERE_AVERAGE_WATER_VAPOR_LAPSE_RATE;
00089 static const double dL_Table[5] = TROPOSPHERE_SEASONAL_VARIATION_WATER_VAPOR_LAPSE_RATE;
00090
00091
00092
00093
00094
00095
00096 static void _TROPOSPHERE_Interpolate(
00097 const double x1,
00098 const double y1,
00099 const double x2,
00100 const double y2,
00101 const double x,
00102 double* y );
00103
00104
00105
00106
00107 void TROPOSPHERE_GetDayAndWetMappingValues_UsingThe_UNBabc_MappingFunction(
00108 const double elevation,
00109 const double latitude,
00110 const double height,
00111 double* drymap,
00112 double* wetmap )
00113 {
00114 double a,
00115 b,
00116 c,
00117 num,
00118 dem,
00119 sine;
00120
00121 if( elevation > HALFPI )
00122 sine = 1.0;
00123 else if( elevation < 2.0*DEG2RAD )
00124 sine = sin(2.0*DEG2RAD);
00125 else
00126 sine = sin(elevation);
00127
00128
00129 a = (1.18972 - 0.026855*height/1000.0 + 0.10664*cos(latitude)) / 1000.0;
00130 b = 0.0035716;
00131 c = 0.082456;
00132
00133 num = 1.0 + ( a / ( 1.0 + ( b / ( 1.0 + c ) ) ) );
00134 dem = sine + ( a / ( sine + ( b / ( sine + c ) ) ) );
00135
00136 *drymap = num/dem;
00137
00138
00139 a = (0.61120 - 0.035348*height/1000.0 - 0.01526*cos(latitude)) / 1000.0;
00140 b = 0.0018576;
00141 c = 0.062741;
00142
00143 num = 1.0 + ( a / ( 1.0 + ( b / ( 1.0 + c ) ) ) );
00144 dem = sine + ( a / ( sine + ( b / ( sine + c ) ) ) );
00145
00146 *wetmap = num/dem;
00147 }
00148
00149
00150 void TROPOSPHERE_DetermineZenithDelayValues_WAAS_Model(
00151 const double latitude,
00152 const double height,
00153 const unsigned short dayofyear,
00154 double* zenith_dry_delay,
00155 double* zenith_wet_delay
00156 )
00157 {
00158
00159 double P;
00160 double T;
00161 double E;
00162 double B;
00163 double L;
00164
00165 double Dmin;
00166 double d;
00167 double abs_lat;
00168 double common;
00169 double base;
00170 double power;
00171 int i;
00172
00173 abs_lat = fabs(latitude)*RAD2DEG;
00174
00175
00176 if( latitude < 0 )
00177 Dmin = 211.0;
00178 else
00179 Dmin = 28.0;
00180
00181
00182 common = cos( (TWOPI * (dayofyear - Dmin)) / 365.25 );
00183
00184 if( abs_lat <= 15.0 )
00185 {
00186 P = P_Table[0] - dP_Table[0] * common;
00187 T = T_Table[0] - dT_Table[0] * common;
00188 E = E_Table[0] - dE_Table[0] * common;
00189 B = B_Table[0] - dB_Table[0] * common;
00190 L = L_Table[0] - dL_Table[0] * common;
00191 }
00192 else if( abs_lat > 15.0 && abs_lat < 75.0 )
00193 {
00194 i = ((int)abs_lat) / 15;
00195
00196 _TROPOSPHERE_Interpolate( i*15.0, P_Table[i-1], (i+1)*15.0, P_Table[i], abs_lat, &P );
00197 _TROPOSPHERE_Interpolate( i*15.0, dP_Table[i-1], (i+1)*15.0, dP_Table[i], abs_lat, &d );
00198 P = P - d * common;
00199
00200 _TROPOSPHERE_Interpolate( i*15.0, T_Table[i-1], (i+1)*15.0, T_Table[i], abs_lat, &T );
00201 _TROPOSPHERE_Interpolate( i*15.0, dT_Table[i-1], (i+1)*15.0, dT_Table[i], abs_lat, &d );
00202 T = T - d * common;
00203
00204 _TROPOSPHERE_Interpolate( i*15.0, E_Table[i-1], (i+1)*15.0, E_Table[i], abs_lat, &E );
00205 _TROPOSPHERE_Interpolate( i*15.0, dE_Table[i-1], (i+1)*15.0, dE_Table[i], abs_lat, &d );
00206 E = E - d * common;
00207
00208 _TROPOSPHERE_Interpolate( i*15.0, B_Table[i-1], (i+1)*15.0, B_Table[i], abs_lat, &B );
00209 _TROPOSPHERE_Interpolate( i*15.0, dB_Table[i-1], (i+1)*15.0, dB_Table[i], abs_lat, &d );
00210 B = B - d * common;
00211
00212 _TROPOSPHERE_Interpolate( i*15.0, L_Table[i-1], (i+1)*15.0, L_Table[i], abs_lat, &L );
00213 _TROPOSPHERE_Interpolate( i*15.0, dL_Table[i-1], (i+1)*15.0, dL_Table[i], abs_lat, &d );
00214 L = L - d * common;
00215 }
00216 else
00217 {
00218 P = P_Table[4] - dP_Table[4] * common;
00219 T = T_Table[4] - dT_Table[4] * common;
00220 E = E_Table[4] - dE_Table[4] * common;
00221 B = B_Table[4] - dB_Table[4] * common;
00222 L = L_Table[4] - dL_Table[4] * common;
00223 }
00224
00225
00226 *zenith_dry_delay = (1.0e-6 * TROPOSPHERE_K1 * TROPOSPHERE_RD * P) / TROPOSPHERE_GM;
00227
00228
00229 *zenith_wet_delay = (((1.0e-6 * TROPOSPHERE_K2 * TROPOSPHERE_RD) / (TROPOSPHERE_GM * (L + 1.0) - B * TROPOSPHERE_RD)) * (E / T));
00230
00231
00232 base = 1.0 - ((B * height) / T);
00233
00234
00235 power = (TROPOSPHERE_G / (TROPOSPHERE_RD * B));
00236 *zenith_dry_delay = pow(base, power) * (*zenith_dry_delay);
00237
00238
00239 power = (((L + 1.0) * TROPOSPHERE_G) / (TROPOSPHERE_RD * B)) - 1.0;
00240 *zenith_wet_delay = pow(base, power) * (*zenith_wet_delay);
00241 }
00242
00243
00244
00245 void TROPOSPHERE_GetDryAndWetDelay_UsingThe_UNBabc_MappingFunction(
00246 const double zenith_dry_delay,
00247 const double zenith_wet_delay,
00248 const double elevation,
00249 const double latitude,
00250 const double height,
00251 double* drydelay,
00252 double* wetdelay
00253 )
00254 {
00255 double drymap;
00256 double wetmap;
00257
00258 TROPOSPHERE_GetDayAndWetMappingValues_UsingThe_UNBabc_MappingFunction(
00259 elevation,
00260 latitude,
00261 height,
00262 &drymap,
00263 &wetmap );
00264
00265 *drydelay = zenith_dry_delay*drymap;
00266 *wetdelay = zenith_wet_delay*wetmap;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 static void _TROPOSPHERE_Interpolate(
00277 const double x1,
00278 const double y1,
00279 const double x2,
00280 const double y2,
00281 const double x,
00282 double* y )
00283 {
00284 double dx;
00285 dx = x2 - x1;
00286
00287
00288 if( dx < 1e-25 && dx > -1e-25 )
00289 *y = y1;
00290
00291 *y = y1 + (x - x1)/dx * (y2 - y1);
00292 }
00293
00294
00295
00296