ARTS  2.4.0(git:4fb77825)
doit.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2012 Claudia Emde <claudia.emde@dlr.de>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA.
17 */
18 
29 /*===========================================================================
30  === External declarations
31  ===========================================================================*/
32 
33 #include "doit.h"
34 #include <cmath>
35 #include <cstdlib>
36 #include <iostream>
37 #include <stdexcept>
38 #include "agenda_class.h"
39 #include "array.h"
40 #include "auto_md.h"
41 #include "check_input.h"
42 #include "cloudbox.h"
43 #include "geodetic.h"
44 #include "lin_alg.h"
45 #include "logic.h"
46 #include "math_funcs.h"
47 #include "matpackVII.h"
48 #include "messages.h"
49 #include "physics_funcs.h"
50 #include "ppath.h"
51 #include "propagationmatrix.h"
52 #include "rte.h"
53 #include "sorting.h"
54 #include "special_interp.h"
55 #include "xml_io.h"
56 
57 extern const Numeric PI;
58 extern const Numeric RAD2DEG;
59 
60 //FIXME function name of 'rte_step_doit_replacement' should be replaced by
61 //proper name
62 void rte_step_doit_replacement( //Output and Input:
63  VectorView stokes_vec,
64  MatrixView trans_mat,
65  //Input
66  const PropagationMatrix& ext_mat_av,
67  const StokesVector& abs_vec_av,
68  ConstVectorView sca_vec_av,
69  const Numeric& lstep,
70  const Numeric& rtp_planck_value,
71  const bool& trans_is_precalc) {
72  //Stokes dimension:
73  Index stokes_dim = stokes_vec.nelem();
74 
75  //Test sizes
76  assert(ext_mat_av.NumberOfFrequencies() == 1 and
77  abs_vec_av.NumberOfFrequencies() == 1);
78 
79  //Check inputs:
80  assert(is_size(trans_mat, 1, stokes_dim, stokes_dim));
81  assert(stokes_dim == ext_mat_av.StokesDimensions() and
82  stokes_dim == abs_vec_av.StokesDimensions());
83  assert(is_size(sca_vec_av, stokes_dim));
84  assert(rtp_planck_value >= 0);
85  assert(lstep >= 0);
86  //assert (not ext_mat_av.AnySingular()); This is asserted at a later time in this version...
87 
88  // Check, if only the first component of abs_vec is non-zero:
89 // const bool unpol_abs_vec = abs_vec_av.IsUnpolarized(0);
90 
91 // bool unpol_sca_vec = true;
92 
93 // for (Index i = 1; i < stokes_dim; i++)
94 // if (sca_vec_av[i] != 0) unpol_sca_vec = false;
95 
96  // Calculate transmission by general function, if not precalculated
97 // Index extmat_case = 0;
98  if (!trans_is_precalc) {
100  trans_mat, lstep, ext_mat_av, 0);
101  }
102 
103  //--- Scalar case: ---------------------------------------------------------
104  if (stokes_dim == 1) {
105  stokes_vec[0] = stokes_vec[0] * trans_mat(0, 0) +
106  (abs_vec_av.Kjj()[0] * rtp_planck_value + sca_vec_av[0]) /
107  ext_mat_av.Kjj()[0] * (1 - trans_mat(0, 0));
108  }
109 
110  //--- Vector case: ---------------------------------------------------------
111 
112  // We have here two cases, diagonal or non-diagonal ext_mat_gas
113  // For diagonal ext_mat_gas, we expect abs_vec_gas to only have a
114  // non-zero value in position 1.
115 
116  //- Unpolarised
117 // else if (extmat_case == 1 && unpol_abs_vec && unpol_sca_vec) {
118 // const Numeric invK = 1.0 / ext_mat_av.Kjj()[0];
119 // // Stokes dim 1
120 // stokes_vec[0] = stokes_vec[0] * trans_mat(0, 0) +
121 // (abs_vec_av.Kjj()[0] * rtp_planck_value + sca_vec_av[0]) *
122 // invK * (1 - trans_mat(0, 0));
123 //
124 // // Stokes dims > 1
125 // for (Index i = 1; i < stokes_dim; i++) {
126 // stokes_vec[i] = stokes_vec[i] * trans_mat(i, i) +
127 // sca_vec_av[i] * invK * (1 - trans_mat(i, i));
128 // }
129 // }
130 
131  //- General case
132  else {
134  ext_mat_av.MatrixInverseAtPosition(invK);
135 
136  Vector source = abs_vec_av.VectorAtPosition();
137  source *= rtp_planck_value;
138 
139  for (Index i = 0; i < stokes_dim; i++)
140  source[i] += sca_vec_av[i]; // b = abs_vec * B + sca_vec
141 
142  // solve K^(-1)*b = x
144  mult(x, invK, source);
145 
146  Vector term1(stokes_dim);
147  Vector term2(stokes_dim);
148 
150  id_mat(ImT);
151  ImT -= trans_mat;
152  mult(term2, ImT, x); // term2: second term of the solution of the RTE with
153  //fixed scattered field
154 
155  // term1: first term of solution of the RTE with fixed scattered field
156  mult(term1, trans_mat, stokes_vec);
157 
158  for (Index i = 0; i < stokes_dim; i++)
159  stokes_vec[i] = term1[i] + term2[i]; // Compute the new Stokes Vector
160  }
161 }
162 
164  // Output and Input:
165  Tensor5View ext_mat_field,
166  Tensor4View abs_vec_field,
167  // Input:
168  const Agenda& spt_calc_agenda,
169  const Index& za_index,
170  const Index& aa_index,
174  const Verbosity& verbosity) {
175  CREATE_OUT3;
176 
177  // Input variables are checked in the WSMs i_fieldUpdateSeqXXX, from
178  // where this function is called.
179 
180  out3 << "Calculate scattering properties in cloudbox \n";
181 
182  const Index atmosphere_dim = cloudbox_limits.nelem() / 2;
183  const Index N_se = pnd_field.nbooks();
184  const Index stokes_dim = ext_mat_field.ncols();
185 
186  assert(atmosphere_dim == 1 || atmosphere_dim == 3);
187  assert(ext_mat_field.ncols() == ext_mat_field.nrows() &&
188  ext_mat_field.ncols() == abs_vec_field.ncols());
189 
190  const Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
191 
192  // If atmosohere_dim == 1
193  Index Nlat_cloud = 1;
194  Index Nlon_cloud = 1;
195 
196  if (atmosphere_dim == 3) {
197  Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
198  Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
199  }
200 
201  // Initialize ext_mat(_spt), abs_vec(_spt)
202  // Resize and initialize variables for storing optical properties
203  // of all scattering elements.
204  ArrayOfStokesVector abs_vec_spt_local(N_se);
205  for (auto& av : abs_vec_spt_local) {
206  av = StokesVector(1, stokes_dim);
207  av.SetZero();
208  }
209  ArrayOfPropagationMatrix ext_mat_spt_local(N_se);
210  for (auto& pm : ext_mat_spt_local) {
211  pm = PropagationMatrix(1, stokes_dim);
212  pm.SetZero();
213  }
214 
215  StokesVector abs_vec_local;
216  PropagationMatrix ext_mat_local;
217  Numeric rtp_temperature_local;
218 
219  // Calculate ext_mat, abs_vec for all points inside the cloudbox.
220  // sca_vec can be obtained from the workspace variable doit_scat_field.
221  // As we need the average for each layer, it makes sense to calculte
222  // the coefficients once and store them in an array instead of
223  // calculating at each point the coefficient of the point above and
224  // the point below.
225  // To use special interpolation functions for atmospheric fields we
226  // use ext_mat_field and abs_vec_field:
227 
228  // Loop over all positions inside the cloudbox defined by the
229  // cloudbox_limits.
230  for (Index scat_p_index_local = 0; scat_p_index_local < Np_cloud;
231  scat_p_index_local++) {
232  for (Index scat_lat_index_local = 0; scat_lat_index_local < Nlat_cloud;
233  scat_lat_index_local++) {
234  for (Index scat_lon_index_local = 0; scat_lon_index_local < Nlon_cloud;
235  scat_lon_index_local++) {
236  if (atmosphere_dim == 1)
237  rtp_temperature_local =
238  t_field(scat_p_index_local + cloudbox_limits[0], 0, 0);
239  else
240  rtp_temperature_local =
241  t_field(scat_p_index_local + cloudbox_limits[0],
242  scat_lat_index_local + cloudbox_limits[2],
243  scat_lon_index_local + cloudbox_limits[4]);
244 
245  //Calculate optical properties for individual scattering elements:
246  //( Execute agendas silently. )
248  ext_mat_spt_local,
249  abs_vec_spt_local,
250  scat_p_index_local,
251  scat_lat_index_local,
252  scat_lon_index_local,
253  rtp_temperature_local,
254  za_index,
255  aa_index,
257  /*
258 // so far missing here (accessed through workspace within agenda):
259 // - scat_data
260 // - za_grid, aa_grid
261 // - f_index
262  opt_prop_sptFromScat_data(ext_mat_spt_local, abs_vec_spt_local,
263  scat_data, 1,
264  za_grid, aa_grid,
265  za_index, aa_index,
266  f_index,
267  rtp_temperature_local,
268  pnd_field,
269  scat_p_index_local,
270  scat_lat_index_local,
271  scat_lon_index_local,
272  verbosity);
273 */
274 
275  opt_prop_bulkCalc(ext_mat_local,
276  abs_vec_local,
277  ext_mat_spt_local,
278  abs_vec_spt_local,
279  pnd_field,
280  scat_p_index_local,
281  scat_lat_index_local,
282  scat_lon_index_local,
283  verbosity);
284 
285  // Store coefficients in arrays for the whole cloudbox.
286  abs_vec_field(scat_p_index_local,
287  scat_lat_index_local,
288  scat_lon_index_local,
289  joker) = abs_vec_local.VectorAtPosition();
290 
291  ext_mat_local.MatrixAtPosition(ext_mat_field(scat_p_index_local,
292  scat_lat_index_local,
293  scat_lon_index_local,
294  joker,
295  joker));
296  }
297  }
298  }
299 }
300 
302  // Input and output
304  // ppath_step_agenda:
305  const Index& p_index,
306  const Index& za_index,
310  // Calculate scalar gas absorption:
313  // Propagation path calculation:
314  const Agenda& ppath_step_agenda,
315  const Numeric& ppath_lmax,
316  const Numeric& ppath_lraytrace,
320  // Calculate thermal emission:
323  const Index& f_index,
324  //particle optical properties
325  ConstTensor5View ext_mat_field,
326  ConstTensor4View abs_vec_field,
328  //const Agenda& surface_rtprop_agenda,
329  const Index& scat_za_interp,
330  const Verbosity& verbosity) {
332  // Input variables are checked in the WSMs i_fieldUpdateSeqXXX, from
333  // where this function is called.
334 
335  //Initialize ppath for 1D.
337  // See documentation of ppath_init_structure for understanding
338  // the parameters.
339 
340  // Assign value to ppath.pos:
341  ppath_step.pos(0, 0) = z_field(p_index, 0, 0);
342  ppath_step.r[0] = refellipsoid[0] + z_field(p_index, 0, 0);
343 
344  // Define the direction:
345  ppath_step.los(0, 0) = za_grid[za_index];
346 
347  // Define the grid positions:
348  ppath_step.gp_p[0].idx = p_index;
349  ppath_step.gp_p[0].fd[0] = 0;
350  ppath_step.gp_p[0].fd[1] = 1;
351 
352  // Call ppath_step_agenda:
354  ppath_step,
355  ppath_lmax,
357  Vector(1, f_grid[f_index]),
359 
360  // Check whether the next point is inside or outside the
361  // cloudbox. Only if the next point lies inside the
362  // cloudbox a radiative transfer step caclulation has to
363  // be performed.
364 
365  if ((cloudbox_limits[0] <= ppath_step.gp_p[1].idx &&
366  cloudbox_limits[1] > ppath_step.gp_p[1].idx) ||
367  (cloudbox_limits[1] == ppath_step.gp_p[1].idx &&
368  abs(ppath_step.gp_p[1].fd[0]) < 1e-6)) {
369  // Stokes dimension
370  const Index stokes_dim = cloudbox_field_mono.ncols();
371  // Number of species
372  const Index N_species = vmr_field.nbooks();
373 
374  // Ppath_step normally has 2 points, the starting
375  // point and the intersection point.
376  // But there can be points in between, when a maximum
377  // lstep is given. We have to interpolate on all the
378  // points in the ppath_step.
379 
380  // Initialize variables for interpolated values
381  Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np, 0.);
382  Matrix abs_vec_int(stokes_dim, ppath_step.np, 0.);
383  Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
384  Matrix cloudbox_field_mono_int(stokes_dim, ppath_step.np, 0.);
385  Vector t_int(ppath_step.np, 0.);
386  Matrix vmr_list_int(N_species, ppath_step.np, 0.);
387  Vector p_int(ppath_step.np, 0.);
388 
389  interp_cloud_coeff1D(ext_mat_int,
390  abs_vec_int,
391  sca_vec_int,
392  cloudbox_field_mono_int,
393  t_int,
394  vmr_list_int,
395  p_int,
396  ext_mat_field,
397  abs_vec_field,
400  t_field,
401  vmr_field,
402  p_grid,
403  ppath_step,
405  za_grid,
406  scat_za_interp,
407  verbosity);
408 
409  // ppath_what_background(ppath_step) tells the
410  // radiative background. More information in the
411  // function get_iy_of_background.
412  // if there is no background we proceed the RT
414 
415  // Radiative transfer from one layer to the next, starting
416  // at the intersection with the next layer and propagating
417  // to the considered point.
421  ppath_step,
422  t_int,
423  vmr_list_int,
424  ext_mat_int,
425  abs_vec_int,
426  sca_vec_int,
427  cloudbox_field_mono_int,
428  p_int,
430  f_grid,
431  f_index,
432  p_index,
433  0,
434  0,
435  za_index,
436  0,
437  verbosity);
438 
439  // bkgr=2 indicates that the background is the surface
440  if (bkgr == 2) {
441  // cout << "hit surface "<< ppath_step.gp_p << endl;
442  cloud_RT_surface(ws,
445  f_grid,
446  f_index,
447  stokes_dim,
448  ppath_step,
450  za_grid,
451  za_index);
452  }
453 
454  } //end if inside cloudbox
455 }
456 
458  // Output
460  // ppath_step_agenda:
461  const Index& p_index,
462  const Index& za_index,
467  // Calculate scalar gas absorption:
470  // Propagation path calculation:
471  const Agenda& ppath_step_agenda,
472  const Numeric& ppath_lmax,
473  const Numeric& ppath_lraytrace,
477  // Calculate thermal emission:
480  // used for surface ?
481  const Index& f_index,
482  //particle optical properties
483  ConstTensor5View ext_mat_field,
484  ConstTensor4View abs_vec_field,
486  const Index& scat_za_interp,
487  const Verbosity& verbosity) {
489  // Input variables are checked in the WSMs i_fieldUpdateSeqXXX, from
490  // where this function is called.
491 
492  //Initialize ppath for 1D.
494  // See documentation of ppath_init_structure for understanding
495  // the parameters.
496 
497  // Assign value to ppath.pos:
498  ppath_step.pos(0, 0) = z_field(p_index, 0, 0);
499  ppath_step.r[0] = refellipsoid[0] + z_field(p_index, 0, 0);
500 
501  // Define the direction:
502  ppath_step.los(0, 0) = za_grid[za_index];
503 
504  // Define the grid positions:
505  ppath_step.gp_p[0].idx = p_index;
506  ppath_step.gp_p[0].fd[0] = 0;
507  ppath_step.gp_p[0].fd[1] = 1;
508 
509  // Call ppath_step_agenda:
511  ppath_step,
512  ppath_lmax,
514  Vector(1, f_grid[f_index]),
516 
517  // Check whether the next point is inside or outside the
518  // cloudbox. Only if the next point lies inside the
519  // cloudbox a radiative transfer step caclulation has to
520  // be performed.
521 
522  if ((cloudbox_limits[0] <= ppath_step.gp_p[1].idx &&
523  cloudbox_limits[1] > ppath_step.gp_p[1].idx) ||
524  (cloudbox_limits[1] == ppath_step.gp_p[1].idx &&
525  abs(ppath_step.gp_p[1].fd[0]) < 1e-6)) {
526  // Stokes dimension
527  const Index stokes_dim = cloudbox_field_mono.ncols();
528  // Number of species
529  const Index N_species = vmr_field.nbooks();
530 
531  // Ppath_step normally has 2 points, the starting
532  // point and the intersection point.
533  // But there can be points in between, when a maximum
534  // lstep is given. We have to interpolate on all the
535  // points in the ppath_step.
536 
537  // Initialize variables for interpolated values
538  Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np, 0.);
539  Matrix abs_vec_int(stokes_dim, ppath_step.np, 0.);
540  Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
541  Matrix cloudbox_field_mono_int(stokes_dim, ppath_step.np, 0.);
542  Vector t_int(ppath_step.np, 0.);
543  Matrix vmr_list_int(N_species, ppath_step.np, 0.);
544  Vector p_int(ppath_step.np, 0.);
545 
546  interp_cloud_coeff1D(ext_mat_int,
547  abs_vec_int,
548  sca_vec_int,
549  cloudbox_field_mono_int,
550  t_int,
551  vmr_list_int,
552  p_int,
553  ext_mat_field,
554  abs_vec_field,
557  t_field,
558  vmr_field,
559  p_grid,
560  ppath_step,
562  za_grid,
563  scat_za_interp,
564  verbosity);
565 
566  // ppath_what_background(ppath_step) tells the
567  // radiative background. More information in the
568  // function get_iy_of_background.
569  // if there is no background we proceed the RT
571 
572  // if 0, there is no background
573  // do this in any case. cause we need downwelling cloudbox_field_mono
574  // at the surface for calculating surface scattering
575 
576  // Radiative transfer from one layer to the next, starting
577  // at the intersection with the next layer and propagating
578  // to the considered point.
582  ppath_step,
583  t_int,
584  vmr_list_int,
585  ext_mat_int,
586  abs_vec_int,
587  sca_vec_int,
588  cloudbox_field_mono_int,
589  p_int,
591  f_grid,
592  f_index,
593  p_index,
594  0,
595  0,
596  za_index,
597  0,
598  verbosity);
599 
600  if (bkgr == 2) {
601  cloud_RT_surface(ws,
604  f_grid,
605  f_index,
606  stokes_dim,
607  ppath_step,
609  za_grid,
610  za_index);
611  }
612  } //end if inside cloudbox
613 }
614 
617  const Index& p_index,
618  const Index& za_index,
622  // Calculate scalar gas absorption:
625  // Propagation path calculation:
628  // Calculate thermal emission:
631  const Index& f_index,
632  //particle opticla properties
633  ConstTensor5View ext_mat_field,
634  ConstTensor4View abs_vec_field,
635  const Verbosity& verbosity) {
636  CREATE_OUT3;
637 
638  const Index N_species = vmr_field.nbooks();
639  const Index stokes_dim = cloudbox_field_mono.ncols();
640  const Index atmosphere_dim = 1;
644  Matrix matrix_tmp(stokes_dim, stokes_dim);
645  Vector vector_tmp(stokes_dim);
646  Vector rtp_vmr(N_species, 0.);
647  EnergyLevelMap rtp_nlte_dummy;
648  Vector sca_vec_av(stokes_dim, 0);
649 
650  // Radiative transfer from one layer to the next, starting
651  // at the intersection with the next layer and propagating
652  // to the considered point.
653  Vector stokes_vec(stokes_dim);
654  Index bkgr;
655  if ((p_index == 0) && (za_grid[za_index] > 90)) {
656  bkgr = 2;
657  } else {
658  bkgr = 0;
659  }
660 
661  // if 0, there is no background
662  if (bkgr == 0) {
663  if (za_grid[za_index] <= 90.0) {
664  stokes_vec = cloudbox_field_mono(
665  p_index - cloudbox_limits[0] + 1, 0, 0, za_index, 0, joker);
666  Numeric z_field_above = z_field(p_index + 1, 0, 0);
667  Numeric z_field_0 = z_field(p_index, 0, 0);
668 
669  Numeric cos_theta, lstep;
670  if (za_grid[za_index] == 90.0) {
671  //cos_theta = cos((za_grid[za_index] -1)*PI/180.);
672  // cos_theta = cos(89.999999999999*PI/180.);
673  cos_theta = 1e-20;
674 
675  } else {
676  cos_theta = cos(za_grid[za_index] * PI / 180.0);
677  }
678  Numeric dz = (z_field_above - z_field_0);
679 
680  lstep = abs(dz / cos_theta);
681 
682  // Average temperature
684  0.5 * (t_field(p_index, 0, 0) + t_field(p_index + 1, 0, 0));
685  //
686  // Average pressure
687  Numeric rtp_pressure = 0.5 * (p_grid[p_index] + p_grid[p_index + 1]);
688 
689  // Average vmrs
690  for (Index j = 0; j < N_species; j++)
691  rtp_vmr[j] = 0.5 * (vmr_field(j, p_index, 0, 0) +
692  vmr_field(j, p_index + 1, 0, 0));
693  //
694  // Calculate scalar gas absorption and add it to abs_vec
695  // and ext_mat.
696  //
697 
698  const Vector rtp_mag_dummy(3, 0);
699  const Vector ppath_los_dummy;
700 
701  ArrayOfStokesVector nlte_dummy; //FIXME: do this right?
703  partial_dummy; // This is right since there should be only clearsky partials
704  ArrayOfStokesVector partial_source_dummy,
705  partial_nlte_dummy; // This is right since there should be only clearsky partials
708  nlte_dummy,
709  partial_dummy,
710  partial_source_dummy,
711  partial_nlte_dummy,
713  f_grid[Range(f_index, 1)],
714  rtp_mag_dummy,
715  ppath_los_dummy,
716  rtp_pressure,
718  rtp_nlte_dummy,
719  rtp_vmr,
721 
723 
724  for (Index k = 0; k < stokes_dim; k++) {
725  //
726  // Averaging of sca_vec:
727  //
728  sca_vec_av[k] +=
729  0.5 *
731  p_index - cloudbox_limits[0], 0, 0, za_index, 0, k) +
733  p_index - cloudbox_limits[0] + 1, 0, 0, za_index, 0, k));
734  }
735 
736  //
737  // Add average particle absorption to abs_vec.
738  //
739  abs_vec.AddAverageAtPosition(
740  abs_vec_field(p_index - cloudbox_limits[0], 0, 0, joker),
741  abs_vec_field(p_index - cloudbox_limits[0] + 1, 0, 0, joker));
742 
743  //
744  // Add average particle extinction to ext_mat.
745  ext_mat.AddAverageAtPosition(
746  ext_mat_field(p_index - cloudbox_limits[0], 0, 0, joker, joker),
747  ext_mat_field(p_index - cloudbox_limits[0] + 1, 0, 0, joker, joker));
748 
749  // Frequency
750  Numeric f = f_grid[f_index];
751  //
752  // Calculate Planck function
753  //
754  Numeric rte_planck_value = planck(f, rtp_temperature);
755 
756  // Some messages:
757  if (out3.sufficient_priority()) {
758  vector_tmp = abs_vec.VectorAtPosition();
759  ext_mat.MatrixAtPosition(matrix_tmp);
760  out3 << "-----------------------------------------\n";
761  out3 << "Input for radiative transfer step \n"
762  << "calculation inside"
763  << " the cloudbox:"
764  << "\n";
765  out3 << "Stokes vector at intersection point: \n" << stokes_vec << "\n";
766  out3 << "lstep: ..." << lstep << "\n";
767  out3 << "------------------------------------------\n";
768  out3 << "Averaged coefficients: \n";
769  out3 << "Planck function: " << rte_planck_value << "\n";
770  out3 << "Scattering vector: " << sca_vec_av << "\n";
771  out3 << "Absorption vector: " << vector_tmp << "\n";
772  out3 << "Extinction matrix: " << matrix_tmp << "\n";
773 
774  assert(!is_singular(matrix_tmp));
775  }
776 
777  // Radiative transfer step calculation. The Stokes vector
778  // is updated until the considered point is reached.
779  rte_step_doit_replacement(stokes_vec,
781  ext_mat,
782  abs_vec,
783  sca_vec_av,
784  lstep,
785  rte_planck_value);
786 
787  // Assign calculated Stokes Vector to cloudbox_field_mono.
789  p_index - cloudbox_limits[0], 0, 0, za_index, 0, joker) =
790  stokes_vec;
791  }
792  if (za_grid[za_index] > 90) {
793  stokes_vec = cloudbox_field_mono(
794  p_index - cloudbox_limits[0] - 1, 0, 0, za_index, 0, joker);
795  Numeric z_field_below = z_field(p_index - 1, 0, 0);
796  Numeric z_field_0 = z_field(p_index, 0, 0);
797 
798  Numeric cos_theta, lstep;
799  if (za_grid[za_index] == 90.0) {
800  cos_theta = cos((za_grid[za_index] - 1) * PI / 180.);
801  //cos_theta = cos(90.00000001*PI/180.);
802  //cout<<"cos_theta"<<cos_theta<<endl;
803  } else {
804  cos_theta = cos(za_grid[za_index] * PI / 180.0);
805  }
806  Numeric dz = (z_field_0 - z_field_below);
807  lstep = abs(dz / cos_theta);
808 
809  // Average temperature
811  0.5 * (t_field(p_index, 0, 0) + t_field(p_index - 1, 0, 0));
812  //
813  // Average pressure
814  Numeric rtp_pressure = 0.5 * (p_grid[p_index] + p_grid[p_index - 1]);
815 
816  //
817  // Average vmrs
818  for (Index k = 0; k < N_species; k++)
819  rtp_vmr[k] = 0.5 * (vmr_field(k, p_index, 0, 0) +
820  vmr_field(k, p_index - 1, 0, 0));
821  //
822  // Calculate scalar gas absorption and add it to abs_vec
823  // and ext_mat.
824  //
825 
826  const Vector rtp_mag_dummy(3, 0);
827  const Vector ppath_los_dummy;
828  ArrayOfStokesVector nlte_dummy; //FIXME: do this right?
830  partial_dummy; // This is right since there should be only clearsky partials
831  ArrayOfStokesVector partial_source_dummy,
832  partial_nlte_dummy; // This is right since there should be only clearsky partials
835  nlte_dummy,
836  partial_dummy,
837  partial_source_dummy,
838  partial_nlte_dummy,
840  f_grid[Range(f_index, 1)],
841  rtp_mag_dummy,
842  ppath_los_dummy,
843  rtp_pressure,
845  rtp_nlte_dummy,
846  rtp_vmr,
848 
850 
851  //
852  // Add average particle extinction to ext_mat.
853  //
854 
855  // cout<<"cloudbox_limits[1]"<<cloudbox_limits[1]<<endl;
856  // cout<<"p_index - cloudbox_limits[0]"<<p_index - cloudbox_limits[0]<<endl;
857  for (Index k = 0; k < stokes_dim; k++) {
858  //
859  // Averaging of sca_vec:
860  //
861  sca_vec_av[k] +=
862  0.5 *
864  p_index - cloudbox_limits[0], 0, 0, za_index, 0, k) +
866  p_index - cloudbox_limits[0] - 1, 0, 0, za_index, 0, k));
867  }
868  //
869  // Add average particle absorption to abs_vec.
870  //
871  abs_vec.AddAverageAtPosition(
872  abs_vec_field(p_index - cloudbox_limits[0], 0, 0, joker),
873  abs_vec_field(p_index - cloudbox_limits[0] - 1, 0, 0, joker));
874 
875  //
876  // Add average particle extinction to ext_mat.
877  ext_mat.AddAverageAtPosition(
878  ext_mat_field(p_index - cloudbox_limits[0], 0, 0, joker, joker),
879  ext_mat_field(p_index - cloudbox_limits[0] + 1, 0, 0, joker, joker));
880 
881  // Frequency
882  Numeric f = f_grid[f_index];
883  //
884  // Calculate Planck function
885  //
886  Numeric rte_planck_value = planck(f, rtp_temperature);
887 
888  // Some messages:
889  if (out3.sufficient_priority()) {
890  vector_tmp = abs_vec.VectorAtPosition();
891  ext_mat.MatrixAtPosition(matrix_tmp);
892  out3 << "-----------------------------------------\n";
893  out3 << "Input for radiative transfer step \n"
894  << "calculation inside"
895  << " the cloudbox:"
896  << "\n";
897  out3 << "Stokes vector at intersection point: \n" << stokes_vec << "\n";
898  out3 << "lstep: ..." << lstep << "\n";
899  out3 << "------------------------------------------\n";
900  out3 << "Averaged coefficients: \n";
901  out3 << "Planck function: " << rte_planck_value << "\n";
902  out3 << "Scattering vector: " << sca_vec_av << "\n";
903  out3 << "Absorption vector: " << vector_tmp << "\n";
904  out3 << "Extinction matrix: " << matrix_tmp << "\n";
905 
906  assert(!is_singular(matrix_tmp));
907  }
908 
909  // Radiative transfer step calculation. The Stokes vector
910  // is updated until the considered point is reached.
911  rte_step_doit_replacement(stokes_vec,
913  ext_mat,
914  abs_vec,
915  sca_vec_av,
916  lstep,
917  rte_planck_value);
918 
919  // Assign calculated Stokes Vector to cloudbox_field_mono.
921  p_index - cloudbox_limits[0], 0, 0, za_index, 0, joker) =
922  stokes_vec;
923  }
924 
925  } // if loop end - for non_ground background
926 
927  // bkgr=2 indicates that the background is the surface
928  else if (bkgr == 2) {
929  //Set rte_pos, rte_gp_p and rte_los to match the last point
930  //in ppath.
931  //pos
933  Numeric z_field_0 = z_field(0, 0, 0);
934  rte_pos = z_field_0; //ppath_step.pos(np-1,Range(0,atmosphere_dim));
935  //los
936  Vector rte_los(1);
937  rte_los = za_grid[za_index]; //ppath_step.los(np-1,joker);
938  //gp_p
939  //GridPos rte_gp_p;
940  //rte_gp_p.idx = p_index;
941  //rte_gp_p.fd[0] = 0;
942  //rte_gp_p.fd[1] = 1;
943  //gridpos_copy( rte_gp_p, ppath_step.gp_p[np-1] );
944  // Executes the surface agenda
945  // FIXME: Convert to new agenda scheme before using
946  // surface_rtprop_agenda.execute();
947 
948  throw runtime_error(
949  "Surface reflections inside cloud box not yet handled.");
950  /*
951  See comment in function above
952  // Check returned variables
953  if( surface_emission.nrows() != f_grid.nelem() ||
954  surface_emission.ncols() != stokes_dim )
955  throw runtime_error(
956  "The size of the created *surface_emission* is not correct.");
957 
958  Index nlos = surface_los.nrows();
959 
960  // Define a local vector cloudbox_field_mono_sum which adds the
961  // products of groudnd_refl_coeffs with the downwelling
962  // radiation for each elements of surface_los
963  Vector cloudbox_field_mono_sum(stokes_dim,0);
964  // Loop over the surface_los elements
965  for( Index ilos=0; ilos < nlos; ilos++ )
966  {
967  if( stokes_dim == 1 )
968  {
969  cloudbox_field_mono_sum[0] += surface_refl_coeffs(ilos,f_index,0,0) *
970  cloudbox_field_mono(cloudbox_limits[0],
971  0, 0,
972  (za_grid.nelem() -1 - za_index), 0,
973  0);
974  }
975  else
976  {
977  Vector stokes_vec2(stokes_dim);
978  mult( stokes_vec2,
979  surface_refl_coeffs(ilos,0,joker,joker),
980  cloudbox_field_mono(cloudbox_limits[0],
981  0, 0,
982  (za_grid.nelem() -1 - za_index), 0,
983  joker));
984  for( Index is=0; is < stokes_dim; is++ )
985  {
986  cloudbox_field_mono_sum[is] += stokes_vec2[is];
987  }
988 
989  }
990  }
991  // Copy from *cloudbox_field_mono_sum* to *cloudbox_field_mono*, and add the surface emission
992  for( Index is=0; is < stokes_dim; is++ )
993  {
994  cloudbox_field_mono (cloudbox_limits[0],
995  0, 0,
996  za_index, 0,
997  is) = cloudbox_field_mono_sum[is] + surface_emission(f_index,is);
998  }
999 
1000  //cout<<"za_grid"<<za_grid[za_index]<<endl;
1001  //cout<<"p_index"<<p_index<<endl;
1002  //cout<<"cloudboxlimit[0]"<<cloudbox_limits[0]<<endl;
1003  // now the RT is done to the next point in the path.
1004  //
1005  Vector stokes_vec_local;
1006  stokes_vec_local = cloudbox_field_mono (0,
1007  0, 0,
1008  za_index, 0,
1009  joker);
1010 
1011  Numeric z_field_above = z_field(p_index +1, 0, 0);
1012  //Numeric z_field_0 = z_field(p_index, 0, 0);
1013  Numeric cos_theta;
1014  if (za_grid[za_index] == 90.0)
1015  {
1016  //cos_theta = cos((za_grid[za_index] -1)*PI/180.);
1017  cos_theta = cos(90.00000001*PI/180.);
1018  }
1019  else
1020  {
1021  cos_theta = cos(za_grid[za_index]* PI/180.0);
1022  }
1023  Numeric dz = (z_field_above - z_field_0);
1024 
1025  Numeric lstep = abs(dz/cos_theta) ;
1026 
1027  // Average temperature
1028  Numeric rtp_temperature = 0.5 * (t_field(p_index,0,0)
1029  + t_field(p_index + 1,0,0));
1030 
1031  //
1032  // Average pressure
1033  Numeric rtp_pressure = 0.5 * (p_grid[p_index]
1034  + p_grid[p_index + 1]);
1035 
1036  //
1037  const Index N_species = vmr_field.nbooks();
1038  // Average vmrs
1039  for (Index k = 0; k < N_species; k++)
1040  {
1041  rtp_vmr[k] = 0.5 * (vmr_field(k,p_index,0,0) +
1042  vmr_field(k,p_index + 1,0,0));
1043  }
1044  //
1045  // Calculate scalar gas absorption and add it to abs_vec
1046  // and ext_mat.
1047  //
1048 
1049  // FIXME: Convert to new agenda scheme before using
1050  //abs_scalar_gas_agenda.execute(p_index);
1051 
1052  opt_prop_gas_agendaExecute(ext_mat, abs_vec, abs_scalar_gas,
1053  opt_prop_gas_agenda);
1054 
1055  //
1056  // Add average particle extinction to ext_mat.
1057  //
1058  //cout<<"Reached Here ????????????????????????????????????????????????";
1059  for (Index k = 0; k < stokes_dim; k++)
1060  {
1061  for (Index j = 0; j < stokes_dim; j++)
1062  {
1063  ext_mat(0,k,j) += 0.5 *
1064  (ext_mat_field(p_index - cloudbox_limits[0],0,0,k,j) +
1065  ext_mat_field(p_index - cloudbox_limits[0]+ 1,0,0,k,j));
1066  }
1067 
1068 
1069  //
1070  //
1071  // Add average particle absorption to abs_vec.
1072  //
1073  abs_vec(0,k) += 0.5 *
1074  (abs_vec_field(p_index - cloudbox_limits[0],0,0,k) +
1075  abs_vec_field(p_index - cloudbox_limits[0]+1,0,0,k));
1076  //
1077  // Averaging of sca_vec:
1078  //
1079  sca_vec_av[k] = 0.5*( doit_scat_field(p_index- cloudbox_limits[0],
1080  0, 0, za_index, 0, k)
1081  + doit_scat_field(p_index- cloudbox_limits[0]+1,
1082  0, 0, za_index, 0, k)) ;
1083 
1084  }
1085  // Frequency
1086  Numeric f = f_grid[f_index];
1087  //
1088  // Calculate Planck function
1089  //
1090  Numeric rte_planck_value = planck(f, rtp_temperature);
1091 
1092  assert (!is_singular( ext_mat(0,joker,joker)));
1093 
1094  // Radiative transfer step calculation. The Stokes vector
1095  // is updated until the considered point is reached.
1096  rte_step_doit(stokes_vec_local, ext_mat(0,joker,joker),
1097  abs_vec(0,joker),
1098  sca_vec_av, lstep, rte_planck_value);
1099  // Assign calculated Stokes Vector to cloudbox_field_mono.
1100  cloudbox_field_mono(p_index - cloudbox_limits[0],
1101  0, 0,
1102  za_index, 0,
1103  joker) = stokes_vec_local;
1104  */
1105  } //end else loop over surface
1106 }
1107 
1110  // ppath_step_agenda:
1111  const Index& p_index,
1112  const Index& lat_index,
1113  const Index& lon_index,
1114  const Index& za_index,
1115  const Index& aa_index,
1120  // Calculate scalar gas absorption:
1123  // Propagation path calculation:
1124  const Agenda& ppath_step_agenda,
1125  const Numeric& ppath_lmax,
1126  const Numeric& ppath_lraytrace,
1132  // Calculate thermal emission:
1135  const Index& f_index,
1136  //particle optical properties
1137  ConstTensor5View ext_mat_field,
1138  ConstTensor4View abs_vec_field,
1139  const Index&, //scat_za_interp
1140  const Verbosity& verbosity) {
1141  CREATE_OUT3;
1142 
1143  Ppath ppath_step;
1144  const Index stokes_dim = cloudbox_field_mono.ncols();
1145 
1146  Vector sca_vec_av(stokes_dim, 0);
1147  Vector aa_g(aa_grid.nelem());
1148 
1149  for (Index i = 0; i < aa_grid.nelem(); i++)
1150  aa_g[i] = aa_grid[i] - 180.;
1151 
1152  //Initialize ppath for 3D.
1154  // See documentation of ppath_init_structure for
1155  // understanding the parameters.
1156 
1157  // The first dimension of pos are the points in
1158  // the propagation path.
1159  // Here we initialize the first point.
1160  // The second is: radius, latitude, longitude
1161 
1162  ppath_step.pos(0, 2) = lon_grid[lon_index];
1163  ppath_step.pos(0, 1) = lat_grid[lat_index];
1164  ppath_step.pos(0, 0) = z_field(p_index, lat_index, lon_index);
1165  // As always on top of the lat. grid positions, OK to call refell2r:
1166  ppath_step.r[0] =
1168 
1169  // Define the direction:
1170  ppath_step.los(0, 0) = za_grid[za_index];
1171  ppath_step.los(0, 1) = aa_g[aa_index];
1172 
1173  // Define the grid positions:
1174  ppath_step.gp_p[0].idx = p_index;
1175  ppath_step.gp_p[0].fd[0] = 0.;
1176  ppath_step.gp_p[0].fd[1] = 1.;
1177 
1178  ppath_step.gp_lat[0].idx = lat_index;
1179  ppath_step.gp_lat[0].fd[0] = 0.;
1180  ppath_step.gp_lat[0].fd[1] = 1.;
1181 
1182  ppath_step.gp_lon[0].idx = lon_index;
1183  ppath_step.gp_lon[0].fd[0] = 0.;
1184  ppath_step.gp_lon[0].fd[1] = 1.;
1185 
1186  // Call ppath_step_agenda:
1188  ppath_step,
1189  ppath_lmax,
1191  Vector(1, f_grid[f_index]),
1193 
1194  // Check whether the next point is inside or outside the
1195  // cloudbox. Only if the next point lies inside the
1196  // cloudbox a radiative transfer step caclulation has to
1197  // be performed.
1199  // Gridpositions inside the cloudbox.
1200  // The optical properties are stored only inside the
1201  // cloudbox. For interpolation we use grids
1202  // inside the cloudbox.
1203 
1204  ArrayOfGridPos cloud_gp_p = ppath_step.gp_p;
1205  ArrayOfGridPos cloud_gp_lat = ppath_step.gp_lat;
1206  ArrayOfGridPos cloud_gp_lon = ppath_step.gp_lon;
1207 
1208  for (Index i = 0; i < ppath_step.np; i++) {
1209  cloud_gp_p[i].idx -= cloudbox_limits[0];
1210  cloud_gp_lat[i].idx -= cloudbox_limits[2];
1211  cloud_gp_lon[i].idx -= cloudbox_limits[4];
1212  }
1213  const Index n1 = cloudbox_limits[1] - cloudbox_limits[0];
1214  const Index n2 = cloudbox_limits[3] - cloudbox_limits[2];
1215  const Index n3 = cloudbox_limits[5] - cloudbox_limits[4];
1216  gridpos_upperend_check(cloud_gp_p[0], n1);
1217  gridpos_upperend_check(cloud_gp_p[ppath_step.np - 1], n1);
1218  gridpos_upperend_check(cloud_gp_lat[0], n2);
1219  gridpos_upperend_check(cloud_gp_lat[ppath_step.np - 1], n2);
1220  gridpos_upperend_check(cloud_gp_lon[0], n3);
1221  gridpos_upperend_check(cloud_gp_lon[ppath_step.np - 1], n3);
1222 
1223  Matrix itw(ppath_step.np, 8);
1224  interpweights(itw, cloud_gp_p, cloud_gp_lat, cloud_gp_lon);
1225 
1226  Matrix itw_p(ppath_step.np, 2);
1227  interpweights(itw_p, cloud_gp_p);
1228 
1229  // The zenith angles and azimuth of the propagation path are
1230  // needed as we have to
1231  // interpolate the intensity field and the scattered field on the
1232  // right angles.
1233  VectorView los_grid_za = ppath_step.los(joker, 0);
1234  VectorView los_grid_aa = ppath_step.los(joker, 1);
1235 
1236  for (Index i = 0; i < los_grid_aa.nelem(); i++)
1237  los_grid_aa[i] = los_grid_aa[i] + 180.;
1238 
1239  ArrayOfGridPos gp_za(los_grid_za.nelem());
1240  gridpos(gp_za, za_grid, los_grid_za);
1241 
1242  ArrayOfGridPos gp_aa(los_grid_aa.nelem());
1243  gridpos(gp_aa, aa_grid, los_grid_aa);
1244 
1245  Matrix itw_p_za(ppath_step.np, 32);
1246  interpweights(
1247  itw_p_za, cloud_gp_p, cloud_gp_lat, cloud_gp_lon, gp_za, gp_aa);
1248 
1249  // Ppath_step normally has 2 points, the starting
1250  // point and the intersection point.
1251  // But there can be points in between, when a maximum
1252  // lstep is given. We have to interpolate on all the
1253  // points in the ppath_step.
1254 
1255  Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np);
1256  Matrix abs_vec_int(stokes_dim, ppath_step.np);
1257  Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
1258  Matrix cloudbox_field_mono_int(stokes_dim, ppath_step.np, 0.);
1259  Vector t_int(ppath_step.np);
1260  Vector vmr_int(ppath_step.np);
1261  Vector p_int(ppath_step.np);
1262  Vector stokes_vec(stokes_dim);
1263  //Tensor3 ext_mat_gas(stokes_dim, stokes_dim, ppath_step.np);
1264  //Matrix abs_vec_gas(stokes_dim, ppath_step.np);
1265 
1266  // Calculate the average of the coefficients for the layers
1267  // to be considered in the
1268  // radiative transfer calculation.
1269 
1270  for (Index i = 0; i < stokes_dim; i++) {
1271  // Extinction matrix requires a second loop
1272  // over stokes_dim
1273  out3 << "Interpolate ext_mat:\n";
1274  for (Index j = 0; j < stokes_dim; j++) {
1275  //
1276  // Interpolation of ext_mat
1277  //
1278  interp(ext_mat_int(i, j, joker),
1279  itw,
1280  ext_mat_field(joker, joker, joker, i, j),
1281  cloud_gp_p,
1282  cloud_gp_lat,
1283  cloud_gp_lon);
1284  }
1285  // Absorption vector:
1286  //
1287  // Interpolation of abs_vec
1288  //
1289  interp(abs_vec_int(i, joker),
1290  itw,
1291  abs_vec_field(joker, joker, joker, i),
1292  cloud_gp_p,
1293  cloud_gp_lat,
1294  cloud_gp_lon);
1295  //
1296  // Scattered field:
1297  //
1298  // Interpolation of sca_vec:
1299  //
1300  out3 << "Interpolate doit_scat_field:\n";
1301  interp(sca_vec_int(i, joker),
1302  itw_p_za,
1304  cloud_gp_p,
1305  cloud_gp_lat,
1306  cloud_gp_lon,
1307  gp_za,
1308  gp_aa);
1309  out3 << "Interpolate cloudbox_field_mono:\n";
1310  interp(cloudbox_field_mono_int(i, joker),
1311  itw_p_za,
1313  cloud_gp_p,
1314  cloud_gp_lat,
1315  cloud_gp_lon,
1316  gp_za,
1317  gp_aa);
1318  }
1319  //
1320  // Planck function
1321  //
1322  // Interpolate temperature field
1323  //
1324  out3 << "Interpolate temperature field\n";
1325  interp(t_int,
1326  itw,
1327  t_field(joker, joker, joker),
1328  ppath_step.gp_p,
1329  ppath_step.gp_lat,
1330  ppath_step.gp_lon);
1331 
1332  //
1333  // The vmr_field is needed for the gaseous absorption
1334  // calculation.
1335  //
1336  const Index N_species = vmr_field.nbooks();
1337  //
1338  // Interpolated vmr_list, holds a vmr_list for each point in
1339  // ppath_step.
1340  //
1341  Matrix vmr_list_int(N_species, ppath_step.np);
1342 
1343  for (Index i = 0; i < N_species; i++) {
1344  out3 << "Interpolate vmr field\n";
1345  interp(vmr_int,
1346  itw,
1347  vmr_field(i, joker, joker, joker),
1348  ppath_step.gp_p,
1349  ppath_step.gp_lat,
1350  ppath_step.gp_lon);
1351 
1352  vmr_list_int(i, joker) = vmr_int;
1353  }
1354 
1355  // Presssure (needed for the calculation of gas absorption)
1356  itw2p(p_int, p_grid, ppath_step.gp_p, itw_p);
1357 
1358  out3 << "Calculate radiative transfer inside cloudbox.\n";
1362  ppath_step,
1363  t_int,
1364  vmr_list_int,
1365  ext_mat_int,
1366  abs_vec_int,
1367  sca_vec_int,
1368  cloudbox_field_mono_int,
1369  p_int,
1371  f_grid,
1372  f_index,
1373  p_index,
1374  lat_index,
1375  lon_index,
1376  za_index,
1377  aa_index,
1378  verbosity);
1379  } //end if inside cloudbox
1380 }
1381 
1383  //Output
1385  // Input
1387  const Ppath& ppath_step,
1388  ConstVectorView t_int,
1389  ConstMatrixView vmr_list_int,
1390  ConstTensor3View ext_mat_int,
1391  ConstMatrixView abs_vec_int,
1392  ConstMatrixView sca_vec_int,
1393  ConstMatrixView cloudbox_field_mono_int,
1394  ConstVectorView p_int,
1397  const Index& f_index,
1398  const Index& p_index,
1399  const Index& lat_index,
1400  const Index& lon_index,
1401  const Index& za_index,
1402  const Index& aa_index,
1403  const Verbosity& verbosity) {
1404  CREATE_OUT3;
1405 
1406  const Index N_species = vmr_list_int.nrows();
1407  const Index stokes_dim = cloudbox_field_mono.ncols();
1408  const Index atmosphere_dim = cloudbox_limits.nelem() / 2;
1409 
1410  Vector sca_vec_av(stokes_dim, 0);
1411  Vector stokes_vec(stokes_dim, 0.);
1412  EnergyLevelMap rtp_nlte_dummy;
1413  Vector rtp_vmr_local(N_species, 0.);
1414 
1415  // Two propmat_clearsky to average between
1416  ArrayOfPropagationMatrix cur_propmat_clearsky;
1417  ArrayOfPropagationMatrix prev_propmat_clearsky;
1418 
1419  PropagationMatrix ext_mat_local;
1420  StokesVector abs_vec_local;
1421  Matrix matrix_tmp(stokes_dim, stokes_dim);
1422  Vector vector_tmp(stokes_dim);
1423 
1424  // Incoming stokes vector
1425  stokes_vec = cloudbox_field_mono_int(joker, ppath_step.np - 1);
1426 
1427  for (Index k = ppath_step.np - 1; k >= 0; k--) {
1428  // Save propmat_clearsky from previous level by
1429  // swapping it with current level
1430  std::swap(cur_propmat_clearsky, prev_propmat_clearsky);
1431 
1432  //
1433  // Calculate scalar gas absorption
1434  //
1435  const Vector rtp_mag_dummy(3, 0);
1436  const Vector ppath_los_dummy;
1437 
1438  ArrayOfStokesVector nlte_dummy; //FIXME: do this right?
1440  partial_dummy; // This is right since there should be only clearsky partials
1441  ArrayOfStokesVector partial_source_dummy,
1442  partial_nlte_dummy; // This is right since there should be only clearsky partials
1444  cur_propmat_clearsky,
1445  nlte_dummy,
1446  partial_dummy,
1447  partial_source_dummy,
1448  partial_nlte_dummy,
1450  f_grid[Range(f_index, 1)],
1451  rtp_mag_dummy,
1452  ppath_los_dummy,
1453  p_int[k],
1454  t_int[k],
1455  rtp_nlte_dummy,
1456  vmr_list_int(joker, k),
1458 
1459  // Skip any further calculations for the first point.
1460  // We need values at two ppath points before we can average.
1461  if (k == ppath_step.np - 1) continue;
1462 
1463  // Average prev_propmat_clearsky with cur_propmat_clearsky
1464  for (Index i = 0; i < prev_propmat_clearsky.nelem(); i++) {
1465  prev_propmat_clearsky[i] += cur_propmat_clearsky[i];
1466  prev_propmat_clearsky[i] *= 0.5;
1467  }
1468 
1470  ext_mat_local, abs_vec_local, prev_propmat_clearsky);
1471 
1472  for (Index i = 0; i < stokes_dim; i++) {
1473  //
1474  // Averaging of sca_vec:
1475  //
1476  sca_vec_av[i] = 0.5 * (sca_vec_int(i, k) + sca_vec_int(i, k + 1));
1477  }
1478 
1479  //
1480  // Add average particle absorption to abs_vec.
1481  //
1482  abs_vec_local.AddAverageAtPosition(abs_vec_int(joker, k),
1483  abs_vec_int(joker, k + 1));
1484 
1485  //
1486  // Add average particle extinction to ext_mat.
1487  //
1488  ext_mat_local.AddAverageAtPosition(ext_mat_int(joker, joker, k),
1489  ext_mat_int(joker, joker, k + 1));
1490 
1491  // Frequency
1492  Numeric f = f_grid[f_index];
1493  //
1494  // Calculate Planck function
1495  //
1496  Numeric rte_planck_value = planck(f, 0.5 * (t_int[k] + t_int[k + 1]));
1497 
1498  // Length of the path between the two layers.
1499  Numeric lstep = ppath_step.lstep[k];
1500 
1501  // Some messages:
1502  if (out3.sufficient_priority()) {
1503  vector_tmp = abs_vec_local.VectorAtPosition();
1504  ext_mat_local.MatrixAtPosition(matrix_tmp);
1505  out3 << "-----------------------------------------\n";
1506  out3 << "Input for radiative transfer step \n"
1507  << "calculation inside"
1508  << " the cloudbox:"
1509  << "\n";
1510  out3 << "Stokes vector at intersection point: \n" << stokes_vec << "\n";
1511  out3 << "lstep: ..." << lstep << "\n";
1512  out3 << "------------------------------------------\n";
1513  out3 << "Averaged coefficients: \n";
1514  out3 << "Planck function: " << rte_planck_value << "\n";
1515  out3 << "Scattering vector: " << sca_vec_av << "\n";
1516  out3 << "Absorption vector: " << vector_tmp << "\n";
1517  out3 << "Extinction matrix: " << matrix_tmp << "\n";
1518 
1519  assert(!is_singular(matrix_tmp));
1520  }
1521 
1522  // Radiative transfer step calculation. The Stokes vector
1523  // is updated until the considered point is reached.
1524  rte_step_doit_replacement(stokes_vec,
1526  ext_mat_local,
1527  abs_vec_local,
1528  sca_vec_av,
1529  lstep,
1530  rte_planck_value);
1531 
1532  } // End of loop over ppath_step.
1533  // Assign calculated Stokes Vector to cloudbox_field_mono.
1534  if (atmosphere_dim == 1)
1536  p_index - cloudbox_limits[0], 0, 0, za_index, 0, joker) =
1537  stokes_vec;
1538  else if (atmosphere_dim == 3)
1539  cloudbox_field_mono(p_index - cloudbox_limits[0],
1540  lat_index - cloudbox_limits[2],
1541  lon_index - cloudbox_limits[4],
1542  za_index,
1543  aa_index,
1544  joker) = stokes_vec;
1545 }
1546 
1548  //Output
1550  //Input
1553  const Index& f_index,
1554  const Index& stokes_dim,
1555  const Ppath& ppath_step,
1558  const Index& za_index) {
1559  chk_not_empty("surface_rtprop_agenda", surface_rtprop_agenda);
1560 
1561  Matrix iy;
1562 
1563  // Local output of surface_rtprop_agenda.
1568 
1569  //Set rte_pos and rte_los to match the last point in ppath.
1570 
1571  Index np = ppath_step.np;
1572 
1573  Vector rte_pos; // ppath_step.pos contains two columns for 1D
1574  rte_pos.resize(ppath_step.dim);
1575  rte_pos = ppath_step.pos(np - 1, Range(0, ppath_step.dim));
1576 
1577  Vector rte_los;
1578  rte_los.resize(ppath_step.los.ncols());
1579  rte_los = ppath_step.los(np - 1, joker);
1580 
1581  //Execute the surface_rtprop_agenda which gives the surface
1582  //parameters.
1586  surface_los,
1588  Vector(1, f_grid[f_index]),
1589  rte_pos,
1590  rte_los,
1592 
1593  iy = surface_emission;
1594 
1595  Index nlos = surface_los.nrows();
1596 
1597  if (nlos > 0) {
1598  Vector rtmp(stokes_dim); // Reflected Stokes vector for 1 frequency
1599 
1600  for (Index ilos = 0; ilos < nlos; ilos++) {
1601  // Several things needs to be fixed here. As far as I understand it,
1602  // this works only for specular cases and if the lower cloudbox limit
1603  // is exactly at the surface (PE, 120828)
1604 
1605  mult(rtmp,
1606  surface_rmatrix(ilos, 0, joker, joker),
1608  0,
1609  0,
1610  (za_grid.nelem() - 1 - za_index),
1611  0,
1612  joker));
1613  iy(0, joker) += rtmp;
1614  }
1615  }
1617  iy(0, joker);
1618 }
1619 
1621  const ArrayOfTensor6& acceleration_input,
1622  const Index& accelerated,
1623  const Verbosity&) {
1624  const Index N_p = cloudbox_field_mono.nvitrines();
1625  const Index N_za = cloudbox_field_mono.npages();
1626 
1627  // Loop over 4 components of Stokes Vector
1628  for (Index i = 0; i < accelerated; ++i) {
1629  ConstMatrixView S1 = acceleration_input[0](joker, 0, 0, joker, 0, i);
1630  ConstMatrixView S2 = acceleration_input[1](joker, 0, 0, joker, 0, i);
1631  ConstMatrixView S3 = acceleration_input[2](joker, 0, 0, joker, 0, i);
1632  ConstMatrixView S4 = acceleration_input[3](joker, 0, 0, joker, 0, i);
1633 
1634  ConstMatrixView J = S4;
1635  Matrix Q1;
1636  Matrix Q2;
1637  Matrix Q3;
1638  Numeric A1 = 0;
1639  Numeric A2B1 = 0;
1640  Numeric B2 = 0;
1641  Numeric C1 = 0;
1642  Numeric C2 = 0;
1643  Numeric NGA = 0;
1644  Numeric NGB = 0;
1645 
1646  // Q1 = -2*S3 + S4 + S2
1647 
1648  Q1 = S3;
1649  Q1 *= -2;
1650  Q1 += S4;
1651  Q1 += S2;
1652 
1653  // Q2 = S4 - S3 - S2 + S1
1654  Q2 = S4;
1655  Q2 -= S3;
1656  Q2 -= S2;
1657  Q2 += S1;
1658 
1659  //Q3 = S4 - S3
1660  Q3 = S4;
1661  Q3 -= S3;
1662 
1663  for (Index p_index = 0; p_index < N_p; ++p_index) {
1664  for (Index za_index = 0; za_index < N_za; ++za_index) {
1665  A1 += Q1(p_index, za_index) * Q1(p_index, za_index) *
1666  J(p_index, za_index);
1667  A2B1 += Q2(p_index, za_index) * Q1(p_index, za_index) *
1668  J(p_index, za_index);
1669  B2 += Q2(p_index, za_index) * Q2(p_index, za_index) *
1670  J(p_index, za_index);
1671  C1 += Q1(p_index, za_index) * Q3(p_index, za_index) *
1672  J(p_index, za_index);
1673  C2 += Q2(p_index, za_index) * Q3(p_index, za_index) *
1674  J(p_index, za_index);
1675  }
1676  }
1677 
1678  NGA = (C1 * B2 - C2 * A2B1) / (A1 * B2 - A2B1 * A2B1);
1679  NGB = (C2 * A1 - C1 * A2B1) / (A1 * B2 - A2B1 * A2B1);
1680 
1681  if (!std::isnan(NGB) && !std::isnan(NGA)) {
1682  // Calculating the accelerated field
1683  for (Index p_index = 0; p_index < N_p; ++p_index) {
1684  for (Index za_index = 0; za_index < N_za; ++za_index) {
1685  Q1(p_index, za_index) = (1 - NGA - NGB) * S4(p_index, za_index) +
1686  NGA * S3(p_index, za_index) +
1687  NGB * S2(p_index, za_index);
1688  }
1689  }
1690  cloudbox_field_mono(joker, 0, 0, joker, 0, i) = Q1;
1691  }
1692  }
1693 }
1694 
1695 void interp_cloud_coeff1D( //Output
1696  Tensor3View ext_mat_int,
1697  MatrixView abs_vec_int,
1698  MatrixView sca_vec_int,
1699  MatrixView cloudbox_field_mono_int,
1700  VectorView t_int,
1701  MatrixView vmr_list_int,
1702  VectorView p_int,
1703  //Input
1704  ConstTensor5View ext_mat_field,
1705  ConstTensor4View abs_vec_field,
1711  const Ppath& ppath_step,
1714  const Index& scat_za_interp,
1715  const Verbosity& verbosity) {
1716  CREATE_OUT3;
1717 
1718  // Stokes dimension
1719  const Index stokes_dim = cloudbox_field_mono.ncols();
1720 
1721  // Gridpositions inside the cloudbox.
1722  // The optical properties are stored only inside the
1723  // cloudbox. For interpolation we use grids
1724  // inside the cloudbox.
1725  ArrayOfGridPos cloud_gp_p = ppath_step.gp_p;
1726 
1727  for (Index i = 0; i < ppath_step.np; i++)
1728  cloud_gp_p[i].idx -= cloudbox_limits[0];
1729 
1730  // Grid index for points at upper limit of cloudbox must be shifted
1731  const Index n1 = cloudbox_limits[1] - cloudbox_limits[0];
1732  gridpos_upperend_check(cloud_gp_p[0], n1);
1733  gridpos_upperend_check(cloud_gp_p[ppath_step.np - 1], n1);
1734 
1735  Matrix itw(cloud_gp_p.nelem(), 2);
1736  interpweights(itw, cloud_gp_p);
1737 
1738  // The zenith angles of the propagation path are needed as we have to
1739  // interpolate the intensity field and the scattered field on the
1740  // right angles.
1741  Vector los_grid = ppath_step.los(joker, 0);
1742 
1743  ArrayOfGridPos gp_za(los_grid.nelem());
1744  gridpos(gp_za, za_grid, los_grid);
1745 
1746  Matrix itw_p_za(cloud_gp_p.nelem(), 4);
1747  interpweights(itw_p_za, cloud_gp_p, gp_za);
1748 
1749  // Calculate the average of the coefficients for the layers
1750  // to be considered in the
1751  // radiative transfer calculation.
1752 
1753  for (Index i = 0; i < stokes_dim; i++) {
1754  // Extinction matrix requires a second loop
1755  // over stokes_dim
1756  out3 << "Interpolate ext_mat:\n";
1757  for (Index j = 0; j < stokes_dim; j++) {
1758  //
1759  // Interpolation of ext_mat
1760  //
1761  interp(ext_mat_int(i, j, joker),
1762  itw,
1763  ext_mat_field(joker, 0, 0, i, j),
1764  cloud_gp_p);
1765  }
1766  // Particle absorption vector:
1767  //
1768  // Interpolation of abs_vec
1769  // //
1770  out3 << "Interpolate abs_vec:\n";
1771  interp(
1772  abs_vec_int(i, joker), itw, abs_vec_field(joker, 0, 0, i), cloud_gp_p);
1773  //
1774  // Scattered field:
1775  //
1776  //
1777 
1778  out3 << "Interpolate doit_scat_field and cloudbox_field_mono:\n";
1779  if (scat_za_interp == 0) // linear interpolation
1780  {
1781  interp(sca_vec_int(i, joker),
1782  itw_p_za,
1783  doit_scat_field(joker, 0, 0, joker, 0, i),
1784  cloud_gp_p,
1785  gp_za);
1786  interp(cloudbox_field_mono_int(i, joker),
1787  itw_p_za,
1788  cloudbox_field_mono(joker, 0, 0, joker, 0, i),
1789  cloud_gp_p,
1790  gp_za);
1791  } else if (scat_za_interp == 1) //polynomial interpolation
1792  {
1793  // These intermediate variables are needed because polynomial
1794  // interpolation is not implemented as multidimensional
1795  // interpolation.
1796  Tensor3 sca_vec_int_za(
1797  stokes_dim, ppath_step.np, za_grid.nelem(), 0.);
1798  Tensor3 cloudbox_field_mono_int_za(
1799  stokes_dim, ppath_step.np, za_grid.nelem(), 0.);
1800  for (Index za = 0; za < za_grid.nelem(); za++) {
1801  interp(sca_vec_int_za(i, joker, za),
1802  itw,
1803  doit_scat_field(joker, 0, 0, za, 0, i),
1804  cloud_gp_p);
1805  out3 << "Interpolate cloudbox_field_mono:\n";
1806  interp(cloudbox_field_mono_int_za(i, joker, za),
1807  itw,
1808  cloudbox_field_mono(joker, 0, 0, za, 0, i),
1809  cloud_gp_p);
1810  }
1811  for (Index ip = 0; ip < ppath_step.np; ip++) {
1812  sca_vec_int(i, ip) = interp_poly(za_grid,
1813  sca_vec_int_za(i, ip, joker),
1814  los_grid[ip],
1815  gp_za[ip]);
1816  cloudbox_field_mono_int(i, ip) =
1818  cloudbox_field_mono_int_za(i, ip, joker),
1819  los_grid[ip],
1820  gp_za[ip]);
1821  }
1822  }
1823  }
1824  //
1825  // Planck function
1826  //
1827  // Interpolate temperature field
1828  //
1829  out3 << "Interpolate temperature field\n";
1830  interp(t_int, itw, t_field(joker, 0, 0), ppath_step.gp_p);
1831  //
1832  // The vmr_field is needed for the gaseous absorption
1833  // calculation.
1834  //
1835  const Index N_species = vmr_field.nbooks();
1836  //
1837  // Interpolated vmr_list, holds a vmr_list for each point in
1838  // ppath_step.
1839  //
1840  Vector vmr_int(ppath_step.np);
1841 
1842  for (Index i_sp = 0; i_sp < N_species; i_sp++) {
1843  out3 << "Interpolate vmr field\n";
1844  interp(vmr_int, itw, vmr_field(i_sp, joker, 0, 0), ppath_step.gp_p);
1845  vmr_list_int(i_sp, joker) = vmr_int;
1846  }
1847  //
1848  // Interpolate pressure
1849  //
1850  itw2p(p_int, p_grid, ppath_step.gp_p, itw);
1851 }
1852 
1853 void za_gridOpt( //Output:
1854  Vector& za_grid_opt,
1855  Matrix& cloudbox_field_opt,
1856  // Input
1857  ConstVectorView za_grid_fine,
1859  const Numeric& acc,
1860  const Index& scat_za_interp) {
1861  Index N_za = za_grid_fine.nelem();
1862 
1863  assert(cloudbox_field_mono.npages() == N_za);
1864 
1865  Index N_p = cloudbox_field_mono.nvitrines();
1866 
1867  Vector i_approx_interp(N_za);
1868  Vector za_reduced(2);
1869 
1870  ArrayOfIndex idx;
1871  idx.push_back(0);
1872  idx.push_back(N_za - 1);
1873  ArrayOfIndex idx_unsorted;
1874 
1875  Numeric max_diff = 100;
1876 
1877  ArrayOfGridPos gp_za(N_za);
1878  Matrix itw(za_grid_fine.nelem(), 2);
1879 
1880  ArrayOfIndex i_sort;
1881  Vector diff_vec(N_za);
1882  Vector max_diff_za(N_p);
1883  ArrayOfIndex ind_za(N_p);
1884  Numeric max_diff_p;
1885  Index ind_p = 0;
1886 
1887  while (max_diff > acc) {
1888  za_reduced.resize(idx.nelem());
1889  cloudbox_field_opt.resize(N_p, idx.nelem());
1890  max_diff_za = 0.;
1891  max_diff_p = 0.;
1892 
1893  // Interpolate reduced intensity field on fine za_grid for
1894  // all pressure levels
1895  for (Index i_p = 0; i_p < N_p; i_p++) {
1896  for (Index i_za_red = 0; i_za_red < idx.nelem(); i_za_red++) {
1897  za_reduced[i_za_red] = za_grid_fine[idx[i_za_red]];
1898  cloudbox_field_opt(i_p, i_za_red) =
1899  cloudbox_field_mono(i_p, 0, 0, idx[i_za_red], 0, 0);
1900  }
1901  // Calculate grid positions
1902  gridpos(gp_za, za_reduced, za_grid_fine);
1903  //linear interpolation
1904  if (scat_za_interp == 0 || idx.nelem() < 3) {
1905  interpweights(itw, gp_za);
1906  interp(i_approx_interp, itw, cloudbox_field_opt(i_p, joker), gp_za);
1907  } else if (scat_za_interp == 1) {
1908  for (Index i_za = 0; i_za < N_za; i_za++) {
1909  i_approx_interp[i_za] = interp_poly(za_reduced,
1910  cloudbox_field_opt(i_p, joker),
1911  za_grid_fine[i_za],
1912  gp_za[i_za]);
1913  }
1914  } else
1915  // Interpolation method not defined
1916  assert(false);
1917 
1918  // Calculate differences between approximated i-vector and
1919  // exact i_vector for the i_p pressure level
1920  for (Index i_za = 0; i_za < N_za; i_za++) {
1921  diff_vec[i_za] = abs(cloudbox_field_mono(i_p, 0, 0, i_za, 0, 0) -
1922  i_approx_interp[i_za]);
1923  if (diff_vec[i_za] > max_diff_za[i_p]) {
1924  max_diff_za[i_p] = diff_vec[i_za];
1925  ind_za[i_p] = i_za;
1926  }
1927  }
1928  // Take maximum value of max_diff_za
1929  if (max_diff_za[i_p] > max_diff_p) {
1930  max_diff_p = max_diff_za[i_p];
1931  ind_p = i_p;
1932  }
1933  }
1934 
1935  //Transform in %
1936  max_diff =
1937  max_diff_p / cloudbox_field_mono(ind_p, 0, 0, ind_za[ind_p], 0, 0) * 100.;
1938 
1939  idx.push_back(ind_za[ind_p]);
1940  idx_unsorted = idx;
1941 
1942  i_sort.resize(idx_unsorted.nelem());
1943  get_sorted_indexes(i_sort, idx_unsorted);
1944 
1945  for (Index i = 0; i < idx_unsorted.nelem(); i++)
1946  idx[i] = idx_unsorted[i_sort[i]];
1947 
1948  za_reduced.resize(idx.nelem());
1949  }
1950 
1951  za_grid_opt.resize(idx.nelem());
1952  cloudbox_field_opt.resize(N_p, idx.nelem());
1953  for (Index i = 0; i < idx.nelem(); i++) {
1954  za_grid_opt[i] = za_grid_fine[idx[i]];
1955  cloudbox_field_opt(joker, i) = cloudbox_field_mono(joker, 0, 0, idx[i], 0, 0);
1956  }
1957 }
1958 
1963  const Agenda& spt_calc_agenda,
1964  const Index& atmosphere_dim,
1965  const Vector& za_grid,
1966  const Vector& aa_grid,
1967  const Tensor4& pnd_field,
1968  const Tensor3& t_field,
1969  const Numeric& norm_error_threshold,
1970  const Index& norm_debug,
1971  const Verbosity& verbosity) {
1972  if (atmosphere_dim != 1)
1973  throw runtime_error("Only 1D is supported here for now");
1974 
1975  CREATE_OUT0;
1976  CREATE_OUT2;
1977 
1978  // Number of zenith angles.
1979  const Index Nza = za_grid.nelem();
1980 
1981  if (za_grid[0] != 0. || za_grid[Nza - 1] != 180.)
1982  throw runtime_error("The range of *za_grid* must [0 180].");
1983 
1984  // Number of azimuth angles.
1985  const Index Naa = aa_grid.nelem();
1986 
1987  if (Naa > 1 && (aa_grid[0] != 0. || aa_grid[Naa - 1] != 360.))
1988  throw runtime_error("The range of *aa_grid* must [0 360].");
1989 
1990  // Get stokes dimension from *doit_scat_field*:
1991  const Index stokes_dim = doit_scat_field.ncols();
1992  assert(stokes_dim > 0 || stokes_dim < 5);
1993 
1994  // To use special interpolation functions for atmospheric fields we
1995  // use ext_mat_field and abs_vec_field:
1996  Tensor5 ext_mat_field(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1997  1,
1998  1,
1999  stokes_dim,
2000  stokes_dim,
2001  0.);
2002  Tensor4 abs_vec_field(
2003  cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1, stokes_dim, 0.);
2004 
2005  const Index Np = doit_scat_field.nvitrines();
2006 
2007  Tensor5 doit_scat_ext_field(doit_scat_field.nvitrines(),
2008  doit_scat_field.nshelves(),
2009  doit_scat_field.nbooks(),
2010  doit_scat_field.npages(),
2011  doit_scat_field.nrows(),
2012  0.);
2013 
2014  Index aa_index_local = 0;
2015 
2016  // Calculate scattering extinction field
2017  for (Index za_index_local = 0; za_index_local < Nza;
2018  za_index_local++) {
2019  // This function has to be called inside the angular loop, as
2020  // spt_calc_agenda takes *za_index* and *aa_index*
2021  // from the workspace.
2022  cloud_fieldsCalc(ws,
2023  ext_mat_field,
2024  abs_vec_field,
2026  za_index_local,
2027  aa_index_local,
2029  t_field,
2030  pnd_field,
2031  verbosity);
2032 
2033  for (Index p_index = 0;
2034  p_index <= (cloudbox_limits[1] - cloudbox_limits[0]);
2035  p_index++) {
2036  // For all in p_grid (in cloudbox):
2037  // I_ext = (ext_mat_field - abs_vec_field) * cloudbox_field_mono
2038  // equivalent to:
2039  // I_ext = I * (K11-a1) + Q * (K12 - a2) + U * (K13 - a3) + V * (K14 - a4)
2040  for (Index i = 0; i < stokes_dim; i++) {
2041  doit_scat_ext_field(p_index, 0, 0, za_index_local, 0) +=
2042  cloudbox_field_mono(p_index, 0, 0, za_index_local, 0, i) *
2043  (ext_mat_field(p_index, 0, 0, 0, i) -
2044  abs_vec_field(p_index, 0, 0, i));
2045  }
2046  }
2047  }
2048 
2049  Numeric corr_max = .0;
2050  Index corr_max_p_index = -1;
2051 
2052  for (Index p_index = 0; p_index < Np; p_index++) {
2053  // Calculate scattering integrals
2054  const Numeric scat_int = AngIntegrate_trapezoid(
2055  doit_scat_field(p_index, 0, 0, joker, 0, 0), za_grid);
2056 
2057  const Numeric scat_ext_int = AngIntegrate_trapezoid(
2058  doit_scat_ext_field(p_index, 0, 0, joker, 0), za_grid);
2059 
2060  // Calculate factor between scattered extinction field integral
2061  // and scattered field integral
2062  const Numeric corr_factor = scat_ext_int / scat_int;
2063 
2064  // If no scattering is present, the correction factor can become
2065  // inf or nan. We just don't apply it for those cases.
2066  if (!std::isnan(corr_factor) && !std::isinf(corr_factor)) {
2067  if (abs(corr_factor) > abs(corr_max)) {
2068  corr_max = corr_factor;
2069  corr_max_p_index = p_index;
2070  }
2071  if (norm_debug) {
2072  out0 << " DOIT corr_factor: " << 1. - corr_factor
2073  << " ( scat_ext_int: " << scat_ext_int
2074  << ", scat_int: " << scat_int << ")"
2075  << " at p_index " << p_index << "\n";
2076  }
2077  if (abs(1. - corr_factor) > norm_error_threshold) {
2078  ostringstream os;
2079  os << "ERROR: DOIT correction factor exceeds threshold (="
2080  << norm_error_threshold << "): " << setprecision(4)
2081  << 1. - corr_factor << " at p_index " << p_index << "\n";
2082  throw runtime_error(os.str());
2083  } else if (abs(1. - corr_factor) > norm_error_threshold / 2.) {
2084  out0 << " WARNING: DOIT correction factor above threshold/2: "
2085  << 1. - corr_factor << " at p_index " << p_index << "\n";
2086  }
2087 
2088  // Scale scattered field with correction factor
2089  doit_scat_field(p_index, 0, 0, joker, 0, joker) *= corr_factor;
2090  } else if (norm_debug) {
2091  out0 << " DOIT corr_factor ignored: " << 1. - corr_factor
2092  << " ( scat_ext_int: " << scat_ext_int << ", scat_int: " << scat_int
2093  << ")"
2094  << " at p_index " << p_index << "\n";
2095  }
2096  }
2097 
2098  ostringstream os;
2099  if (corr_max_p_index != -1) {
2100  os << " Max. DOIT correction factor in this iteration: " << 1. - corr_max
2101  << " at p_index " << corr_max_p_index << "\n";
2102  } else {
2103  os << " No DOIT correction performed in this iteration.\n";
2104  }
2105 
2106  if (norm_debug)
2107  out0 << os.str();
2108  else
2109  out2 << os.str();
2110 }
PropagationMatrix::MatrixAtPosition
void MatrixAtPosition(MatrixView ret, const Index iv=0, const Index iz=0, const Index ia=0) const
Sets the dense matrix.
Definition: propagationmatrix.cc:1928
Matrix
The Matrix class.
Definition: matpackI.h:1193
ARTS::Var::atmosphere_dim
Index atmosphere_dim(Workspace &ws) noexcept
Definition: autoarts.h:2510
ARTS::Var::Ppath::pos
std::size_t pos() const noexcept
Definition: autoarts.h:1300
ARTS::Var::abs_vec
StokesVector abs_vec(Workspace &ws) noexcept
Definition: autoarts.h:2239
ARTS::Var::ppath_step
Ppath ppath_step(Workspace &ws) noexcept
Definition: autoarts.h:5213
compute_transmission_matrix_from_averaged_matrix_at_frequency
void compute_transmission_matrix_from_averaged_matrix_at_frequency(MatrixView T, const Numeric &r, const PropagationMatrix &averaged_propagation_matrix, const Index iv, const Index iz, const Index ia)
Compute the matrix exponent as the transmission matrix of this propagation matrix.
Definition: propagationmatrix.cc:272
ARTS::Var::z_field
Tensor3 z_field(Workspace &ws) noexcept
Definition: autoarts.h:7690
rte_step_doit_replacement
void rte_step_doit_replacement(VectorView stokes_vec, MatrixView trans_mat, const PropagationMatrix &ext_mat_av, const StokesVector &abs_vec_av, ConstVectorView sca_vec_av, const Numeric &lstep, const Numeric &rtp_planck_value, const bool &trans_is_precalc)
Solves monochromatic VRTE for an atmospheric slab with constant conditions.
Definition: doit.cc:62
ppath_init_structure
void ppath_init_structure(Ppath &ppath, const Index &atmosphere_dim, const Index &np)
Initiates a Ppath structure to hold the given number of points.
Definition: ppath.cc:1426
ARTS::Group::PropagationMatrix
PropagationMatrix PropagationMatrix
Definition: autoarts.h:93
StokesVector
Stokes vector is as Propagation matrix but only has 4 possible values.
Definition: propagationmatrix.h:1075
MatrixView
The MatrixView class.
Definition: matpackI.h:1093
ARTS::Var::ppath_step_agenda
Agenda ppath_step_agenda(Workspace &ws) noexcept
Definition: autoarts.h:5220
auto_md.h
ARTS::Var::doit_scat_field
Tensor6 doit_scat_field(Workspace &ws) noexcept
Definition: autoarts.h:3167
RAD2DEG
const Numeric RAD2DEG
interp_poly
Numeric interp_poly(ConstVectorView x, ConstVectorView y, const Numeric &x_i, const GridPos &gp)
Polynomial interpolation.
Definition: interpolation.cc:2723
gridpos
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
Definition: interpolation.cc:156
Tensor3
The Tensor3 class.
Definition: matpackIII.h:339
id_mat
void id_mat(MatrixView I)
Identity Matrix.
Definition: lin_alg.cc:2240
itw2p
void itw2p(VectorView p_values, ConstVectorView p_grid, const ArrayOfGridPos &gp, ConstMatrixView itw)
Converts interpolation weights to pressures.
Definition: special_interp.cc:718
ConstTensor5View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackV.cc:56
ARTS::Var::lat_grid
Vector lat_grid(Workspace &ws) noexcept
Definition: autoarts.h:3962
joker
const Joker joker
ARTS::Var::surface_rmatrix
Tensor4 surface_rmatrix(Workspace &ws) noexcept
Definition: autoarts.h:6800
ARTS::Var::pnd_field
Tensor4 pnd_field(Workspace &ws) noexcept
Definition: autoarts.h:5081
interp
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
Definition: interpolation.cc:970
oem::Matrix
invlib::Matrix< ArtsMatrix > Matrix
invlib wrapper type for ARTS matrices.
Definition: oem.h:34
abs
#define abs(x)
Definition: legacy_continua.cc:20626
ARTS::Var::verbosity
Verbosity verbosity(Workspace &ws) noexcept
Definition: autoarts.h:7112
PropagationMatrix::MatrixInverseAtPosition
void MatrixInverseAtPosition(MatrixView ret, const Index iv=0, const Index iz=0, const Index ia=0) const
Return the matrix inverse at the position.
Definition: propagationmatrix.cc:1506
mult
void mult(ComplexVectorView y, const ConstComplexMatrixView &M, const ConstComplexVectorView &x)
Matrix-Vector Multiplication.
Definition: complex.cc:1579
opt_prop_bulkCalc
void opt_prop_bulkCalc(PropagationMatrix &ext_mat, StokesVector &abs_vec, const ArrayOfPropagationMatrix &ext_mat_spt, const ArrayOfStokesVector &abs_vec_spt, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &)
WORKSPACE METHOD: opt_prop_bulkCalc.
Definition: m_optproperties.cc:857
swap
void swap(ComplexVector &v1, ComplexVector &v2)
Swaps two objects.
Definition: complex.cc:731
chk_not_empty
void chk_not_empty(const String &x_name, const Agenda &x)
chk_not_empty
Definition: check_input.cc:694
ARTS::Var::f_index
Index f_index(Workspace &ws) noexcept
Definition: autoarts.h:3464
ARTS::Var::cloudbox_limits
ArrayOfIndex cloudbox_limits(Workspace &ws) noexcept
Definition: autoarts.h:2762
PropagationMatrix
Definition: propagationmatrix.h:87
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.cc:404
cloud_ppath_update1D_noseq
void cloud_ppath_update1D_noseq(Workspace &ws, Tensor6View cloudbox_field_mono, const Index &p_index, const Index &za_index, ConstVectorView za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View cloudbox_field_mono_old, ConstTensor6View doit_scat_field, const Agenda &propmat_clearsky_agenda, ConstTensor4View vmr_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, ConstVectorView p_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Agenda &surface_rtprop_agenda, const Index &scat_za_interp, const Verbosity &verbosity)
Calculation of radiation field along a propagation path step for specified zenith direction and press...
Definition: doit.cc:457
is_singular
bool is_singular(ConstMatrixView A)
Checks if a square matrix is singular.
Definition: logic.cc:295
doit.h
Radiative transfer in cloudbox.
ARTS::Var::rtp_vmr
Vector rtp_vmr(Workspace &ws) noexcept
Definition: autoarts.h:5826
ARTS::Var::za_index
Index za_index(Workspace &ws) noexcept
Definition: autoarts.h:7793
ARTS::Var::stokes_dim
Index stokes_dim(Workspace &ws) noexcept
Definition: autoarts.h:6650
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:429
ArrayOfRetrievalQuantity
Array< RetrievalQuantity > ArrayOfRetrievalQuantity
Definition: jacobian.h:402
ARTS::Var::cloudbox_field_mono
Tensor6 cloudbox_field_mono(Workspace &ws) noexcept
Definition: autoarts.h:2699
CREATE_OUT2
#define CREATE_OUT2
Definition: messages.h:206
ARTS::Var::iy
Matrix iy(Workspace &ws) noexcept
Definition: autoarts.h:3690
Tensor4
The Tensor4 class.
Definition: matpackIV.h:421
array.h
This file contains the definition of Array.
cloud_ppath_update1D
void cloud_ppath_update1D(Workspace &ws, Tensor6View cloudbox_field_mono, const Index &p_index, const Index &za_index, ConstVectorView za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &propmat_clearsky_agenda, ConstTensor4View vmr_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, ConstVectorView p_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Agenda &surface_rtprop_agenda, const Index &scat_za_interp, const Verbosity &verbosity)
Calculates radiation field along a propagation path step for specified zenith direction and pressure ...
Definition: doit.cc:301
is_size
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
Definition: logic.cc:79
Ppath
The structure to describe a propagation path and releated quantities.
Definition: ppath.h:48
ARTS::Var::surface_rtprop_agenda
Agenda surface_rtprop_agenda(Workspace &ws) noexcept
Definition: autoarts.h:6807
Agenda
The Agenda class.
Definition: agenda_class.h:44
PropagationMatrix::AddAverageAtPosition
void AddAverageAtPosition(ConstMatrixView mat1, ConstMatrixView mat2, const Index iv=0, const Index iz=0, const Index ia=0)
Add the average of the two input at position.
Definition: propagationmatrix.cc:1610
ConstTensor4View
A constant view of a Tensor4.
Definition: matpackIV.h:133
Tensor3View
The Tensor3View class.
Definition: matpackIII.h:239
Array
This can be used to make arrays out of anything.
Definition: array.h:108
za_gridOpt
void za_gridOpt(Vector &za_grid_opt, Matrix &cloudbox_field_opt, ConstVectorView za_grid_fine, ConstTensor6View cloudbox_field_mono, const Numeric &acc, const Index &scat_za_interp)
Optimize the zenith angle grid.
Definition: doit.cc:1853
get_sorted_indexes
void get_sorted_indexes(ArrayOfIndex &sorted, const T &data)
get_sorted_indexes
Definition: sorting.h:73
interp_cloud_coeff1D
void interp_cloud_coeff1D(Tensor3View ext_mat_int, MatrixView abs_vec_int, MatrixView sca_vec_int, MatrixView cloudbox_field_mono_int, VectorView t_int, MatrixView vmr_list_int, VectorView p_int, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, ConstTensor6View doit_scat_field, ConstTensor6View cloudbox_field_mono, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView p_grid, const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, ConstVectorView za_grid, const Index &scat_za_interp, const Verbosity &verbosity)
Interpolate all inputs of the VRTE on a propagation path step.
Definition: doit.cc:1695
agenda_class.h
Declarations for agendas.
CREATE_OUT3
#define CREATE_OUT3
Definition: messages.h:207
CREATE_OUT0
#define CREATE_OUT0
Definition: messages.h:204
messages.h
Declarations having to do with the four output streams.
ARTS::Var::rte_pos
Vector rte_pos(Workspace &ws) noexcept
Definition: autoarts.h:5672
gridpos_upperend_check
void gridpos_upperend_check(GridPos &gp, const Index &ie)
gridpos_upperend_check
Definition: interpolation.cc:589
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:51
VectorView
The VectorView class.
Definition: matpackI.h:610
surface_rtprop_agendaExecute
void surface_rtprop_agendaExecute(Workspace &ws, Numeric &surface_skin_t, Matrix &surface_emission, Matrix &surface_los, Tensor4 &surface_rmatrix, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Agenda &input_agenda)
Definition: auto_md.cc:25033
is_inside_cloudbox
bool is_inside_cloudbox(const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, const bool include_boundaries)
Definition: cloudbox.cc:579
cloud_ppath_update3D
void cloud_ppath_update3D(Workspace &ws, Tensor6View cloudbox_field_mono, const Index &p_index, const Index &lat_index, const Index &lon_index, const Index &za_index, const Index &aa_index, ConstVectorView za_grid, ConstVectorView aa_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &propmat_clearsky_agenda, ConstTensor4View vmr_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Index &, const Verbosity &verbosity)
Radiative transfer calculation along a path inside the cloudbox (3D).
Definition: doit.cc:1108
ARTS::Var::vmr_field
Tensor4 vmr_field(Workspace &ws) noexcept
Definition: autoarts.h:7130
ARTS::Var::rte_los
Vector rte_los(Workspace &ws) noexcept
Definition: autoarts.h:5651
physics_funcs.h
This file contains declerations of functions of physical character.
ARTS::Var::p_grid
Vector p_grid(Workspace &ws) noexcept
Definition: autoarts.h:4763
ConstTensor4View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:66
PropagationMatrix::NumberOfFrequencies
Index NumberOfFrequencies() const
The number of frequencies of the propagation matrix.
Definition: propagationmatrix.h:204
spt_calc_agendaExecute
void spt_calc_agendaExecute(Workspace &ws, ArrayOfPropagationMatrix &ext_mat_spt, ArrayOfStokesVector &abs_vec_spt, const Index scat_p_index, const Index scat_lat_index, const Index scat_lon_index, const Numeric rtp_temperature, const Index za_index, const Index aa_index, const Agenda &input_agenda)
Definition: auto_md.cc:24979
ConstTensor6View
A constant view of a Tensor6.
Definition: matpackVI.h:149
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
lin_alg.h
Linear algebra functions.
ARTS::Var::cloudbox_field_mono_old
Tensor6 cloudbox_field_mono_old(Workspace &ws) noexcept
Definition: autoarts.h:2721
Verbosity
Definition: messages.h:49
Tensor5View
The Tensor5View class.
Definition: matpackV.h:333
propmat_clearsky_agendaExecute
void propmat_clearsky_agendaExecute(Workspace &ws, ArrayOfPropagationMatrix &propmat_clearsky, ArrayOfStokesVector &nlte_source, ArrayOfPropagationMatrix &dpropmat_clearsky_dx, ArrayOfStokesVector &dnlte_dx_source, ArrayOfStokesVector &nlte_dsource_dx, const ArrayOfRetrievalQuantity &jacobian_quantities, const Vector &f_grid, const Vector &rtp_mag, const Vector &rtp_los, const Numeric rtp_pressure, const Numeric rtp_temperature, const EnergyLevelMap &rtp_nlte, const Vector &rtp_vmr, const Agenda &input_agenda)
Definition: auto_md.cc:23513
math_funcs.h
geodetic.h
ARTS::Var::refellipsoid
Vector refellipsoid(Workspace &ws) noexcept
Definition: autoarts.h:5519
ARTS::Var::f_grid
Vector f_grid(Workspace &ws) noexcept
Definition: autoarts.h:3449
ARTS::Var::ext_mat
PropagationMatrix ext_mat(Workspace &ws) noexcept
Definition: autoarts.h:3390
EnergyLevelMap
Definition: energylevelmap.h:60
propagationmatrix.h
Stuff related to the propagation matrix.
cloud_fieldsCalc
void cloud_fieldsCalc(Workspace &ws, Tensor5View ext_mat_field, Tensor4View abs_vec_field, const Agenda &spt_calc_agenda, const Index &za_index, const Index &aa_index, const ArrayOfIndex &cloudbox_limits, ConstTensor3View t_field, ConstTensor4View pnd_field, const Verbosity &verbosity)
Calculate ext_mat, abs_vec for all points inside the cloudbox for one.
Definition: doit.cc:163
Matrix::resize
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1056
AngIntegrate_trapezoid
Numeric AngIntegrate_trapezoid(ConstMatrixView Integrand, ConstVectorView za_grid, ConstVectorView aa_grid)
AngIntegrate_trapezoid.
Definition: math_funcs.cc:296
ARTS::Var::za_grid
Vector za_grid(Workspace &ws) noexcept
Definition: autoarts.h:7771
ARTS::Var::surface_emission
Matrix surface_emission(Workspace &ws) noexcept
Definition: autoarts.h:6700
ARTS::Var::rtp_pressure
Numeric rtp_pressure(Workspace &ws) noexcept
Definition: autoarts.h:5790
ARTS::Var::lon_grid
Vector lon_grid(Workspace &ws) noexcept
Definition: autoarts.h:4090
ARTS::Var::ppath_lmax
Numeric ppath_lmax(Workspace &ws) noexcept
Definition: autoarts.h:5183
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:982
cloudbox.h
Internal cloudbox functions.
ARTS::Var::ppath_lraytrace
Numeric ppath_lraytrace(Workspace &ws) noexcept
Definition: autoarts.h:5195
Tensor5
The Tensor5 class.
Definition: matpackV.h:506
planck
Numeric planck(const Numeric &f, const Numeric &t)
planck
Definition: physics_funcs.cc:269
oem::Vector
invlib::Vector< ArtsVector > Vector
invlib wrapper type for ARTS vectors.
Definition: oem.h:32
Range
The range class.
Definition: matpackI.h:160
ppath_step_agendaExecute
void ppath_step_agendaExecute(Workspace &ws, Ppath &ppath_step, const Numeric ppath_lmax, const Numeric ppath_lraytrace, const Vector &f_grid, const Agenda &input_agenda)
Definition: auto_md.cc:24832
ConstTensor5View::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackV.cc:53
ppath.h
Propagation path structure and functions.
opt_prop_sum_propmat_clearsky
void opt_prop_sum_propmat_clearsky(PropagationMatrix &ext_mat, StokesVector &abs_vec, const ArrayOfPropagationMatrix &propmat_clearsky)
Get optical properties from propmat_clearsky.
Definition: optproperties.cc:2414
ARTS::Var::rtp_temperature
Numeric rtp_temperature(Workspace &ws) noexcept
Definition: autoarts.h:5807
cloud_ppath_update1D_planeparallel
void cloud_ppath_update1D_planeparallel(Workspace &ws, Tensor6View cloudbox_field_mono, const Index &p_index, const Index &za_index, ConstVectorView za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &propmat_clearsky_agenda, ConstTensor4View vmr_field, ConstVectorView p_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Verbosity &verbosity)
Radiative transfer calculation inside cloudbox for planeparallel case.
Definition: doit.cc:615
logic.h
Header file for logic.cc.
cloudbox_field_ngAcceleration
void cloudbox_field_ngAcceleration(Tensor6 &cloudbox_field_mono, const ArrayOfTensor6 &acceleration_input, const Index &accelerated, const Verbosity &)
Convergence acceleration.
Definition: doit.cc:1620
PropagationMatrix::StokesDimensions
Index StokesDimensions() const
The stokes dimension of the propagation matrix.
Definition: propagationmatrix.h:201
doit_scat_fieldNormalize
void doit_scat_fieldNormalize(Workspace &ws, Tensor6 &doit_scat_field, const Tensor6 &cloudbox_field_mono, const ArrayOfIndex &cloudbox_limits, const Agenda &spt_calc_agenda, const Index &atmosphere_dim, const Vector &za_grid, const Vector &aa_grid, const Tensor4 &pnd_field, const Tensor3 &t_field, const Numeric &norm_error_threshold, const Index &norm_debug, const Verbosity &verbosity)
Normalization of scattered field.
Definition: doit.cc:1959
rte.h
Declaration of functions in rte.cc.
ARTS::Var::t_field
Tensor3 t_field(Workspace &ws) noexcept
Definition: autoarts.h:6947
Workspace
Workspace class.
Definition: workspace_ng.h:40
ConstTensor3View
A constant view of a Tensor3.
Definition: matpackIII.h:132
PropagationMatrix::Kjj
VectorView Kjj(const Index iz=0, const Index ia=0)
Vector view to diagonal elements.
Definition: propagationmatrix.h:799
Tensor4View
The Tensor4View class.
Definition: matpackIV.h:284
special_interp.h
Header file for special_interp.cc.
StokesVector::AddAverageAtPosition
void AddAverageAtPosition(ConstVectorView vec1, ConstVectorView vec2, const Index iv=0, const Index iz=0, const Index ia=0)
Add the average of both inputs at position.
Definition: propagationmatrix.h:1300
cloud_RT_no_background
void cloud_RT_no_background(Workspace &ws, Tensor6View cloudbox_field_mono, const Agenda &propmat_clearsky_agenda, const Ppath &ppath_step, ConstVectorView t_int, ConstMatrixView vmr_list_int, ConstTensor3View ext_mat_int, ConstMatrixView abs_vec_int, ConstMatrixView sca_vec_int, ConstMatrixView cloudbox_field_mono_int, ConstVectorView p_int, const ArrayOfIndex &cloudbox_limits, ConstVectorView f_grid, const Index &f_index, const Index &p_index, const Index &lat_index, const Index &lon_index, const Index &za_index, const Index &aa_index, const Verbosity &verbosity)
Calculates RT in the cloudbox (1D)
Definition: doit.cc:1382
ARTS::Var::propmat_clearsky_agenda
Agenda propmat_clearsky_agenda(Workspace &ws) noexcept
Definition: autoarts.h:5405
cloud_RT_surface
void cloud_RT_surface(Workspace &ws, Tensor6View cloudbox_field_mono, const Agenda &surface_rtprop_agenda, ConstVectorView f_grid, const Index &f_index, const Index &stokes_dim, const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, ConstVectorView za_grid, const Index &za_index)
Calculates RT in the cloudbox.
Definition: doit.cc:1547
ARTS::Var::x
Vector x(Workspace &ws) noexcept
Definition: autoarts.h:7346
PI
const Numeric PI
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
ARTS::Var::surface_skin_t
Numeric surface_skin_t(Workspace &ws) noexcept
Definition: autoarts.h:6877
Tensor6
The Tensor6 class.
Definition: matpackVI.h:1088
check_input.h
ARTS::Var::surface_los
Matrix surface_los(Workspace &ws) noexcept
Definition: autoarts.h:6714
ARTS::Var::aa_index
Index aa_index(Workspace &ws) noexcept
Definition: autoarts.h:1733
ppath_what_background
Index ppath_what_background(const Ppath &ppath)
Returns the case number for the radiative background.
Definition: ppath.cc:1494
Vector
The Vector class.
Definition: matpackI.h:860
ARTS::Var::propmat_clearsky
ArrayOfPropagationMatrix propmat_clearsky(Workspace &ws) noexcept
Definition: autoarts.h:5398
ARTS::Var::aa_grid
Vector aa_grid(Workspace &ws) noexcept
Definition: autoarts.h:1717
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:476
sorting.h
Contains sorting routines.
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:195
ARTS::Group::StokesVector
StokesVector StokesVector
Definition: autoarts.h:101
interpweights
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
Definition: interpolation.cc:741
StokesVector::VectorAtPosition
VectorView VectorAtPosition(const Index iv=0, const Index iz=0, const Index ia=0)
Get a vectorview to the position.
Definition: propagationmatrix.h:1266
ConstTensor5View
A constant view of a Tensor5.
Definition: matpackV.h:143
refell2r
Numeric refell2r(ConstVectorView refellipsoid, const Numeric &lat)
refell2r
Definition: geodetic.cc:1135
matpackVII.h
Tensor6View
The Tensor6View class.
Definition: matpackVI.h:621
ARTS::Var::spt_calc_agenda
Agenda spt_calc_agenda(Workspace &ws) noexcept
Definition: autoarts.h:6594
xml_io.h
This file contains basic functions to handle XML data files.