00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018   
00031 
00032 
00033 
00034 
00035 #include <stdexcept>
00036 #include <iostream>
00037 #include <cstdlib>
00038 #include <cmath>
00039 #include "array.h"
00040 #include "auto_md.h"
00041 #include "matpackVII.h"
00042 #include "ppath.h"
00043 #include "agenda_class.h"
00044 #include "physics_funcs.h"
00045 #include "lin_alg.h"
00046 #include "math_funcs.h"
00047 #include "messages.h"
00048 #include "xml_io.h"
00049 #include "rte.h"
00050 #include "special_interp.h"
00051 #include "scatrte.h"
00052 #include "logic.h"
00053 #include "check_input.h"
00054 #include "sorting.h"
00055 
00056 extern const Numeric PI;
00057 extern const Numeric RAD2DEG;
00058 
00060 
00085 void cloud_fieldsCalc(Workspace& ws,
00086                       
00087                       Tensor5View ext_mat_field,
00088                       Tensor4View abs_vec_field,
00089                       
00090                       const Agenda& spt_calc_agenda,
00091                       const Agenda& opt_prop_part_agenda,
00092                       const Index& scat_za_index, 
00093                       const Index& scat_aa_index,
00094                       const ArrayOfIndex& cloudbox_limits,
00095                       const Tensor3View t_field, 
00096                       const Tensor4View pnd_field
00097                      )
00098 {
00099   
00100   
00101   
00102   out3 << "Calculate scattering properties in cloudbox \n";
00103   
00104   const Index atmosphere_dim = cloudbox_limits.nelem()/2;
00105   const Index N_pt = pnd_field.nbooks();
00106   const Index stokes_dim = ext_mat_field.ncols(); 
00107   
00108   assert( atmosphere_dim == 1 || atmosphere_dim ==3 );
00109   assert( ext_mat_field.ncols() == ext_mat_field.nrows() &&
00110           ext_mat_field.ncols() == abs_vec_field.ncols());
00111   
00112   const Index Np_cloud = cloudbox_limits[1]-cloudbox_limits[0]+1;
00113   
00114   
00115   Index Nlat_cloud = 1;
00116   Index Nlon_cloud = 1;
00117   
00118   if (atmosphere_dim == 3)
00119     {
00120       Nlat_cloud = cloudbox_limits[3]-cloudbox_limits[2]+1;
00121       Nlon_cloud = cloudbox_limits[5]-cloudbox_limits[4]+1;
00122     }
00123   
00124   
00125   
00126   
00127   Matrix abs_vec_spt_local(N_pt, stokes_dim, 0.);
00128   Tensor3 ext_mat_spt_local(N_pt, stokes_dim, stokes_dim, 0.);
00129   Matrix abs_vec_local;
00130   Tensor3 ext_mat_local;
00131   Numeric rte_temperature_local;
00132   
00133   
00134   
00135   
00136   
00137   
00138   
00139   
00140   
00141   
00142   
00143   
00144   for(Index scat_p_index_local = 0; scat_p_index_local < Np_cloud; 
00145       scat_p_index_local ++)
00146     {
00147       for(Index scat_lat_index_local = 0; scat_lat_index_local < Nlat_cloud; 
00148           scat_lat_index_local ++)
00149         {
00150           for(Index scat_lon_index_local = 0; 
00151               scat_lon_index_local < Nlon_cloud; 
00152               scat_lon_index_local ++)
00153             {
00154               if (atmosphere_dim == 1)
00155                 rte_temperature_local = 
00156                   t_field(scat_p_index_local + cloudbox_limits[0], 0, 0);
00157               else
00158                 rte_temperature_local = 
00159                   t_field(scat_p_index_local + cloudbox_limits[0],
00160                           scat_lat_index_local + cloudbox_limits[2],
00161                           scat_lon_index_local + cloudbox_limits[4]);
00162               
00163               
00164               
00165               spt_calc_agendaExecute(ws, ext_mat_spt_local, 
00166                                      abs_vec_spt_local,
00167                                      scat_p_index_local,
00168                                      scat_lat_index_local,
00169                                      scat_lon_index_local, 
00170                                      rte_temperature_local,
00171                                      scat_za_index,
00172                                      scat_aa_index,
00173                                      spt_calc_agenda);
00174 
00175               opt_prop_part_agendaExecute(ws, ext_mat_local, abs_vec_local, 
00176                                           ext_mat_spt_local, 
00177                                           abs_vec_spt_local,
00178                                           scat_p_index_local,
00179                                           scat_lat_index_local,
00180                                           scat_lon_index_local,
00181                                           opt_prop_part_agenda);
00182            
00183               
00184               abs_vec_field(scat_p_index_local, scat_lat_index_local,
00185                             scat_lon_index_local,
00186                             joker) = abs_vec_local(0, joker);
00187               
00188               ext_mat_field(scat_p_index_local, scat_lat_index_local,
00189                             scat_lon_index_local,
00190                             joker, joker) = ext_mat_local(0, joker, joker);
00191             } 
00192         }
00193     }
00194 }
00195   
00196 
00197 
00198 
00199 
00201 
00244 void cloud_ppath_update1D(Workspace& ws,
00245                           
00246                           Tensor6View doit_i_field,
00247                           
00248                           const Index& p_index,
00249                           const Index& scat_za_index,
00250                           ConstVectorView scat_za_grid,
00251                           const ArrayOfIndex& cloudbox_limits,
00252                           ConstTensor6View doit_scat_field,
00253                           
00254                           const Agenda& abs_scalar_gas_agenda,
00255                           ConstTensor4View vmr_field,
00256                           
00257                           const Agenda& opt_prop_gas_agenda,
00258                           
00259                           const Agenda& ppath_step_agenda,
00260                           ConstVectorView  p_grid,
00261                           ConstTensor3View z_field,
00262                           ConstMatrixView r_geoid,
00263                           ConstMatrixView z_surface,
00264                           
00265                           ConstTensor3View t_field,
00266                           ConstVectorView f_grid,
00267                           const Index& f_index,
00268                           
00269                           ConstTensor5View ext_mat_field,
00270                           ConstTensor4View abs_vec_field,
00271                           const Agenda& surface_prop_agenda,
00272                           
00273                           const Index& scat_za_interp)
00274 {
00275   Matrix iy;
00276   Matrix surface_emission;
00277   Matrix surface_los;
00278   Tensor4 surface_rmatrix;
00279   Ppath ppath_step;
00280   
00281   
00282   
00283   
00284   ppath_init_structure(ppath_step, 1, 1);
00285   
00286   
00287   
00288   
00289   ppath_step.z[0]     = z_field(p_index,0,0);
00290   ppath_step.pos(0,0) = r_geoid(0,0) + ppath_step.z[0];
00291   
00292   
00293   ppath_step.los(0,0) = scat_za_grid[scat_za_index];
00294   
00295   
00296   
00297   ppath_step.gp_p[0].idx   = p_index;
00298   ppath_step.gp_p[0].fd[0] = 0;
00299   ppath_step.gp_p[0].fd[1] = 1;
00300   
00301   
00302   Vector unused_lat_grid(0);
00303   Vector unused_lon_grid(0);
00304   ppath_step_agendaExecute(ws, ppath_step, 1, p_grid,
00305                            unused_lat_grid, unused_lon_grid,
00306                            z_field, r_geoid, z_surface,
00307                            ppath_step_agenda);
00308   
00309   
00310   
00311   
00312   
00313   
00314   if((cloudbox_limits[0] <= ppath_step.gp_p[1].idx &&
00315      cloudbox_limits[1] > ppath_step.gp_p[1].idx) ||
00316      (cloudbox_limits[1] == ppath_step.gp_p[1].idx &&
00317       abs(ppath_step.gp_p[1].fd[0]) < 1e-6))
00318     {
00319       
00320       const Index stokes_dim = doit_i_field.ncols();
00321       
00322       const Index N_species = vmr_field.nbooks();
00323       
00324       
00325       
00326       
00327       
00328       
00329 
00330       
00331       Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np, 0.);
00332       Matrix abs_vec_int(stokes_dim, ppath_step.np, 0.);
00333       Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
00334       Matrix doit_i_field_int(stokes_dim, ppath_step.np, 0.);
00335       Vector t_int(ppath_step.np, 0.);
00336       Matrix vmr_list_int(N_species, ppath_step.np, 0.);
00337       Vector p_int(ppath_step.np, 0.);
00338       
00339       interp_cloud_coeff1D(ext_mat_int, abs_vec_int, sca_vec_int,
00340                            doit_i_field_int, t_int, vmr_list_int, p_int, 
00341                            ext_mat_field, abs_vec_field, doit_scat_field, 
00342                            doit_i_field, t_field, vmr_field, p_grid, 
00343                            ppath_step, cloudbox_limits, scat_za_grid, 
00344                            scat_za_interp);
00345      
00346           
00347       
00348       
00349       
00350       
00351       Index bkgr = ppath_what_background(ppath_step);
00352 
00353       
00354       
00355       
00356       cloud_RT_no_background(ws, doit_i_field, 
00357                              abs_scalar_gas_agenda,
00358                                  opt_prop_gas_agenda, ppath_step, 
00359                              t_int, vmr_list_int,
00360                              ext_mat_int, abs_vec_int, sca_vec_int,
00361                                  doit_i_field_int,
00362                              p_int, cloudbox_limits, 
00363                                  f_grid, f_index, p_index, 0, 0,
00364                              scat_za_index, 0);
00365       
00366       
00367       if (bkgr == 2)
00368         {
00369           
00370           cloud_RT_surface(ws,
00371                            doit_i_field, surface_prop_agenda, 
00372                            f_index, stokes_dim, ppath_step, cloudbox_limits, 
00373                            scat_za_grid, scat_za_index); 
00374           
00375         }
00376       
00377     }
00378 }
00379 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 void cloud_ppath_update1D_noseq(
00389                           Workspace& ws,
00390                           
00391                           Tensor6View doit_i_field,
00392                           
00393                           const Index& p_index,
00394                           const Index& scat_za_index,
00395                           ConstVectorView scat_za_grid,
00396                           const ArrayOfIndex& cloudbox_limits,
00397                           ConstTensor6View doit_i_field_old,
00398                           ConstTensor6View doit_scat_field,
00399                           
00400                           const Agenda& abs_scalar_gas_agenda,
00401                           ConstTensor4View vmr_field,
00402                           
00403                           const Agenda& opt_prop_gas_agenda,
00404                           
00405                           const Agenda& ppath_step_agenda,
00406                           ConstVectorView  p_grid,
00407                           ConstTensor3View z_field,
00408                           ConstMatrixView r_geoid,
00409                           ConstMatrixView z_surface,
00410                           
00411                           ConstTensor3View t_field,
00412                           ConstVectorView f_grid,
00413                           
00414                           const Index& f_index,
00415                           
00416                           ConstTensor5View ext_mat_field,
00417                           ConstTensor4View abs_vec_field,
00418                           
00419                           const Index& scat_za_interp
00420                          )
00421 {
00422   Matrix iy;
00423   Matrix surface_emission;
00424   Matrix surface_los;
00425   Tensor4 surface_rmatrix;
00426   Ppath ppath_step;
00427   
00428   
00429   
00430   
00431   ppath_init_structure(ppath_step, 1, 1);
00432   
00433   
00434   
00435   
00436   ppath_step.z[0]     = z_field(p_index,0,0);
00437   ppath_step.pos(0,0) = r_geoid(0,0) + ppath_step.z[0];
00438   
00439   
00440   ppath_step.los(0,0) = scat_za_grid[scat_za_index];
00441   
00442   
00443   
00444   ppath_step.gp_p[0].idx   = p_index;
00445   ppath_step.gp_p[0].fd[0] = 0;
00446   ppath_step.gp_p[0].fd[1] = 1;
00447   
00448   
00449   Vector unused_lat_grid(0);
00450   Vector unused_lon_grid(0);
00451   ppath_step_agendaExecute(ws, ppath_step, 1, p_grid,
00452                            unused_lat_grid, unused_lon_grid,
00453                            z_field, r_geoid, z_surface,
00454                            ppath_step_agenda);
00455   
00456   
00457   
00458   
00459   
00460   
00461   if((cloudbox_limits[0] <= ppath_step.gp_p[1].idx &&
00462      cloudbox_limits[1] > ppath_step.gp_p[1].idx) ||
00463      (cloudbox_limits[1] == ppath_step.gp_p[1].idx &&
00464       abs(ppath_step.gp_p[1].fd[0]) < 1e-6))
00465     {
00466       
00467       const Index stokes_dim = doit_i_field.ncols();
00468       
00469       const Index N_species = vmr_field.nbooks();
00470       
00471       
00472       
00473       
00474       
00475       
00476 
00477       
00478       Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np, 0.);
00479       Matrix abs_vec_int(stokes_dim, ppath_step.np, 0.);
00480       Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
00481       Matrix doit_i_field_int(stokes_dim, ppath_step.np, 0.);
00482       Vector t_int(ppath_step.np, 0.);
00483       Matrix vmr_list_int(N_species, ppath_step.np, 0.);
00484       Vector p_int(ppath_step.np, 0.);
00485       
00486       interp_cloud_coeff1D(ext_mat_int, abs_vec_int, sca_vec_int,
00487                            doit_i_field_int, t_int, vmr_list_int, p_int, 
00488                            ext_mat_field, abs_vec_field, doit_scat_field, 
00489                            doit_i_field_old, t_field, vmr_field, p_grid, 
00490                            ppath_step, cloudbox_limits, scat_za_grid, 
00491                            scat_za_interp);
00492       
00493       
00494       
00495       
00496       
00497       Index bkgr = ppath_what_background(ppath_step);
00498       
00499       
00500       if (bkgr == 0)
00501         {
00502           
00503           
00504           
00505           cloud_RT_no_background(ws, doit_i_field,
00506                                  abs_scalar_gas_agenda,
00507                                  opt_prop_gas_agenda, ppath_step, 
00508                                  t_int, vmr_list_int,
00509                                  ext_mat_int, abs_vec_int, sca_vec_int,
00510                                  doit_i_field_int,
00511                                  p_int, cloudbox_limits, 
00512                                  f_grid, f_index, p_index, 0, 0, 
00513                                  scat_za_index, 0);
00514         }
00515       
00516       
00517       else if (bkgr == 2)
00518         {
00519           throw runtime_error("Surface reflections only implemented for sequential update.\n" );
00520         }
00521     }
00522 }
00523 
00524 
00525 
00526 
00528 
00575 void cloud_ppath_update3D(Workspace& ws,
00576                           Tensor6View doit_i_field,
00577                           
00578                           const Index& p_index,
00579                           const Index& lat_index,
00580                           const Index& lon_index,
00581                           const Index& scat_za_index,
00582                           const Index& scat_aa_index,
00583                           ConstVectorView scat_za_grid,
00584                           ConstVectorView scat_aa_grid,
00585                           const ArrayOfIndex& cloudbox_limits,
00586                           ConstTensor6View doit_scat_field,
00587                           
00588                           const Agenda& abs_scalar_gas_agenda,
00589                           ConstTensor4View vmr_field,
00590                           
00591                           const Agenda& opt_prop_gas_agenda,
00592                           
00593                           const Agenda& ppath_step_agenda,
00594                           ConstVectorView p_grid,
00595                           ConstVectorView lat_grid,
00596                           ConstVectorView lon_grid,
00597                           ConstTensor3View z_field,
00598                           ConstMatrixView r_geoid,
00599                           ConstMatrixView z_surface,
00600                           
00601                           ConstTensor3View t_field,
00602                           ConstVectorView f_grid,
00603                           const Index& f_index,
00604                           
00605                           ConstTensor5View ext_mat_field,
00606                           ConstTensor4View abs_vec_field,
00607                           const Index& 
00608                           )
00609 {
00610   Ppath ppath_step;
00611   const Index stokes_dim = doit_i_field.ncols();
00612   
00613   Vector sca_vec_av(stokes_dim,0);
00614   Vector aa_grid(scat_aa_grid.nelem());
00615 
00616   for(Index i = 0; i<scat_aa_grid.nelem(); i++)
00617     aa_grid[i] = scat_aa_grid[i]-180.;
00618 
00619    
00620   ppath_init_structure(ppath_step, 3, 1);
00621   
00622   
00623               
00624   
00625   ppath_step.z[0] = z_field(p_index,lat_index,
00626                             lon_index);
00627 
00628   
00629   
00630   
00631   
00632 
00633   ppath_step.pos(0,0) =
00634     r_geoid(lat_index, lon_index) + ppath_step.z[0];
00635   ppath_step.pos(0,1) = lat_grid[lat_index];
00636   ppath_step.pos(0,2) = lon_grid[lon_index];
00637               
00638   
00639   ppath_step.los(0,0) = scat_za_grid[scat_za_index];
00640   ppath_step.los(0,1) = aa_grid[scat_aa_index];
00641               
00642   
00643   ppath_step.gp_p[0].idx   = p_index;
00644   ppath_step.gp_p[0].fd[0] = 0.;
00645   ppath_step.gp_p[0].fd[1] = 1.;
00646 
00647   ppath_step.gp_lat[0].idx   = lat_index;
00648   ppath_step.gp_lat[0].fd[0] = 0.;
00649   ppath_step.gp_lat[0].fd[1] = 1.;
00650                     
00651   ppath_step.gp_lon[0].idx   = lon_index;
00652   ppath_step.gp_lon[0].fd[0] = 0.;
00653   ppath_step.gp_lon[0].fd[1] = 1.;
00654 
00655   
00656   ppath_step_agendaExecute(ws, ppath_step, 3, p_grid,
00657                            lat_grid, lon_grid, z_field, r_geoid, z_surface,
00658                            ppath_step_agenda);
00659 
00660     
00661   
00662   
00663   
00664   if (is_inside_cloudbox(ppath_step, cloudbox_limits, true))
00665     {      
00666       
00667       
00668       
00669       
00670       
00671       ArrayOfGridPos cloud_gp_p = ppath_step.gp_p;
00672       ArrayOfGridPos cloud_gp_lat = ppath_step.gp_lat;
00673       ArrayOfGridPos cloud_gp_lon = ppath_step.gp_lon;
00674        
00675       for(Index i = 0; i<ppath_step.np; i++ )
00676         {
00677           cloud_gp_p[i].idx -= cloudbox_limits[0];  
00678           cloud_gp_lat[i].idx -= cloudbox_limits[2];
00679           cloud_gp_lon[i].idx -= cloudbox_limits[4];
00680           
00681           
00682           
00683         
00684 
00685 
00686 
00687 
00688           
00689         }
00690       
00691       fix_gridpos_at_boundary(cloud_gp_p, cloudbox_limits[1] - cloudbox_limits[0] +1);
00692       fix_gridpos_at_boundary(cloud_gp_lat, cloudbox_limits[3] - cloudbox_limits[2] +1); 
00693       fix_gridpos_at_boundary(cloud_gp_lon, cloudbox_limits[5] - cloudbox_limits[4] +1);
00694       
00695       Matrix itw(ppath_step.np, 8);
00696       interpweights(itw, cloud_gp_p, cloud_gp_lat, cloud_gp_lon);
00697 
00698       Matrix itw_p(ppath_step.np, 2);
00699       interpweights(itw_p, cloud_gp_p);
00700  
00701       
00702       
00703       
00704       
00705       VectorView los_grid_za = ppath_step.los(joker,0);
00706       VectorView los_grid_aa = ppath_step.los(joker,1);
00707 
00708       for(Index i = 0; i<los_grid_aa.nelem(); i++)
00709         los_grid_aa[i] = los_grid_aa[i] + 180.;
00710   
00711       ArrayOfGridPos gp_za(los_grid_za.nelem()); 
00712       gridpos(gp_za, scat_za_grid, los_grid_za);
00713 
00714       ArrayOfGridPos gp_aa(los_grid_aa.nelem()); 
00715       gridpos(gp_aa, scat_aa_grid, los_grid_aa);
00716 
00717       Matrix itw_p_za(ppath_step.np, 32);
00718       interpweights(itw_p_za, cloud_gp_p, cloud_gp_lat, cloud_gp_lon, 
00719                     gp_za, gp_aa);
00720             
00721       
00722       
00723       
00724       
00725       
00726       
00727       Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np);
00728       Matrix abs_vec_int(stokes_dim, ppath_step.np);
00729       Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
00730       Matrix doit_i_field_int(stokes_dim, ppath_step.np, 0.);
00731       Vector t_int(ppath_step.np);
00732       Vector vmr_int(ppath_step.np);
00733       Vector p_int(ppath_step.np);
00734       Vector stokes_vec(stokes_dim);
00735       
00736       
00737       
00738             
00739       
00740       
00741       
00742       for (Index i = 0; i < stokes_dim; i++)
00743         {
00744           
00745           
00746           out3 << "Interpolate ext_mat:\n";
00747           for (Index j = 0; j < stokes_dim; j++)
00748             {
00749               
00750               
00751               
00752               interp( ext_mat_int(i, j, joker), itw, 
00753                       ext_mat_field(joker, joker, joker, i, j), cloud_gp_p,
00754                       cloud_gp_lat, cloud_gp_lon); 
00755             }
00756           
00757           
00758           
00759           
00760            interp( abs_vec_int(i,joker), itw, 
00761                   abs_vec_field(joker, joker, joker, i),
00762                    cloud_gp_p, cloud_gp_lat, cloud_gp_lon); 
00763           
00764           
00765           
00766           
00767           
00768           out3 << "Interpolate doit_scat_field:\n";
00769           interp( sca_vec_int(i, joker), itw_p_za, 
00770                   doit_scat_field(joker, joker, joker, joker, joker, i),
00771                   cloud_gp_p,
00772                   cloud_gp_lat, cloud_gp_lon, gp_za, gp_aa);
00773           out3 << "Interpolate doit_i_field:\n";
00774           interp( doit_i_field_int(i, joker), itw_p_za, 
00775                   doit_i_field(joker, joker, joker, joker, joker, i), 
00776                   cloud_gp_p,
00777                   cloud_gp_lat, cloud_gp_lon, gp_za, gp_aa);
00778         }
00779       
00780       
00781       
00782       
00783       
00784       out3 << "Interpolate temperature field\n";
00785       interp( t_int, itw, 
00786               t_field(joker, joker, joker), ppath_step.gp_p, 
00787               ppath_step.gp_lat, ppath_step.gp_lon);
00788       
00789       
00790       
00791       
00792       
00793       const Index N_species = vmr_field.nbooks();
00794       
00795       
00796       
00797       
00798       Matrix vmr_list_int(N_species, ppath_step.np);
00799       
00800       for (Index i = 0; i < N_species; i++)
00801         {
00802           out3 << "Interpolate vmr field\n";
00803           interp( vmr_int, itw, 
00804                   vmr_field(i, joker, joker, joker), ppath_step.gp_p,
00805                   ppath_step.gp_lat, ppath_step.gp_lon );
00806           
00807           vmr_list_int(i, joker) = vmr_int;
00808         }
00809       
00810       
00811       itw2p( p_int, p_grid, ppath_step.gp_p, itw_p);
00812       
00813       out3 << "Calculate radiative transfer inside cloudbox.\n";
00814       cloud_RT_no_background(ws, doit_i_field, 
00815                              abs_scalar_gas_agenda,
00816                              opt_prop_gas_agenda, ppath_step, 
00817                              t_int, vmr_list_int,
00818                              ext_mat_int, abs_vec_int, sca_vec_int,
00819                              doit_i_field_int,
00820                              p_int, cloudbox_limits, 
00821                              f_grid, f_index, p_index, lat_index, lon_index, 
00822                              scat_za_index, scat_aa_index);
00823     }
00824 }
00825 
00827 
00828 
00829 
00830 
00831 
00832 
00833 
00834 
00835 
00836 
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00846 
00847 
00848 
00849 
00850 
00851 
00852 
00853 
00854 
00855 
00856 
00857 
00858 void cloud_RT_no_background(Workspace& ws,
00859                             
00860                             Tensor6View doit_i_field,
00861                             
00862                             const Agenda& abs_scalar_gas_agenda,
00863                             const Agenda& opt_prop_gas_agenda,
00864                             const Ppath& ppath_step, 
00865                             ConstVectorView t_int,
00866                             ConstMatrixView vmr_list_int,
00867                             ConstTensor3View ext_mat_int,
00868                             ConstMatrixView abs_vec_int,
00869                             ConstMatrixView sca_vec_int,
00870                             ConstMatrixView doit_i_field_int,
00871                             ConstVectorView p_int,
00872                             const ArrayOfIndex& cloudbox_limits,
00873                             ConstVectorView f_grid,
00874                             const Index& f_index,
00875                             const Index& p_index,
00876                             const Index& lat_index,
00877                             const Index& lon_index, 
00878                             const Index& scat_za_index,
00879                             const Index& scat_aa_index)
00880 {
00881   const Index N_species = vmr_list_int.nrows();
00882   const Index stokes_dim = doit_i_field.ncols();
00883   const Index atmosphere_dim = cloudbox_limits.nelem()/2;
00884 
00885   Vector sca_vec_av(stokes_dim,0);
00886   Vector stokes_vec(stokes_dim, 0.);
00887   Vector rte_vmr_list_local(N_species,0.); 
00888   
00889   Matrix abs_scalar_gas_local(1, N_species, 0.);
00890   Tensor3 ext_mat_local;
00891   Matrix abs_vec_local;  
00892 
00893   
00894   stokes_vec = doit_i_field_int(joker, ppath_step.np-1);
00895 
00896   for( Index k= ppath_step.np-1; k > 0; k--)
00897     {
00898       
00899       Numeric l_step = ppath_step.l_step[k-1];
00900       
00901       Numeric rte_temperature_local = 0.5 * (t_int[k] + t_int[k-1]);
00902       
00903       
00904       Numeric rte_pressure_local = 0.5 * (p_int[k] + p_int[k-1]);
00905       
00906       
00907       for (Index i = 0; i < N_species; i++)
00908         rte_vmr_list_local[i] = 0.5 * (vmr_list_int(i,k) +
00909                                        vmr_list_int(i,k-1));
00910       
00911       
00912       
00913       
00914               
00915       abs_scalar_gas_agendaExecute( ws, abs_scalar_gas_local, 
00916                                     f_index, 
00917                                     rte_pressure_local, 
00918                                     rte_temperature_local, 
00919                                     rte_vmr_list_local,
00920                                     abs_scalar_gas_agenda );
00921               
00922       opt_prop_gas_agendaExecute( ws, ext_mat_local, 
00923                                   abs_vec_local, 
00924                                   f_index, 
00925                                   abs_scalar_gas_local,
00926                                   opt_prop_gas_agenda );
00927               
00928       
00929       
00930       
00931       for (Index i = 0; i < stokes_dim; i++)
00932         {
00933           for (Index j = 0; j < stokes_dim; j++)
00934             {
00935               ext_mat_local(0,i,j) += 0.5 *
00936                 (ext_mat_int(i,j,k) + ext_mat_int(i,j,k-1));
00937             }
00938           
00939           
00940           
00941           abs_vec_local(0,i) += 0.5 * 
00942             (abs_vec_int(i,k) + abs_vec_int(i,k-1));
00943           
00944           
00945           
00946           
00947           sca_vec_av[i] =  0.5 *
00948             (sca_vec_int(i, k) + sca_vec_int(i, k-1));
00949                   
00950         }
00951       
00952       Numeric f = f_grid[f_index];
00953       
00954       
00955       
00956       Numeric rte_planck_value = planck(f, rte_temperature_local);
00957               
00958       
00959       out3 << "-----------------------------------------\n";
00960       out3 << "Input for radiative transfer step \n"
00961            << "calculation inside"
00962            << " the cloudbox:" << "\n";
00963       out3 << "Stokes vector at intersection point: \n" 
00964            << stokes_vec 
00965            << "\n"; 
00966       out3 << "l_step: ..." << l_step << "\n";
00967       out3 << "------------------------------------------\n";
00968       out3 << "Averaged coefficients: \n";
00969       out3 << "Planck function: " << rte_planck_value << "\n";
00970       out3 << "Scattering vector: " << sca_vec_av << "\n"; 
00971       out3 << "Absorption vector: " << abs_vec_local(0,joker) << "\n"; 
00972       out3 << "Extinction matrix: " << ext_mat_local(0,joker,joker) << "\n"; 
00973               
00974               
00975       assert (!is_singular( ext_mat_local(0,joker,joker)));
00976               
00977       
00978       
00979       rte_step_std(stokes_vec, Matrix(stokes_dim,stokes_dim), 
00980                    ext_mat_local(0,joker,joker), abs_vec_local(0,joker), 
00981                    sca_vec_av, l_step, rte_planck_value);
00982               
00983     }
00984   
00985   if (atmosphere_dim == 1)
00986     doit_i_field(p_index - cloudbox_limits[0], 0, 0, scat_za_index, 0, joker)
00987       = stokes_vec;
00988   else if (atmosphere_dim == 3)
00989     doit_i_field(p_index - cloudbox_limits[0],
00990                  lat_index - cloudbox_limits[2],
00991                  lon_index - cloudbox_limits[4],
00992                  scat_za_index, scat_aa_index,
00993                  joker) = stokes_vec;
00994 
00995 }
00996 
00998 
00999 
01000 
01001 
01002 
01003 
01004 
01005 
01006 
01007 void cloud_RT_surface(Workspace& ws,
01008                       
01009                       Tensor6View doit_i_field,
01010                       
01011                       const Agenda& surface_prop_agenda,
01012                       const Index& f_index,
01013                       const Index& stokes_dim,
01014                       const Ppath& ppath_step,
01015                       const ArrayOfIndex& cloudbox_limits, 
01016                       ConstVectorView scat_za_grid, 
01017                       const Index& scat_za_index
01018                      )
01019 {
01020   chk_not_empty( "surface_prop_agenda", surface_prop_agenda );
01021 
01022   Matrix iy; 
01023   
01024   
01025   Matrix surface_emission;
01026   Matrix surface_los; 
01027   Tensor4 surface_rmatrix;
01028 
01029 
01030   
01031   
01032   
01033   Index np = ppath_step.np;
01034   
01035   Vector rte_pos; 
01036   rte_pos.resize( ppath_step.pos.ncols() );
01037   rte_pos = ppath_step.pos(np-1,joker);
01038 
01039   Vector rte_los; 
01040   rte_los.resize( ppath_step.los.ncols() );
01041   rte_los = ppath_step.los(np-1,joker);
01042   
01043   GridPos dummy_ppath_step_gp_lat;
01044   GridPos dummy_ppath_step_gp_lon;
01045   
01046   
01047   
01048   
01049   surface_prop_agendaExecute(ws, surface_emission, surface_los, 
01050                              surface_rmatrix, rte_pos, rte_los, 
01051                              ppath_step.gp_p[np-1], dummy_ppath_step_gp_lat, 
01052                              dummy_ppath_step_gp_lon, surface_prop_agenda);
01053   
01054   iy = surface_emission;
01055 
01056   Vector rtmp(stokes_dim); 
01057   Index nlos = surface_los.nrows();
01058   
01059   if( nlos > 0 )
01060     {
01061       for( Index ilos=0; ilos<nlos; ilos++ )
01062         {
01063           
01064           mult( rtmp, 
01065                 surface_rmatrix(ilos,f_index,joker,joker), 
01066                 doit_i_field(cloudbox_limits[0], 0, 0,
01067                              (scat_za_grid.nelem() -1 - scat_za_index), 0,
01068                              joker) );
01069           iy(f_index,joker) += rtmp;
01070           
01071           doit_i_field(cloudbox_limits[0], 0, 0,
01072                        scat_za_index, 0,
01073                        joker) = iy(0, joker);
01074         }
01075     }  
01076 }
01077 
01078 
01110 void ppath_step_in_cloudbox(Workspace& ws,
01111                             
01112                             Ppath& ppath_step,
01113                             
01114                             const Agenda& ppath_step_agenda,
01115                             const Index& p,
01116                             const Index& lat, 
01117                             const Index& lon,
01118                             ConstTensor3View z_field,
01119                             ConstMatrixView r_geoid,
01120                             ConstMatrixView z_surface,
01121                             ConstVectorView scat_za_grid,
01122                             ConstVectorView aa_grid,
01123                             const Index& scat_za_index,
01124                             const Index& scat_aa_index,
01125                             ConstVectorView p_grid,
01126                             ConstVectorView lat_grid,
01127                             ConstVectorView lon_grid)
01128 {
01129   
01130   ppath_init_structure(ppath_step, 3, 1);
01131   
01132   
01133     
01134   
01135   
01136   ppath_step.z[0] = z_field(p, lat, lon);
01137                                   
01138   
01139   
01140   
01141   
01142 
01143   ppath_step.pos(0,0) = r_geoid(lat, lon) + ppath_step.z[0];
01144   ppath_step.pos(0,1) = lat_grid[lat];
01145   ppath_step.pos(0,2) = lon_grid[lon];
01146               
01147   
01148   ppath_step.los(0,0) = scat_za_grid[scat_za_index];
01149   ppath_step.los(0,1) = aa_grid[scat_aa_index];
01150               
01151   
01152   ppath_step.gp_p[0].idx   = p;
01153   ppath_step.gp_p[0].fd[0] = 0.;
01154   ppath_step.gp_p[0].fd[1] = 1.;
01155 
01156   ppath_step.gp_lat[0].idx   = lat;
01157   ppath_step.gp_lat[0].fd[0] = 0.;
01158   ppath_step.gp_lat[0].fd[1] = 1.;
01159                     
01160   ppath_step.gp_lon[0].idx   = lon;
01161   ppath_step.gp_lon[0].fd[0] = 0.;
01162   ppath_step.gp_lon[0].fd[1] = 1.;
01163               
01164   
01165   ppath_step_agendaExecute(ws, ppath_step, 3, p_grid,
01166                            lat_grid, lon_grid, z_field, r_geoid, z_surface,
01167                            ppath_step_agenda);
01168 }
01169 
01171 
01178 void interp_cloud_coeff1D(
01179                           Tensor3View ext_mat_int,
01180                           MatrixView abs_vec_int,
01181                           MatrixView sca_vec_int,
01182                           MatrixView doit_i_field_int,
01183                           VectorView t_int, 
01184                           MatrixView vmr_list_int,
01185                           VectorView p_int,
01186                           
01187                           ConstTensor5View ext_mat_field, 
01188                           ConstTensor4View abs_vec_field,
01189                           ConstTensor6View doit_scat_field,
01190                           ConstTensor6View doit_i_field,
01191                           ConstTensor3View t_field, 
01192                           ConstTensor4View vmr_field, 
01193                           ConstVectorView p_grid,
01194                           const Ppath& ppath_step,
01195                           const ArrayOfIndex& cloudbox_limits,
01196                           ConstVectorView scat_za_grid,
01197                           const Index& scat_za_interp)
01198 {
01199   
01200   const Index stokes_dim = doit_i_field.ncols();
01201   
01202   
01203   
01204   
01205   
01206   ArrayOfGridPos cloud_gp_p = ppath_step.gp_p;
01207   
01208   for(Index i = 0; i < ppath_step.np; i++ )
01209     cloud_gp_p[i].idx -= cloudbox_limits[0];
01210   
01211   Matrix itw(cloud_gp_p.nelem(),2);
01212   interpweights( itw, cloud_gp_p );
01213   
01214   
01215   
01216   
01217   Vector los_grid = ppath_step.los(joker,0);
01218   
01219   ArrayOfGridPos gp_za(los_grid.nelem()); 
01220   gridpos(gp_za, scat_za_grid, los_grid);
01221   
01222   Matrix itw_p_za(cloud_gp_p.nelem(), 4);
01223   interpweights(itw_p_za, cloud_gp_p, gp_za );
01224   
01225   
01226   
01227   
01228       
01229   for (Index i = 0; i < stokes_dim; i++)
01230     {
01231       
01232       
01233       out3 << "Interpolate ext_mat:\n";
01234       for (Index j = 0; j < stokes_dim; j++)
01235         {
01236           
01237           
01238           
01239           interp( ext_mat_int(i, j, joker), itw, 
01240                   ext_mat_field(joker, 0, 0, i, j), cloud_gp_p ); 
01241         }
01242       
01243       
01244       
01245       
01246       out3 << "Interpolate abs_vec:\n";
01247       interp( abs_vec_int(i,joker), itw, 
01248               abs_vec_field(joker, 0, 0, i), cloud_gp_p ); 
01249       
01250       
01251       
01252       
01253       
01254       out3 << "Interpolate doit_scat_field and doit_i_field:\n";
01255       if(scat_za_interp == 0) 
01256         {
01257           interp( sca_vec_int(i, joker), itw_p_za, 
01258                   doit_scat_field(joker, 0, 0, joker, 0, i), 
01259                   cloud_gp_p, gp_za);
01260           interp( doit_i_field_int(i, joker), itw_p_za, 
01261                   doit_i_field(joker, 0, 0, joker, 0, i), cloud_gp_p, gp_za);
01262         }
01263       else if (scat_za_interp == 1) 
01264         {
01265           
01266           
01267           
01268           Tensor3 sca_vec_int_za(stokes_dim, ppath_step.np,
01269                                  scat_za_grid.nelem(), 0.);
01270           Tensor3 doit_i_field_int_za(stokes_dim, ppath_step.np, 
01271                                       scat_za_grid.nelem(), 0.);
01272           for (Index za = 0; za < scat_za_grid.nelem(); za++)
01273             {
01274               interp( sca_vec_int_za(i, joker, za), itw, 
01275                       doit_scat_field(joker, 0, 0, za, 0, i), cloud_gp_p);
01276               out3 << "Interpolate doit_i_field:\n";
01277               interp( doit_i_field_int_za(i, joker, za), itw, 
01278                       doit_i_field(joker, 0, 0, za, 0, i), cloud_gp_p);
01279             }
01280           for (Index ip = 0; ip < ppath_step.np; ip ++)
01281             {
01282               sca_vec_int(i, ip) = 
01283                 interp_poly(scat_za_grid, sca_vec_int_za(i, ip, joker),
01284                             los_grid[ip], gp_za[ip]);
01285               doit_i_field_int(i, ip) = 
01286                 interp_poly(scat_za_grid, doit_i_field_int_za(i, ip, joker),
01287                             los_grid[ip], gp_za[ip]);
01288             }
01289         }
01290     }
01291   
01292   
01293   
01294   
01295   
01296   out3 << "Interpolate temperature field\n";
01297   interp( t_int, itw, t_field(joker, 0, 0), ppath_step.gp_p );
01298   
01299   
01300   
01301   
01302   const Index N_species = vmr_field.nbooks();
01303   
01304   
01305   
01306   
01307   Vector vmr_int(ppath_step.np);
01308       
01309   for (Index i_sp = 0; i_sp < N_species; i_sp ++)
01310     {
01311       out3 << "Interpolate vmr field\n";
01312       interp( vmr_int, itw, vmr_field(i_sp, joker, 0, 0), ppath_step.gp_p );
01313       vmr_list_int(i_sp, joker) = vmr_int;
01314     }
01315   
01316   
01317   
01318   itw2p( p_int, p_grid, ppath_step.gp_p, itw);
01319 }
01320 
01337 bool is_gp_inside_cloudbox(const GridPos& gp_p,
01338                            const GridPos& gp_lat,
01339                            const GridPos& gp_lon,
01340                            const ArrayOfIndex& cloudbox_limits,
01341                            const bool include_boundaries)
01342                         
01343 {
01344   bool result=true;
01345   
01346   double ipos = fractional_gp( gp_p );
01347   if (include_boundaries){
01348     if( ipos < double( cloudbox_limits[0] )  ||
01349         ipos > double( cloudbox_limits[1] ) )
01350       { result=false; }
01351     
01352     else {
01353       
01354       ipos = fractional_gp( gp_lat );
01355       if( ipos < double( cloudbox_limits[2] )  || 
01356           ipos > double( cloudbox_limits[3] ) )
01357         { result=false; }
01358       
01359       else
01360         {
01361           
01362           ipos = fractional_gp( gp_lon );
01363           if( ipos < double( cloudbox_limits[4] )  || 
01364               ipos > double( cloudbox_limits[5] ) )
01365             { result=false; } 
01366         }
01367     }
01368   }
01369   else
01370     {
01371       if( ipos <= double( cloudbox_limits[0] )  ||
01372           ipos >= double( cloudbox_limits[1] ) )
01373         { result=false; }
01374       
01375       else {
01376         
01377         ipos = fractional_gp( gp_lat );
01378         if( ipos <= double( cloudbox_limits[2] )  || 
01379             ipos >= double( cloudbox_limits[3] ) )
01380           { result=false; }
01381         
01382         else
01383           {
01384             
01385             ipos = fractional_gp( gp_lon );
01386             if( ipos <= double( cloudbox_limits[4] )  || 
01387                 ipos >= double( cloudbox_limits[5] ) )
01388               { result=false; }           
01389           }
01390       }
01391     }
01392   return result;
01393   
01394 }
01395 
01396 
01412 bool is_inside_cloudbox(const Ppath& ppath_step,
01413                         const ArrayOfIndex& cloudbox_limits,
01414                         const bool include_boundaries)
01415                         
01416 {
01417   const Index np=ppath_step.np;
01418   
01419   return is_gp_inside_cloudbox(ppath_step.gp_p[np-1],ppath_step.gp_lat[np-1],
01420                                ppath_step.gp_lon[np-1],cloudbox_limits,include_boundaries);
01421   
01422 }
01423 
01424 
01426 
01466 void cloud_ppath_update1D_planeparallel(Workspace& ws,
01467                                         Tensor6View doit_i_field,
01468                                         const Index& p_index,
01469                                         const Index& scat_za_index,
01470                                         ConstVectorView scat_za_grid,
01471                                         const ArrayOfIndex& cloudbox_limits,
01472                                         ConstTensor6View doit_scat_field,
01473                                         
01474                                         const Agenda& abs_scalar_gas_agenda,
01475                                         ConstTensor4View vmr_field,
01476                                         
01477                                         const Agenda& opt_prop_gas_agenda,
01478                                         
01479                                         const Agenda& ppath_step_agenda _U_,
01480                                         ConstVectorView p_grid,
01481                                         ConstTensor3View z_field,
01482                                         ConstMatrixView r_geoid,
01483                                         
01484                                         ConstTensor3View t_field,
01485                                         ConstVectorView f_grid,
01486                                         const Index& f_index,
01487                                         
01488                                         ConstTensor5View ext_mat_field,
01489                                         ConstTensor4View abs_vec_field
01490                                         )
01491 {
01492   const Index N_species = vmr_field.nbooks();
01493   const Index stokes_dim = doit_i_field.ncols();
01494   const Index atmosphere_dim = 1;   
01495   Matrix abs_scalar_gas(1, N_species, 0.);
01496   Tensor3 ext_mat;
01497   Matrix abs_vec;
01498   Vector rte_vmr_list(N_species,0.); 
01499   Vector sca_vec_av(stokes_dim,0);
01500  
01501   
01502   
01503   
01504   Vector stokes_vec(stokes_dim);
01505   Index bkgr;
01506   if((p_index == 0) && (scat_za_grid[scat_za_index] > 90))
01507     {
01508       bkgr = 2;
01509     }
01510   else
01511     {
01512       bkgr = 0;
01513     }
01514       
01515       
01516       if (bkgr == 0)
01517         {
01518           if(scat_za_grid[scat_za_index] <= 90.0)
01519             {
01520               stokes_vec = doit_i_field(p_index-cloudbox_limits[0] +1, 0, 0, scat_za_index, 0, joker);         
01521               Numeric z_field_above = z_field(p_index +1, 0, 0);
01522               Numeric z_field_0 = z_field(p_index, 0, 0);
01523              
01524               Numeric cos_theta, l_step;
01525               if (scat_za_grid[scat_za_index] == 90.0)
01526                 {
01527                   
01528                   
01529                   cos_theta = 1e-20;
01530                  
01531                 }
01532               else
01533                 {
01534                   cos_theta = cos(scat_za_grid[scat_za_index]* PI/180.0);
01535                 }
01536               Numeric dz = (z_field_above -  z_field_0);
01537               
01538               l_step =  abs(dz/cos_theta) ;
01539               
01540               
01541               Numeric rte_temperature =   0.5 * (t_field(p_index,0,0)
01542                                                  + t_field(p_index + 1,0,0));
01543               
01544               
01545               Numeric rte_pressure = 0.5 * (p_grid[p_index]
01546                                             + p_grid[p_index + 1]);
01547               
01548               
01549               for (Index j = 0; j < N_species; j++)
01550                 rte_vmr_list[j] = 0.5 * (vmr_field(j,p_index,0,0) + 
01551                                          vmr_field(j,p_index + 1,0,0));
01552               
01553               
01554               
01555               
01556               
01557               abs_scalar_gas_agendaExecute( ws, abs_scalar_gas, 
01558                                             f_index, 
01559                                             rte_pressure, 
01560                                             rte_temperature, 
01561                                             rte_vmr_list,
01562                                             abs_scalar_gas_agenda );
01563               
01564               opt_prop_gas_agendaExecute( ws, ext_mat, 
01565                                           abs_vec, 
01566                                           f_index,
01567                                           abs_scalar_gas,
01568                                           opt_prop_gas_agenda );
01569               
01570               
01571               
01572         
01573               for (Index k = 0; k < stokes_dim; k++)
01574                 {
01575                   for (Index j = 0; j < stokes_dim; j++)
01576                     {
01577                       
01578                       ext_mat(0,k,j) += 0.5 *
01579                         (ext_mat_field(p_index - cloudbox_limits[0],0,0,k,j) + 
01580                          ext_mat_field(p_index - cloudbox_limits[0]+ 1,0,0,k,j));
01581                     }
01582                   
01583                   
01584                   
01585                   abs_vec(0,k) += 0.5 * 
01586                     (abs_vec_field(p_index- cloudbox_limits[0],0,0,k) + 
01587                      abs_vec_field(p_index - cloudbox_limits[0]+ 1,0,0,k));
01588                   
01589                   
01590                   
01591                   
01592                   sca_vec_av[k] += 0.5 * 
01593                     (doit_scat_field(p_index- cloudbox_limits[0],0,0,scat_za_index,0, k) + 
01594                      doit_scat_field(p_index - cloudbox_limits[0]+ 1,0,0,scat_za_index,0,k));
01595                    
01596                 }
01597               
01598               Numeric f = f_grid[f_index];
01599               
01600               
01601               
01602               Numeric rte_planck_value = planck(f, rte_temperature);
01603               
01604               
01605               out3 << "-----------------------------------------\n";
01606               out3 << "Input for radiative transfer step \n"
01607                    << "calculation inside"
01608                    << " the cloudbox:" << "\n";
01609               out3 << "Stokes vector at intersection point: \n" 
01610                    << stokes_vec 
01611                    << "\n"; 
01612               out3 << "l_step: ..." << l_step << "\n";
01613               out3 << "------------------------------------------\n";
01614               out3 << "Averaged coefficients: \n";
01615               out3 << "Planck function: " << rte_planck_value << "\n";
01616               out3 << "Scattering vector: " << sca_vec_av << "\n"; 
01617               out3 << "Absorption vector: " << abs_vec(0,joker) << "\n"; 
01618               out3 << "Extinction matrix: " << ext_mat(0,joker,joker) << "\n"; 
01619               
01620               
01621               assert (!is_singular( ext_mat(0,joker,joker)));
01622               
01623               
01624               
01625               rte_step_std(stokes_vec, Matrix(stokes_dim,stokes_dim), 
01626                            ext_mat(0,joker,joker), abs_vec(0,joker), 
01627                            sca_vec_av, l_step, rte_planck_value);
01628               
01629               
01630               doit_i_field(p_index - cloudbox_limits[0],
01631                       0, 0,
01632                       scat_za_index, 0,
01633                       joker) = stokes_vec;
01634             }
01635           if(scat_za_grid[scat_za_index] > 90)
01636             {
01637               stokes_vec = doit_i_field(p_index-cloudbox_limits[0] -1, 0, 0, scat_za_index, 0, joker);
01638               Numeric z_field_below = z_field(p_index -1, 0, 0);
01639               Numeric z_field_0 = z_field(p_index, 0, 0);
01640               
01641               Numeric cos_theta, l_step;
01642               if (scat_za_grid[scat_za_index] == 90.0)
01643                 {
01644                   cos_theta = cos((scat_za_grid[scat_za_index] -1)*PI/180.);
01645                   
01646                   
01647                 }
01648               else
01649                 {
01650                   cos_theta = cos(scat_za_grid[scat_za_index]* PI/180.0);
01651                 }
01652               Numeric dz = ( z_field_0 - z_field_below);
01653               l_step =  abs(dz/cos_theta) ;
01654               
01655               
01656               Numeric rte_temperature =   0.5 * (t_field(p_index,0,0)
01657                                                  + t_field(p_index - 1,0,0));
01658               
01659               
01660               Numeric rte_pressure = 0.5 * (p_grid[p_index]
01661                                             + p_grid[p_index - 1]);
01662               
01663               
01664               
01665               for (Index k = 0; k < N_species; k++)
01666                 rte_vmr_list[k] = 0.5 * (vmr_field(k,p_index,0,0) + 
01667                                          vmr_field(k,p_index - 1,0,0));
01668               
01669               
01670               
01671               
01672 
01673               abs_scalar_gas_agendaExecute( ws, abs_scalar_gas, 
01674                                             f_index, 
01675                                             rte_pressure, 
01676                                             rte_temperature, 
01677                                             rte_vmr_list,
01678                                             abs_scalar_gas_agenda );
01679 
01680               opt_prop_gas_agendaExecute( ws, ext_mat, 
01681                                           abs_vec, 
01682                                           f_index,
01683                                           abs_scalar_gas,
01684                                           opt_prop_gas_agenda );
01685 
01686               
01687               
01688               
01689              
01690               
01691 
01692               for (Index k = 0; k < stokes_dim; k++)
01693                 {
01694                   for (Index j = 0; j < stokes_dim; j++)
01695                     {
01696                       
01697                       ext_mat(0,k,j) += 0.5 *
01698                         (ext_mat_field(p_index - cloudbox_limits[0],0,0,k,j) + 
01699                          ext_mat_field(p_index  - cloudbox_limits[0]- 1,0,0,k,j));
01700                     }
01701                   
01702                   
01703                   
01704                   abs_vec(0,k) += 0.5 * 
01705                     (abs_vec_field(p_index - cloudbox_limits[0],0,0,k) + 
01706                      abs_vec_field(p_index  - cloudbox_limits[0]- 1,0,0,k));
01707                   
01708                   
01709                   
01710                   
01711                   sca_vec_av[k] += 0.5 * 
01712                     (doit_scat_field(p_index- cloudbox_limits[0],0,0,scat_za_index,0, k) + 
01713                      doit_scat_field(p_index - cloudbox_limits[0]- 1,0,0,scat_za_index,0,k));
01714                   
01715                 }
01716               
01717               Numeric f = f_grid[f_index];
01718               
01719               
01720               
01721               Numeric rte_planck_value = planck(f, rte_temperature);
01722               
01723               
01724               out3 << "-----------------------------------------\n";
01725               out3 << "Input for radiative transfer step \n"
01726                    << "calculation inside"
01727                    << " the cloudbox:" << "\n";
01728               out3 << "Stokes vector at intersection point: \n" 
01729                    << stokes_vec 
01730                    << "\n"; 
01731               out3 << "l_step: ..." << l_step << "\n";
01732               out3 << "------------------------------------------\n";
01733               out3 << "Averaged coefficients: \n";
01734               out3 << "Planck function: " << rte_planck_value << "\n";
01735               out3 << "Scattering vector: " << sca_vec_av << "\n"; 
01736               out3 << "Absorption vector: " << abs_vec(0,joker) << "\n"; 
01737               out3 << "Extinction matrix: " << ext_mat(0,joker,joker) << "\n"; 
01738               
01739               
01740               assert (!is_singular( ext_mat(0,joker,joker)));
01741               
01742               
01743               
01744               rte_step_std(stokes_vec, Matrix(stokes_dim,stokes_dim), 
01745                            ext_mat(0,joker,joker), abs_vec(0,joker), 
01746                            sca_vec_av, l_step, rte_planck_value);
01747               
01748               
01749               doit_i_field(p_index - cloudbox_limits[0],
01750                       0, 0,
01751                       scat_za_index, 0,
01752                       joker) = stokes_vec;
01753             }
01754           
01755         
01756         }
01757       
01758       
01759       else if (bkgr == 2)
01760         {
01761           
01762           
01763           
01764           Vector rte_pos( atmosphere_dim );
01765           Numeric z_field_0 = z_field(0, 0, 0);
01766           rte_pos = z_field_0 + r_geoid(0,0);
01767           
01768           Vector rte_los(1);
01769           rte_los = scat_za_grid[scat_za_index];
01770           
01771           
01772           
01773           
01774           
01775           
01776           
01777           
01778           
01779 
01780       throw runtime_error( 
01781                      "Surface reflections inside cloud box not yet handled." );
01782       
01783 
01784 
01785 
01786 
01787 
01788 
01789 
01790 
01791 
01792 
01793 
01794 
01795 
01796 
01797 
01798 
01799 
01800 
01801 
01802 
01803 
01804 
01805 
01806 
01807 
01808 
01809 
01810 
01811 
01812 
01813 
01814 
01815 
01816 
01817 
01818 
01819 
01820 
01821 
01822 
01823 
01824 
01825 
01826 
01827 
01828 
01829 
01830 
01831 
01832 
01833 
01834 
01835 
01836 
01837 
01838 
01839 
01840 
01841 
01842 
01843 
01844 
01845 
01846 
01847 
01848 
01849 
01850 
01851 
01852 
01853 
01854 
01855 
01856 
01857 
01858 
01859 
01860 
01861 
01862 
01863 
01864 
01865 
01866 
01867 
01868 
01869 
01870 
01871 
01872 
01873 
01874 
01875 
01876 
01877 
01878 
01879 
01880 
01881 
01882 
01883 
01884 
01885 
01886 
01887 
01888 
01889 
01890 
01891 
01892 
01893 
01894 
01895 
01896 
01897 
01898 
01899 
01900 
01901 
01902 
01903 
01904 
01905 
01906 
01907 
01908 
01909 
01910 
01911 
01912 
01913 
01914 
01915 
01916 
01917 
01918 
01919 
01920 
01921 
01922 
01923 
01924 
01925 
01926 
01927 
01928 
01929 
01930 
01931 
01932 
01933 
01934 
01935 
01936   
01937         }
01938 }
01939 
01940 
01941 
01942 
01966 void za_gridOpt(
01967                 Vector& za_grid_opt,
01968                 Matrix& doit_i_field_opt,
01969                 
01970                 ConstVectorView za_grid_fine,
01971                 ConstTensor6View doit_i_field,
01972                 const Numeric& acc,
01973                 const Index& scat_za_interp)
01974 {
01975   Index N_za = za_grid_fine.nelem();
01976 
01977   assert(doit_i_field.npages() == N_za);
01978   
01979   Index N_p = doit_i_field.nvitrines();
01980   
01981   Vector i_approx_interp(N_za);
01982   Vector za_reduced(2);
01983 
01984   ArrayOfIndex idx;
01985   idx.push_back(0);
01986   idx.push_back(N_za-1);
01987   ArrayOfIndex idx_unsorted;
01988 
01989   Numeric max_diff = 100;
01990 
01991   ArrayOfGridPos gp_za(N_za);
01992   Matrix itw(za_grid_fine.nelem(), 2);
01993 
01994   ArrayOfIndex i_sort;
01995   Vector diff_vec(N_za);
01996   Vector max_diff_za(N_p);
01997   ArrayOfIndex ind_za(N_p);
01998   Numeric max_diff_p;
01999   Index ind_p=0;
02000   
02001   while( max_diff > acc )
02002     {
02003       za_reduced.resize(idx.nelem());
02004       doit_i_field_opt.resize(N_p, idx.nelem());
02005       max_diff_za = 0.;
02006       max_diff_p = 0.;
02007 
02008       
02009       
02010       for( Index i_p = 0; i_p < N_p; i_p++ )
02011         {
02012           for( Index i_za_red = 0; i_za_red < idx.nelem(); i_za_red ++)
02013             {
02014               za_reduced[i_za_red] = za_grid_fine[idx[i_za_red]];
02015               doit_i_field_opt(i_p, i_za_red) = doit_i_field(i_p, 0, 0, idx[i_za_red], 
02016                                                    0, 0);
02017             }
02018           
02019           gridpos(gp_za, za_reduced, za_grid_fine); 
02020           
02021           if(scat_za_interp == 0 || idx.nelem() < 3)
02022             {
02023               interpweights(itw, gp_za);
02024               interp(i_approx_interp, itw, doit_i_field_opt(i_p, joker), gp_za);
02025             }
02026           else if(scat_za_interp == 1)
02027             {
02028               for(Index i_za = 0; i_za < N_za; i_za ++)
02029                 {
02030                   i_approx_interp[i_za] = 
02031                     interp_poly(za_reduced, doit_i_field_opt(i_p, joker),
02032                                  za_grid_fine[i_za],
02033                                  gp_za[i_za]);
02034                 }
02035             }
02036           else
02037             
02038             assert(false);
02039           
02040           
02041           
02042           for (Index i_za = 0; i_za < N_za; i_za ++)
02043             {
02044               diff_vec[i_za]  =  abs( doit_i_field(i_p, 0, 0, i_za, 0 ,0)
02045                                       -  i_approx_interp[i_za]);
02046               if( diff_vec[i_za] > max_diff_za[i_p] )
02047                 {
02048                   max_diff_za[i_p] = diff_vec[i_za];
02049                   ind_za[i_p] = i_za;
02050                 }
02051             }
02052           
02053           if( max_diff_za[i_p] > max_diff_p )
02054             {
02055               max_diff_p = max_diff_za[i_p];
02056               ind_p = i_p;
02057             }
02058         }
02059       
02060       
02061       
02062       max_diff = max_diff_p/doit_i_field(ind_p, 0, 0, ind_za[ind_p], 0, 0)*100.;
02063       
02064       idx.push_back(ind_za[ind_p]);
02065       idx_unsorted = idx;
02066 
02067       i_sort.resize(idx_unsorted.nelem());
02068       get_sorted_indexes(i_sort, idx_unsorted);
02069       
02070       for (Index i = 0; i<idx_unsorted.nelem(); i++)
02071         idx[i] = idx_unsorted[i_sort[i]];
02072   
02073       za_reduced.resize(idx.nelem());
02074     }
02075    
02076   za_grid_opt.resize(idx.nelem());
02077   doit_i_field_opt.resize(N_p, idx.nelem());
02078   for(Index i = 0; i<idx.nelem(); i++)
02079     {
02080       za_grid_opt[i] = za_grid_fine[idx[i]];
02081       doit_i_field_opt(joker, i) = doit_i_field(joker, 0, 0, idx[i], 0, 0);
02082     }
02083 }
02084           
02085 
02086 
02087             
02088                     
02089 
02090   
02091