40   assert( 
abs( sqrt( dx*dx + dy*dy + dz*dz ) - 1 ) < 1e-6 );
    46   const double   coslat = cos( 
DEG2RAD * lat );
    47   const double   sinlat = sin( 
DEG2RAD * lat );
    48   const double   coslon = cos( 
DEG2RAD * lon );
    49   const double   sinlon = sin( 
DEG2RAD * lon );
    50   const double   dr   = coslat*coslon*dx    + coslat*sinlon*dy   + sinlat*dz;
    51   const double   dlat = -sinlat*coslon/r*dx - sinlat*sinlon/r*dy + coslat/r*dz;
    52   const double   dlon = -sinlon/coslat/r*dx + coslon/coslat/r*dy;
    57   if( za < ANGTOL  ||  za > 180-
ANGTOL  )
    78     { aa = 
RAD2DEG * atan2( dy, dx ); }
   104   r   = sqrt( x*x + y*y + z*z );
   149                  sqrt( r1*r1 + r2*r2 - 2 * r1 * r2 * cos( 
DEG2RAD * dlat ) ) );
   204   assert( lat_start >= -90 );
   205   assert( lat_start <= 90 );
   206   assert( lat_hit >= -90 );
   207   assert( lat_hit <= 90 );
   210   if( za_start == 0  ||  za_start == 180  ||  
abs(lat_hit) == 90 )
   214   else if( 
abs( lat_hit ) < 1e-7 )
   220       const Numeric   a      = t2 * ( dx*dx + dy*dy ) - dz*dz;
   221       const Numeric   b      = 2 * ( t2 * ( x*dx + y*dy ) - z*dz );
   222       const Numeric   c      = t2 * ( x*x + y*y ) - z*z;
   232           const Numeric   e      = -0.5*sqrt(b*b-4*a*c)/a;      
   241           if( l1 > 0   &&   
abs(
sign(z+dz*l1)-zsign)>0.01 ) 
   243           if( l2 > 0   &&   
abs(
sign(z+dz*l2)-zsign)>0.01 ) 
   253           if( lmin >= 0  && lmax < 1e-6 )
   259               else if( lmax > 1e-6 )
   271       r   = sqrt( pow(xp,2.0) + pow(yp,2.0) + pow(z+dz*l,2.0) );
   272       lon = 
RAD2DEG * atan2( yp, xp );
   326   if( lon_hit == lon_start  ||  za_start == 0  ||  za_start == 180  ||
   327                                 aa_start == 0  ||  
abs(aa_start) == 180 )
   332       const double   tanlon = tan( 
DEG2RAD * lon_hit );
   333       l = ( y - x*tanlon ) / ( dx*tanlon - dy );
   342       r   = sqrt( pow(x+dx*l,2.0) + pow(y+dy*l,2.0) + pow(zp,2.0) );
   343       lat = 
RAD2DEG * asin( zp / r );
   411   assert( za_start <= 180 );
   412   assert( lat_start >=lat1  &&  lat_start <= lat3 );
   413   assert( lon_start >=lon5  &&  lon_start <= lon6 );
   427           l   = 
max( 1e-9, r - r_start0 ); 
   432   else if( za_start > 180-
ANGTOL )
   440           l   = 
max( 1e-9, r_start0 - r ); 
   454       if( rmax-rmin < 
RTOL/10 )
   460             { 
if( r_start < rmax ) { r_start = r = rmax; } }
   462             { 
if( r_start > rmin ) { r_start = r = rmin; } }
   464           r_crossing_3d( lat, lon, l, r, r_start, lat_start, lon_start,
   465                          za_start, ppc, x, y, z, dx, dy, dz );
   468           if( lat > lat3  ||  lat < lat1  || lon > lon6  ||  lon < lon5 )
   478             { 
if( r_start < rmin ) { r_start = rmin; } }
   480             { 
if( r_start > rmax ) { r_start = rmax; } }
   486               r_crossing_3d( lat, lon, l, r, r_start, lat_start, lon_start,
   487                              za_start, ppc, x, y, z, dx, dy, dz );
   489           else if( r_start < rmin )
   492               r_crossing_3d( lat, lon, l, r, r_start, lat_start, lon_start,
   493                              za_start, ppc, x, y, z, dx, dy, dz );
   496             { r = r_start; lat = lat_start; lon = lon_start; l = 0; }
   499           if( lat < lat1  ||  lat > lat3  ||  lon < lon5  ||  lon > lon6 )
   507                                                 r15, r35, r36, r16, lat, lon );
   511                 { 
if( r < rpl ) { r = rpl; } }
   513                 { 
if( r > rpl ) { r = rpl; } }
   518                 { za = za_start; aa = aa_start; }
   520                 { 
cart2poslos( d1, d2, d3, za, aa, x+dx*l, y+dy*l, z+dz*l, 
   521                                dx, dy, dz, ppc, lat_start, lon_start, 
   522                                za_start, aa_start ); 
   523                   assert( 
abs(d1-r) < 1e-3 );
   524                   assert( 
abs(d2-lat) < 1e-8 );
   525                   assert( 
abs(d3-lon) < 1e-8 );
   531                                r15, r35, r36, r16, lat, lon, aa );
   545               if( lat < lat1  ||  lat > lat3  ||  lon < lon5  ||  lon > lon6 )
   551                                                 r15, r35, r36, r16, lat, lon );
   552                   distance3D( l, r_start, lat_start, lon_start, r, lat, lon );
   652   poslos2cart( x, y, z, dx, dy, dz, r_start, lat_start, lon_start, 
   653                                              za_start,  aa_start ); 
   657                       za_start, aa_start, x, y, z, dx, dy, dz, ppc, 
   658                       lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, 
true );
   663   if( rsurface15 >= r15a  ||  rsurface35 >= r35a  ||
   664       rsurface36 >= r36a  ||  rsurface16 >= r16a )
   668                           za_start, aa_start, x, y, z, dx, dy, dz, ppc, 
   669                           lat1, lat3, lon5, lon6, rsurface15, rsurface35, 
   670                           rsurface36, rsurface16, 
true );
   672       if( rt > 0  &&  lt <= l )  
   673         { endface = 7;   r = rt;   lat = latt;   lon = lont;   l = lt; }
   681                           za_start, aa_start, x, y, z, dx, dy, dz, ppc, 
   682                           lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, 
   684     if( rt > 0  &&  lt < l )  
   685       { endface = 4;   r = rt;   lat = latt;   lon = lont;   l = lt; }
   692                                                          x, y, z, dx, dy, dz );
   693     if( rt > 0  &&  lt < l )  
   694       { endface = 1;   r = rt;   lat = lat1;   lon = lont;   l = lt; }
   701                                                          x, y, z, dx, dy, dz );
   702     if( rt > 0  &&  lt < l )  
   703       { endface = 3;   r = rt;   lat = lat3;   lon = lont;   l = lt; }
   707   if( !( r>0 && lat>=lat1 && lat<=lat3 && lon>=lon5 && lon<=lon6 ) )
   711                                                          x, y, z, dx, dy, dz );
   712       if( rt > 0  &&  lt < l )  
   713         { endface = 5;   r = rt;   lat = latt;   lon = lon5;   l = lt; }
   717   if( !( r>0 && lat>=lat1 && lat<=lat3 && lon>=lon5 && lon<=lon6 ) )
   721                                                          x, y, z, dx, dy, dz );
   722       if( rt > 0  &&  lt < l )  
   723         { endface = 6;   r = rt;   lat = latt;   lon = lon6;   l = lt; }
   736                                                      za_start, aa_start, ppc );
   749       n = 
Index( ceil( 
abs( l / lmax ) ) );
   761   lat_v[0] = lat_start;
   762   lon_v[0] = lon_start;
   768   for( 
Index j=1; j<=n; j++ )
   772       cart2poslos( r_v[j], lat_v[j], lon_v[j], za_v[j], aa_v[j],
   773                    x+dx*lj, y+dy*lj, z+dz*lj, dx, dy, dz, ppc,
   774                    lat_start, lon_start, za_start, aa_start );
   874   if( rsurface1 >= r1a  ||  rsurface3 >= r3a )
   878                                     lat1, lat3, rsurface1, rsurface3, 
true );
   880       if( rt > 0  &&  lt <= l )  
   881         { endface = 7;   r = rt;   lat = latt;   l = lt; }
   888                                                  lat1, lat3, r1b, r3b, 
false );
   889     if( rt > 0  &&  lt < l )  
   890       { endface = 4;   r = rt;   lat = latt;   }
   897         { endface = 1;  lat = lat1; }
   899         { endface = 3;  lat = lat3; }
   908   if( absza > 90  &&  ( absza - 
abs(lat_start-lat) ) < 90 ) 
   911     { tanpoint = 
false; }
   914                           za_start, r, tanpoint, lmax );
   917   if( endface == 1  ||  endface == 3 )
   918     { lat_v[lat_v.
nelem()-1] = lat; }
   987         const Agenda&          refr_index_air_agenda,
  1010                      refr_index_air_agenda, p_grid, refellipsoid, z_field,
  1011                      t_field, vmr_field, f_grid, r1 );
  1013                      refr_index_air_agenda, p_grid, refellipsoid, z_field,
  1014                      t_field, vmr_field, f_grid, r3 );
  1015   if( refr3 < refr1 * (r1/r3) * sin( 
DEG2RAD * 
abs(za) ) )
  1018       os << 
"For path between r1=" << r1 << 
"(n-1=" << refr1-1. << 
") and r2="  1019          << r3 << 
"(n-1=" << refr3-1. << 
"),\n"  1020          << 
"path calculation will run into refractive back-bending issues.\n"  1021          << 
"We are currently NOT ABLE to handle them. Consider repeating\n"  1022          << 
"your calculation without taking refraction into account.";
  1023       throw runtime_error(os.str());
  1031   Numeric refr_index_air, refr_index_air_group;
  1033                      refr_index_air_agenda, p_grid, refellipsoid, z_field,
  1034                      t_field, vmr_field, f_grid, r );
  1035   r_array.push_back( r );
  1036   lat_array.push_back( lat );
  1037   za_array.push_back( za );
  1038   n_array.push_back( refr_index_air );
  1039   ng_array.push_back( refr_index_air_group );
  1055       if( ( r < r1 - 
RTOL ) || ( r > r3 + 
RTOL ) )
  1057           throw runtime_error(
  1058             "Ooops. Path undetectedly left the grid cell.\n"  1059             "This should not happen. But there are issues with cases of high\n"  1060             "refractivity gradients. Seems you unfortunately encountered such\n"  1061             "a case. Little to be done about this now (if this is an option\n"  1062             "for you, run the case without considering refraction). For further\n"  1063             "details, contact Patrick Eriksson.");
  1067       do_gridrange_1d( r_v, lat_v, za_v, lstep, endface, r, lat, za, ppc_step, 
  1068                                                        -1, r1, r3, r_surface );
  1069       assert( r_v.
nelem() == 2 );
  1073       if( lstep <= lraytrace )
  1078           za_flagside = za_v[1];
  1090                 { za_flagside = 80; }     
  1102                          refr_index_air_agenda, p_grid, refellipsoid, 
  1103                          z_field, t_field, vmr_field, f_grid, r );
  1107       const Numeric ppc_local = ppc / refr_index_air; 
  1109       if( r >= ppc_local )
  1118       if( ready  ||  ( lmax > 0  &&  lcum + lraytrace > lmax ) )
  1120           r_array.push_back( r );
  1121           lat_array.push_back( lat );
  1122           za_array.push_back( za );
  1123           n_array.push_back( refr_index_air );
  1124           ng_array.push_back( refr_index_air_group );
  1125           l_array.push_back( lcum );
 INDEX Index
The type to use for all integer numbers and indices. 
 
void latlon_at_aa(Numeric &lat2, Numeric &lon2, const Numeric &lat1, const Numeric &lon1, const Numeric &aa, const Numeric &ddeg)
latlon_at_aa 
 
Numeric geompath_za_at_r(const Numeric &ppc, const Numeric &a_za, const Numeric &r)
geompath_za_at_r 
 
const Numeric LON_NOT_FOUND
 
Numeric za_geom2other_point(const Numeric &r1, const Numeric &lat1, const Numeric &r2, const Numeric &lat2)
za_geom2other_point 
 
Numeric geompath_r_at_l(const Numeric &ppc, const Numeric &l)
geompath_r_at_l 
 
void do_gridcell_2d(Vector &r_v, Vector &lat_v, Vector &za_v, Numeric &lstep, Index &endface, const Numeric &r_start, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc, const Numeric &lmax, const Numeric &lat1, const Numeric &lat3, const Numeric &r1a, const Numeric &r3a, const Numeric &r3b, const Numeric &r1b, const Numeric &rsurface1, const Numeric &rsurface3)
do_gridcell_2d 
 
void plevel_slope_3d(Numeric &c1, Numeric &c2, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15, const Numeric &r35, const Numeric &r36, const Numeric &r16, const Numeric &lat, const Numeric &lon, const Numeric &aa)
plevel_slope_3d 
 
Numeric rslope_crossing3d(const Numeric &rp, const Numeric &za, const Numeric &r0, Numeric c1, Numeric c2)
rslope_crossing3d 
 
const Numeric LAT_NOT_FOUND
 
void get_refr_index_1d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r)
get_refr_index_1d 
 
Numeric geompath_lat_at_za(const Numeric &za0, const Numeric &lat0, const Numeric &za)
geompath_lat_at_za 
 
void plevel_crossing_3d(Numeric &r, Numeric &lat, Numeric &lon, Numeric &l, const Numeric &r_start0, const Numeric &lat_start, const Numeric &lon_start, const Numeric &za_start, const Numeric &aa_start, const Numeric &x, const Numeric &y, const Numeric &z, const Numeric &dx, const Numeric &dy, const Numeric &dz, const Numeric &ppc, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15, const Numeric &r35, const Numeric &r36, const Numeric &r16, const bool &above)
plevel_crossing_3d 
 
void resolve_lon(Numeric &lon, const Numeric &lon5, const Numeric &lon6)
resolve_lon 
 
Index nelem() const
Returns the number of elements. 
 
Numeric geometrical_ppc(const Numeric &r, const Numeric &za)
geometrical_ppc 
 
A constant view of a Tensor4. 
 
Numeric sign(const Numeric &x)
sign 
 
const Numeric L_NOT_FOUND
 
void do_gridrange_1d(Vector &r_v, Vector &lat_v, Vector &za_v, Numeric &lstep, Index &endface, const Numeric &r_start0, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc, const Numeric &lmax, const Numeric &ra, const Numeric &rb, const Numeric &rsurface)
do_gridrange_1d 
 
void geompath_from_r1_to_r2(Vector &r, Vector &lat, Vector &za, Numeric &lstep, const Numeric &ppc, const Numeric &r1, const Numeric &lat1, const Numeric &za1, const Numeric &r2, const bool &tanpoint, const Numeric &lmax)
geompath_from_r1_to_r2 
 
void cart2poslos(double &r, double &lat, double &lon, double &za, double &aa, const double &x, const double &y, const double &z, const double &dx, const double &dy, const double &dz)
cart2poslos 
 
void cart2sph(double &r, double &lat, double &lon, const double &x, const double &y, const double &z)
cart2sph 
 
const Numeric R_NOT_FOUND
 
NUMERIC Numeric
The type to use for all floating point numbers. 
 
void distance3D(Numeric &l, const Numeric &r1, const Numeric &lat1, const Numeric &lon1, const Numeric &r2, const Numeric &lat2, const Numeric &lon2)
distance3D 
 
const Numeric DEG2RAD
Global constant, conversion from degrees to radians. 
 
void r_crossing_3d(Numeric &lat, Numeric &lon, Numeric &l, const Numeric &r_hit, const Numeric &r_start, const Numeric &lat_start, const Numeric &lon_start, const Numeric &za_start, const Numeric &ppc, const Numeric &x, const Numeric &y, const Numeric &z, const Numeric &dx, const Numeric &dy, const Numeric &dz)
r_crossing_3d 
 
void raytrace_1d_linear_basic(Workspace &ws, Array< Numeric > &r_array, Array< Numeric > &lat_array, Array< Numeric > &za_array, Array< Numeric > &l_array, Array< Numeric > &n_array, Array< Numeric > &ng_array, Index &endface, ConstVectorView refellipsoid, ConstVectorView p_grid, ConstVectorView z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &lmax, const Agenda &refr_index_air_agenda, const Numeric &lraytrace, const Numeric &ppc, const Numeric &r_surface, const Numeric &r1, const Numeric &r3, Numeric &r, Numeric &lat, Numeric &za)
raytrace_1d_linear_basic 
 
Numeric rsurf_at_latlon(const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15, const Numeric &r35, const Numeric &r36, const Numeric &r16, const Numeric &lat, const Numeric &lon)
rsurf_at_latlon 
 
void lat_crossing_3d(Numeric &r, Numeric &lon, Numeric &l, const Numeric &lat_hit, const Numeric &lat_start, const Numeric &za_start, const Numeric &x, const Numeric &y, const Numeric &z, const Numeric &dx, const Numeric &dy, const Numeric &dz)
lat_crossing_3d 
 
Numeric geompath_r_at_lat(const Numeric &ppc, const Numeric &lat0, const Numeric &za0, const Numeric &lat)
geompath_r_at_lat 
 
void resize(Index n)
Assignment operator from VectorView. 
 
A constant view of a Tensor3. 
 
A constant view of a Vector. 
 
void do_gridcell_3d(Vector &r_v, Vector &lat_v, Vector &lon_v, Vector &za_v, Vector &aa_v, Numeric &lstep, Index &endface, const Numeric &r_start, const Numeric &lat_start, const Numeric &lon_start, const Numeric &za_start, const Numeric &aa_start, const Numeric &ppc, const Numeric &lmax, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15a, const Numeric &r35a, const Numeric &r36a, const Numeric &r16a, const Numeric &r15b, const Numeric &r35b, const Numeric &r36b, const Numeric &r16b, const Numeric &rsurface15, const Numeric &rsurface35, const Numeric &rsurface36, const Numeric &rsurface16)
do_gridcell_3d 
 
void lon_crossing_3d(Numeric &r, Numeric &lat, Numeric &l, const Numeric &lon_hit, const Numeric &lon_start, const Numeric &za_start, const Numeric &aa_start, const Numeric &x, const Numeric &y, const Numeric &z, const Numeric &dx, const Numeric &dy, const Numeric &dz)
lon_crossing_3d 
 
void plevel_crossing_2d(Numeric &r, Numeric &lat, Numeric &l, const Numeric &r_start0, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc, const Numeric &lat1, const Numeric &lat3, const Numeric &r1, const Numeric &r3, const bool &above)
plevel_crossing_2d 
 
void geompath_tanpos_3d(Numeric &r_tan, Numeric &lat_tan, Numeric &lon_tan, Numeric &l_tan, const Numeric &r, const Numeric &lat, const Numeric &lon, const Numeric &za, const Numeric &aa, const Numeric &ppc)
geompath_tanpos_3d 
 
void poslos2cart(Numeric &x, Numeric &z, Numeric &dx, Numeric &dz, const Numeric &r, const Numeric &lat, const Numeric &za)
poslos2cart 
 
Numeric geompath_l_at_r(const Numeric &ppc, const Numeric &r)
geompath_l_at_r 
 
const Numeric RAD2DEG
Global constant, conversion from radians to degrees.