00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00034
00035
00036
00037
00038 #include <cmath>
00039 #include "auto_md.h"
00040 #include "interpolation.h"
00041 #include "refraction.h"
00042 #include "special_interp.h"
00043
00044 extern const Numeric DEG2RAD;
00045 extern const Numeric RAD2DEG;
00046
00047
00048
00049
00050
00051
00052
00053
00055
00082 void get_refr_index_1d(
00083 Workspace& ws,
00084 Numeric& refr_index,
00085 Numeric& a_pressure,
00086 Numeric& a_temperature,
00087 Vector& a_vmr_list,
00088 const Agenda& refr_index_agenda,
00089 ConstVectorView p_grid,
00090 const Numeric& r_geoid,
00091 ConstVectorView z_field,
00092 ConstVectorView t_field,
00093 ConstMatrixView vmr_field,
00094 const Numeric& r )
00095 {
00096
00097 ArrayOfGridPos gp(1);
00098 gridpos( gp, z_field, Vector( 1, r - r_geoid ) );
00099
00100
00101 Matrix itw(1,2);
00102 interpweights( itw, gp );
00103
00104
00105 Vector dummy(1);
00106 itw2p( dummy, p_grid, gp, itw );
00107 a_pressure = dummy[0];
00108
00109
00110 interp( dummy, itw, t_field, gp );
00111 a_temperature = dummy[0];
00112
00113
00114 const Index ns = vmr_field.nrows();
00115
00116 a_vmr_list.resize(ns);
00117
00118 for( Index is=0; is<ns; is++ )
00119 {
00120 interp( dummy, itw, vmr_field(is,joker), gp );
00121 a_vmr_list[is] = dummy[0];
00122 }
00123
00124 refr_index_agendaExecute( ws,
00125 refr_index, a_pressure, a_temperature, a_vmr_list,
00126 refr_index_agenda );
00127 }
00128
00129
00130
00132
00162 void get_refr_index_2d(
00163 Workspace& ws,
00164 Numeric& refr_index,
00165 Numeric& a_pressure,
00166 Numeric& a_temperature,
00167 Vector& a_vmr_list,
00168 const Agenda& refr_index_agenda,
00169 ConstVectorView p_grid,
00170 ConstVectorView lat_grid,
00171 ConstVectorView r_geoid,
00172 ConstMatrixView z_field,
00173 ConstMatrixView t_field,
00174 ConstTensor3View vmr_field,
00175 const Numeric& r,
00176 const Numeric& lat )
00177 {
00178
00179 const Index np = p_grid.nelem();
00180 Vector z_grid(np);
00181 ArrayOfGridPos gp_lat(1);
00182
00183 gridpos( gp_lat, lat_grid, lat );
00184 z_at_lat_2d( z_grid, p_grid, lat_grid, z_field, gp_lat[0] );
00185
00186
00187 Matrix itw(1,2);
00188 Vector dummy(1);
00189 interpweights( itw, gp_lat );
00190 interp( dummy, itw, r_geoid, gp_lat );
00191 const Numeric rgeoid = dummy[0];
00192
00193
00194 ArrayOfGridPos gp_p(1);
00195 gridpos( gp_p, z_grid, Vector( 1, r - rgeoid ) );
00196
00197
00198 interpweights( itw, gp_p );
00199
00200
00201 itw2p( dummy, p_grid, gp_p, itw );
00202 a_pressure = dummy[0];
00203
00204
00205 itw.resize(1,4);
00206 interpweights( itw, gp_p, gp_lat );
00207 interp( dummy, itw, t_field, gp_p, gp_lat );
00208 a_temperature = dummy[0];
00209
00210
00211 const Index ns = vmr_field.npages();
00212
00213 a_vmr_list.resize(ns);
00214
00215 for( Index is=0; is<ns; is++ )
00216 {
00217 interp( dummy, itw, vmr_field(is,joker,joker), gp_p, gp_lat );
00218 a_vmr_list[is] = dummy[0];
00219 }
00220
00221 refr_index_agendaExecute( ws,
00222 refr_index, a_pressure, a_temperature, a_vmr_list,
00223 refr_index_agenda );
00224 }
00225
00226
00227
00256 void get_refr_index_3d(
00257 Workspace& ws,
00258 Numeric& refr_index,
00259 Numeric& a_pressure,
00260 Numeric& a_temperature,
00261 Vector& a_vmr_list,
00262 const Agenda& refr_index_agenda,
00263 ConstVectorView p_grid,
00264 ConstVectorView lat_grid,
00265 ConstVectorView lon_grid,
00266 ConstMatrixView r_geoid,
00267 ConstTensor3View z_field,
00268 ConstTensor3View t_field,
00269 ConstTensor4View vmr_field,
00270 const Numeric& r,
00271 const Numeric& lat,
00272 const Numeric& lon )
00273 {
00274
00275 const Index np = p_grid.nelem();
00276 Vector z_grid(np);
00277 ArrayOfGridPos gp_lat(1), gp_lon(1);
00278
00279 gridpos( gp_lat, lat_grid, lat );
00280 gridpos( gp_lon, lon_grid, lon );
00281 z_at_latlon( z_grid, p_grid, lat_grid, lon_grid, z_field,
00282 gp_lat[0], gp_lon[0] );
00283
00284
00285 Matrix itw(1,4);
00286 Vector dummy(1);
00287 interpweights( itw, gp_lat, gp_lon );
00288 interp( dummy, itw, r_geoid, gp_lat, gp_lon );
00289 const Numeric rgeoid = dummy[0];
00290
00291
00292 ArrayOfGridPos gp_p(1);
00293 gridpos( gp_p, z_grid, Vector( 1, r - rgeoid ) );
00294
00295
00296 itw.resize(1,2);
00297 interpweights( itw, gp_p );
00298
00299
00300 itw2p( dummy, p_grid, gp_p, itw );
00301 a_pressure = dummy[0];
00302
00303
00304 itw.resize(1,8);
00305 interpweights( itw, gp_p, gp_lat, gp_lon );
00306 interp( dummy, itw, t_field, gp_p, gp_lat, gp_lon );
00307 a_temperature = dummy[0];
00308
00309
00310 const Index ns = vmr_field.nbooks();
00311
00312 a_vmr_list.resize(ns);
00313
00314 for( Index is=0; is<ns; is++ )
00315 {
00316 interp( dummy, itw, vmr_field(is,joker,joker,joker), gp_p, gp_lat,
00317 gp_lon );
00318 a_vmr_list[is] = dummy[0];
00319 }
00320
00321 refr_index_agendaExecute( ws,
00322 refr_index, a_pressure, a_temperature, a_vmr_list,
00323 refr_index_agenda );
00324 }
00325
00326
00327
00329
00359 void refr_gradients_1d(
00360 Workspace& ws,
00361 Numeric& refr_index,
00362 Numeric& dndr,
00363 Numeric& a_pressure,
00364 Numeric& a_temperature,
00365 Vector& a_vmr_list,
00366 const Agenda& refr_index_agenda,
00367 ConstVectorView p_grid,
00368 const Numeric& r_geoid,
00369 ConstVectorView z_field,
00370 ConstVectorView t_field,
00371 ConstMatrixView vmr_field,
00372 const Numeric& r )
00373 {
00374 get_refr_index_1d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00375 refr_index_agenda, p_grid,
00376 r_geoid, z_field, t_field, vmr_field, r );
00377
00378 const Numeric n0 = refr_index;
00379
00380 get_refr_index_1d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00381 refr_index_agenda, p_grid,
00382 r_geoid, z_field, t_field, vmr_field, r+1 );
00383
00384 dndr = refr_index - n0;
00385
00386 refr_index = n0;
00387 }
00388
00389
00390
00392
00430 void refr_gradients_2d(
00431 Workspace& ws,
00432 Numeric& refr_index,
00433 Numeric& dndr,
00434 Numeric& dndlat,
00435 Numeric& a_pressure,
00436 Numeric& a_temperature,
00437 Vector& a_vmr_list,
00438 const Agenda& refr_index_agenda,
00439 ConstVectorView p_grid,
00440 ConstVectorView lat_grid,
00441 ConstVectorView r_geoid,
00442 ConstMatrixView z_field,
00443 ConstMatrixView t_field,
00444 ConstTensor3View vmr_field,
00445 const Numeric& r,
00446 const Numeric& lat )
00447 {
00448 get_refr_index_2d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00449 refr_index_agenda, p_grid, lat_grid,
00450 r_geoid, z_field, t_field, vmr_field, r, lat );
00451
00452 const Numeric n0 = refr_index;
00453
00454 get_refr_index_2d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00455 refr_index_agenda, p_grid, lat_grid, r_geoid,
00456 z_field, t_field, vmr_field, r+1, lat );
00457
00458 dndr = refr_index - n0;
00459
00460 const Numeric dlat = 1e-4;
00461
00462 get_refr_index_2d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00463 refr_index_agenda, p_grid, lat_grid, r_geoid,
00464 z_field, t_field, vmr_field, r, lat+dlat );
00465
00466 dndlat = ( refr_index - n0 ) / ( DEG2RAD * dlat * r );
00467
00468 refr_index = n0;
00469 }
00470
00471
00472
00474
00511 void refr_gradients_3d(
00512 Workspace& ws,
00513 Numeric& refr_index,
00514 Numeric& dndr,
00515 Numeric& dndlat,
00516 Numeric& dndlon,
00517 Numeric& a_pressure,
00518 Numeric& a_temperature,
00519 Vector& a_vmr_list,
00520 const Agenda& refr_index_agenda,
00521 ConstVectorView p_grid,
00522 ConstVectorView lat_grid,
00523 ConstVectorView lon_grid,
00524 ConstMatrixView r_geoid,
00525 ConstTensor3View z_field,
00526 ConstTensor3View t_field,
00527 ConstTensor4View vmr_field,
00528 const Numeric& r,
00529 const Numeric& lat,
00530 const Numeric& lon )
00531 {
00532 get_refr_index_3d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00533 refr_index_agenda, p_grid, lat_grid,
00534 lon_grid, r_geoid, z_field, t_field, vmr_field, r, lat, lon );
00535
00536 const Numeric n0 = refr_index;
00537
00538 get_refr_index_3d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00539 refr_index_agenda, p_grid, lat_grid,
00540 lon_grid, r_geoid, z_field, t_field, vmr_field, r+1, lat, lon );
00541
00542 dndr = refr_index - n0;
00543
00544 const Numeric dlat = 1e-4;
00545
00546 get_refr_index_3d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00547 refr_index_agenda, p_grid, lat_grid,
00548 lon_grid, r_geoid, z_field, t_field, vmr_field,
00549 r, lat+dlat, lon );
00550
00551 dndlat = ( refr_index - n0 ) / ( DEG2RAD * dlat * r );
00552
00553 const Numeric dlon = 1e-4;
00554
00555 get_refr_index_3d( ws, refr_index, a_pressure, a_temperature, a_vmr_list,
00556 refr_index_agenda, p_grid, lat_grid,
00557 lon_grid, r_geoid, z_field, t_field, vmr_field,
00558 r, lat, lon+dlon);
00559
00560 dndlon = ( refr_index - n0 ) / ( DEG2RAD * dlon * r * cos( DEG2RAD*lat ) );
00561
00562 refr_index = n0;
00563 }
00564
00565
00566
00568
00581 void refr_index_thayer_1974(
00582 Numeric& refr_index,
00583 const Numeric& p,
00584 const Numeric& t,
00585 const Numeric& h2o_vmr )
00586 {
00587 const Numeric e = p * h2o_vmr;
00588
00589 refr_index = 1 + ( 77.6e-8 * ( p - e ) +
00590 ( 64.8e-8 + 3.776e-3 / t ) * e ) / t;
00591 }
00592
00594
00602 void refr_index_ir(
00603 Numeric& refr_index,
00604 const Numeric& p,
00605 const Numeric& t )
00606 {
00607 const Numeric bn0 = 1.000272620045304;
00608 const Numeric bk = 288.16 * (pow(bn0,Numeric(2.0))-1.0)/
00609 (1013.25*(pow(bn0,Numeric(2.0))+2.0));
00610
00611
00612 refr_index = sqrt((2.0*bk*p/100.0+t)/(t-bk*p/100.0));
00613 }