00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00037
00038
00039
00040
00041 #include "absorption.h"
00042 #include "arts.h"
00043 #include "check_input.h"
00044 #include "matpackI.h"
00045 #include "messages.h"
00046 #include "refraction.h"
00047 #include "special_interp.h"
00048 #include "abs_species_tags.h"
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 void refr_indexFieldAndGradients(
00059 Workspace& ws,
00060
00061 Numeric& refr_index,
00062 Numeric& a_pressure,
00063 Numeric& a_temperature,
00064 Vector& a_vmr_list,
00065
00066 Tensor4& out,
00067
00068 const Agenda& refr_index_agenda,
00069 const Index& atmosphere_dim,
00070 const Vector& p_grid,
00071 const Vector& lat_grid,
00072 const Vector& lon_grid,
00073 const Matrix& r_geoid,
00074 const Tensor3& z_field,
00075 const Tensor3& t_field,
00076 const Tensor4& vmr_field,
00077
00078 const Vector& p_values,
00079 const Vector& lat_values,
00080 const Vector& lon_values)
00081 {
00082
00083 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
00084 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
00085 chk_atm_surface( "r_geoid", r_geoid, atmosphere_dim, lat_grid, lon_grid );
00086 chk_atm_field( "z_field", z_field, atmosphere_dim, p_grid, lat_grid,
00087 lon_grid );
00088 chk_atm_field( "t_field", t_field, atmosphere_dim, p_grid, lat_grid,
00089 lon_grid );
00090 chk_atm_field( "first book of vmr_field", vmr_field(0,joker,joker,joker),
00091 atmosphere_dim, p_grid, lat_grid, lon_grid );
00092
00093
00094 const Index np = p_values.nelem(), npgrid = p_grid.nelem();
00095 Index nlat=1, nlon=1, nlatgrid = 1, nlongrid = 1;
00096 Numeric dndr, dndlat, dndlon;
00097
00098 if( atmosphere_dim == 1 )
00099 {
00100 out.resize(2,np,1,1);
00101 }
00102 else if( atmosphere_dim == 2 )
00103 {
00104 nlat = lat_values.nelem();
00105 nlatgrid = lat_grid.nelem();
00106 out.resize(3,np,nlat,1);
00107 }
00108 else
00109 {
00110 nlat = lat_values.nelem();
00111 nlatgrid = lat_grid.nelem();
00112 nlon = lon_values.nelem();
00113 nlongrid = lon_grid.nelem();
00114 out.resize(4,np,nlat,nlon);
00115 }
00116
00117
00118 Tensor3 r_field(npgrid,nlatgrid,nlongrid);
00119
00120 for( Index ilon=0; ilon<nlongrid; ilon++ )
00121 {
00122 for( Index ilat=0; ilat<nlatgrid; ilat++ )
00123 {
00124 for( Index ip=0; ip<npgrid; ip++ )
00125 {
00126 r_field(ip,ilat,ilon) = r_geoid(ilat,ilon) +
00127 z_field(ip,ilat,ilon);
00128 }
00129 }
00130 }
00131
00132
00133 for( Index ilon=0; ilon<nlon; ilon++ )
00134 {
00135 for( Index ilat=0; ilat<nlat; ilat++ )
00136 {
00137 ArrayOfGridPos gp_p(np), gp_lat(1), gp_lon(1);
00138 Vector r_grid( p_grid.nelem() ), r(np);
00139 Matrix itw(np,2);
00140
00141 if( atmosphere_dim == 1 )
00142 {
00143 r_grid = r_field(joker,0,0);
00144 }
00145 else if( atmosphere_dim == 2 )
00146 {
00147 gridpos( gp_lat, lat_grid, lat_values[ilat] );
00148 z_at_lat_2d( r_grid, p_grid, lat_grid, r_field(joker,joker,0),
00149 gp_lat[0] );
00150 }
00151 else
00152 {
00153 gridpos( gp_lat, lat_grid, lat_values[ilat] );
00154 gridpos( gp_lon, lon_grid, lon_values[ilon] );
00155 z_at_latlon( r_grid, p_grid, lat_grid, lon_grid, r_field,
00156 gp_lat[0], gp_lon[0] );
00157 }
00158
00159 p2gridpos( gp_p, p_grid, p_values );
00160 interpweights( itw, gp_p );
00161 interp( r, itw, r_grid, gp_p );
00162
00163 for( Index ip=0; ip<np; ip++ )
00164 {
00165
00166 if( atmosphere_dim == 1 )
00167 {
00168 refr_gradients_1d( ws, refr_index, dndr, a_pressure,
00169 a_temperature, a_vmr_list, refr_index_agenda,
00170 p_grid, r_geoid(0,0), z_field(joker,0,0),
00171 t_field(joker,0,0), vmr_field(joker,joker,0,0),
00172 r[ip] );
00173 }
00174
00175 else if( atmosphere_dim == 2 )
00176 {
00177 refr_gradients_2d( ws, refr_index, dndr, dndlat, a_pressure,
00178 a_temperature, a_vmr_list, refr_index_agenda,
00179 p_grid, lat_grid, r_geoid(joker,0),
00180 z_field(joker,joker,0), t_field(joker,joker,0),
00181 vmr_field(joker,joker,joker,0),
00182 r[ip], lat_values[ilat] );
00183 out(2,ip,ilat,ilon) = dndlat;
00184 }
00185
00186 else
00187 {
00188 refr_gradients_3d( ws, refr_index, dndr, dndlat, dndlon,
00189 a_pressure,
00190 a_temperature, a_vmr_list, refr_index_agenda,
00191 p_grid, lat_grid, lon_grid, r_geoid,
00192 z_field, t_field, vmr_field,
00193 r[ip], lat_values[ilat], lon_values[ilon] );
00194 out(2,ip,ilat,ilon) = dndlat;
00195 out(3,ip,ilat,ilon) = dndlon;
00196 }
00197
00198 out(0,ip,ilat,ilon) = refr_index;
00199 out(1,ip,ilat,ilon) = dndr;
00200 }
00201 }
00202 }
00203 }
00204
00205
00206
00207 void refr_indexIR(
00208
00209 Numeric& refr_index,
00210
00211 const Numeric& a_pressure,
00212 const Numeric& a_temperature,
00213 const Vector& a_vmr_list )
00214 {
00215
00216 a_vmr_list.nelem();
00217
00218 refr_index_ir( refr_index, a_pressure, a_temperature );
00219 }
00220
00221
00222
00223 void refr_indexThayer(
00224 Numeric& refr_index,
00225 const Numeric& a_pressure,
00226 const Numeric& a_temperature,
00227 const Vector& a_vmr_list,
00228 const ArrayOfArrayOfSpeciesTag& abs_species )
00229 {
00230 if( abs_species.nelem() != a_vmr_list.nelem() )
00231 throw runtime_error( "The number of tag groups differ between "
00232 "*a_vmr_list* and *abs_species*." );
00233
00234 Index firstH2O = find_first_species_tg( abs_species,
00235 species_index_from_species_name("H2O") );
00236
00237 if( firstH2O < 0 )
00238 throw runtime_error(
00239 "Water vapour is a requiered (must be a tag group in *abs_species*)." );
00240
00241 refr_index_thayer_1974( refr_index, a_pressure, a_temperature,
00242 a_vmr_list[firstH2O] );
00243 }
00244
00245
00246
00247 void refr_indexUnit(
00248 Numeric& refr_index )
00249 {
00250 refr_index = 1;
00251 }
00252