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